11
11
#define GRAVITY_BOOST -0.3
12
12
#define GRAVITY_TICK 0.15
13
13
#define PARTIVLE_VELOCITY 2
14
+ #define SCIENTIST_VELOCITY_MIN 2
15
+ #define SCIENTIST_VELOCITY_MAX 2
14
16
15
17
#define SCIENTISTS_MAX 6
16
18
#define COINS_MAX 25
@@ -24,7 +26,6 @@ typedef struct {
24
26
typedef struct {
25
27
float gravity ;
26
28
POINT point ;
27
- IconAnimation * sprite ;
28
29
bool isBoosting ;
29
30
} BARRY ;
30
31
@@ -37,17 +38,29 @@ typedef struct {
37
38
POINT point ;
38
39
} PARTICLE ;
39
40
41
+ typedef enum {
42
+ ScientistStateAlive ,
43
+ ScientistStateDead ,
44
+ } ScientistState ;
40
45
typedef struct {
41
46
float gravity ;
42
47
POINT point ;
43
- IconAnimation * sprite ;
48
+ int velocity_x ;
49
+ ScientistState state ;
44
50
} SCIENTIST ;
45
51
46
52
typedef enum {
47
53
GameStateLife ,
48
54
GameStateGameOver ,
49
55
} State ;
50
56
57
+ typedef struct {
58
+ IconAnimation * barry ;
59
+ IconAnimation * scientist ;
60
+ Icon * coin ;
61
+ Icon * dead_scientist ;
62
+ } GameSprites ;
63
+
51
64
typedef struct {
52
65
int points ;
53
66
int distance ;
@@ -56,6 +69,7 @@ typedef struct {
56
69
COIN coins [COINS_MAX ];
57
70
PARTICLE particles [PARTICLES_MAX ];
58
71
State state ;
72
+ GameSprites sprites ;
59
73
FuriMutex * mutex ;
60
74
} GameState ;
61
75
@@ -80,6 +94,22 @@ static void jetpack_game_random_coins(GameState* const game_state) {
80
94
}
81
95
}
82
96
97
+ static void jetpack_game_random_scientists (GameState * const game_state ) {
98
+ // Check for an available slot for a new scientist
99
+ for (int i = 0 ; i < SCIENTISTS_MAX ; ++ i ) {
100
+ if (game_state -> scientists [i ].point .x <= 0 &&
101
+ (rand () % 1000 ) < 10 ) { // Spawn rate is less frequent than coins
102
+ game_state -> scientists [i ].state = ScientistStateAlive ;
103
+ game_state -> scientists [i ].point .x = 127 ;
104
+ game_state -> scientists [i ].point .y = 49 ;
105
+ game_state -> scientists [i ].velocity_x =
106
+ (rand () % (SCIENTIST_VELOCITY_MAX - SCIENTIST_VELOCITY_MIN + 1 )) +
107
+ SCIENTIST_VELOCITY_MIN ; // random velocity between SCIENTIST_VELOCITY_MIN and SCIENTIST_VELOCITY_MAX
108
+ break ;
109
+ }
110
+ }
111
+ }
112
+
83
113
static void jetpack_game_spawn_particles (GameState * const game_state ) {
84
114
for (int i = 0 ; i < PARTICLES_MAX ; i ++ ) {
85
115
if (game_state -> particles [i ].point .y <= 0 ) {
@@ -97,14 +127,19 @@ static void jetpack_game_state_init(GameState* const game_state) {
97
127
barry .gravity = 0 ;
98
128
barry .point .x = 64 ;
99
129
barry .point .y = 32 ;
100
- barry .sprite = icon_animation_alloc (& A_barry );
101
130
barry .isBoosting = false;
102
131
103
- icon_animation_start (barry .sprite );
132
+ GameSprites sprites ;
133
+ sprites .barry = icon_animation_alloc (& A_barry );
134
+ sprites .scientist = icon_animation_alloc (& A_scientist );
135
+
136
+ icon_animation_start (sprites .scientist );
137
+ icon_animation_start (sprites .barry );
104
138
105
139
game_state -> barry = barry ;
106
140
game_state -> points = 0 ;
107
141
game_state -> distance = 0 ;
142
+ game_state -> sprites = sprites ;
108
143
game_state -> state = GameStateLife ;
109
144
110
145
memset (game_state -> scientists , 0 , sizeof (game_state -> scientists ));
@@ -113,7 +148,8 @@ static void jetpack_game_state_init(GameState* const game_state) {
113
148
}
114
149
115
150
static void jetpack_game_state_free (GameState * const game_state ) {
116
- icon_animation_free (game_state -> barry .sprite );
151
+ icon_animation_free (game_state -> sprites .barry );
152
+ icon_animation_free (game_state -> sprites .scientist );
117
153
free (game_state );
118
154
}
119
155
@@ -152,13 +188,49 @@ static void jetpack_game_tick(GameState* const game_state) {
152
188
for (int i = 0 ; i < PARTICLES_MAX ; i ++ ) {
153
189
if (game_state -> particles [i ].point .y > 0 ) {
154
190
game_state -> particles [i ].point .y += PARTIVLE_VELOCITY ;
191
+
192
+ // Check collision with scientists
193
+ for (int j = 0 ; j < SCIENTISTS_MAX ; j ++ ) {
194
+ if (game_state -> scientists [j ].state == ScientistStateAlive &&
195
+ game_state -> scientists [j ].point .x > 0 ) {
196
+ // Added half the width and height of the scientist sprite to the scientist's x and y respectively
197
+ float scientist_center_x = game_state -> scientists [j ].point .x + 5.5 ;
198
+ float scientist_center_y = game_state -> scientists [j ].point .y + 7.5 ;
199
+ if (!(game_state -> particles [i ].point .x >
200
+ scientist_center_x +
201
+ 5.5 || // particle is to the right of the scientist
202
+ game_state -> particles [i ].point .x + 11 <
203
+ scientist_center_x -
204
+ 5.5 || // particle is to the left of the scientist
205
+ game_state -> particles [i ].point .y >
206
+ scientist_center_y + 7.5 || // particle is below the scientist
207
+ game_state -> particles [i ].point .y + 15 <
208
+ scientist_center_y - 7.5 )) { // particle is above the scientist
209
+ game_state -> scientists [j ].state = ScientistStateDead ;
210
+ game_state -> points += 2 ; // Increase the score by 2
211
+ }
212
+ }
213
+ }
214
+
155
215
if (game_state -> particles [i ].point .x < 0 || game_state -> particles [i ].point .x > 128 ||
156
216
game_state -> particles [i ].point .y < 0 || game_state -> particles [i ].point .y > 64 ) {
157
217
game_state -> particles [i ].point .y = 0 ;
158
218
}
159
219
}
160
220
}
161
221
222
+ // Move scientists
223
+ for (int i = 0 ; i < SCIENTISTS_MAX ; i ++ ) {
224
+ if (game_state -> scientists [i ].point .x > 0 ) {
225
+ game_state -> scientists [i ].point .x -=
226
+ game_state -> scientists [i ].velocity_x ; // move based on velocity_x
227
+ if (game_state -> scientists [i ].point .x < -16 ) { // if the scientist is out of screen
228
+ game_state -> scientists [i ].point .x =
229
+ 0 ; // set scientist x coordinate to 0 to mark it as "inactive"
230
+ }
231
+ }
232
+ }
233
+
162
234
// Spawn scientists and coins...
163
235
jetpack_game_random_coins (game_state );
164
236
// Sprite height of Barry
@@ -175,6 +247,7 @@ static void jetpack_game_tick(GameState* const game_state) {
175
247
176
248
// spawn scientists and coins...
177
249
jetpack_game_random_coins (game_state );
250
+ jetpack_game_random_scientists (game_state );
178
251
179
252
if (game_state -> barry .isBoosting ) {
180
253
game_state -> barry .gravity += GRAVITY_BOOST ;
@@ -187,8 +260,6 @@ static void jetpack_game_render_callback(Canvas* const canvas, void* ctx) {
187
260
const GameState * game_state = ctx ;
188
261
furi_mutex_acquire (game_state -> mutex , FuriWaitForever );
189
262
190
- canvas_draw_frame (canvas , 0 , 0 , 128 , 64 );
191
-
192
263
if (game_state -> state == GameStateLife ) {
193
264
// Draw scene
194
265
@@ -200,9 +271,28 @@ static void jetpack_game_render_callback(Canvas* const canvas, void* ctx) {
200
271
}
201
272
}
202
273
274
+ // Draw scientists
275
+ for (int i = 0 ; i < SCIENTISTS_MAX ; ++ i ) {
276
+ if (game_state -> scientists [i ].point .x > 0 ) {
277
+ if (game_state -> scientists [i ].state == ScientistStateAlive ) {
278
+ canvas_draw_icon_animation (
279
+ canvas ,
280
+ game_state -> scientists [i ].point .x ,
281
+ game_state -> scientists [i ].point .y ,
282
+ game_state -> sprites .scientist );
283
+ } else {
284
+ canvas_draw_icon (
285
+ canvas ,
286
+ game_state -> scientists [i ].point .x ,
287
+ game_state -> scientists [i ].point .y ,
288
+ & I_dead_scientist );
289
+ }
290
+ }
291
+ }
292
+
203
293
// Draw particles
204
294
for (int i = 0 ; i < PARTICLES_MAX ; i ++ ) {
205
- if (game_state -> particles [i ].point .x > 0 ) {
295
+ if (game_state -> particles [i ].point .y > 0 ) {
206
296
canvas_draw_line (
207
297
canvas ,
208
298
game_state -> particles [i ].point .x ,
@@ -214,7 +304,10 @@ static void jetpack_game_render_callback(Canvas* const canvas, void* ctx) {
214
304
215
305
// Draw barry
216
306
canvas_draw_icon_animation (
217
- canvas , game_state -> barry .point .x , game_state -> barry .point .y , game_state -> barry .sprite );
307
+ canvas ,
308
+ game_state -> barry .point .x ,
309
+ game_state -> barry .point .y ,
310
+ game_state -> sprites .barry );
218
311
219
312
canvas_set_font (canvas , FontSecondary );
220
313
char buffer [12 ];
@@ -229,6 +322,8 @@ static void jetpack_game_render_callback(Canvas* const canvas, void* ctx) {
229
322
// Show highscore
230
323
}
231
324
325
+ canvas_draw_frame (canvas , 0 , 0 , 128 , 64 );
326
+
232
327
furi_mutex_release (game_state -> mutex );
233
328
}
234
329
0 commit comments