瀏覽代碼

missiles!

Tim Strasser 2 年之前
父節點
當前提交
3b2aba91a9
共有 6 個文件被更改,包括 118 次插入7 次删除
  1. 1 0
      includes/game_sprites.h
  2. 4 6
      includes/game_state.h
  3. 54 0
      includes/missile.c
  4. 23 0
      includes/missile.h
  5. 9 0
      includes/states.h
  6. 27 1
      jetpack.c

+ 1 - 0
includes/game_sprites.h

@@ -6,6 +6,7 @@
 typedef struct {
 typedef struct {
     IconAnimation* barry;
     IconAnimation* barry;
     IconAnimation* scientist;
     IconAnimation* scientist;
+    IconAnimation* missile;
 } GameSprites;
 } GameSprites;
 
 
 #endif // GAME_SPRITES_H
 #endif // GAME_SPRITES_H

+ 4 - 6
includes/game_state.h

@@ -9,12 +9,8 @@
 #include "coin.h"
 #include "coin.h"
 #include "particle.h"
 #include "particle.h"
 #include "game_sprites.h"
 #include "game_sprites.h"
-
-typedef enum {
-    GameStateLife,
-    GameStateGameOver,
-} State;
-
+#include "states.h"
+#include "missile.h"
 typedef struct {
 typedef struct {
     int points;
     int points;
     int distance;
     int distance;
@@ -22,9 +18,11 @@ typedef struct {
     COIN coins[COINS_MAX];
     COIN coins[COINS_MAX];
     PARTICLE particles[PARTICLES_MAX];
     PARTICLE particles[PARTICLES_MAX];
     SCIENTIST scientists[SCIENTISTS_MAX];
     SCIENTIST scientists[SCIENTISTS_MAX];
+    MISSILE missiles[MISSILES_MAX];
     State state;
     State state;
     GameSprites sprites;
     GameSprites sprites;
     FuriMutex* mutex;
     FuriMutex* mutex;
+    FuriTimer* timer;
 } GameState;
 } GameState;
 
 
 void game_state_tick(GameState* const game_state);
 void game_state_tick(GameState* const game_state);

+ 54 - 0
includes/missile.c

@@ -0,0 +1,54 @@
+#include <stdlib.h>
+#include <stdbool.h>
+
+#include <jetpack_joyride_icons.h>
+#include <gui/gui.h>
+
+#include "states.h"
+#include "game_sprites.h"
+#include "missile.h"
+#include "barry.h"
+
+void missile_tick(MISSILE* const missiles, BARRY* const barry, State* const state) {
+    // Move missiles towards the player
+    for(int i = 0; i < MISSILES_MAX; i++) {
+        if(missile_colides(&missiles[i], barry)) {
+            (*state) = GameStateGameOver;
+            UNUSED(state);
+        }
+        if(missiles[i].point.x > 0) {
+            missiles[i].point.x -= 2; // move left by 2 units
+            if(missiles[i].point.x < -16) { // if the coin is out of screen
+                missiles[i].point.x = 0; // set coin x coordinate to 0 to mark it as "inactive"
+            }
+        }
+    }
+}
+
+bool missile_colides(MISSILE* const missile, BARRY* const barry) {
+    return !(
+        barry->point.x > missile->point.x + 26 || // Barry is to the right of the missile
+        barry->point.x + 11 < missile->point.x || // Barry is to the left of the missile
+        barry->point.y > missile->point.y + 12 || // Barry is below the missile
+        barry->point.y + 15 < missile->point.y); // Barry is above the missile
+}
+
+void spawn_random_missile(MISSILE* const missiles) {
+    // Check for an available slot for a new coin
+    for(int i = 0; i < MISSILES_MAX; ++i) {
+        if(missiles[i].point.x <= 0) {
+            missiles[i].point.x = 127;
+            missiles[i].point.y = rand() % 64;
+            break;
+        }
+    }
+}
+
+void draw_missiles(const MISSILE* missiles, Canvas* const canvas, const GameSprites* sprites) {
+    for(int i = 0; i < MISSILES_MAX; ++i) {
+        if(missiles[i].point.x > 0) {
+            canvas_draw_icon_animation(
+                canvas, missiles[i].point.x, missiles[i].point.y, sprites->missile);
+        }
+    }
+}

+ 23 - 0
includes/missile.h

@@ -0,0 +1,23 @@
+#ifndef MISSILE_H
+#define MISSILE_H
+
+#include <gui/gui.h>
+#include "game_sprites.h"
+
+#include "states.h"
+#include "point.h"
+#include "barry.h"
+
+#define MISSILES_MAX 5
+
+typedef struct {
+    float gravity;
+    POINT point;
+} MISSILE;
+
+void missile_tick(MISSILE* const missiles, BARRY* const barry, State* const state);
+void spawn_random_missile(MISSILE* const MISSILEs);
+bool missile_colides(MISSILE* const MISSILE, BARRY* const barry);
+void draw_missiles(const MISSILE* missiles, Canvas* const canvas, const GameSprites* sprites);
+
+#endif // MISSILE_H

+ 9 - 0
includes/states.h

@@ -0,0 +1,9 @@
+#ifndef STATE_H
+#define STATE_H
+
+typedef enum {
+    GameStateLife,
+    GameStateGameOver,
+} State;
+
+#endif // STATE_H

+ 27 - 1
jetpack.c

@@ -11,6 +11,7 @@
 #include "includes/scientist.h"
 #include "includes/scientist.h"
 #include "includes/particle.h"
 #include "includes/particle.h"
 #include "includes/coin.h"
 #include "includes/coin.h"
+#include "includes/missile.h"
 
 
 #include "includes/game_state.h"
 #include "includes/game_state.h"
 
 
@@ -30,16 +31,18 @@ static void jetpack_game_state_init(GameState* const game_state) {
     UNUSED(game_state);
     UNUSED(game_state);
     BARRY barry;
     BARRY barry;
     barry.gravity = 0;
     barry.gravity = 0;
-    barry.point.x = 64;
+    barry.point.x = 32 + 5;
     barry.point.y = 32;
     barry.point.y = 32;
     barry.isBoosting = false;
     barry.isBoosting = false;
 
 
     GameSprites sprites;
     GameSprites sprites;
     sprites.barry = icon_animation_alloc(&A_barry);
     sprites.barry = icon_animation_alloc(&A_barry);
     sprites.scientist = icon_animation_alloc(&A_scientist);
     sprites.scientist = icon_animation_alloc(&A_scientist);
+    sprites.missile = icon_animation_alloc(&A_missile);
 
 
     icon_animation_start(sprites.scientist);
     icon_animation_start(sprites.scientist);
     icon_animation_start(sprites.barry);
     icon_animation_start(sprites.barry);
+    icon_animation_start(sprites.missile);
 
 
     game_state->barry = barry;
     game_state->barry = barry;
     game_state->points = 0;
     game_state->points = 0;
@@ -55,20 +58,27 @@ static void jetpack_game_state_init(GameState* const game_state) {
 static void jetpack_game_state_free(GameState* const game_state) {
 static void jetpack_game_state_free(GameState* const game_state) {
     icon_animation_free(game_state->sprites.barry);
     icon_animation_free(game_state->sprites.barry);
     icon_animation_free(game_state->sprites.scientist);
     icon_animation_free(game_state->sprites.scientist);
+    icon_animation_free(game_state->sprites.missile);
     free(game_state);
     free(game_state);
 }
 }
 
 
 static void jetpack_game_tick(GameState* const game_state) {
 static void jetpack_game_tick(GameState* const game_state) {
+    if(game_state->state == GameStateGameOver) return;
     barry_tick(&game_state->barry);
     barry_tick(&game_state->barry);
     game_state_tick(game_state);
     game_state_tick(game_state);
     coin_tick(game_state->coins, &game_state->barry, &game_state->points);
     coin_tick(game_state->coins, &game_state->barry, &game_state->points);
     particle_tick(game_state->particles, game_state->scientists, &game_state->points);
     particle_tick(game_state->particles, game_state->scientists, &game_state->points);
     scientist_tick(game_state->scientists);
     scientist_tick(game_state->scientists);
+    missile_tick(game_state->missiles, &game_state->barry, &game_state->state);
 
 
     if((rand() % 100) < 1) {
     if((rand() % 100) < 1) {
         spawn_random_coin(game_state->coins);
         spawn_random_coin(game_state->coins);
     }
     }
 
 
+    if((rand() % 100) < 1) {
+        spawn_random_missile(game_state->missiles);
+    }
+
     spawn_random_scientist(game_state->scientists);
     spawn_random_scientist(game_state->scientists);
 
 
     if(game_state->barry.isBoosting) {
     if(game_state->barry.isBoosting) {
@@ -90,6 +100,7 @@ static void jetpack_game_render_callback(Canvas* const canvas, void* ctx) {
         draw_coins(game_state->coins, canvas);
         draw_coins(game_state->coins, canvas);
         draw_scientists(game_state->scientists, canvas, &game_state->sprites);
         draw_scientists(game_state->scientists, canvas, &game_state->sprites);
         draw_particles(game_state->particles, canvas);
         draw_particles(game_state->particles, canvas);
+        draw_missiles(game_state->missiles, canvas, &game_state->sprites);
 
 
         draw_barry(&game_state->barry, canvas, &game_state->sprites);
         draw_barry(&game_state->barry, canvas, &game_state->sprites);
 
 
@@ -104,6 +115,19 @@ static void jetpack_game_render_callback(Canvas* const canvas, void* ctx) {
 
 
     if(game_state->state == GameStateGameOver) {
     if(game_state->state == GameStateGameOver) {
         // Show highscore
         // Show highscore
+
+        char buffer[12];
+        snprintf(buffer, sizeof(buffer), "Dist: %u", game_state->distance);
+        canvas_draw_str_aligned(canvas, 123, 12, AlignRight, AlignBottom, buffer);
+
+        snprintf(buffer, sizeof(buffer), "Score: %u", game_state->points);
+        canvas_draw_str_aligned(canvas, 5, 12, AlignLeft, AlignBottom, buffer);
+
+        canvas_draw_str_aligned(canvas, 64, 32, AlignCenter, AlignCenter, "boom.");
+
+        // if(furi_timer_is_running(game_state->timer)) {
+        //     furi_timer_start(game_state->timer, 0);
+        // }
     }
     }
 
 
     canvas_draw_frame(canvas, 0, 0, 128, 64);
     canvas_draw_frame(canvas, 0, 0, 128, 64);
@@ -150,6 +174,8 @@ int32_t jetpack_game_app(void* p) {
         furi_timer_alloc(jetpack_game_update_timer_callback, FuriTimerTypePeriodic, event_queue);
         furi_timer_alloc(jetpack_game_update_timer_callback, FuriTimerTypePeriodic, event_queue);
     furi_timer_start(timer, furi_kernel_get_tick_frequency() / 25);
     furi_timer_start(timer, furi_kernel_get_tick_frequency() / 25);
 
 
+    game_state->timer = timer;
+
     // Open GUI and register view_port
     // Open GUI and register view_port
     Gui* gui = furi_record_open(RECORD_GUI);
     Gui* gui = furi_record_open(RECORD_GUI);
     gui_add_view_port(gui, view_port, GuiLayerFullscreen);
     gui_add_view_port(gui, view_port, GuiLayerFullscreen);