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

View File

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

225
rc.c
View File

@ -51,7 +51,6 @@ int fruittypes[] = {
/* the order in which powerups will appear */ /* the order in which powerups will appear */
int poweruptypes[] = { int poweruptypes[] = {
P_SPEED,
P_NUMNETS, P_NUMNETS,
P_BELL, P_BELL,
P_BIGNET, P_BIGNET,
@ -98,7 +97,7 @@ int toggletimer = 0;
int main (int argc, char **argv) { int main (int argc, char **argv) {
Uint8 *keys; Uint8 *keys;
sprite_t *s,*nextsprite; //sprite_t *s,*nextsprite;
char filename[BUFLEN]; char filename[BUFLEN];
int i; int i;
int *animtile; int *animtile;
@ -255,38 +254,8 @@ int main (int argc, char **argv) {
while (1) { while (1) {
removeall(); removeall();
/* check for death & update movement status*/ // check for sprite death and update moevment counters
for (s = sprite ; s ; s = nextsprite) { checksprites();
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 end of level */ /* check for end of level */
if (levelcomplete == LV_CLEAR) { if (levelcomplete == LV_CLEAR) {
@ -370,6 +339,30 @@ int main (int argc, char **argv) {
if (keys[SDLK_n]) { if (keys[SDLK_n]) {
if (toggletimer == 0) { if (toggletimer == 0) {
// nextlevel(); // 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; toggletimer = 50;
} }
} }
@ -598,9 +591,9 @@ int main (int argc, char **argv) {
} }
// move sprites // move sprites
for (s = sprite; s ; s = s->next) { moveallsprites();
movesprite(s);
} // animate text
movetext(); movetext();
@ -609,11 +602,13 @@ int main (int argc, char **argv) {
dogravity(player); dogravity(player);
dotileeffects(player); dotileeffects(player);
} else { } else {
sprite_t *s;
switch (levelcomplete) { switch (levelcomplete) {
case LV_INPROGRESS: case LV_INPROGRESS:
case LV_CLEAR: case LV_CLEAR:
case LV_WAIT: case LV_WAIT:
case LV_FINAL: case LV_FINAL:
case LV_CLOUD:
/* gravity */ /* gravity */
for (s = sprite ; s ; s = s->next) { for (s = sprite ; s ; s = s->next) {
dogravity(s); dogravity(s);
@ -654,12 +649,7 @@ int main (int argc, char **argv) {
} }
} }
/* check collisions for player and effects */ checkcollideall();
for (s = sprite ; s ; s = s->next) {
if ((s == player) || needscollisions(s->id)) {
checkcollide(s);
}
}
} }
@ -670,6 +660,7 @@ int main (int argc, char **argv) {
if (timer % 2 == 0) { if (timer % 2 == 0) {
int found; int found;
sprite_t *s; sprite_t *s;
// find cannon // find cannon
found = B_FALSE; found = B_FALSE;
for (s = sprite; s ; s = s->next) { for (s = sprite; s ; s = s->next) {
@ -678,6 +669,7 @@ int main (int argc, char **argv) {
break; break;
} }
} }
if (!found) { if (!found) {
printf("weird error - no cannon!!\n"); printf("weird error - no cannon!!\n");
player->powerup = B_FALSE; player->powerup = B_FALSE;
@ -737,14 +729,10 @@ int main (int argc, char **argv) {
} }
/* draw non-puff sprites */ // draw sprites
for (s = sprite ; s ; s = s->next) { drawallsprites();
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 text */ /* draw text */
drawtext(); 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; int rv;
tiletype_t *tt; tiletype_t *tt;
if (levelcomplete == LV_INIT) { if (levelcomplete == LV_INIT) {
// most things can't move in this state // most things can't move in this state
//if ((s->id != P_PUFF) && (s != player)) { //if ((s->id != P_PUFF) && (s != player)) {
if (!iseffect(s->id) && (s != player)) { if (!iseffect(s->id) && (s != player)) {
// caught or dead sprites can move, in case // caught or dead sprites can move, in case
// the player catches something before level start time // 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 // only player can move if you have a clock
if (player->powerup == PW_CLOCK) { if (player->powerup == PW_CLOCK) {
if (!iseffect(s->id) && (s != player) && !s->caughtby && !s->dead) { if (!iseffect(s->id) && (s != player) && !s->caughtby && !s->dead) {
return; return B_FALSE;
} }
} }
// iced monsters can't move // iced monsters can't move
if (ismonster(s->id) && s->iced) { if (ismonster(s->id) && s->iced) {
return; return B_FALSE;
} }
/* timer */ /* timer */
if (s->doomcount) { if (s->doomcount) {
if (s->id == P_PUFF) printf("PUFF WITH DOOMCOUNT!\n");
s->doomcount--; s->doomcount--;
if (s->doomcount == 0) { if (s->doomcount == 0) {
s->dead = D_FINAL; 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); 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 */ } else if (s->dead == D_INITIAL) { /* just set to dead */
if (s == boss) { if (s == boss) {
// flash // flash
@ -1519,7 +1510,7 @@ void movesprite(sprite_t *s) {
s->jumping = 1; s->jumping = 1;
} }
} }
return; return B_FALSE;
} else if (s->dead == D_BOUNCING) { /* dying */ } else if (s->dead == D_BOUNCING) { /* dying */
if (s == player) { if (s == player) {
/* shoot up in the air, then fall */ /* 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 */ } else if (s->dead == D_LASTBOUNCE) { /* final fall */
if (s == player) { if (s == player) {
/* just delay... */ /* just delay... */
@ -1583,7 +1574,7 @@ void movesprite(sprite_t *s) {
} }
} }
} }
return; return B_FALSE;
} else if (s->teleporting > 0) { } else if (s->teleporting > 0) {
SDL_Surface *ts; SDL_Surface *ts;
if (timer % 2 == 0) { if (timer % 2 == 0) {
@ -1631,7 +1622,7 @@ void movesprite(sprite_t *s) {
} }
} else if (s->jumping) { } else if (s->jumping) {
movex(s, s->jumpdir*getspeed(s)); movex(s, s->jumpdir*getspeed(s));
return; return B_FALSE;
} }
if (!iseffect(s->id)) { if (!iseffect(s->id)) {
@ -1653,7 +1644,7 @@ void movesprite(sprite_t *s) {
s->jumping = 1; s->jumping = 1;
s->jumpspeed = s->willjumpspeed; s->jumpspeed = s->willjumpspeed;
if (s->jumpdir != 0) s->dir = s->jumpdir; if (s->jumpdir != 0) s->dir = s->jumpdir;
return; return B_FALSE;
} else if (s->jumptimer % 20 == 0) { } else if (s->jumptimer % 20 == 0) {
s->dir = -s->dir; s->dir = -s->dir;
} }
@ -1698,6 +1689,7 @@ void movesprite(sprite_t *s) {
} }
} }
} else if (s->timer1 >= PUFFFRAMES) { } else if (s->timer1 >= PUFFFRAMES) {
s->timer1 = 999; // TODO: REMOVE THIS - debugging!
s->dead = D_FINAL; s->dead = D_FINAL;
} }
} }
@ -2285,6 +2277,8 @@ void movesprite(sprite_t *s) {
double amtleft; double amtleft;
double xdis,ydis,dis; double xdis,ydis,dis;
int turnsleft; int turnsleft;
if (!player->dead) {
/* /*
If small, grow and move towards player's feet (at a speed If small, grow and move towards player's feet (at a speed
which will get us there when we are fully grown. which will get us there when we are fully grown.
@ -2314,7 +2308,7 @@ void movesprite(sprite_t *s) {
levelcomplete = LV_CLOUDLOOP; levelcomplete = LV_CLOUDLOOP;
} }
printf("init angle = %0.2f\n", s->angle / (M_PI/180)); printf("init angle = %0.2f\n", s->angle / (M_PI/180));
} else { } else {
// calculate distance to player // calculate distance to player
@ -2339,17 +2333,23 @@ printf("init angle = %0.2f\n", s->angle / (M_PI/180));
s->xs = (cos(s->angle) * s->speed); s->xs = (cos(s->angle) * s->speed);
s->ys = (sin(s->angle) * s->speed); s->ys = (sin(s->angle) * s->speed);
//printf("cloud: amtleft = %0.2f (1.0 - ssize=%0.2f)",amtleft,s->size); //printf("cloud: amtleft = %0.2f (1.0 - ssize=%0.2f)",amtleft,s->size);
// printf("cloud: speed = %0.2f, xdis=%0.2f,ydis=%0.2f,dis=%0.2f, turnsleft=%d,xs=%0.2f,ys=%0.2f\n",speed,xdis,ydis,dis,turnsleft,s->xs,s->ys); // printf("cloud: speed = %0.2f, xdis=%0.2f,ydis=%0.2f,dis=%0.2f, turnsleft=%d,xs=%0.2f,ys=%0.2f\n",speed,xdis,ydis,dis,turnsleft,s->xs,s->ys);
// move // move
s->x += s->xs; s->x += s->xs;
s->y += s->ys; s->y += s->ys;
} }
}
} else if (levelcomplete == LV_CLOUDLOOP) { } else if (levelcomplete == LV_CLOUDLOOP) {
// stick player to us // stick player to us
player->x = s->x; player->x = s->x;
player->y = s->y - (imageset[P_PINKCLOUD].img[F_WALK1]->h / 2); 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) // keep turning towards exit (2 degrees at a time)
s->angle += (PCTURN * (M_PI/180)); 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)) { if (s->xs > abs(s->ys)) {
// level clear! // level clear!
levelcomplete = LV_NEXTLEV; levelcomplete = LV_NEXTLEV;
nextlevel(); return B_TRUE;
// kill ourselves
s->dead = D_FINAL;
} }
} }
} else { } else if ((levelcomplete == LV_INIT) || (levelcomplete == LV_INPROGRESS)) {
SDL_Surface *ts; SDL_Surface *ts;
// shrink // shrink
s->size -= ((double)PCSHRINKSPEED); 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) { void dotileeffects(sprite_t *s) {
@ -3544,7 +3543,8 @@ void dogravity(sprite_t *s) {
if (!s->swimming) { if (!s->swimming) {
s->swimming = B_TRUE; s->swimming = B_TRUE;
playfx(FX_SPLASH); playfx(FX_SPLASH);
adjustx(s, F_SWIM1); if (s == player) adjustx(s, F_SWIM1);
else adjustx(s, F_WALK1);
} }
} else { } else {
if (s->swimming) { if (s->swimming) {
@ -3856,7 +3856,7 @@ void dogravity(sprite_t *s) {
pointsinc *= 2; pointsinc *= 2;
pointsinc += 32000; // change? pointsinc = 64000; // hardcode for a boss
psize += 10; psize += 10;
gotsomething++; gotsomething++;
@ -3886,11 +3886,17 @@ void dogravity(sprite_t *s) {
if (boss) { // no fruits on boss levels if (boss) { // no fruits on boss levels
s2->willbecome = -1; s2->willbecome = -1;
} else { } 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]; s2->willbecome = poweruptypes[curpoweruptype];
if (poweruptypes[++curpoweruptype] == -1) { if (poweruptypes[++curpoweruptype] == -1) {
curpoweruptype = 0; curpoweruptype = 0;
} }
} }
}
} else if (player->powerup == PW_MACE) { } else if (player->powerup == PW_MACE) {
s2->willbecome = P_DIAMOND; s2->willbecome = P_DIAMOND;
} else { // should never happen } else { // should never happen
@ -4063,7 +4069,7 @@ void adjustheight(sprite_t *s) {
int dofruiteffect(sprite_t *s) { int dofruiteffect(sprite_t *s) {
if (s->id == P_SPEED) { if (s->id == P_SPEED) {
playfx(FX_POWERUP); 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); addoutlinetext(s->x,s->y - s->img->h/2, TEXTSIZE_POINTS, "Speed up!", &white,&black,POINTSDELAY);
return B_TRUE; return B_TRUE;
} else if (s->id == P_NUMNETS) { } else if (s->id == P_NUMNETS) {
@ -4550,6 +4556,7 @@ void dumpsprites(void) {
if (isbullet(s->id)) printf("BULLET, "); if (isbullet(s->id)) printf("BULLET, ");
if (iseffect(s->id)) printf("EFFECT, "); if (iseffect(s->id)) printf("EFFECT, ");
printf(")\n"); printf(")\n");
i++;
} }
printf("--------\n"); printf("--------\n");
@ -4713,3 +4720,79 @@ void adjustx(sprite_t *s,int framenum) {
s->x += diff; 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); void dotileeffects(sprite_t *s);
int movex(sprite_t *s,double amt); int movex(sprite_t *s,double amt);
void bouncesprite(sprite_t *s); void bouncesprite(sprite_t *s);
void movesprite(sprite_t *s); int movesprite(sprite_t *s);
int isinwater(sprite_t *s); int isinwater(sprite_t *s);
int isinwaterpoint(int x, int y); int isinwaterpoint(int x, int y);
int isroofabove(sprite_t *s); int isroofabove(sprite_t *s);
@ -52,4 +52,8 @@ char *addcommas(char *buffer, int num);
void addscore(sprite_t *s, int amt); void addscore(sprite_t *s, int amt);
void doice(void); void doice(void);
void checklevelend(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].starty = y*TILEH+(TILEH-2)+2;
level->initm[level->nummonsters].id = monid; level->initm[level->nummonsters].id = monid;
if (ismonster(monid)) numenemies++; if (ismonster(monid)) numenemies++;
if (monid == P_HELP) { if (monid == P_HELP) {
@ -663,7 +664,7 @@ int loadlevel(int wnum, int lnum) {
if (level->initm[i].id == P_HELP) { if (level->initm[i].id == P_HELP) {
strncpy(name, level->initm[i].help, MIDBUFLEN); strncpy(name, level->initm[i].help, MIDBUFLEN);
} else { } else {
strcpy(name, "Monster"); sprintf(name, "Monster-%d",i);
} }
if (ismonster(level->initm[i].id)) { if (ismonster(level->initm[i].id)) {
@ -2363,7 +2364,7 @@ int isnettable(int monid) {
int getbosshealth(int mid) { int getbosshealth(int mid) {
switch (mid) { switch (mid) {
case P_KINGRAT: case P_KINGRAT:
return 10; return 8;
} }
return 0; return 0;
} }

View File

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