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
         }
349
         }
350
 
350
 
351
         int32_t prev_score = score;
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
         if (damage > 0) {
353
         if (damage > 0) {
354
             if (debug_flags & DBG_GOD_MODE) {
354
             if (debug_flags & DBG_GOD_MODE) {
355
                 damage = 0;
355
                 damage = 0;

+ 1
- 1
src/main.c View File

138
     int16_t spd_off_x = 0;
138
     int16_t spd_off_x = 0;
139
     int16_t spd_off_y = 0;
139
     int16_t spd_off_y = 0;
140
     int32_t score = 0;
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
     switch (state) {
143
     switch (state) {
144
         case 0:
144
         case 0:

+ 101
- 55
src/obj.c View File

73
 #define SCORE_SMALL 5
73
 #define SCORE_SMALL 5
74
 #define SCORE_LARGE 10
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
 struct obj {
82
 struct obj {
81
     uint8_t active;
83
     uint8_t active;
90
 static struct obj objs[MAX_OBJ];
92
 static struct obj objs[MAX_OBJ];
91
 static uint8_t obj_cnt[SPRITE_COUNT];
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
 void obj_init(void) BANKED {
110
 void obj_init(void) BANKED {
94
     memset(objs, 0, sizeof(objs));
111
     memset(objs, 0, sizeof(objs));
95
     memset(obj_cnt, 0, sizeof(obj_cnt));
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
         if ((dst_x < PLACEMENT_DISTANCE) && (dst_y < PLACEMENT_DISTANCE)) {
128
         if ((dst_x < PLACEMENT_DISTANCE) && (dst_y < PLACEMENT_DISTANCE)) {
103
             return 1;
129
             return 1;
104
         }
130
         }
105
     }
131
     }
132
+
106
     return 0;
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
     int8_t x = 0;
137
     int8_t x = 0;
111
     int8_t y = 0;
138
     int8_t y = 0;
112
 
139
 
113
     do {
140
     do {
114
         x = arand();
141
         x = arand();
115
         y = arand();
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
 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 {
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
     for (uint8_t i = 0; i < MAX_OBJ; i++) {
169
     for (uint8_t i = 0; i < MAX_OBJ; i++) {
153
         if (!objs[i].active) {
170
         if (!objs[i].active) {
154
-            obj_cnt = i;
171
+            next = i;
155
             break;
172
             break;
156
         }
173
         }
157
     }
174
     }
158
-    if (obj_cnt >= MAX_OBJ) {
175
+    if (next >= MAX_OBJ) {
159
         return OBJ_LIST_FULL;
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
     return OBJ_ADDED;
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
     int16_t damage = 0;
197
     int16_t damage = 0;
176
 
198
 
177
     // initial speed
199
     // initial speed
206
         // remove objects that have traveled for too long
228
         // remove objects that have traveled for too long
207
         if (objs[i].travel >= MAX_TRAVEL) {
229
         if (objs[i].travel >= MAX_TRAVEL) {
208
             objs[i].active = 0;
230
             objs[i].active = 0;
231
+            obj_cnt[objs[i].sprite]--;
209
             continue;
232
             continue;
210
         }
233
         }
211
 
234
 
215
         // handle collision
238
         // handle collision
216
         switch (objs[i].sprite) {
239
         switch (objs[i].sprite) {
217
             case SPR_DARK:
240
             case SPR_DARK:
241
+#ifdef DESPAWN_RANGE
218
                 if ((abs_off_x >= DESPAWN_RANGE) || (abs_off_y >= DESPAWN_RANGE)) {
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
                 if ((abs_off_x <= GRAVITY_RANGE) && (abs_off_y <= GRAVITY_RANGE)) {
249
                 if ((abs_off_x <= GRAVITY_RANGE) && (abs_off_y <= GRAVITY_RANGE)) {
224
                     if (objs[i].off_x > 0) {
250
                     if (objs[i].off_x > 0) {
239
                 break;
265
                 break;
240
 
266
 
241
             case SPR_LIGHT:
267
             case SPR_LIGHT:
268
+#ifdef DESPAWN_RANGE
242
                 if ((abs_off_x >= DESPAWN_RANGE) || (abs_off_y >= DESPAWN_RANGE)) {
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
                 if ((abs_off_x <= GRAVITY_RANGE) && (abs_off_y <= GRAVITY_RANGE)) {
276
                 if ((abs_off_x <= GRAVITY_RANGE) && (abs_off_y <= GRAVITY_RANGE)) {
248
                     if (objs[i].off_x > 0) {
277
                     if (objs[i].off_x > 0) {
263
                 break;
292
                 break;
264
 
293
 
265
             case SPR_SHOT_DARK:
294
             case SPR_SHOT_DARK:
295
+#ifdef DESPAWN_RANGE
266
                 if ((abs_off_x >= DESPAWN_RANGE) || (abs_off_y >= DESPAWN_RANGE)) {
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
                 if ((abs_off_x <= PICKUP_SMALL_RANGE) && (abs_off_y <= PICKUP_SMALL_RANGE)) {
303
                 if ((abs_off_x <= PICKUP_SMALL_RANGE) && (abs_off_y <= PICKUP_SMALL_RANGE)) {
272
                     (*score) -= SCORE_SMALL;
304
                     (*score) -= SCORE_SMALL;
273
                     objs[i].active = 0;
305
                     objs[i].active = 0;
306
+                    obj_cnt[objs[i].sprite]--;
307
+                    obj_respawn(RESPAWN_DISTANCE);
274
                 }
308
                 }
275
                 break;
309
                 break;
276
 
310
 
277
             case SPR_SHOT_LIGHT:
311
             case SPR_SHOT_LIGHT:
312
+#ifdef DESPAWN_RANGE
278
                 if ((abs_off_x >= DESPAWN_RANGE) || (abs_off_y >= DESPAWN_RANGE)) {
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
                 if ((abs_off_x <= PICKUP_SMALL_RANGE) && (abs_off_y <= PICKUP_SMALL_RANGE)) {
320
                 if ((abs_off_x <= PICKUP_SMALL_RANGE) && (abs_off_y <= PICKUP_SMALL_RANGE)) {
284
                     (*score) += SCORE_SMALL;
321
                     (*score) += SCORE_SMALL;
285
                     objs[i].active = 0;
322
                     objs[i].active = 0;
323
+                    obj_cnt[objs[i].sprite]--;
324
+                    obj_respawn(RESPAWN_DISTANCE);
286
                 }
325
                 }
287
                 break;
326
                 break;
288
 
327
 
297
                         objs[i].active = 0;
336
                         objs[i].active = 0;
298
                         objs[j].active = 0;
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
                         if (objs[j].sprite == SPR_LIGHT) {
346
                         if (objs[j].sprite == SPR_LIGHT) {
301
                             (*score) += SCORE_LARGE;
347
                             (*score) += SCORE_LARGE;
302
                         } else {
348
                         } else {

+ 2
- 1
src/obj.h View File

28
 enum OBJ_STATE {
28
 enum OBJ_STATE {
29
     OBJ_ADDED = 0,
29
     OBJ_ADDED = 0,
30
     OBJ_LIST_FULL,
30
     OBJ_LIST_FULL,
31
+    OBJ_TYPE_FULL,
31
 };
32
 };
32
 
33
 
33
 void obj_init(void) BANKED;
34
 void obj_init(void) BANKED;
34
 void obj_spawn(void) BANKED;
35
 void obj_spawn(void) BANKED;
35
 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
 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
 #endif // __OBJ_H__
39
 #endif // __OBJ_H__

+ 1
- 1
src/sound.c View File

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

Loading…
Cancel
Save