Sfoglia il codice sorgente

rework backgrounds

Tim Strasser 2 anni fa
parent
commit
fc7e1cdca3

BIN
assets/air_vent.png


BIN
assets/door.png


BIN
assets/pillar.png


+ 81 - 0
includes/background_asset.c

@@ -0,0 +1,81 @@
+#include <jetpack_joyride_icons.h>
+
+#include "background_assets.h"
+
+static AssetProperties assetProperties[BG_ASSETS_MAX] = {
+    {.width = 27, .spawn_chance = 1, .x_offset = 24, .y_offset = 36, .sprite = &I_door},
+    {.width = 12, .spawn_chance = 6, .x_offset = 33, .y_offset = 14, .sprite = &I_air_vent}};
+
+void background_assets_tick(BackgroundAsset* const assets) {
+    // Move assets towards the player
+    for(int i = 0; i < BG_ASSETS_MAX; i++) {
+        if(assets[i].visible) {
+            assets[i].point.x -= 1; // move left by 2 units
+            if(assets[i].point.x <=
+               -assets[i].properties->width) { // if the asset is out of screen
+                assets[i].visible = false; // set asset x coordinate to 0 to mark it as "inactive"
+            }
+        }
+    }
+}
+
+void spawn_random_background_asset(BackgroundAsset* const assets) {
+    // Calculate the total spawn chances for all assets
+    int total_spawn_chance = 0;
+    for(int i = 0; i < BG_ASSETS_MAX; ++i) {
+        total_spawn_chance += assetProperties[i].spawn_chance;
+    }
+
+    // Generate a random number between 0 and total_spawn_chance
+    int random_number = rand() % total_spawn_chance;
+
+    // Select the asset based on the random number
+    int chosen_asset = -1;
+    int accumulated_chance = 0;
+    for(int i = 0; i < BG_ASSETS_MAX; ++i) {
+        accumulated_chance += assetProperties[i].spawn_chance;
+        if(random_number < accumulated_chance) {
+            chosen_asset = i;
+            break;
+        }
+    }
+
+    // If no asset is chosen, return
+    if(chosen_asset == -1) {
+        return;
+    }
+
+    // Look for an available slot for the chosen asset
+    for(int i = 0; i < BG_ASSETS_MAX; ++i) {
+        if(assets[i].visible == false) {
+            // Spawn the asset
+            assets[i].point.x = 127 + assetProperties[chosen_asset].x_offset;
+            assets[i].point.y = assetProperties[chosen_asset].y_offset;
+            assets[i].properties = &assetProperties[chosen_asset];
+            assets[i].visible = true;
+            break;
+        }
+    }
+}
+
+void draw_background_assets(const BackgroundAsset* assets, Canvas* const canvas, int distance) {
+    canvas_draw_box(canvas, 0, 6, 128, 1);
+    canvas_draw_box(canvas, 0, 56, 128, 2);
+
+    // Calculate the pillar offset based on the traveled distance
+    int pillar_offset = distance % 64;
+
+    // Draw pillars
+    for(int x = -pillar_offset; x < 128; x += 64) {
+        canvas_draw_icon(canvas, x, 6, &I_pillar);
+    }
+
+    // Draw assets
+    for(int i = 0; i < BG_ASSETS_MAX; ++i) {
+        if(assets[i].visible) {
+            canvas_set_color(canvas, ColorBlack);
+            canvas_draw_icon(
+                canvas, assets[i].point.x, assets[i].point.y, assets[i].properties->sprite);
+        }
+    }
+}

+ 34 - 0
includes/background_assets.h

@@ -0,0 +1,34 @@
+#ifndef BACKGROUND_ASSETS_H
+#define BACKGROUND_ASSETS_H
+
+#include <stdlib.h>
+#include <stdbool.h>
+
+#include <gui/gui.h>
+
+#include "point.h"
+#include "states.h"
+#include "game_sprites.h"
+#include <jetpack_joyride_icons.h>
+
+#define BG_ASSETS_MAX 3
+
+typedef struct {
+    int width;
+    int spawn_chance;
+    int x_offset;
+    int y_offset;
+    const Icon* sprite;
+} AssetProperties;
+
+typedef struct {
+    POINT point;
+    AssetProperties* properties;
+    bool visible;
+} BackgroundAsset;
+
+void background_assets_tick(BackgroundAsset* const assets);
+void spawn_random_background_asset(BackgroundAsset* const assets);
+void draw_background_assets(const BackgroundAsset* assets, Canvas* const canvas, int distance);
+
+#endif // BACKGROUND_ASSETS_H

+ 0 - 2
includes/game_sprites.h

@@ -13,8 +13,6 @@ typedef struct {
     const Icon* scientist_right_infill;
     IconAnimation* missile;
     const Icon* missile_infill;
-    const Icon* bg[3];
-    POINT bg_pos[3];
 } GameSprites;
 
 #endif // GAME_SPRITES_H

+ 2 - 0
includes/game_state.h

@@ -11,6 +11,7 @@
 #include "game_sprites.h"
 #include "states.h"
 #include "missile.h"
+#include "background_assets.h"
 typedef struct {
     int points;
     int distance;
@@ -19,6 +20,7 @@ typedef struct {
     PARTICLE particles[PARTICLES_MAX];
     SCIENTIST scientists[SCIENTISTS_MAX];
     MISSILE missiles[MISSILES_MAX];
+    BackgroundAsset bg_assets[BG_ASSETS_MAX];
     State state;
     GameSprites sprites;
     FuriMutex* mutex;

+ 30 - 19
jetpack.c

@@ -12,6 +12,7 @@
 #include "includes/particle.h"
 #include "includes/coin.h"
 #include "includes/missile.h"
+#include "includes/background_assets.h"
 
 #include "includes/game_state.h"
 
@@ -47,14 +48,14 @@ static void jetpack_game_state_init(GameState* const game_state) {
     sprites.missile = icon_animation_alloc(&A_missile);
     sprites.missile_infill = &I_missile_infill;
 
-    sprites.bg[0] = &I_bg1;
-    sprites.bg[1] = &I_bg2;
-    sprites.bg[2] = &I_bg3;
+    // sprites.bg[0] = &I_bg1;
+    // sprites.bg[1] = &I_bg2;
+    // sprites.bg[2] = &I_bg3;
 
-    for(int i = 0; i < 3; ++i) {
-        sprites.bg_pos[i].x = i * 128;
-        sprites.bg_pos[i].y = 0;
-    }
+    // for(int i = 0; i < 3; ++i) {
+    //     sprites.bg_pos[i].x = i * 128;
+    //     sprites.bg_pos[i].y = 0;
+    // }
 
     icon_animation_start(sprites.barry);
     icon_animation_start(sprites.missile);
@@ -86,13 +87,19 @@ static void jetpack_game_tick(GameState* const game_state) {
     scientist_tick(game_state->scientists);
     missile_tick(game_state->missiles, &game_state->barry, &game_state->state);
 
-    for(int i = 0; i < 3; ++i) {
-        game_state->sprites.bg_pos[i].x -= 1;
-        if(game_state->sprites.bg_pos[i].x <= -128) {
-            game_state->sprites.bg_pos[i].x = 128 * 2; // 2 other images are 128 px each
-        }
+    background_assets_tick(game_state->bg_assets);
+
+    if(game_state->distance % 64 == 0) {
+        spawn_random_background_asset(game_state->bg_assets);
     }
 
+    // for(int i = 0; i < 3; ++i) {
+    //     game_state->sprites.bg_pos[i].x -= 1;
+    //     if(game_state->sprites.bg_pos[i].x <= -128) {
+    //         game_state->sprites.bg_pos[i].x = 128 * 2; // 2 other images are 128 px each
+    //     }
+    // }
+
     if((rand() % 100) < 1) {
         spawn_random_coin(game_state->coins);
     }
@@ -116,13 +123,17 @@ static void jetpack_game_render_callback(Canvas* const canvas, void* ctx) {
     if(game_state->state == GameStateLife) {
         // canvas_draw_box(canvas, 0, 0, 128, 32);
 
-        for(int i = 0; i < 3; ++i) {
-            // Check if the image is within the screen's boundaries
-            if(game_state->sprites.bg_pos[i].x >= -127 && game_state->sprites.bg_pos[i].x < 128) {
-                // canvas_draw_icon(
-                //     canvas, game_state->sprites.bg_pos[i].x, 0, game_state->sprites.bg[i]);
-            }
-        }
+        // for(int i = 0; i < 3; ++i) {
+        //     // Check if the image is within the screen's boundaries
+        //     if(game_state->sprites.bg_pos[i].x >= -127 && game_state->sprites.bg_pos[i].x < 128) {
+        //         canvas_draw_icon(
+        //             canvas, game_state->sprites.bg_pos[i].x, 0, game_state->sprites.bg[i]);
+        //     }
+        // }
+
+        canvas_set_bitmap_mode(canvas, false);
+
+        draw_background_assets(game_state->bg_assets, canvas, game_state->distance);
 
         canvas_set_bitmap_mode(canvas, true);