Initial code for moving platforms

This commit is contained in:
Rob Pearce 2008-11-06 09:15:09 +00:00
parent 7e2a9cf509
commit 5e40cf4c02
9 changed files with 283 additions and 16 deletions

View File

@ -39,3 +39,10 @@
18,level8.5.dat,Look out above...
40,level40.dat,King Snail
109,level109.dat,THE END SO FAR
99,level99.dat,TEST LEVEL
118,level118.dat,NEW LEVEL
119,level119.dat,NEW LEVEL
120,level120.dat,NEW LEVEL
121,level121.dat,NEW LEVEL
122,level122.dat,NEW LEVEL
123,level123.dat,NEW LEVEL

BIN
data/sprites/platform.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

15
defs.h
View File

@ -212,6 +212,8 @@
#define MAXHISCORES 10
#define MAXHISCORENAME 12
#define MAXWAYPOINTS 10
#define HISCORE_DISPLAYTIME 10 // how many secs to display hiscores for
// Fixed text buffer sizes
@ -320,7 +322,7 @@
#define S_SLOPE 2
// Sprite types
#define MAXPTYPES 132
#define MAXPTYPES 133
#define P_PLAYER 0
#define P_RAT 1
#define P_CHEESE 2
@ -458,6 +460,7 @@
#define P_KSSHELL 129
#define P_BIGNUMNETS 130
#define P_RANDOM 131
#define P_PLATFORM 132
// cards
#define CARDFONTX 4
@ -640,6 +643,9 @@ typedef struct initialmonster_s {
int startx;
int starty;
int id;
int wayx[MAXWAYPOINTS];
int wayy[MAXWAYPOINTS];
int numwaypoints;
char *help;
} initialmonster_t;
@ -760,6 +766,12 @@ typedef struct sprite_s {
int card[MAXCARDS];
int usedcard[MAXCARDS];
// for moving platforms
double wayx[MAXWAYPOINTS];
double wayy[MAXWAYPOINTS];
int numwaypoints;
int curwaypoint;
// monster only
int iced; // turned to ice?
SDL_Surface *iceimg; // Image to blit for ice
@ -788,6 +800,7 @@ typedef struct sprite_s {
double size;
// player and monster
struct sprite_s *onplatform;// are we on platform?
int lives; // only for player and bosses
int swimming; // are we in the water?
int falling; // are we falling?

70
edit.c
View File

@ -35,6 +35,9 @@ int skipto = -1;
int layer = 1; // which layer we are editting, either 1 or 2
int layertransparent = B_TRUE;
sprite_t *waypointm = NULL;
SDL_Surface *whitebox;
SDL_Color red = {255, 0, 0, 0};
@ -367,6 +370,17 @@ int main (int argc, char **argv) {
}
}
} else if (state == LS_WAYPOINTS) {
// add waypoint at selected position
// TODO: lock x/y with keys...
if (toggletimer == 0) {
waypointm->wayx[waypointm->numwaypoints] = mx;
waypointm->wayy[waypointm->numwaypoints] = my;
waypointm->numwaypoints++;
sprintf(tempm, "Waypoint #%d added at %d,%d",waypointm->numwaypoints,mx,my);
setstatustext(tempm, &blue);
toggletimer = 20;
}
} else if (state == LS_SAVE) {
// get pos
int i;
@ -444,6 +458,36 @@ int main (int argc, char **argv) {
toggletimer = 15;
}
}
if (keys[SDLK_w]) { // set waypoints
int donesomething = B_FALSE;
sprite_t *s, *nextone;
for (s = sprite ; s ; s = nextone) {
nextone = s->next;
/* if mouse is over this sprite */
if ( (mx >= s->x - (s->img->w/2)) &&
(mx <= s->x + (s->img->w/2)) &&
(my >= s->y - s->img->h) &&
(my <= s->y )) {
if (isplatform(s->id)) {
// select it
waypointm = s;
state = LS_WAYPOINTS;
donesomething = B_TRUE;
}
}
}
if (donesomething) {
// clear waypoints for selection
waypointm->numwaypoints = 0;
// redraw
draweditorlevel();
drawsprites();
setmod(B_TRUE);
setstatustext("Waypoint selection mode...",&green);
}
}
if (keys[SDLK_x]) { // delete monster
int donesomething = B_FALSE;
@ -571,6 +615,14 @@ int main (int argc, char **argv) {
draweditorlevel();
drawsprites();
}
} else if (state == LS_WAYPOINTS) {
if (keys[SDLK_ESCAPE]) {
waypointm = NULL;
state = LS_EDIT;
draweditorlevel();
drawsprites();
setstatustext("Finished adding waypoints.", &green);
}
}
@ -763,6 +815,13 @@ void drawsprites(void) {
sprite_t *s;
for (s = sprite; s != NULL; s = s->next) {
drawsprite(s);
// waypoint selection mode
if (state == LS_WAYPOINTS) {
if (waypointm == s) {
drawbox16(screen, s->x - s->img->w/2,s->y - s->img->h,
s->x + s->img->w/2, s->y, &red, NULL);
}
}
}
}
@ -919,8 +978,18 @@ int savelevel(int wnum, int lnum) {
mid = s->id;
mx = (s->x - (TILEW/2)) / TILEW;
my = (s->y - TILEH/2) / TILEH;
if (s->numwaypoints > 0) {
int i;
fprintf(f,"%d %d %d",mid,mx,my);
for (i = 0; i < s->numwaypoints; i++) {
fprintf(f," %0.0f %0.0f",s->wayx[i],s->wayy[i]);
}
fprintf(f,"\n");
} else {
// no waypoints
fprintf(f,"%d %d %d\n",mid,mx,my);
}
}
fprintf(f, "endmonsters\n");
/* exit dir */
@ -1019,6 +1088,7 @@ int isplacabletile(int tid) {
}
int isplacablesprite(int sid) {
if (sid == P_PLATFORM) return B_TRUE;
if (sid == P_HELP) return B_TRUE;
if (sid == P_PLAYER) return B_TRUE;
if (sid == P_POWERUPPOS) return B_TRUE;

1
edit.h
View File

@ -35,6 +35,7 @@
// level states
#define LS_EDIT 0
#define LS_SAVE 1
#define LS_WAYPOINTS 2
// Editor specific functions

141
rc.c
View File

@ -1513,6 +1513,54 @@ void cleanup(void) {
printf("complete.\n");
}
void checkcollideplatform(sprite_t *s) {
double xdiff,ydiff;
double xthresh,ythresh;
sprite_t *s2;
SDL_Surface *walkimg;
for (s2 = sprite ; s2 ; s2 = s2->next) {
// only monsters and players and fruits can be on platforms
if (!ismonster(s2->id) && (s2 != player) && (!isfruit(s2->id))) {
continue;
}
if (s2->onplatform == s) {
// if already on us, default to not being on us in case
// it's moved away
s2->onplatform = NULL;
}
// is s2 touching us?
/*
xdiff = s->x - s2->x;
if (xdiff < 0) xdiff = -xdiff;
ydiff = (s->y-(s->img->h/2)) - (s2->y-(s2->img->h/2));
if (ydiff < 0) ydiff = -ydiff;
xthresh = s->img->w/2 + s2->img->w/2;
ythresh = s->img->h/2 + s2->img->h/2;
*/
//if ((xdiff <= xthresh) && (ydiff <= ythresh)) {
walkimg = imageset[s2->id].img[F_WALK1];
// has it hit the top half of us?
if ((s2->x >= (s->x - s->img->w/2 - walkimg->w/2 ) ) && (s2->x <= (s->x + s->img->w/2 + walkimg->w/2)) &&
(s2->y >= (s->y - s->img->h) ) && (s2->y <= s->y - s->img->h/2)) {
/* COLLISION! */
if (!s2->jumping) {
s2->y = s->y - s->img->h;
s2->onplatform = s;
}
}
}
}
void checkcollide(sprite_t *s) {
sprite_t *s2;
int keepchecking;
@ -1520,6 +1568,7 @@ void checkcollide(sprite_t *s) {
double xthresh, ythresh;
int netsleft;
// for all other sprites
for (s2 = sprite ; s2 ; s2 = s2->next) {
@ -2141,7 +2190,7 @@ int movesprite(sprite_t *s) {
// timer3 is the target y position
//
// move towards end position
movetostart(s, s->timer2, s->timer3, CARDSPEED, CARDSPEED);
moveto(s, s->timer2, s->timer3, CARDSPEED, CARDSPEED);
// are we there yet?
if ((s->x == s->timer2) && (s->y == s->timer3)) {
@ -2236,7 +2285,7 @@ int movesprite(sprite_t *s) {
}
} else {
// move towards centre of the screen
movetostart(s, 320, 240, FIVECARDSPEED, FIVECARDSPEED);
moveto(s, 320, 240, FIVECARDSPEED, FIVECARDSPEED);
}
} else if (s->id == P_MASK) { // mask effect
// stay on top of player
@ -2920,6 +2969,42 @@ int movesprite(sprite_t *s) {
}
}
} else if (s->id == P_PLATFORM) { // moving platform
double dstx,dsty;
int rv;
if (s->numwaypoints > 0) {
sprite_t *s2;
double oldx,oldy,xdiff,ydiff;
oldx = s->x;
oldy = s->y;
// move torwaeds next waypoints
dstx = s->wayx[s->curwaypoint];
dsty = s->wayy[s->curwaypoint];
rv = moveto(s,dstx,dsty,getspeed(s),getspeed(s));
// got there?
if (rv) {
// go to next waypoint
s->curwaypoint++;
if (s->curwaypoint >= s->numwaypoints) {
s->curwaypoint = 0;
}
}
// remember how far we moved
xdiff = s->x - oldx;
ydiff = s->y - oldy;
// move anything on top of us by the same amount
for (s2 = sprite ; s2 ; s2 = s2->next) {
if (s2->onplatform == s) {
s2->x += xdiff;
s2->y += ydiff;
}
}
}
} else if (s->id == P_TICK) {
if (!s->falling) {
@ -3758,7 +3843,7 @@ void drawlevel(void) {
// the real one along.
for (x = 0; x < 640; x += speed) {
// move player
movetostart(player,dstx,dsty,pspeed,pspeed);
moveto(player,dstx,dsty,pspeed,pspeed);
// set cloud location
cloud->x = player->x;
cloud->y = player->y + (cloud->img->h / 2);
@ -3822,7 +3907,7 @@ void drawlevel(void) {
// the real one along.
for (y = 0; y < 480; y += speed) {
// move player
movetostart(player,dstx,dsty,pspeed,pspeed);
moveto(player,dstx,dsty,pspeed,pspeed);
// set cloud location
cloud->x = player->x;
cloud->y = player->y + (cloud->img->h / 2);
@ -3886,7 +3971,7 @@ void drawlevel(void) {
// the real one along.
for (y = 0; y < 480; y += speed) {
// move player
movetostart(player,dstx,dsty,pspeed,pspeed);
moveto(player,dstx,dsty,pspeed,pspeed);
// set cloud location
cloud->x = player->x;
cloud->y = player->y + (cloud->img->h / 2);
@ -3950,7 +4035,7 @@ void drawlevel(void) {
// the real one along.
for (x = 0; x < 640; x += speed) {
// move player
movetostart(player,dstx,dsty,pspeed,pspeed);
moveto(player,dstx,dsty,pspeed,pspeed);
// set cloud location
cloud->x = player->x;
cloud->y = player->y + (cloud->img->h / 2);
@ -4052,6 +4137,8 @@ double getspeed(sprite_t *s ) {
else speed = 1.5;
} else if (id == P_KINGRAT) {
speed = 1.5;
} else if (id == P_PLATFORM) {
speed = 2;
}
if (isinwater(s) && (s->id != P_FISH)) {
@ -4739,6 +4826,10 @@ int isroofnabove(sprite_t *s, int howfar) {
}
int isonground(sprite_t *s) {
// are we on a platform?
if (s->onplatform) {
return B_TRUE;
}
/* get tile below sprite's feet */
if (isongroundpoint(s, s->x, s->y)) {
return B_TRUE;
@ -4773,6 +4864,10 @@ int isongroundpoint(sprite_t *s, int x,int y) {
int xoff;
int groundy;
if (s->onplatform) {
return B_TRUE;
}
tt = gettileat(x,y, &tilex, &tiley);
@ -6268,8 +6363,10 @@ void channeldone(int channel) {
// move player towards new position
void movetostart(sprite_t *p, int dstx, int dsty, double xspeed, double yspeed) {
// return true if we're there
int moveto(sprite_t *p, int dstx, int dsty, double xspeed, double yspeed) {
double ang,xs,ys;
int therex = B_FALSE,therey = B_FALSE;
// figure out angle to player
ang = atan2(dsty - p->y, dstx - p->x);
xs = (cos(ang) * xspeed);
@ -6277,20 +6374,38 @@ void movetostart(sprite_t *p, int dstx, int dsty, double xspeed, double yspeed)
if (p->x < dstx) {
p->x += xs;
if (p->x > dstx) p->x = dstx;
if (p->x >= dstx) {
p->x = dstx;
}
}
if (p->x > dstx) {
p->x += xs;
if (p->x < dstx) p->x = dstx;
if (p->x <= dstx) {
p->x = dstx;
}
}
if (p->x == dstx) {
therex = B_TRUE;
}
if (p->y < dsty) {
p->y += ys;
if (p->y > dsty) p->y = dsty;
if (p->y >= dsty) {
p->y = dsty;
}
}
if (p->y > dsty) {
p->y += ys;
if (p->y < dsty) p->y = dsty;
if (p->y <= dsty) {
p->y = dsty;
}
}
if (p->y == dsty) {
therey = B_TRUE;
}
if (therex && therey) return B_TRUE;
return B_FALSE;
}
// grabs area behind a sprite into a temp buffer
@ -6648,9 +6763,13 @@ void checkcollideall(void) {
checkcollide(s);
}
} else if (needscollisions(s->id)) {
if (isplatform(s->id)) {
checkcollideplatform(s);
} else {
checkcollide(s);
}
}
}
}
void drawallsprites(void) {

3
rc.h
View File

@ -26,6 +26,7 @@ int isonbridge(sprite_t *s);
int isladderabove(sprite_t *s);
int dofruiteffect(sprite_t *s);
void checkcollide(sprite_t *s);
void checkcollideplatform(sprite_t *s);
void die(sprite_t *s);
void nextlevel(void);
void jump(sprite_t *s, int dir);
@ -42,7 +43,7 @@ void playfx(int num);
void playmusic(Mix_Music *toplay);
void stopmusic(void);
void channeldone(int channel);
void movetostart(sprite_t *p, int dstx, int dsty, double xspeed,double yspeed);
int moveto(sprite_t *p, int dstx, int dsty, double xspeed,double yspeed);
SDL_Surface *grabbehind(sprite_t *s, SDL_Surface *surf);
void dumpsprites(void);
int countmonsters(int montype);

View File

@ -257,6 +257,26 @@ int loadlevel(int wnum, int lnum, int wantmonsters) {
}
y = atoi(p); // monster y pos
// waypoints
if (isplatform(monid)) {
level->initm[level->nummonsters].numwaypoints = 0;
// read waypoints
p = strtok(NULL, " ");
while (p) {
level->initm[level->nummonsters].wayx[level->initm[level->nummonsters].numwaypoints] = atoi(p);
p = strtok(NULL, " ");
level->initm[level->nummonsters].wayy[level->initm[level->nummonsters].numwaypoints] = atoi(p);
level->initm[level->nummonsters].numwaypoints++;
// go to next one
p = strtok(NULL, " ");
}
if ( level->initm[level->nummonsters].numwaypoints <= 0 ){
printf("missing waypoint data for platform!\n");
}
}
if (monid == P_PLAYER) {
level->p1x = x;
@ -520,7 +540,19 @@ int loadlevel(int wnum, int lnum, int wantmonsters) {
level->initm[i].startx, level->initm[i].starty, name );
#else
if (isplatform(level->initm[i].id)) {
sprite_t *newsp;
int w;
newsp = addsprite(level->initm[i].id, level->initm[i].startx, level->initm[i].starty, name );
newsp->numwaypoints = level->initm[i].numwaypoints;
for (w = 0; w < newsp->numwaypoints; w++) {
newsp->wayx[w] = level->initm[i].wayx[w];
newsp->wayy[w] = level->initm[i].wayy[w];
}
} else {
puffin(level->initm[i].id, level->initm[i].startx, level->initm[i].starty, name, delay );
}
#endif
}
}
@ -596,6 +628,8 @@ void setdefaults(sprite_t *s) {
s->frame = 0;
s->onplatform = NULL;
s->hasmask = B_FALSE;
s->hasbell = B_FALSE;
s->gemboost = 1;
@ -609,6 +643,7 @@ void setdefaults(sprite_t *s) {
s->recoiling = B_FALSE;
s->teleporting = 0;
s->climbing = 0;
s->swimming = 0;
s->jumping = 0;
s->jumpspeed = 0;
s->jumpdir = 1;
@ -763,6 +798,10 @@ sprite_t *addsprite(int id, int x, int y, char *name ) {
}
s->iceimg = NULL;
// waypoints for moving platforms
s->numwaypoints = 0;
s->curwaypoint = 0;
// don't set these in setdefaults() as setdefaults() is called after each player death
s->permspeed = B_FALSE;
s->permbignet = B_FALSE;
@ -1355,6 +1394,11 @@ int loadimagesets(void) {
loadspriteimage(P_ZAPPOWERUP,F_WALK1, "sprites/zapper.png");
imageset[P_ZAPPOWERUP].numimages = 1;
// moving platforms
loadspriteimage(P_PLATFORM,F_WALK1, "sprites/platform.png");
imageset[P_PLATFORM].numimages = 1;
loadspriteimage(P_ZAPPER,0, "sprites/zap1.png");
loadspriteimage(P_ZAPPER,1, "sprites/zap2.png");
loadspriteimage(P_ZAPPER,2, "sprites/zap3.png");
@ -2172,6 +2216,15 @@ int isbullet(int id) {
return B_FALSE;
}
int isplatform(int id) {
switch (id) {
case P_PLATFORM:
return B_TRUE;
}
return B_FALSE;
}
int iseffect(int id) {
switch (id) {
case P_PUFF:
@ -2193,6 +2246,7 @@ int iseffect(int id) {
// these last two aren't REALLY effects since they never have a sprite allocated
case P_WINGLEFT:
case P_WINGRIGHT:
case P_PLATFORM:
return B_TRUE;
}
@ -2204,6 +2258,7 @@ int needscollisions(int id) {
if (id == P_STAR) return B_TRUE;
if (id == P_METEOR) return B_TRUE;
if (id == P_ZAPPER) return B_TRUE;
if (isplatform(id)) return B_TRUE;
return B_FALSE;
}

View File

@ -20,6 +20,7 @@ int isfruit(int id);
int isflower(int id);
int iscard(int id);
int iseffect(int id);
int isplatform(int id);
int needscollisions(int id);
int candoslopes(int sid);
int flowertogem(int id);