Browse Source

add proper obj respawning

Thomas B 1 month ago
parent
commit
6f8baf7662
5 changed files with 106 additions and 59 deletions
  1. 1
    1
      src/game.c
  2. 1
    1
      src/main.c
  3. 101
    55
      src/obj.c
  4. 2
    1
      src/obj.h
  5. 1
    1
      src/sound.c

+ 1
- 1
src/game.c View File

@@ -349,7 +349,7 @@ int32_t game(void) NONBANKED {
349 349
         }
350 350
 
351 351
         int32_t prev_score = score;
352
-        int16_t damage = obj_do(&spd_x, &spd_y, &score, &hiwater);
352
+        int16_t damage = obj_do(&spd_x, &spd_y, &score, &hiwater, 0);
353 353
         if (damage > 0) {
354 354
             if (debug_flags & DBG_GOD_MODE) {
355 355
                 damage = 0;

+ 1
- 1
src/main.c View File

@@ -138,7 +138,7 @@ static void splash_anim(uint8_t *hiwater) NONBANKED {
138 138
     int16_t spd_off_x = 0;
139 139
     int16_t spd_off_y = 0;
140 140
     int32_t score = 0;
141
-    obj_do(&spd_off_x, &spd_off_y, &score, hiwater);
141
+    obj_do(&spd_off_x, &spd_off_y, &score, hiwater, 1);
142 142
 
143 143
     switch (state) {
144 144
         case 0:

+ 101
- 55
src/obj.c View File

@@ -73,9 +73,11 @@
73 73
 #define SCORE_SMALL 5
74 74
 #define SCORE_LARGE 10
75 75
 
76
-#define DESPAWN_RANGE (250 << POS_SCALE_OBJS)
76
+//#define DESPAWN_RANGE (0x7F << POS_SCALE_OBJS)
77 77
 
78
-#define PLACEMENT_DISTANCE 42
78
+#define INITIAL_DISTANCE 30 // from center
79
+#define RESPAWN_DISTANCE 100 // from center
80
+#define PLACEMENT_DISTANCE 42 // relative to each other
79 81
 
80 82
 struct obj {
81 83
     uint8_t active;
@@ -90,88 +92,108 @@ struct obj {
90 92
 static struct obj objs[MAX_OBJ];
91 93
 static uint8_t obj_cnt[SPRITE_COUNT];
92 94
 
95
+static const uint8_t obj_max[SPRITE_COUNT] = {
96
+    1, // SPR_SHIP
97
+    MAX_LIGHT, // SPR_LIGHT
98
+    MAX_DARK, // SPR_DARK
99
+    MAX_SHOT, // SPR_SHOT
100
+    MAX_SHOT_LIGHT, // SPR_SHOT_LIGHT
101
+    MAX_SHOT_DARK, // SPR_SHOT_DARK
102
+    4, // SPR_HEALTH
103
+    4, // SPR_POWER
104
+    1, // SPR_EXPL
105
+    1, // SPR_PAUSE
106
+    1, // SPR_DEBUG
107
+    1, // SPR_DEBUG_LARGE
108
+};
109
+
93 110
 void obj_init(void) BANKED {
94 111
     memset(objs, 0, sizeof(objs));
95 112
     memset(obj_cnt, 0, sizeof(obj_cnt));
96 113
 }
97 114
 
98
-static uint8_t is_too_close(int8_t x, int8_t y, uint8_t n, int8_t *x_c, int8_t *y_c) {
99
-    for (uint8_t i = 0; i < n; i++) {
100
-        int dst_x = abs(x_c[i] - x);
101
-        int dst_y = abs(y_c[i] - y);
115
+static uint8_t is_too_close(int8_t x, int8_t y, int8_t center_dist) {
116
+    if ((abs(x) < center_dist) && (abs(y) < center_dist)) {
117
+        return 1;
118
+    }
119
+
120
+    for (uint8_t i = 0; i < MAX_OBJ; i++) {
121
+        if (!objs[i].active) {
122
+            continue;
123
+        }
124
+
125
+        int dst_x = abs((objs[i].off_x >> POS_SCALE_OBJS) - x);
126
+        int dst_y = abs((objs[i].off_y >> POS_SCALE_OBJS) - y);
127
+
102 128
         if ((dst_x < PLACEMENT_DISTANCE) && (dst_y < PLACEMENT_DISTANCE)) {
103 129
             return 1;
104 130
         }
105 131
     }
132
+
106 133
     return 0;
107 134
 }
108 135
 
109
-static void generate_coords(uint8_t n, int8_t *x_c, int8_t *y_c) {
136
+static void generate_coords(int8_t *x_c, int8_t *y_c, int8_t center_dist) {
110 137
     int8_t x = 0;
111 138
     int8_t y = 0;
112 139
 
113 140
     do {
114 141
         x = arand();
115 142
         y = arand();
116
-    } while (is_too_close(x, y, n, x_c, y_c));
143
+    } while (is_too_close(x, y, center_dist));
117 144
 
118
-    x_c[n] = x;
119
-    y_c[n] = y;
145
+    *x_c = x;
146
+    *y_c = y;
120 147
 }
121 148
 
122
-void obj_spawn(void) BANKED {
123
-    int8_t x_coords[MAX_DARK + MAX_LIGHT + MAX_SHOT_DARK + MAX_SHOT_LIGHT + 1];
124
-    int8_t y_coords[MAX_DARK + MAX_LIGHT + MAX_SHOT_DARK + MAX_SHOT_LIGHT + 1];
125
-    memset(x_coords, 0, sizeof(x_coords));
126
-    memset(y_coords, 0, sizeof(y_coords));
127
-
128
-    for (uint8_t i = 0; i < MAX_DARK; i++) {
129
-        uint8_t n = i + 1;
130
-        generate_coords(n, x_coords, y_coords);
131
-        obj_add(SPR_DARK, x_coords[n], y_coords[n], 0, 0);
132
-    }
133
-    for (uint8_t i = 0; i < MAX_LIGHT; i++) {
134
-        uint8_t n = MAX_DARK + i + 1;
135
-        generate_coords(n, x_coords, y_coords);
136
-        obj_add(SPR_LIGHT, x_coords[n], y_coords[n], 0, 0);
137
-    }
138
-    for (uint8_t i = 0; i < MAX_SHOT_DARK; i++) {
139
-        uint8_t n = MAX_DARK + MAX_LIGHT + i + 1;
140
-        generate_coords(n, x_coords, y_coords);
141
-        obj_add(SPR_SHOT_DARK, x_coords[n], y_coords[n], 0, 0);
142
-    }
143
-    for (uint8_t i = 0; i < MAX_SHOT_LIGHT; i++) {
144
-        uint8_t n = MAX_DARK + MAX_LIGHT + MAX_SHOT_LIGHT + i + 1;
145
-        generate_coords(n, x_coords, y_coords);
146
-        obj_add(SPR_SHOT_LIGHT, x_coords[n], y_coords[n], 0, 0);
149
+static void obj_respawn(int8_t center_dist) {
150
+    for (uint8_t spr = SPR_LIGHT; spr <= SPR_SHOT_DARK; spr++) {
151
+        if (spr == SPR_SHOT) {
152
+            continue;
153
+        }
154
+
155
+        while (obj_cnt[spr] < obj_max[spr]) {
156
+            int8_t x, y;
157
+            generate_coords(&x, &y, center_dist);
158
+            obj_add(spr, x, y, 0, 0);
159
+        }
147 160
     }
148 161
 }
149 162
 
163
+void obj_spawn(void) BANKED {
164
+    obj_respawn(INITIAL_DISTANCE);
165
+}
166
+
150 167
 enum OBJ_STATE obj_add(enum SPRITES sprite, int16_t off_x, int16_t off_y, int16_t spd_x, int16_t spd_y) BANKED {
151
-    uint8_t obj_cnt = 0xFF;
168
+    uint8_t next = 0xFF;
152 169
     for (uint8_t i = 0; i < MAX_OBJ; i++) {
153 170
         if (!objs[i].active) {
154
-            obj_cnt = i;
171
+            next = i;
155 172
             break;
156 173
         }
157 174
     }
158
-    if (obj_cnt >= MAX_OBJ) {
175
+    if (next >= MAX_OBJ) {
159 176
         return OBJ_LIST_FULL;
160 177
     }
161 178
 
162
-    objs[obj_cnt].active = 1;
163
-    objs[obj_cnt].sprite = sprite;
164
-    objs[obj_cnt].off_x = off_x << POS_SCALE_OBJS;
165
-    objs[obj_cnt].off_y = off_y << POS_SCALE_OBJS;
166
-    objs[obj_cnt].spd_x = spd_x;
167
-    objs[obj_cnt].spd_y = spd_y;
168
-    objs[obj_cnt].travel = 0;
179
+    if (obj_cnt[sprite] >= obj_max[sprite]) {
180
+        return OBJ_TYPE_FULL;
181
+    }
182
+
183
+    obj_cnt[sprite]++;
184
+
185
+    objs[next].active = 1;
186
+    objs[next].sprite = sprite;
187
+    objs[next].off_x = off_x << POS_SCALE_OBJS;
188
+    objs[next].off_y = off_y << POS_SCALE_OBJS;
189
+    objs[next].spd_x = spd_x;
190
+    objs[next].spd_y = spd_y;
191
+    objs[next].travel = 0;
169 192
 
170
-    obj_cnt += 1;
171 193
     return OBJ_ADDED;
172 194
 }
173 195
 
174
-int16_t obj_do(int16_t *spd_off_x, int16_t *spd_off_y, int32_t *score, uint8_t *hiwater) BANKED {
196
+int16_t obj_do(int16_t *spd_off_x, int16_t *spd_off_y, int32_t *score, uint8_t *hiwater, uint8_t is_splash) BANKED {
175 197
     int16_t damage = 0;
176 198
 
177 199
     // initial speed
@@ -206,6 +228,7 @@ int16_t obj_do(int16_t *spd_off_x, int16_t *spd_off_y, int32_t *score, uint8_t *
206 228
         // remove objects that have traveled for too long
207 229
         if (objs[i].travel >= MAX_TRAVEL) {
208 230
             objs[i].active = 0;
231
+            obj_cnt[objs[i].sprite]--;
209 232
             continue;
210 233
         }
211 234
 
@@ -215,10 +238,13 @@ int16_t obj_do(int16_t *spd_off_x, int16_t *spd_off_y, int32_t *score, uint8_t *
215 238
         // handle collision
216 239
         switch (objs[i].sprite) {
217 240
             case SPR_DARK:
241
+#ifdef DESPAWN_RANGE
218 242
                 if ((abs_off_x >= DESPAWN_RANGE) || (abs_off_y >= DESPAWN_RANGE)) {
219
-                    // TODO find new (random) position
220
-                    //objs[i].active = 0;
243
+                    objs[i].active = 0;
244
+                    obj_cnt[objs[i].sprite]--;
245
+                    obj_respawn(RESPAWN_DISTANCE);
221 246
                 }
247
+#endif // DESPAWN_RANGE
222 248
 
223 249
                 if ((abs_off_x <= GRAVITY_RANGE) && (abs_off_y <= GRAVITY_RANGE)) {
224 250
                     if (objs[i].off_x > 0) {
@@ -239,10 +265,13 @@ int16_t obj_do(int16_t *spd_off_x, int16_t *spd_off_y, int32_t *score, uint8_t *
239 265
                 break;
240 266
 
241 267
             case SPR_LIGHT:
268
+#ifdef DESPAWN_RANGE
242 269
                 if ((abs_off_x >= DESPAWN_RANGE) || (abs_off_y >= DESPAWN_RANGE)) {
243
-                    // TODO find new (random) position
244
-                    //objs[i].active = 0;
270
+                    objs[i].active = 0;
271
+                    obj_cnt[objs[i].sprite]--;
272
+                    obj_respawn(RESPAWN_DISTANCE);
245 273
                 }
274
+#endif // DESPAWN_RANGE
246 275
 
247 276
                 if ((abs_off_x <= GRAVITY_RANGE) && (abs_off_y <= GRAVITY_RANGE)) {
248 277
                     if (objs[i].off_x > 0) {
@@ -263,26 +292,36 @@ int16_t obj_do(int16_t *spd_off_x, int16_t *spd_off_y, int32_t *score, uint8_t *
263 292
                 break;
264 293
 
265 294
             case SPR_SHOT_DARK:
295
+#ifdef DESPAWN_RANGE
266 296
                 if ((abs_off_x >= DESPAWN_RANGE) || (abs_off_y >= DESPAWN_RANGE)) {
267
-                    // TODO find new (random) position
268
-                    //objs[i].active = 0;
297
+                    objs[i].active = 0;
298
+                    obj_cnt[objs[i].sprite]--;
299
+                    obj_respawn(RESPAWN_DISTANCE);
269 300
                 }
301
+#endif // DESPAWN_RANGE
270 302
 
271 303
                 if ((abs_off_x <= PICKUP_SMALL_RANGE) && (abs_off_y <= PICKUP_SMALL_RANGE)) {
272 304
                     (*score) -= SCORE_SMALL;
273 305
                     objs[i].active = 0;
306
+                    obj_cnt[objs[i].sprite]--;
307
+                    obj_respawn(RESPAWN_DISTANCE);
274 308
                 }
275 309
                 break;
276 310
 
277 311
             case SPR_SHOT_LIGHT:
312
+#ifdef DESPAWN_RANGE
278 313
                 if ((abs_off_x >= DESPAWN_RANGE) || (abs_off_y >= DESPAWN_RANGE)) {
279
-                    // TODO find new (random) position
280
-                    //objs[i].active = 0;
314
+                    objs[i].active = 0;
315
+                    obj_cnt[objs[i].sprite]--;
316
+                    obj_respawn(RESPAWN_DISTANCE);
281 317
                 }
318
+#endif // DESPAWN_RANGE
282 319
 
283 320
                 if ((abs_off_x <= PICKUP_SMALL_RANGE) && (abs_off_y <= PICKUP_SMALL_RANGE)) {
284 321
                     (*score) += SCORE_SMALL;
285 322
                     objs[i].active = 0;
323
+                    obj_cnt[objs[i].sprite]--;
324
+                    obj_respawn(RESPAWN_DISTANCE);
286 325
                 }
287 326
                 break;
288 327
 
@@ -297,6 +336,13 @@ int16_t obj_do(int16_t *spd_off_x, int16_t *spd_off_y, int32_t *score, uint8_t *
297 336
                         objs[i].active = 0;
298 337
                         objs[j].active = 0;
299 338
 
339
+                        obj_cnt[objs[i].sprite]--;
340
+                        obj_cnt[objs[j].sprite]--;
341
+
342
+                        if (!is_splash) {
343
+                            obj_respawn(RESPAWN_DISTANCE);
344
+                        }
345
+
300 346
                         if (objs[j].sprite == SPR_LIGHT) {
301 347
                             (*score) += SCORE_LARGE;
302 348
                         } else {

+ 2
- 1
src/obj.h View File

@@ -28,11 +28,12 @@
28 28
 enum OBJ_STATE {
29 29
     OBJ_ADDED = 0,
30 30
     OBJ_LIST_FULL,
31
+    OBJ_TYPE_FULL,
31 32
 };
32 33
 
33 34
 void obj_init(void) BANKED;
34 35
 void obj_spawn(void) BANKED;
35 36
 enum OBJ_STATE obj_add(enum SPRITES sprite, int16_t off_x, int16_t off_y, int16_t spd_x, int16_t spd_y) BANKED;
36
-int16_t obj_do(int16_t *spd_off_x, int16_t *spd_off_y, int32_t *score, uint8_t *hiwater) BANKED;
37
+int16_t obj_do(int16_t *spd_off_x, int16_t *spd_off_y, int32_t *score, uint8_t *hiwater, uint8_t is_splash) BANKED;
37 38
 
38 39
 #endif // __OBJ_H__

+ 1
- 1
src/sound.c View File

@@ -123,7 +123,7 @@ void snd_play(void) NONBANKED {
123 123
             } else {
124 124
                 off = 0xFFFF;
125 125
             }
126
-            last_t = timer_get();
126
+            last_t += music->duration;
127 127
         }
128 128
     END_ROM_BANK();
129 129
 }

Loading…
Cancel
Save