- Added screenhsots

- Fixed another end of level crash related to killing sprites after nextlevel()
- Fixed crash in adjustx() when mosnters were in water
- Should turn off player->climbing when the pink Turncloud hits them
- If player isn't fast, force next mosterkill powerup to be speed
This commit is contained in:
Rob Pearce 2008-10-07 07:58:36 +00:00
parent f2832e4da4
commit 095c92d17f
10 changed files with 220 additions and 130 deletions

4
defs.h
View File

@ -83,6 +83,8 @@
#define NETSPEED 9 // how fast the player's net moves
#define POWERUPTIME 15 // # secs before a powerup appears
#define PLAYERFAST 2 // how fast player goes with speed powerup
#define CANNONSIZE 10
@ -286,7 +288,7 @@
#define LV_CLEAR 1 // all monsters dead
#define LV_WAIT 2 // LEVEL COMPLETE displayed, delay to collect fruits
#define LV_FINAL 3 // delay 5 seconds more...
#define LV_CLOUD 4 // cloud appearing
#define LV_CLOUD 4 // cloud appearing and tracking player
#define LV_CLOUDLOOP 6 // cloud looping
#define LV_NEXTLEV 7 // cloud done , nextlevel() in 5 seconds
#define LV_GAMEOVER 8 // No lives left.

View File

@ -4,9 +4,9 @@
4,level4.dat,Bridge School
5,level5.dat,Hole in the Hill
6,level6.dat,Roller School
7,level7.dat,Platforms and Ladders
8,level9.dat,The Garden
9,level10.dat,Planks
7,level7.dat,Platforms and Ladders
10,level11.dat,The Hive
11,level5.5.dat,Spike Pit
12,level7.5.dat,Snake Holes

219
rc.c
View File

@ -51,7 +51,6 @@ int fruittypes[] = {
/* the order in which powerups will appear */
int poweruptypes[] = {
P_SPEED,
P_NUMNETS,
P_BELL,
P_BIGNET,
@ -98,7 +97,7 @@ int toggletimer = 0;
int main (int argc, char **argv) {
Uint8 *keys;
sprite_t *s,*nextsprite;
//sprite_t *s,*nextsprite;
char filename[BUFLEN];
int i;
int *animtile;
@ -255,38 +254,8 @@ int main (int argc, char **argv) {
while (1) {
removeall();
/* check for death & update movement status*/
for (s = sprite ; s ; s = nextsprite) {
s->moved = MV_NONE;
nextsprite = s->next;
if (s->dead == D_FINAL) {
if (s == player) {
if (player->lives > 0) {
/* if we have lives left, go back to start position */
setdefaults(s);
s->x = (curlevel->p1x * TILEW) + (TILEW/2);
s->y = (curlevel->p1y * TILEH) + (TILEH/2);
s->invuln = INVULNTIME;
} else {
if (levelcomplete == LV_GAMEOVER) {
// TODO: Wait until "game over" text is gone, then slowly fade out the screen
// then show hiscores
// then back to title screen
} else {
addoutlinetext(320,240,TEXTSIZE_GAMEOVER,"Game Over",&red,&black,GAMEOVERDELAY);
levelcomplete = LV_GAMEOVER;
stopmusic();
playfx(FX_GAMEOVER);
}
}
} else {
killsprite(s);
// check for level completion
checklevelend();
}
}
}
// check for sprite death and update moevment counters
checksprites();
/* check for end of level */
if (levelcomplete == LV_CLEAR) {
@ -370,6 +339,30 @@ int main (int argc, char **argv) {
if (keys[SDLK_n]) {
if (toggletimer == 0) {
// nextlevel();
sprite_t *s2, *nexts;
// make the screen shake
player->powerup = PW_BOMB;
player->timer1 = BOMBSHAKETIME;
// kill all monsters
playfx(FX_BOOM);
sprintf(tempm, "KABOOM!!");
addoutlinetext(player->x,player->y - player->img->h/2, TEXTSIZE_BOMB, tempm,&red,&yellow,POINTSDELAY);
for (s2 = sprite; s2 ; s2 = nexts) {
nexts = s2->next;
if (isbullet(s2->id)) {
s2->dead = D_FINAL;
} else if (ismonster(s2->id)) {
s2->willbecome = P_DIAMOND;
if (s2->caughtby) {
s2->caughtby = NULL;
player->netcaught--;
}
die(s2);
}
}
toggletimer = 50;
}
}
@ -598,9 +591,9 @@ int main (int argc, char **argv) {
}
// move sprites
for (s = sprite; s ; s = s->next) {
movesprite(s);
}
moveallsprites();
// animate text
movetext();
@ -609,11 +602,13 @@ int main (int argc, char **argv) {
dogravity(player);
dotileeffects(player);
} else {
sprite_t *s;
switch (levelcomplete) {
case LV_INPROGRESS:
case LV_CLEAR:
case LV_WAIT:
case LV_FINAL:
case LV_CLOUD:
/* gravity */
for (s = sprite ; s ; s = s->next) {
dogravity(s);
@ -654,12 +649,7 @@ int main (int argc, char **argv) {
}
}
/* check collisions for player and effects */
for (s = sprite ; s ; s = s->next) {
if ((s == player) || needscollisions(s->id)) {
checkcollide(s);
}
}
checkcollideall();
}
@ -670,6 +660,7 @@ int main (int argc, char **argv) {
if (timer % 2 == 0) {
int found;
sprite_t *s;
// find cannon
found = B_FALSE;
for (s = sprite; s ; s = s->next) {
@ -678,6 +669,7 @@ int main (int argc, char **argv) {
break;
}
}
if (!found) {
printf("weird error - no cannon!!\n");
player->powerup = B_FALSE;
@ -737,14 +729,10 @@ int main (int argc, char **argv) {
}
/* draw non-puff sprites */
for (s = sprite ; s ; s = s->next) {
if (s->id != P_PUFF) drawsprite(s);
}
/* draw puff sprites */
for (s = sprite ; s ; s = s->next) {
if (s->id == P_PUFF) drawsprite(s);
}
// draw sprites
drawallsprites();
/* draw text */
drawtext();
@ -1429,34 +1417,37 @@ void bouncesprite(sprite_t *s) {
}
void movesprite(sprite_t *s) {
// returns TRUE if we finished the level
int movesprite(sprite_t *s) {
int rv;
tiletype_t *tt;
if (levelcomplete == LV_INIT) {
// most things can't move in this state
//if ((s->id != P_PUFF) && (s != player)) {
if (!iseffect(s->id) && (s != player)) {
// caught or dead sprites can move, in case
// the player catches something before level start time
if ((!s->caughtby) && (!s->dead)) return;
if ((!s->caughtby) && (!s->dead)) return B_FALSE;
}
}
// only player can move if you have a clock
if (player->powerup == PW_CLOCK) {
if (!iseffect(s->id) && (s != player) && !s->caughtby && !s->dead) {
return;
return B_FALSE;
}
}
// iced monsters can't move
if (ismonster(s->id) && s->iced) {
return;
return B_FALSE;
}
/* timer */
if (s->doomcount) {
if (s->id == P_PUFF) printf("PUFF WITH DOOMCOUNT!\n");
s->doomcount--;
if (s->doomcount == 0) {
s->dead = D_FINAL;
@ -1496,7 +1487,7 @@ void movesprite(sprite_t *s) {
s->x = s->caughtby->x + (s->caughtby->img->w/2) * -(s->caughtby->dir);
}
}
return;
return B_FALSE;
} else if (s->dead == D_INITIAL) { /* just set to dead */
if (s == boss) {
// flash
@ -1519,7 +1510,7 @@ void movesprite(sprite_t *s) {
s->jumping = 1;
}
}
return;
return B_FALSE;
} else if (s->dead == D_BOUNCING) { /* dying */
if (s == player) {
/* shoot up in the air, then fall */
@ -1549,7 +1540,7 @@ void movesprite(sprite_t *s) {
}
}
}
return;
return B_FALSE;
} else if (s->dead == D_LASTBOUNCE) { /* final fall */
if (s == player) {
/* just delay... */
@ -1583,7 +1574,7 @@ void movesprite(sprite_t *s) {
}
}
}
return;
return B_FALSE;
} else if (s->teleporting > 0) {
SDL_Surface *ts;
if (timer % 2 == 0) {
@ -1631,7 +1622,7 @@ void movesprite(sprite_t *s) {
}
} else if (s->jumping) {
movex(s, s->jumpdir*getspeed(s));
return;
return B_FALSE;
}
if (!iseffect(s->id)) {
@ -1653,7 +1644,7 @@ void movesprite(sprite_t *s) {
s->jumping = 1;
s->jumpspeed = s->willjumpspeed;
if (s->jumpdir != 0) s->dir = s->jumpdir;
return;
return B_FALSE;
} else if (s->jumptimer % 20 == 0) {
s->dir = -s->dir;
}
@ -1698,6 +1689,7 @@ void movesprite(sprite_t *s) {
}
}
} else if (s->timer1 >= PUFFFRAMES) {
s->timer1 = 999; // TODO: REMOVE THIS - debugging!
s->dead = D_FINAL;
}
}
@ -2285,6 +2277,8 @@ void movesprite(sprite_t *s) {
double amtleft;
double xdis,ydis,dis;
int turnsleft;
if (!player->dead) {
/*
If small, grow and move towards player's feet (at a speed
which will get us there when we are fully grown.
@ -2345,11 +2339,17 @@ printf("init angle = %0.2f\n", s->angle / (M_PI/180));
s->x += s->xs;
s->y += s->ys;
}
}
} else if (levelcomplete == LV_CLOUDLOOP) {
// stick player to us
player->x = s->x;
player->y = s->y - (imageset[P_PINKCLOUD].img[F_WALK1]->h / 2);
// turn off payer attributes
player->climbing = B_FALSE;
player->netting = B_FALSE;
player->slamming = B_FALSE;
// keep turning towards exit (2 degrees at a time)
s->angle += (PCTURN * (M_PI/180));
@ -2401,12 +2401,10 @@ printf("init angle = %0.2f\n", s->angle / (M_PI/180));
if (s->xs > abs(s->ys)) {
// level clear!
levelcomplete = LV_NEXTLEV;
nextlevel();
// kill ourselves
s->dead = D_FINAL;
return B_TRUE;
}
}
} else {
} else if ((levelcomplete == LV_INIT) || (levelcomplete == LV_INPROGRESS)) {
SDL_Surface *ts;
// shrink
s->size -= ((double)PCSHRINKSPEED);
@ -2478,6 +2476,7 @@ printf("init angle = %0.2f\n", s->angle / (M_PI/180));
}
}
return B_FALSE;
}
void dotileeffects(sprite_t *s) {
@ -3544,7 +3543,8 @@ void dogravity(sprite_t *s) {
if (!s->swimming) {
s->swimming = B_TRUE;
playfx(FX_SPLASH);
adjustx(s, F_SWIM1);
if (s == player) adjustx(s, F_SWIM1);
else adjustx(s, F_WALK1);
}
} else {
if (s->swimming) {
@ -3856,7 +3856,7 @@ void dogravity(sprite_t *s) {
pointsinc *= 2;
pointsinc += 32000; // change?
pointsinc = 64000; // hardcode for a boss
psize += 10;
gotsomething++;
@ -3886,11 +3886,17 @@ void dogravity(sprite_t *s) {
if (boss) { // no fruits on boss levels
s2->willbecome = -1;
} else {
// if player isn't fast, give a speed.
if (player->speed != PLAYERFAST) {
s2->willbecome = P_SPEED;
} else {
// otherwise use normal powerup counter
s2->willbecome = poweruptypes[curpoweruptype];
if (poweruptypes[++curpoweruptype] == -1) {
curpoweruptype = 0;
}
}
}
} else if (player->powerup == PW_MACE) {
s2->willbecome = P_DIAMOND;
} else { // should never happen
@ -4063,7 +4069,7 @@ void adjustheight(sprite_t *s) {
int dofruiteffect(sprite_t *s) {
if (s->id == P_SPEED) {
playfx(FX_POWERUP);
player->speed = 2;
player->speed = PLAYERFAST;
addoutlinetext(s->x,s->y - s->img->h/2, TEXTSIZE_POINTS, "Speed up!", &white,&black,POINTSDELAY);
return B_TRUE;
} else if (s->id == P_NUMNETS) {
@ -4550,6 +4556,7 @@ void dumpsprites(void) {
if (isbullet(s->id)) printf("BULLET, ");
if (iseffect(s->id)) printf("EFFECT, ");
printf(")\n");
i++;
}
printf("--------\n");
@ -4713,3 +4720,79 @@ void adjustx(sprite_t *s,int framenum) {
s->x += diff;
}
}
/* check for death & update movement status*/
void checksprites(void) {
sprite_t *s, *nextsprite;
for (s = sprite ; s ; s = nextsprite) {
s->moved = MV_NONE;
nextsprite = s->next;
if (s->dead == D_FINAL) {
if (s == player) {
if (player->lives > 0) {
/* if we have lives left, go back to start position */
setdefaults(s);
s->x = (curlevel->p1x * TILEW) + (TILEW/2);
s->y = (curlevel->p1y * TILEH) + (TILEH/2);
s->invuln = INVULNTIME;
} else {
if (levelcomplete == LV_GAMEOVER) {
// TODO: Wait until "game over" text is gone, then slowly fade out the screen
// then show hiscores
// then back to title screen
} else {
addoutlinetext(320,240,TEXTSIZE_GAMEOVER,"Game Over",&red,&black,GAMEOVERDELAY);
levelcomplete = LV_GAMEOVER;
stopmusic();
playfx(FX_GAMEOVER);
}
}
} else {
if ((s->id == P_PUFF) && (s->timer1 != 999)) {
printf("puff deid without changing!!!\n");
}
killsprite(s);
// check for level completion
checklevelend();
}
}
}
// check if we've hit the cloud
if (levelcomplete == LV_NEXTLEV) {
nextlevel();
}
}
void moveallsprites(void) {
sprite_t *s;
for (s = sprite; s ; s = s->next) {
movesprite(s);
}
}
void checkcollideall(void) {
sprite_t *s;
/* check collisions for player and effects */
for (s = sprite ; s ; s = s->next) {
if ((s == player) || needscollisions(s->id)) {
checkcollide(s);
}
}
}
void drawallsprites(void) {
sprite_t *s;
/* draw non-puff sprites */
for (s = sprite ; s ; s = s->next) {
if (s->id != P_PUFF) drawsprite(s);
}
/* draw puff sprites */
for (s = sprite ; s ; s = s->next) {
if (s->id == P_PUFF) drawsprite(s);
}
}

6
rc.h
View File

@ -14,7 +14,7 @@ void dogravity(sprite_t *s);
void dotileeffects(sprite_t *s);
int movex(sprite_t *s,double amt);
void bouncesprite(sprite_t *s);
void movesprite(sprite_t *s);
int movesprite(sprite_t *s);
int isinwater(sprite_t *s);
int isinwaterpoint(int x, int y);
int isroofabove(sprite_t *s);
@ -52,4 +52,8 @@ char *addcommas(char *buffer, int num);
void addscore(sprite_t *s, int amt);
void doice(void);
void checklevelend(void);
void checksprites(void);
void moveallsprites(void);
void checkcollideall(void);
void drawallsprites(void);

BIN
screenshots/kingrat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 333 KiB

BIN
screenshots/rc_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 KiB

Binary file not shown.

Binary file not shown.

View File

@ -290,6 +290,7 @@ int loadlevel(int wnum, int lnum) {
level->initm[level->nummonsters].starty = y*TILEH+(TILEH-2)+2;
level->initm[level->nummonsters].id = monid;
if (ismonster(monid)) numenemies++;
if (monid == P_HELP) {
@ -663,7 +664,7 @@ int loadlevel(int wnum, int lnum) {
if (level->initm[i].id == P_HELP) {
strncpy(name, level->initm[i].help, MIDBUFLEN);
} else {
strcpy(name, "Monster");
sprintf(name, "Monster-%d",i);
}
if (ismonster(level->initm[i].id)) {
@ -2363,7 +2364,7 @@ int isnettable(int monid) {
int getbosshealth(int mid) {
switch (mid) {
case P_KINGRAT:
return 10;
return 8;
}
return 0;
}

View File

@ -1,4 +1,4 @@
bgfile backgrounds/forest.png
bgfile backgrounds/fire1.png
bg 0
hurryup 30
help