timstrasser 2 лет назад
Родитель
Сommit
9119e769e3
14 измененных файлов с 365 добавлено и 244 удалено
  1. 1 2
      .gitignore
  2. 28 0
      includes/barry.c
  3. 25 0
      includes/barry.h
  4. 51 0
      includes/coin.c
  5. 21 0
      includes/coin.h
  6. 11 0
      includes/game_sprites.h
  7. 5 0
      includes/game_state.c
  8. 32 0
      includes/game_state.h
  9. 64 0
      includes/particle.c
  10. 21 0
      includes/particle.h
  11. 9 0
      includes/point.h
  12. 47 0
      includes/scientist.c
  13. 29 0
      includes/scientist.h
  14. 21 242
      jetpack.c

+ 1 - 2
.gitignore

@@ -1,5 +1,4 @@
 dist/*
 .vscode
 .clang-format
-.editorconfig
-**/.DS_Store
+.editorconfig

+ 28 - 0
includes/barry.c

@@ -0,0 +1,28 @@
+#include "barry.h"
+#include "game_sprites.h"
+
+#include <gui/gui.h>
+#include <furi.h>
+
+void barry_tick(BARRY* const barry) {
+    // Do jetpack things
+    barry->gravity += GRAVITY_TICK;
+    barry->point.y += barry->gravity;
+
+    // Constrain barry's height within sprite_height and 64 - sprite_height
+    if(barry->point.y > (64 - BARRY_HEIGHT)) {
+        barry->point.y = 64 - BARRY_HEIGHT;
+        barry->gravity = 0; // stop upward momentum
+    } else if(barry->point.y < 0) {
+        barry->point.y = 0;
+        barry->gravity = 0; // stop downward momentum
+    }
+
+    if(barry->isBoosting) {
+        barry->gravity += GRAVITY_BOOST;
+    }
+}
+
+void draw_barry(const BARRY* barry, Canvas* const canvas, const GameSprites* sprites) {
+    canvas_draw_icon_animation(canvas, barry->point.x, barry->point.y, sprites->barry);
+}

+ 25 - 0
includes/barry.h

@@ -0,0 +1,25 @@
+#ifndef BARRY_H
+#define BARRY_H
+
+#include <stdbool.h>
+
+#include <gui/gui.h>
+#include "point.h"
+#include "game_sprites.h"
+
+#define GRAVITY_BOOST -0.3
+#define GRAVITY_TICK 0.15
+
+#define BARRY_HEIGHT 15
+#define BARRY_WIDTH 11
+
+typedef struct {
+    float gravity;
+    POINT point;
+    bool isBoosting;
+} BARRY;
+
+void barry_tick(BARRY* const barry);
+void draw_barry(const BARRY* barry, Canvas* const canvas, const GameSprites* sprites);
+
+#endif // BARRY_H

+ 51 - 0
includes/coin.c

@@ -0,0 +1,51 @@
+#include <stdlib.h>
+#include <stdbool.h>
+
+#include <jetpack_joyride_icons.h>
+#include <gui/gui.h>
+
+#include "coin.h"
+#include "barry.h"
+
+void coin_tick(COIN* const coins, BARRY* const barry, int* const poins) {
+    // Move coins towards the player
+    for(int i = 0; i < COINS_MAX; i++) {
+        if(coin_colides(&coins[i], barry)) {
+            coins[i].point.x = 0; // Remove the coin
+            (*poins)++;
+        }
+        if(coins[i].point.x > 0) {
+            coins[i].point.x -= 1; // move left by 1 unit
+            if(coins[i].point.x < -16) { // if the coin is out of screen
+                coins[i].point.x = 0; // set coin x coordinate to 0 to mark it as "inactive"
+            }
+        }
+    }
+}
+
+bool coin_colides(COIN* const coin, BARRY* const barry) {
+    return !(
+        barry->point.x > coin->point.x + 7 || // Barry is to the right of the coin
+        barry->point.x + 11 < coin->point.x || // Barry is to the left of the coin
+        barry->point.y > coin->point.y + 7 || // Barry is below the coin
+        barry->point.y + 15 < coin->point.y); // Barry is above the coin
+}
+
+void spawn_random_coin(COIN* const coins) {
+    // Check for an available slot for a new coin
+    for(int i = 0; i < COINS_MAX; ++i) {
+        if(coins[i].point.x <= 0) {
+            coins[i].point.x = 127;
+            coins[i].point.y = rand() % 64;
+            break;
+        }
+    }
+}
+
+void draw_coins(const COIN* coins, Canvas* const canvas) {
+    for(int i = 0; i < COINS_MAX; ++i) {
+        if(coins[i].point.x > 0) {
+            canvas_draw_icon(canvas, coins[i].point.x, coins[i].point.y, &I_coin);
+        }
+    }
+}

+ 21 - 0
includes/coin.h

@@ -0,0 +1,21 @@
+#ifndef COIN_H
+#define COIN_H
+
+#include <gui/gui.h>
+
+#include "point.h"
+#include "barry.h"
+
+#define COINS_MAX 25
+
+typedef struct {
+    float gravity;
+    POINT point;
+} COIN;
+
+void coin_tick(COIN* const coins, BARRY* const barry, int* const poins);
+void spawn_random_coin(COIN* const coins);
+bool coin_colides(COIN* const coin, BARRY* const barry);
+void draw_coins(const COIN* coins, Canvas* const canvas);
+
+#endif // COIN_H

+ 11 - 0
includes/game_sprites.h

@@ -0,0 +1,11 @@
+#ifndef GAME_SPRITES_H
+#define GAME_SPRITES_H
+
+#include <gui/icon_animation.h>
+
+typedef struct {
+    IconAnimation* barry;
+    IconAnimation* scientist;
+} GameSprites;
+
+#endif // GAME_SPRITES_H

+ 5 - 0
includes/game_state.c

@@ -0,0 +1,5 @@
+#include "game_state.h"
+
+void game_state_tick(GameState* const game_state) {
+    game_state->distance++;
+}

+ 32 - 0
includes/game_state.h

@@ -0,0 +1,32 @@
+#ifndef GAMESTATE_H
+#define GAMESTATE_H
+
+#include <gui/icon_animation.h>
+#include <furi.h>
+
+#include "barry.h"
+#include "scientist.h"
+#include "coin.h"
+#include "particle.h"
+#include "game_sprites.h"
+
+typedef enum {
+    GameStateLife,
+    GameStateGameOver,
+} State;
+
+typedef struct {
+    int points;
+    int distance;
+    BARRY barry;
+    COIN coins[COINS_MAX];
+    PARTICLE particles[PARTICLES_MAX];
+    SCIENTIST scientists[SCIENTISTS_MAX];
+    State state;
+    GameSprites sprites;
+    FuriMutex* mutex;
+} GameState;
+
+void game_state_tick(GameState* const game_state);
+
+#endif // GAMESTATE_H

+ 64 - 0
includes/particle.c

@@ -0,0 +1,64 @@
+#include <stdlib.h>
+
+#include "particle.h"
+#include "scientist.h"
+#include "barry.h"
+
+void particle_tick(PARTICLE* const particles, SCIENTIST* const scientists, int* const points) {
+    // Move particles
+    for(int i = 0; i < PARTICLES_MAX; i++) {
+        if(particles[i].point.y > 0) {
+            particles[i].point.y += PARTICLE_VELOCITY;
+
+            // Check collision with scientists
+            for(int j = 0; j < SCIENTISTS_MAX; j++) {
+                if(scientists[j].state == ScientistStateAlive && scientists[j].point.x > 0) {
+                    // Added half the width and height of the scientist sprite to the scientist's x and y respectively
+                    float scientist_center_x = scientists[j].point.x + 5.5;
+                    float scientist_center_y = scientists[j].point.y + 7.5;
+                    if(!(particles[i].point.x >
+                             scientist_center_x +
+                                 5.5 || // particle is to the right of the scientist
+                         particles[i].point.x + 11 <
+                             scientist_center_x -
+                                 5.5 || // particle is to the left of the scientist
+                         particles[i].point.y >
+                             scientist_center_y + 7.5 || // particle is below the scientist
+                         particles[i].point.y + 15 <
+                             scientist_center_y - 7.5)) { // particle is above the scientist
+                        scientists[j].state = ScientistStateDead;
+                        (*points) += 2; // Increase the score by 2
+                    }
+                }
+            }
+
+            if(particles[i].point.x < 0 || particles[i].point.x > 128 ||
+               particles[i].point.y < 0 || particles[i].point.y > 64) {
+                particles[i].point.y = 0;
+            }
+        }
+    }
+}
+
+void spawn_random_particles(PARTICLE* const particles, BARRY* const barry) {
+    for(int i = 0; i < PARTICLES_MAX; i++) {
+        if(particles[i].point.y <= 0) {
+            particles[i].point.x = barry->point.x + (rand() % 7) - 3;
+            particles[i].point.y = barry->point.y;
+            break;
+        }
+    }
+}
+
+void draw_particles(const PARTICLE* particles, Canvas* const canvas) {
+    for(int i = 0; i < PARTICLES_MAX; i++) {
+        if(particles[i].point.y > 0) {
+            canvas_draw_line(
+                canvas,
+                particles[i].point.x,
+                particles[i].point.y,
+                particles[i].point.x,
+                particles[i].point.y + 3);
+        }
+    }
+}

+ 21 - 0
includes/particle.h

@@ -0,0 +1,21 @@
+
+
+#ifndef PARTICLE_H
+#define PARTICLE_H
+
+#include "point.h"
+#include "scientist.h"
+#include "barry.h"
+
+#define PARTICLES_MAX 50
+#define PARTICLE_VELOCITY 2
+
+typedef struct {
+    POINT point;
+} PARTICLE;
+
+void particle_tick(PARTICLE* const particles, SCIENTIST* const scientists, int* const points);
+void spawn_random_particles(PARTICLE* const particles, BARRY* const barry);
+void draw_particles(const PARTICLE* particles, Canvas* const canvas);
+
+#endif // PARTICLE_H

+ 9 - 0
includes/point.h

@@ -0,0 +1,9 @@
+#ifndef POINT_H
+#define POINT_H
+
+typedef struct {
+    int x;
+    int y;
+} POINT;
+
+#endif // POINT_H

+ 47 - 0
includes/scientist.c

@@ -0,0 +1,47 @@
+#include "scientist.h"
+#include "game_sprites.h"
+
+#include <jetpack_joyride_icons.h>
+#include <gui/gui.h>
+
+void scientist_tick(SCIENTIST* const scientists) {
+    for(int i = 0; i < SCIENTISTS_MAX; i++) {
+        if(scientists[i].point.x > 0) {
+            scientists[i].point.x -= scientists[i].velocity_x; // move based on velocity_x
+            if(scientists[i].point.x < -16) { // if the scientist is out of screen
+                scientists[i].point.x =
+                    0; // set scientist x coordinate to 0 to mark it as "inactive"
+            }
+        }
+    }
+}
+
+void spawn_random_scientist(SCIENTIST* const scientists) {
+    // Check for an available slot for a new scientist
+    for(int i = 0; i < SCIENTISTS_MAX; ++i) {
+        if(scientists[i].point.x <= 0 &&
+           (rand() % 1000) < 10) { // Spawn rate is less frequent than coins
+            scientists[i].state = ScientistStateAlive;
+            scientists[i].point.x = 127;
+            scientists[i].point.y = 49;
+            scientists[i].velocity_x =
+                (rand() % (SCIENTIST_VELOCITY_MAX - SCIENTIST_VELOCITY_MIN + 1)) +
+                SCIENTIST_VELOCITY_MIN; // random velocity between SCIENTIST_VELOCITY_MIN and SCIENTIST_VELOCITY_MAX
+            break;
+        }
+    }
+}
+
+void draw_scientists(const SCIENTIST* scientists, Canvas* const canvas, const GameSprites* sprites) {
+    for(int i = 0; i < SCIENTISTS_MAX; ++i) {
+        if(scientists[i].point.x > 0) {
+            if(scientists[i].state == ScientistStateAlive) {
+                canvas_draw_icon_animation(
+                    canvas, scientists[i].point.x, scientists[i].point.y, sprites->scientist);
+            } else {
+                canvas_draw_icon(
+                    canvas, scientists[i].point.x, scientists[i].point.y, &I_dead_scientist);
+            }
+        }
+    }
+}

+ 29 - 0
includes/scientist.h

@@ -0,0 +1,29 @@
+#ifndef SCIENTIST_H
+#define SCIENTIST_H
+
+#include "point.h"
+#include "game_sprites.h"
+#include <gui/gui.h>
+
+#define SCIENTIST_VELOCITY_MIN 2
+#define SCIENTIST_VELOCITY_MAX 2
+
+#define SCIENTISTS_MAX 6
+
+typedef enum {
+    ScientistStateAlive,
+    ScientistStateDead,
+} ScientistState;
+
+typedef struct {
+    float gravity;
+    POINT point;
+    int velocity_x;
+    ScientistState state;
+} SCIENTIST;
+
+void scientist_tick(SCIENTIST* const scientist);
+void spawn_random_scientist(SCIENTIST* const scientists);
+void draw_scientists(const SCIENTIST* scientists, Canvas* const canvas, const GameSprites* sprites);
+
+#endif // SCIENTIST_H

+ 21 - 242
jetpack.c

@@ -6,72 +6,15 @@
 #include <gui/icon_animation.h>
 #include <input/input.h>
 
-#define TAG "Jetpack Joyride"
-
-#define GRAVITY_BOOST -0.3
-#define GRAVITY_TICK 0.15
-#define PARTIVLE_VELOCITY 2
-#define SCIENTIST_VELOCITY_MIN 2
-#define SCIENTIST_VELOCITY_MAX 2
-
-#define SCIENTISTS_MAX 6
-#define COINS_MAX 25
-#define PARTICLES_MAX 50
-
-typedef struct {
-    int x;
-    int y;
-} POINT;
-
-typedef struct {
-    float gravity;
-    POINT point;
-    bool isBoosting;
-} BARRY;
-
-typedef struct {
-    float gravity;
-    POINT point;
-} COIN;
-
-typedef struct {
-    POINT point;
-} PARTICLE;
-
-typedef enum {
-    ScientistStateAlive,
-    ScientistStateDead,
-} ScientistState;
-typedef struct {
-    float gravity;
-    POINT point;
-    int velocity_x;
-    ScientistState state;
-} SCIENTIST;
+#include "includes/point.h"
+#include "includes/barry.h"
+#include "includes/scientist.h"
+#include "includes/particle.h"
+#include "includes/coin.h"
 
-typedef enum {
-    GameStateLife,
-    GameStateGameOver,
-} State;
+#include "includes/game_state.h"
 
-typedef struct {
-    IconAnimation* barry;
-    IconAnimation* scientist;
-    Icon* coin;
-    Icon* dead_scientist;
-} GameSprites;
-
-typedef struct {
-    int points;
-    int distance;
-    BARRY barry;
-    SCIENTIST scientists[SCIENTISTS_MAX];
-    COIN coins[COINS_MAX];
-    PARTICLE particles[PARTICLES_MAX];
-    State state;
-    GameSprites sprites;
-    FuriMutex* mutex;
-} GameState;
+#define TAG "Jetpack Joyride"
 
 typedef enum {
     EventTypeTick,
@@ -83,44 +26,6 @@ typedef struct {
     InputEvent input;
 } GameEvent;
 
-static void jetpack_game_random_coins(GameState* const game_state) {
-    // Check for an available slot for a new coin
-    for(int i = 0; i < COINS_MAX; ++i) {
-        if(game_state->coins[i].point.x <= 0 && (rand() % 1000) < 1) {
-            game_state->coins[i].point.x = 127;
-            game_state->coins[i].point.y = rand() % 64;
-            break;
-        }
-    }
-}
-
-static void jetpack_game_random_scientists(GameState* const game_state) {
-    // Check for an available slot for a new scientist
-    for(int i = 0; i < SCIENTISTS_MAX; ++i) {
-        if(game_state->scientists[i].point.x <= 0 &&
-           (rand() % 1000) < 10) { // Spawn rate is less frequent than coins
-            game_state->scientists[i].state = ScientistStateAlive;
-            game_state->scientists[i].point.x = 127;
-            game_state->scientists[i].point.y = 49;
-            game_state->scientists[i].velocity_x =
-                (rand() % (SCIENTIST_VELOCITY_MAX - SCIENTIST_VELOCITY_MIN + 1)) +
-                SCIENTIST_VELOCITY_MIN; // random velocity between SCIENTIST_VELOCITY_MIN and SCIENTIST_VELOCITY_MAX
-            break;
-        }
-    }
-}
-
-static void jetpack_game_spawn_particles(GameState* const game_state) {
-    for(int i = 0; i < PARTICLES_MAX; i++) {
-        if(game_state->particles[i].point.y <= 0) {
-            game_state->particles[i].point.x = game_state->barry.point.x + (rand() % 7) - 3;
-
-            game_state->particles[i].point.y = game_state->barry.point.y;
-            break;
-        }
-    }
-}
-
 static void jetpack_game_state_init(GameState* const game_state) {
     UNUSED(game_state);
     BARRY barry;
@@ -154,104 +59,20 @@ static void jetpack_game_state_free(GameState* const game_state) {
 }
 
 static void jetpack_game_tick(GameState* const game_state) {
-    // Do jetpack things
-    game_state->barry.gravity += GRAVITY_TICK;
-    game_state->barry.point.y += game_state->barry.gravity;
-
-    // Increment distance
-    game_state->distance++;
-
-    // Move coins towards the player
-    for(int i = 0; i < COINS_MAX; i++) {
-        if(game_state->coins[i].point.x > 0) {
-            if(!(game_state->barry.point.x >
-                     game_state->coins[i].point.x + 7 || // Barry is to the right of the coin
-                 game_state->barry.point.x + 11 <
-                     game_state->coins[i].point.x || // Barry is to the left of the coin
-                 game_state->barry.point.y >
-                     game_state->coins[i].point.y + 7 || // Barry is below the coin
-                 game_state->barry.point.y + 15 <
-                     game_state->coins[i].point.y)) { // Barry is above the coin
-                game_state->coins[i].point.x = 0; // Remove the coin
-                game_state->points++; // Increase the score
-            }
-
-            game_state->coins[i].point.x -= 1; // move left by 1 unit
-            if(game_state->coins[i].point.x < -16) { // if the coin is out of screen
-                game_state->coins[i].point.x =
-                    0; // set coin x coordinate to 0 to mark it as "inactive"
-            }
-        }
+    barry_tick(&game_state->barry);
+    game_state_tick(game_state);
+    coin_tick(game_state->coins, &game_state->barry, &game_state->points);
+    particle_tick(game_state->particles, game_state->scientists, &game_state->points);
+    scientist_tick(game_state->scientists);
+
+    if((rand() % 100) < 1) {
+        spawn_random_coin(game_state->coins);
     }
 
-    // Move particles
-    for(int i = 0; i < PARTICLES_MAX; i++) {
-        if(game_state->particles[i].point.y > 0) {
-            game_state->particles[i].point.y += PARTIVLE_VELOCITY;
-
-            // Check collision with scientists
-            for(int j = 0; j < SCIENTISTS_MAX; j++) {
-                if(game_state->scientists[j].state == ScientistStateAlive &&
-                   game_state->scientists[j].point.x > 0) {
-                    // Added half the width and height of the scientist sprite to the scientist's x and y respectively
-                    float scientist_center_x = game_state->scientists[j].point.x + 5.5;
-                    float scientist_center_y = game_state->scientists[j].point.y + 7.5;
-                    if(!(game_state->particles[i].point.x >
-                             scientist_center_x +
-                                 5.5 || // particle is to the right of the scientist
-                         game_state->particles[i].point.x + 11 <
-                             scientist_center_x -
-                                 5.5 || // particle is to the left of the scientist
-                         game_state->particles[i].point.y >
-                             scientist_center_y + 7.5 || // particle is below the scientist
-                         game_state->particles[i].point.y + 15 <
-                             scientist_center_y - 7.5)) { // particle is above the scientist
-                        game_state->scientists[j].state = ScientistStateDead;
-                        game_state->points += 2; // Increase the score by 2
-                    }
-                }
-            }
-
-            if(game_state->particles[i].point.x < 0 || game_state->particles[i].point.x > 128 ||
-               game_state->particles[i].point.y < 0 || game_state->particles[i].point.y > 64) {
-                game_state->particles[i].point.y = 0;
-            }
-        }
-    }
-
-    // Move scientists
-    for(int i = 0; i < SCIENTISTS_MAX; i++) {
-        if(game_state->scientists[i].point.x > 0) {
-            game_state->scientists[i].point.x -=
-                game_state->scientists[i].velocity_x; // move based on velocity_x
-            if(game_state->scientists[i].point.x < -16) { // if the scientist is out of screen
-                game_state->scientists[i].point.x =
-                    0; // set scientist x coordinate to 0 to mark it as "inactive"
-            }
-        }
-    }
-
-    // Spawn scientists and coins...
-    jetpack_game_random_coins(game_state);
-    // Sprite height of Barry
-    int sprite_height = 15;
-
-    // Constrain barry's height within sprite_height and 64 - sprite_height
-    if(game_state->barry.point.y > (64 - sprite_height)) {
-        game_state->barry.point.y = 64 - sprite_height;
-        game_state->barry.gravity = 0; // stop upward momentum
-    } else if(game_state->barry.point.y < 0) {
-        game_state->barry.point.y = 0;
-        game_state->barry.gravity = 0; // stop downward momentum
-    }
-
-    // spawn scientists and coins...
-    jetpack_game_random_coins(game_state);
-    jetpack_game_random_scientists(game_state);
+    spawn_random_scientist(game_state->scientists);
 
     if(game_state->barry.isBoosting) {
-        game_state->barry.gravity += GRAVITY_BOOST;
-        jetpack_game_spawn_particles(game_state);
+        spawn_random_particles(game_state->particles, &game_state->barry);
     }
 }
 
@@ -261,53 +82,11 @@ static void jetpack_game_render_callback(Canvas* const canvas, void* ctx) {
     furi_mutex_acquire(game_state->mutex, FuriWaitForever);
 
     if(game_state->state == GameStateLife) {
-        // Draw scene
-
-        // Draw coins
-        for(int i = 0; i < COINS_MAX; ++i) {
-            if(game_state->coins[i].point.x > 0) {
-                canvas_draw_icon(
-                    canvas, game_state->coins[i].point.x, game_state->coins[i].point.y, &I_coin);
-            }
-        }
-
-        // Draw scientists
-        for(int i = 0; i < SCIENTISTS_MAX; ++i) {
-            if(game_state->scientists[i].point.x > 0) {
-                if(game_state->scientists[i].state == ScientistStateAlive) {
-                    canvas_draw_icon_animation(
-                        canvas,
-                        game_state->scientists[i].point.x,
-                        game_state->scientists[i].point.y,
-                        game_state->sprites.scientist);
-                } else {
-                    canvas_draw_icon(
-                        canvas,
-                        game_state->scientists[i].point.x,
-                        game_state->scientists[i].point.y,
-                        &I_dead_scientist);
-                }
-            }
-        }
-
-        // Draw particles
-        for(int i = 0; i < PARTICLES_MAX; i++) {
-            if(game_state->particles[i].point.y > 0) {
-                canvas_draw_line(
-                    canvas,
-                    game_state->particles[i].point.x,
-                    game_state->particles[i].point.y,
-                    game_state->particles[i].point.x,
-                    game_state->particles[i].point.y + 3);
-            }
-        }
+        draw_coins(game_state->coins, canvas);
+        draw_scientists(game_state->scientists, canvas, &game_state->sprites);
+        draw_particles(game_state->particles, canvas);
 
-        // Draw barry
-        canvas_draw_icon_animation(
-            canvas,
-            game_state->barry.point.x,
-            game_state->barry.point.y,
-            game_state->sprites.barry);
+        draw_barry(&game_state->barry, canvas, &game_state->sprites);
 
         canvas_set_font(canvas, FontSecondary);
         char buffer[12];