Added powerup: extra life

This commit is contained in:
Rob Pearce 2008-10-10 00:51:40 +00:00
parent 3f0346dafe
commit 730f603dd6
6 changed files with 205 additions and 68 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 682 B

After

Width:  |  Height:  |  Size: 844 B

5
defs.h
View File

@ -214,7 +214,7 @@
#define S_SLOPE 2 #define S_SLOPE 2
// Sprite types // Sprite types
#define MAXPTYPES 53 #define MAXPTYPES 55
#define P_PLAYER 0 #define P_PLAYER 0
#define P_RAT 1 #define P_RAT 1
#define P_CHEESE 2 #define P_CHEESE 2
@ -268,6 +268,8 @@
#define P_SLUG 50 #define P_SLUG 50
#define P_BUBBLE 51 #define P_BUBBLE 51
#define P_PHONE 52 #define P_PHONE 52
#define P_HONEY 53
#define P_LIFE 54
// powerups // powerups
#define PW_NONE 0 #define PW_NONE 0
@ -491,6 +493,7 @@ typedef struct sprite_s {
int nety; // y position of end of net (used when shooting >1 net) int nety; // y position of end of net (used when shooting >1 net)
int netxstart; // x position of start of net int netxstart; // x position of start of net
int netystart; // y position of start of net int netystart; // y position of start of net
int netsticky; // can net pick up powerups?
int powerup; // what temp powerup does the player have? int powerup; // what temp powerup does the player have?
int ontramp; // on a trampoline? int ontramp; // on a trampoline?

174
rc.c
View File

@ -52,12 +52,13 @@ int fruittypes[] = {
/* the order in which powerups will appear */ /* the order in which powerups will appear */
int poweruptypes[] = { int poweruptypes[] = {
P_NUMNETS, P_NUMNETS,
P_BELL,
P_BIGNET, P_BIGNET,
P_BELL,
P_GEMBOOST, P_GEMBOOST,
P_NUMNETS, P_NUMNETS,
P_GEMBOOST, P_HONEY,
P_NUMNETS, P_NUMNETS,
P_GEMBOOST,
P_HELMET, P_HELMET,
-1 -1
}; };
@ -82,6 +83,7 @@ sprite_t *lastsprite;
SDL_Color red = {255, 0, 0, 0}; SDL_Color red = {255, 0, 0, 0};
SDL_Color orange = {255, 167, 88, 1};
SDL_Color black = {0, 0, 0, 0}; SDL_Color black = {0, 0, 0, 0};
SDL_Color blue = {0, 0, 255, 0}; SDL_Color blue = {0, 0, 255, 0};
SDL_Color cyan = {0, 255, 255, 0}; SDL_Color cyan = {0, 255, 255, 0};
@ -299,7 +301,8 @@ int main (int argc, char **argv) {
player->netmax = 4; // all nets player->netmax = 4; // all nets
player->netbig = B_TRUE; // big net player->netbig = B_TRUE; // big net
player->speed = 2; // fast player->speed = 2; // fast
sprintf(tempm, "Full power!"); player->netsticky = B_TRUE;
sprintf(tempm, "Cheat!");
addoutlinetext(player->x,player->y - player->img->h/2, TEXTSIZE_POINTS, tempm,&white,&black,POINTSDELAY); addoutlinetext(player->x,player->y - player->img->h/2, TEXTSIZE_POINTS, tempm,&white,&black,POINTSDELAY);
toggletimer = 80; toggletimer = 80;
} }
@ -1339,7 +1342,7 @@ void checkcollide(sprite_t *s) {
/* check for colission with our net */ /* check for colission with our net */
if (s->netting ) { if (s->netting ) {
if (isnettable(s2->id) && !s2->invuln) { if ((isnettable(s2->id) && !s2->invuln) || (s->netsticky && isfruit(s2->id))){
xdiff = (s->x + s->netlen*s->netdir) - s2->x; xdiff = (s->x + s->netlen*s->netdir) - s2->x;
if (xdiff < 0) xdiff = -xdiff; if (xdiff < 0) xdiff = -xdiff;
ydiff = s->netystart - (s2->y - s2->img->h/2); ydiff = s->netystart - (s2->y - s2->img->h/2);
@ -1356,48 +1359,54 @@ void checkcollide(sprite_t *s) {
if ((xdiff <= s2->img->w/2) && (ydiff <= ythresh)) { if ((xdiff <= s2->img->w/2) && (ydiff <= ythresh)) {
// we hit something! // we hit something!
// if we have a boxing glove, it dies if (s->netsticky && isfruit(s2->id)) {
if (s->powerup == PW_BOXING) { getfruit(s, s2);
s2->dead = D_BOUNCING;// die as soon as it hits a wall
s2->bounces = 1;
s2->quickdie = B_TRUE;
/* go FAST in the direction player is facing */
s2->xs = s->dir * 5;
s2->ys = 0;
/* slightly raise the sprite to avoid isonground() being true */
s2->y -= 3;
/* make sure we're not too high since we'll never get lower now */
if (s2->y <= TILEH) s2->y = TILEH+1;
// become something special
s2->willbecome = P_DIAMOND;
playfx(FX_KILL);
sprintf(tempm, bifftext[rand() % MAXBIFFTEXT]);
addoutlinetext(s2->x,s2->y - s->img->h/2, TEXTSIZE_BIFF, tempm,&red,&yellow,POINTSDELAY);
keepchecking = B_FALSE;
} else if (s2->iced) {
// it dies
playfx(FX_ICEBREAK);
if (s2->id == P_SNAIL) s2->id = P_SLUG;
die(s2);
} else { } else {
// otherwise we caught it if we have enough nets // Otherwise, it must be a monster
if (s->netcaught < s->netmax) { // if we have a boxing glove, it dies
s2->caughtby = s; if (s->powerup == PW_BOXING) {
s2->jumping = B_FALSE; s2->dead = D_BOUNCING;// die as soon as it hits a wall
s2->falling = 0; s2->bounces = 1;
s2->caughtstate = C_NETTING; s2->quickdie = B_TRUE;
s->netcaught++;
/* go FAST in the direction player is facing */
s2->xs = s->dir * 5;
s2->ys = 0;
/* slightly raise the sprite to avoid isonground() being true */
s2->y -= 3;
/* make sure we're not too high since we'll never get lower now */
if (s2->y <= TILEH) s2->y = TILEH+1;
// become something special
s2->willbecome = P_DIAMOND;
playfx(FX_KILL);
sprintf(tempm, bifftext[rand() % MAXBIFFTEXT]);
addoutlinetext(s2->x,s2->y - s->img->h/2, TEXTSIZE_BIFF, tempm,&red,&yellow,POINTSDELAY);
keepchecking = B_FALSE; keepchecking = B_FALSE;
} else if (s2->iced) {
// it dies
playfx(FX_ICEBREAK);
if (s2->id == P_SNAIL) s2->id = P_SLUG;
die(s2);
} else {
// otherwise we caught it if we have enough nets
if (s->netcaught < s->netmax) {
s2->caughtby = s;
s2->jumping = B_FALSE;
s2->falling = 0;
s2->caughtstate = C_NETTING;
s->netcaught++;
keepchecking = B_FALSE;
}
} }
} } // end if isfruit or ismonster
} }
} }
} // end if s->netting } // end if s->netting
@ -1420,18 +1429,7 @@ void checkcollide(sprite_t *s) {
if (s == player) { if (s == player) {
//if (isfruit(s2->id) && (s2->teleporting == 0)) { //if (isfruit(s2->id) && (s2->teleporting == 0)) {
if (isfruit(s2->id)) { if (isfruit(s2->id)) {
int gotscore = s2->score; getfruit(player, s2);
/* kill the fruit */
s2->dead = D_FINAL;
/* give points to the player */
addscore(player, gotscore);
/* handle fruit effects */
if (!dofruiteffect(s2)) {
playfx(FX_FRUIT);
sprintf(tempm, "%d", gotscore);
addoutlinetext(s2->x,s2->y - s2->img->h/2, TEXTSIZE_POINTS, tempm, &white,&black,POINTSDELAY);
}
} else if (ismonster(s2->id) || isbullet(s2->id)) { } else if (ismonster(s2->id) || isbullet(s2->id)) {
if (s2->iced) { if (s2->iced) {
// monster dies // monster dies
@ -3451,7 +3449,11 @@ void drawnetting(sprite_t *s) {
yy += y; yy += y;
xx = s->x + s->netdir*s->netlen; xx = s->x + s->netdir*s->netlen;
drawline16(screen,sx,s->nety,xx,yy,white); if (s->netsticky) {
drawdotline16(screen,sx,s->nety,xx,yy,orange,yellow);
} else {
drawline16(screen,sx,s->nety,xx,yy,white);
}
// add sparkle // add sparkle
xx = s->x + s->netdir*s->netlen; xx = s->x + s->netdir*s->netlen;
addsprite(P_SPARKLE, xx + (rand() % 14) - 7, yy + (rand() % 8) - 4, "sparkle"); addsprite(P_SPARKLE, xx + (rand() % 14) - 7, yy + (rand() % 8) - 4, "sparkle");
@ -3464,23 +3466,33 @@ void drawnetting(sprite_t *s) {
double dist; double dist;
int x,y; int x,y;
int ii; int ii;
SDL_Color *col1,*col2;
dist = (s->slamangle * (180/M_PI))/2; dist = (s->slamangle * (180/M_PI))/2;
s->netxstart = s->x + cos(s->slamangle-(180*(M_PI/180)))*dist*s->dir; s->netxstart = s->x + cos(s->slamangle-(180*(M_PI/180)))*dist*s->dir;
s->netystart = s->y + sin(s->slamangle-(180*(M_PI/180)))*dist; s->netystart = s->y + sin(s->slamangle-(180*(M_PI/180)))*dist;
/* middle line */ // select colours
drawline16(screen,s->x,s->y - s->img->h/2, if (s->netsticky) {
s->netxstart,s->netystart,white); col1 = &orange;
/* left line */ col2 = &yellow;
} else {
col1 = &white;
col2 = &white;
}
/* middle dotline */
drawdotline16(screen,s->x,s->y - s->img->h/2,
s->netxstart,s->netystart,*col1,*col2);
/* left dotline */
x = s->x + cos(s->slamangle-(5*(M_PI/180))-(180*(M_PI/180)))*dist*s->dir; x = s->x + cos(s->slamangle-(5*(M_PI/180))-(180*(M_PI/180)))*dist*s->dir;
y = s->y + sin(s->slamangle-(5*(M_PI/180))-(180*(M_PI/180)))*dist; y = s->y + sin(s->slamangle-(5*(M_PI/180))-(180*(M_PI/180)))*dist;
drawline16(screen,s->x,s->y - s->img->h/2,x, y, white); drawdotline16(screen,s->x,s->y - s->img->h/2,x, y, *col1,*col2);
/* right line */ /* right dotline */
x = s->x + cos(s->slamangle+(5*(M_PI/180))-(180*(M_PI/180)))*dist*s->dir; x = s->x + cos(s->slamangle+(5*(M_PI/180))-(180*(M_PI/180)))*dist*s->dir;
y = s->y + sin(s->slamangle+(5*(M_PI/180))-(180*(M_PI/180)))*dist; y = s->y + sin(s->slamangle+(5*(M_PI/180))-(180*(M_PI/180)))*dist;
drawline16(screen,s->x,s->y - s->img->h/2,x, y, white); drawdotline16(screen,s->x,s->y - s->img->h/2,x, y, *col1,*col2);
// add sparkles // add sparkles
for (ii = 0 ; ii < player->netmax; ii++) { for (ii = 0 ; ii < player->netmax; ii++) {
@ -4562,6 +4574,15 @@ int dofruiteffect(sprite_t *s) {
player->powerup = PW_CANNON; player->powerup = PW_CANNON;
puffin(P_CANNON, player->x, player->y,"cannon", 0); puffin(P_CANNON, player->x, player->y,"cannon", 0);
return B_TRUE; return B_TRUE;
} else if (s->id == P_HONEY) {
playfx(FX_POWERUP);
player->netsticky = B_TRUE;
sprintf(tempm, "Sticky net!");
addoutlinetext(s->x,s->y - s->img->h/2, TEXTSIZE_POINTS, tempm,&white,&black,POINTSDELAY);
return B_TRUE;
} else if (s->id == P_LIFE) {
extralife(player);
return B_TRUE;
} else if (s->id == P_PHONE) { } else if (s->id == P_PHONE) {
sprite_t *s2, *nexts; sprite_t *s2, *nexts;
playfx(FX_PHONE); playfx(FX_PHONE);
@ -4947,13 +4968,17 @@ void addscore(sprite_t *s, int amt) {
// each multiple of 100,000 // each multiple of 100,000
if (s == player) { if (s == player) {
if ((s->score / 100000) > (oldscore / 100000)) { if ((s->score / 100000) > (oldscore / 100000)) {
playfx(FX_LIFE); extralife(s);
s->lives++;
addoutlinetext(s->x,s->y - s->img->h/2, TEXTSIZE_LIFE, "Extra life!",&green,&black,LIFEDELAY);
} }
} }
} }
void extralife(sprite_t *which) {
playfx(FX_LIFE);
which->lives += 1;
addoutlinetext(which->x,which->y - which->img->h/2, TEXTSIZE_LIFE, "Extra life!",&green,&black,LIFEDELAY);
}
void doice(void) { void doice(void) {
int yy,xx,changed; int yy,xx,changed;
sprite_t *s; sprite_t *s;
@ -5238,3 +5263,20 @@ void initsdl(void) {
} }
SDL_ShowCursor(SDL_DISABLE); SDL_ShowCursor(SDL_DISABLE);
} }
// player collects the given fruit
void getfruit(sprite_t *giveto, sprite_t *fruit) {
char tempm[MIDBUFLEN];
int gotscore = fruit->score;
/* kill the fruit */
fruit->dead = D_FINAL;
/* give points to the player */
addscore(giveto, gotscore);
/* handle fruit effects */
if (!dofruiteffect(fruit)) {
playfx(FX_FRUIT);
sprintf(tempm, "%d", gotscore);
addoutlinetext(fruit->x,fruit->y - fruit->img->h/2, TEXTSIZE_POINTS, tempm, &white,&black,POINTSDELAY);
}
}

2
rc.h
View File

@ -50,6 +50,7 @@ int getpoints(int id);
int isladder(int tid); int isladder(int tid);
char *addcommas(char *buffer, int num); char *addcommas(char *buffer, int num);
void addscore(sprite_t *s, int amt); void addscore(sprite_t *s, int amt);
void extralife(sprite_t *s);
void doice(void); void doice(void);
void checklevelend(void); void checklevelend(void);
void checksprites(void); void checksprites(void);
@ -64,3 +65,4 @@ int getjumpdelay(int mid);
void togglepause(void); void togglepause(void);
void togglefullscreen(void); void togglefullscreen(void);
void initsdl(void); void initsdl(void);
void getfruit(sprite_t *giveto, sprite_t *fruit);

View File

@ -567,6 +567,7 @@ void setdefaults(sprite_t *s) {
s->gemboost = 1; s->gemboost = 1;
s->powerup = 0; s->powerup = 0;
s->netbig = 0; s->netbig = 0;
s->netsticky = B_FALSE;
// player-only states // player-only states
s->netting = 0; s->netting = 0;
s->netmax = 1; s->netmax = 1;
@ -1147,9 +1148,15 @@ int loadimagesets(void) {
loadspriteimage(P_BOMB,F_WALK1, "sprites/bomb.png"); loadspriteimage(P_BOMB,F_WALK1, "sprites/bomb.png");
imageset[P_BOMB].numimages = 1; imageset[P_BOMB].numimages = 1;
loadspriteimage(P_LIFE,F_WALK1, "sprites/dwarfhead-small.png");
imageset[P_LIFE].numimages = 1;
loadspriteimage(P_PHONE,F_WALK1, "sprites/phone.png"); loadspriteimage(P_PHONE,F_WALK1, "sprites/phone.png");
imageset[P_PHONE].numimages = 1; imageset[P_PHONE].numimages = 1;
loadspriteimage(P_HONEY,F_WALK1, "sprites/honey.png");
imageset[P_HONEY].numimages = 1;
loadspriteimage(P_SHIELD,F_WALK1, "sprites/shield.png"); loadspriteimage(P_SHIELD,F_WALK1, "sprites/shield.png");
imageset[P_SHIELD].numimages = 1; imageset[P_SHIELD].numimages = 1;
@ -1659,6 +1666,7 @@ int isfruit(int id) {
case P_GEMBOOST: case P_GEMBOOST:
case P_BELL: case P_BELL:
case P_TROPHY: case P_TROPHY:
case P_HONEY:
return FT_PERM; return FT_PERM;
/* one-off level only powerups */ /* one-off level only powerups */
case P_BOXING: case P_BOXING:
@ -1666,6 +1674,7 @@ int isfruit(int id) {
case P_FTODIAMOND: case P_FTODIAMOND:
case P_FTOGEM: case P_FTOGEM:
case P_BOMB: case P_BOMB:
case P_LIFE:
case P_PHONE: case P_PHONE:
case P_HELMET: case P_HELMET:
case P_SHIELD: case P_SHIELD:
@ -1818,6 +1827,80 @@ void drawline16(SDL_Surface *screen, int x1, int y1, int x2, int y2, SDL_Color c
if (d < 0) {
d += dinc1;
x += xinc1;
y += yinc1;
} else {
d += dinc2;
x += xinc2;
y += yinc2;
}
}
}
// draw line with alternating colours
void drawdotline16(SDL_Surface *screen, int x1, int y1, int x2, int y2, SDL_Color c, SDL_Color c2) {
int deltax, deltay;
int numpixels;
int d;
int dinc1,dinc2,xinc1,xinc2,yinc1,yinc2;
int i;
int x;
int y;
int maskcount = 0;
int maskindex = 0;
deltax = (x2 - x1);
if (deltax < 0) deltax = -deltax;
deltay = (y2 - y1);
if (deltay < 0) deltay = -deltay;
if (deltax >= deltay) {
numpixels = deltax + 1;
d = (deltay*2) - deltax;
dinc1 = deltay << 1;
dinc2 = (deltay-deltax) << 1;
xinc1 = 1;
xinc2 = 1;
yinc1 = 0;
yinc2 = 1;
} else {
numpixels = deltay + 1;
d = (deltax*2) - deltay;
dinc1 = deltax << 1;
dinc2 = (deltax - deltay) << 1;
xinc1 = 0;
xinc2 = 1;
yinc1 = 1;
yinc2 = 1;
}
if (x1 > x2) {
xinc1 = - xinc1;
xinc2 = - xinc2;
}
if (y1 > y2) {
yinc1 = - yinc1;
yinc2 = - yinc2;
}
x = x1; y = y1;
maskcount = 0;
maskindex = 0;
for (i = 0; i < numpixels; i++) {
if (i % 2 == 0) {
drawpixel16(screen,x,y,c);
} else {
drawpixel16(screen,x,y,c2);
}
if (d < 0) { if (d < 0) {
d += dinc1; d += dinc1;
x += xinc1; x += xinc1;
@ -2241,7 +2324,7 @@ int loadlevellist(void) {
int randompowerup(void) { int randompowerup(void) {
int num; int num;
num = rand() % 20; num = rand() % 22;
switch (num) { switch (num) {
case 0: case 0:
@ -2285,6 +2368,10 @@ int randompowerup(void) {
return P_CANNONPOWERUP; return P_CANNONPOWERUP;
case 19: case 19:
return P_PHONE; return P_PHONE;
case 20:
return P_HONEY;
case 21:
return P_LIFE;
} }
} }
@ -2403,6 +2490,8 @@ void setfruitinfo(void) {
setinfo(P_SPRAY, "Fly Spray", "Sickens all monsters, causing them to slow down to half speed.","spray.png"); setinfo(P_SPRAY, "Fly Spray", "Sickens all monsters, causing them to slow down to half speed.","spray.png");
setinfo(P_CANNONPOWERUP, "Fusion Cannon", "A powerful weapon which will shoot out laser beams in all directions!", "cannonpowerup.png"); setinfo(P_CANNONPOWERUP, "Fusion Cannon", "A powerful weapon which will shoot out laser beams in all directions!", "cannonpowerup.png");
setinfo(P_PHONE, "Phone", "Calls in your helper cloud and immediately skips two levels.", "phone.png"); setinfo(P_PHONE, "Phone", "Calls in your helper cloud and immediately skips two levels.", "phone.png");
setinfo(P_HONEY, "Honey", "Coats your net in a layer of sticky honey, allowing it to pick up fruits from afar.", "honey.png");
setinfo(P_RAT, "Rat", "The weakest of the monsters, the rat will simply walk back and forth waiting to be caught. Beward an angry rat though, as it will try to fall or jump in order to catch you!", "rat.png"); setinfo(P_RAT, "Rat", "The weakest of the monsters, the rat will simply walk back and forth waiting to be caught. Beward an angry rat though, as it will try to fall or jump in order to catch you!", "rat.png");
setinfo(P_BEE, "Bee", "Bees, while still relatively weak, gain an advantage over bats in that they are able to fly. They move in a simple diagonal pattern, changing direction when they get near a wall or spikes. Bees will speed up when angry.", "newbee.png"); setinfo(P_BEE, "Bee", "Bees, while still relatively weak, gain an advantage over bats in that they are able to fly. They move in a simple diagonal pattern, changing direction when they get near a wall or spikes. Bees will speed up when angry.", "newbee.png");

View File

@ -26,6 +26,7 @@ inline void drawpixel16(SDL_Surface *screen, int x, int y, SDL_Color c);
inline void drawpixel32(SDL_Surface *screen, int x, int y, SDL_Color c); inline void drawpixel32(SDL_Surface *screen, int x, int y, SDL_Color c);
inline void drawbox16(SDL_Surface *screen, int x1,int y1,int x2,int y2,SDL_Color *c,SDL_Color *fc); inline void drawbox16(SDL_Surface *screen, int x1,int y1,int x2,int y2,SDL_Color *c,SDL_Color *fc);
void drawline16(SDL_Surface *screen, int x1, int y1, int x2, int y2, SDL_Color c); void drawline16(SDL_Surface *screen, int x1, int y1, int x2, int y2, SDL_Color c);
void drawdotline16(SDL_Surface *screen, int x1, int y1, int x2, int y2, SDL_Color c, SDL_Color c2);
int getcolor(SDL_Surface *dest, int x, int y, SDL_Color *col); int getcolor(SDL_Surface *dest, int x, int y, SDL_Color *col);
/* /*
int chartomonster(char ch); int chartomonster(char ch);