JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
we now return you to your regularly scheduled exploding ship.
authorJoshua Grams <josh@qualdan.com>
Fri, 24 Mar 2006 00:09:35 +0000 (00:09 +0000)
committerJoshua Grams <josh@qualdan.com>
Fri, 24 Mar 2006 00:09:35 +0000 (00:09 +0000)
Makefile
config.h
main.c
sprite.c
sprite.h
todo

index 650a98b..42d1fe9 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -75,7 +75,7 @@ main.o: args.h common.h dust.h file.h globals.h mt.h rocks.h score.h sprite.h so
 
 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
 
index da4c6a5..f49de04 100644 (file)
--- a/config.h
+++ b/config.h
@@ -23,8 +23,8 @@
 #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
diff --git a/main.c b/main.c
index 880f14e..a068033 100644 (file)
--- a/main.c
+++ b/main.c
@@ -77,6 +77,7 @@ float t_frame;  // length of this frame (in ticks = 1/20th second)
 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;
@@ -388,6 +389,7 @@ init(void) {
        init_dust();
 
        init_sprites();
+       add_sprite(SPRITE(&ship));
 
        // Remove the mouse cursor
 #ifdef SDL_DISABLE
@@ -397,16 +399,14 @@ init(void) {
        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);
 
@@ -509,13 +509,7 @@ draw() {
                        ; // 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;
@@ -531,15 +525,18 @@ draw() {
 
        // 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
@@ -556,6 +553,7 @@ gameloop() {
                                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;
@@ -620,7 +618,6 @@ gameloop() {
                        bangx += bangdx*t_frame - xscroll;
                        bangy += bangdy*t_frame - yscroll;
 
-                       move_sprite(SPRITE(&ship));
                        move_sprites();
 
 
@@ -638,13 +635,15 @@ gameloop() {
                                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;
@@ -652,8 +651,7 @@ gameloop() {
                                        state_timeout = 200.0;
                                        fadetimer = 0.0;
                                        faderate = t_frame;
-                               }
-                               else {
+                               } else {
                                        state = DEAD_PAUSE;
                                        state_timeout = DEAD_PAUSE_LENGTH;
                                }
@@ -664,17 +662,18 @@ gameloop() {
 
                        // 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;
index 1905510..1609368 100644 (file)
--- a/sprite.c
+++ b/sprite.c
@@ -111,10 +111,25 @@ square(int x, int y, int set)
 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.
@@ -128,8 +143,9 @@ sort_sprite(Sprite *s)
        // 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);
 }
 
@@ -139,7 +155,7 @@ move_sprites(void)
        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) {
@@ -215,14 +231,25 @@ collide(Sprite *a, Sprite *b)
 }
 
 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 *
@@ -279,7 +306,7 @@ int
 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;
 }
index 0c04cac..f9070b4 100644 (file)
--- a/sprite.h
+++ b/sprite.h
@@ -31,6 +31,7 @@ void do_collision(Sprite *a, Sprite *b);
 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);
@@ -98,7 +99,7 @@ static inline 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);
 }
diff --git a/todo b/todo
index d1b9de2..06d61c8 100644 (file)
--- a/todo
+++ b/todo
@@ -1,7 +1,6 @@
 ****   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?