mt.o: mt.h
-rocks.o: rocks.h common.h file.h globals.h mt.h
+rocks.o: rocks.h common.h file.h globals.h mt.h sprite.h
score.o: score.h common.h file.h
#define NROCKS 50
// initial/final counts for rocks-on-screen
-#define I_ROCKS 25
-#define F_ROCKS 45
+#define I_ROCKS 20
+#define F_ROCKS 40
// number of rock structs to allocate
#define MAXROCKS 120
int ms_frame; // length of this frame (milliseconds)
int ms_end; // end of this frame (milliseconds)
+int bang = false;
float bangx, bangy, bangdx, bangdy;
int score;
init_dust();
init_sprites();
+ add_sprite(SPRITE(&ship));
// Remove the mouse cursor
#ifdef SDL_DISABLE
return 0;
}
-int
-draw() {
+void
+draw(void) {
int i;
SDL_Rect dest;
- int bang, x;
+ int x;
char *text;
float fadegame,fadeover;
- bang = 0;
-
// Draw a fully black background
SDL_FillRect(surf_screen,NULL,0);
; // no action necessary
}
- if(state == GAMEPLAY) {
- Sprite *r = collides(SPRITE(&ship));
- if(r) {
- bounce(r, SPRITE(&ship));
- }
- collisions();
- }
+ collisions();
ms_frame = SDL_GetTicks() - ms_end;
ms_end += ms_frame;
// Update the surface
SDL_Flip(surf_screen);
-
-
- return bang;
}
void
do_collision(Sprite *a, Sprite *b)
{
- bounce(a, b);
+ if(a->type == SHIP) {
+ a->type = -SHIP; bang = true;
+ } else if (b->type == SHIP) {
+ b->type = -SHIP; bang = true;
+ } else {
+ bounce(a, b);
+ }
}
int
switch(state) {
case DEAD_PAUSE:
// Create a new ship and start all over again
+ ship.sprite_type = SHIP;
state = GAMEPLAY;
play_tune(TUNE_GAMEPLAY);
break;
bangx += bangdx*t_frame - xscroll;
bangy += bangdy*t_frame - yscroll;
- move_sprite(SPRITE(&ship));
move_sprites();
ship.dy = screendy - (ship.dy-screendy)*opt_bounciness;
}
+ draw();
- if(draw() && state == GAMEPLAY) {
+ if(state == GAMEPLAY && bang) {
// Died
+ bang = false;
play_sound(SOUND_BANG); // Play the explosion sound
bangx = ship.x; bangy = ship.y; bangdx = ship.dx; bangdy = ship.dy;
- new_bang_dots(ship.x,ship.y,ship.dx,ship.dy,ship.image);
- ship.dx *= 0.5; ship.dy *= 0.5;
+ new_bang_dots(ship.x,ship.y,ship.dx,ship.dy,ship.image);
+ ship.dx *= 0.5; ship.dy *= 0.5;
if(ship.dx < SCREENDXMIN) ship.dx = SCREENDXMIN;
if(--ship.lives <= 0) {
state = GAME_OVER;
state_timeout = 200.0;
fadetimer = 0.0;
faderate = t_frame;
- }
- else {
+ } else {
state = DEAD_PAUSE;
state_timeout = DEAD_PAUSE_LENGTH;
}
// new game
if(keystate[SDLK_SPACE] && (state == HIGH_SCORE_DISPLAY || state == TITLE_PAGE)) {
-
+ reset_sprites();
reset_rocks();
+ ship.x = XSIZE/2.2; ship.y = YSIZE/2;
+ ship.dx = screendx; ship.dy = screendy;
ship.lives = 4;
+ add_sprite(SPRITE(&ship));
+
score = 0;
state = GAMEPLAY;
play_tune(TUNE_GAMEPLAY);
-
- ship.x = XSIZE/2.2; ship.y = YSIZE/2;
- ship.dx = screendx; ship.dy = screendy;
}
ship.jets = 0;
void
add_sprite(Sprite *s)
{
+ if(s->type < 0) s->type = -s->type;
insert_sprite(square(s->x, s->y, set), s);
}
void
+reset_sprites(void)
+{
+ int i;
+
+ for(i=0; i<gw*gh; i++)
+ while(sprites[set][i]) {
+ Sprite *s = remove_sprite(&sprites[set][i]);
+ if(s->type < 0) s->type = -s->type;
+ insert_sprite(&free_sprites[s->type], s);
+ if(s->type > 0) s->type = -s->type;
+ }
+}
+
+void
move_sprite(Sprite *s)
{
// move it.
// clip it, or sort it into the other set of sprites.
if(s->x + s->w < 0 || s->x >= XSIZE
|| s->y + s->h < 0 || s->y >= YSIZE) {
+ if(s->type < 0) s->type = -s->type;
insert_sprite(&free_sprites[s->type], s);
- s->type = NONE;
+ if(s->type > 0) s->type = -s->type;
} else insert_sprite(square(s->x, s->y, 1-set), s);
}
int sq;
Sprite **head;
- // Move all the sprites (position and set)
+ // Move all the sprites
for(sq=0; sq<gw*gh; sq++) {
head=&sprites[set][sq];
while(*head) {
}
void
+collide_with_list(Sprite *s, Sprite *list)
+{
+ for(; list; list=list->next)
+ if(collide(s, list)) do_collision(s, list);
+}
+
+void
collisions(void)
{
- int i;
- Sprite *a, *b;
- for(i=0; i<gw*gh; i++)
- for(a=sprites[set][i]; a; a=a->next)
- for(b=a->next; b; b=b->next)
- if(collide(a, b)) do_collision(a, b);
+ int i, end = gw*gh;
+ Sprite *s;
+ for(i=0; i<end; i++) {
+ for(s=sprites[set][i]; s; s=s->next) {
+ collide_with_list(s, s->next);
+ if(i+1 < end) collide_with_list(s, sprites[set][i+1]);
+ if(i+gw < end) collide_with_list(s, sprites[set][i+gw]);
+ if(i+gw+1 < end) collide_with_list(s, sprites[set][i+gw+1]);
+ }
+ }
}
Sprite *
pixel_hit_in_square(Sprite *r, float x, float y)
{
for(; r; r=r->next) {
- if(pixel_collide(r, x, y)) return 1;
+ if(r->type >= 0 && pixel_collide(r, x, y)) return 1;
}
return 0;
}
void collisions(void);
void init_sprites(void);
+void reset_sprites(void);
void add_sprite(Sprite *s);
void move_sprite(Sprite *s);
void move_sprites(void);
draw_sprite(Sprite *s)
{
SDL_Rect dest;
- if(s->type == NONE) return;
+ if(s->type < 0) return;
dest.x = s->x; dest.y = s->y;
SDL_BlitSurface(s->image, NULL, surf_screen, &dest);
}
**** Finish porting to Windows (should be only file.c and args.c, I think)
-*** Switch over to sprites rather than totally separate structures.
-* Rocks collide with each other?
+** BUG: Rocks can be created touching, often giving a high-velocity bounce.
*** Add a scripting language and separate game logic from the engine.
Forth? Scheme? Lua?