Просмотр исходного кода

Squashed 't_rex_runner/' changes from c4d52ce22..4fc31cd23

4fc31cd23 fixing some big bugs
eaf07d843 update apps
0bd9fe007 bump versions and set bt trigger to use keys from ble remote
d75276bfb fix plugins, remove dupe
3f9040b64 Proper fap_descriptions
706ff2294 categories part 1
421d7ea24 more manifestos, xbox controller and videopoker ufbt fixes
c315ce2a5 Add Screenshots
6e9769cf8 API 31 / unzip sources
REVERT: c4d52ce22 Updated cactus: random spawn and increase speed with time
REVERT: 45fd615ed Removed test commands
REVERT: 58198e39e Updated cactus icon and sprite transparency
REVERT: 26026c6e8 Fixed background loop
REVERT: 2ba52c201 Merge branch 'main' of https://github.com/Rrycbarm/t-rex-runner
REVERT: 1848305a7 Added score system
REVERT: bb3a98a2f Update .gitignore
REVERT: 1dc2bfcdf Removed useless files
REVERT: db52e0729 updated readme
REVERT: eec5ed845 added moving background and minor fixes
REVERT: 91ca9ddb8 Updated readme
REVERT: 604dd45aa Updated cactus speed
REVERT: 4d34b687a Added fap file
REVERT: 0da067594 Update README.md
REVERT: 41b436b62 Update readme
REVERT: d6dca031b First game implementation
REVERT: e80f65946 refactor: use ms in update method
REVERT: 73591be3e adds CMake configuration for CLion
REVERT: 7ffcbc51e Added horizon line assets.
REVERT: c2d5d5cdf Refactored dino run animation.
REVERT: cdfb8aedf Adds "animation" of running dino.
REVERT: 6189edcbe Displays dino icon.
REVERT: 6f0c4b05b Adds empty app and icon.
REVERT: 446439eaa Initial commit

git-subtree-dir: t_rex_runner
git-subtree-split: 4fc31cd23216bafbc11eba7e4e8d699862ff7060
Willy-JL 2 лет назад
Родитель
Сommit
9e8dabb6d1
9 измененных файлов с 93 добавлено и 67 удалено
  1. 1 0
      README-catalog.md
  2. 5 1
      application.fam
  3. BIN
      dist/debug/t-rex-runner_d.elf
  4. BIN
      dist/debug/t_rex_runner_d.elf
  5. BIN
      dist/t_rex_runner.fap
  6. BIN
      img/1.png
  7. BIN
      img/2.png
  8. 87 66
      trexrunner.c
  9. BIN
      video.gif

+ 1 - 0
README-catalog.md

@@ -0,0 +1 @@
+Your objective is to achieve the highest score possible by pressing the OK button at the precise moment. Be careful not to touch cactuses with the dinosaur, as doing so will result in losing the game.

+ 5 - 1
application.fam

@@ -8,6 +8,10 @@ App(
     stack_size=8 * 1024,
     stack_size=8 * 1024,
     fap_category="Games",
     fap_category="Games",
     fap_icon="trexrunner_icon.png",
     fap_icon="trexrunner_icon.png",
-    fap_icon_assets="assets",  
+    fap_icon_assets="assets",
     order=36,
     order=36,
+    fap_author="@Rrycbarm",
+    fap_weburl="https://github.com/Rrycbarm/t-rex-runner",
+    fap_version="1.3",
+    fap_description="Play the port of the Chrome browser T-Rex game on your Flipper Zero.",
 )
 )

BIN
dist/debug/t-rex-runner_d.elf


BIN
dist/debug/t_rex_runner_d.elf


BIN
dist/t_rex_runner.fap




+ 87 - 66
trexrunner.c

@@ -39,7 +39,7 @@ typedef struct {
 } PluginEvent;
 } PluginEvent;
 
 
 typedef struct {
 typedef struct {
-    FuriTimer *timer;
+    FuriTimer* timer;
     uint32_t last_tick;
     uint32_t last_tick;
     const Icon* dino_icon;
     const Icon* dino_icon;
     int dino_frame_ms;
     int dino_frame_ms;
@@ -63,11 +63,11 @@ typedef struct {
     int score;
     int score;
 } GameState;
 } GameState;
 
 
-static void timer_callback(void *ctx) {
-    GameState *game_state = ctx;
+static void timer_callback(void* ctx) {
+    GameState* game_state = ctx;
     furi_mutex_acquire(game_state->mutex, FuriWaitForever);
     furi_mutex_acquire(game_state->mutex, FuriWaitForever);
 
 
-    if (game_state == NULL) {
+    if(game_state == NULL) {
         return;
         return;
     }
     }
 
 
@@ -78,92 +78,104 @@ static void timer_callback(void *ctx) {
     // dino update
     // dino update
     game_state->dino_frame_ms += delta_time_ms;
     game_state->dino_frame_ms += delta_time_ms;
     // TODO: switch by dino state
     // TODO: switch by dino state
-    if (game_state->dino_frame_ms >= DINO_RUNNING_MS_PER_FRAME) {
-        if (game_state->dino_icon == &I_DinoRun0) {
+    if(game_state->dino_frame_ms >= DINO_RUNNING_MS_PER_FRAME) {
+        if(game_state->dino_icon == &I_DinoRun0) {
             game_state->dino_icon = &I_DinoRun1;
             game_state->dino_icon = &I_DinoRun1;
         } else {
         } else {
             game_state->dino_icon = &I_DinoRun0;
             game_state->dino_icon = &I_DinoRun0;
         }
         }
         game_state->dino_frame_ms = 0;
         game_state->dino_frame_ms = 0;
     }
     }
-    
+
     // Compute dino dynamics
     // Compute dino dynamics
     game_state->y_acceleration = game_state->y_acceleration - GRAVITY * delta_time_ms / 1000;
     game_state->y_acceleration = game_state->y_acceleration - GRAVITY * delta_time_ms / 1000;
     game_state->y_speed = game_state->y_speed + game_state->y_acceleration * delta_time_ms / 1000;
     game_state->y_speed = game_state->y_speed + game_state->y_acceleration * delta_time_ms / 1000;
     game_state->y_position = game_state->y_position - game_state->y_speed * delta_time_ms / 1000;
     game_state->y_position = game_state->y_position - game_state->y_speed * delta_time_ms / 1000;
 
 
     // Touch ground
     // Touch ground
-    if (game_state->y_position >= DINO_START_Y) {
+    if(game_state->y_position >= DINO_START_Y) {
         game_state->y_acceleration = 0;
         game_state->y_acceleration = 0;
         game_state->y_speed = 0;
         game_state->y_speed = 0;
         game_state->y_position = DINO_START_Y;
         game_state->y_position = DINO_START_Y;
     }
     }
 
 
     // Update Cactus state
     // Update Cactus state
-    if (game_state->has_cactus){
-        game_state->cactus_position = game_state->cactus_position - (game_state->x_speed - 15) * delta_time_ms / 1000;
-        if (game_state->cactus_position <= 0 ) {
+    if(game_state->has_cactus) {
+        game_state->cactus_position =
+            game_state->cactus_position - (game_state->x_speed - 15) * delta_time_ms / 1000;
+        if(game_state->cactus_position <= 0) {
             game_state->has_cactus = 0;
             game_state->has_cactus = 0;
             game_state->score = game_state->score + 1;
             game_state->score = game_state->score + 1;
 
 
             // Increase speed
             // Increase speed
             game_state->x_speed = game_state->x_speed + X_INCREASE;
             game_state->x_speed = game_state->x_speed + X_INCREASE;
         }
         }
-    } 
+    }
     // Create cactus (random frame in 1.5s)
     // Create cactus (random frame in 1.5s)
     else {
     else {
         uint8_t randomuint8[1];
         uint8_t randomuint8[1];
-        furi_hal_random_fill_buf(randomuint8,1);
-        if (randomuint8[0] % 30 == 0) {
+        furi_hal_random_fill_buf(randomuint8, 1);
+        if(randomuint8[0] % 30 == 0) {
             game_state->has_cactus = 1;
             game_state->has_cactus = 1;
             game_state->cactus_position = 120;
             game_state->cactus_position = 120;
         }
         }
     }
     }
 
 
     // Move horizontal line
     // Move horizontal line
-    if (game_state->background_position <= -BACKGROUND_W)
+    if(game_state->background_position <= -BACKGROUND_W)
         game_state->background_position += BACKGROUND_W;
         game_state->background_position += BACKGROUND_W;
-    game_state->background_position = game_state->background_position - game_state->x_speed * delta_time_ms / 1000;
+    game_state->background_position =
+        game_state->background_position - game_state->x_speed * delta_time_ms / 1000;
 
 
     // Lose condition
     // Lose condition
-    if (game_state->has_cactus && ((game_state->y_position + 22 >= (64 - CACTUS_H)) && ((DINO_START_X+20) >= game_state->cactus_position) && (DINO_START_X <= (game_state->cactus_position + CACTUS_W))))
+    if(game_state->has_cactus && ((game_state->y_position + 22 >= (64 - CACTUS_H)) &&
+                                  ((DINO_START_X + 20) >= game_state->cactus_position) &&
+                                  (DINO_START_X <= (game_state->cactus_position + CACTUS_W))))
         game_state->lost = 1;
         game_state->lost = 1;
 
 
     furi_mutex_release(game_state->mutex);
     furi_mutex_release(game_state->mutex);
 }
 }
 
 
-static void input_callback(InputEvent *input_event, FuriMessageQueue *event_queue) {
+static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
     furi_assert(event_queue);
     furi_assert(event_queue);
 
 
     PluginEvent event = {.type = EventTypeKey, .input = *input_event};
     PluginEvent event = {.type = EventTypeKey, .input = *input_event};
     furi_message_queue_put(event_queue, &event, FuriWaitForever);
     furi_message_queue_put(event_queue, &event, FuriWaitForever);
 }
 }
 
 
-static void render_callback(Canvas *const canvas, void *ctx) {
-    const GameState *game_state = ctx;
+static void render_callback(Canvas* const canvas, void* ctx) {
+    const GameState* game_state = ctx;
     furi_mutex_acquire(game_state->mutex, FuriWaitForever);
     furi_mutex_acquire(game_state->mutex, FuriWaitForever);
 
 
-    if (game_state == NULL) {
+    if(game_state == NULL) {
         return;
         return;
     }
     }
 
 
     char score_string[12];
     char score_string[12];
-    if(!game_state->lost){
+    if(!game_state->lost) {
         // Show Ground
         // Show Ground
-        canvas_draw_icon(canvas, game_state->background_position, 64 - BACKGROUND_H, &I_HorizonLine0);
-        canvas_draw_icon(canvas, game_state->background_position + BACKGROUND_W, 64 - BACKGROUND_H, &I_HorizonLine0);
+        canvas_draw_icon(
+            canvas, game_state->background_position, 64 - BACKGROUND_H, &I_HorizonLine0);
+        canvas_draw_icon(
+            canvas,
+            game_state->background_position + BACKGROUND_W,
+            64 - BACKGROUND_H,
+            &I_HorizonLine0);
 
 
         // Show DINO
         // Show DINO
         canvas_draw_icon(canvas, DINO_START_X, game_state->y_position, game_state->dino_icon);
         canvas_draw_icon(canvas, DINO_START_X, game_state->y_position, game_state->dino_icon);
 
 
         // Show cactus
         // Show cactus
-        if (game_state->has_cactus)
+        if(game_state->has_cactus)
             //canvas_draw_triangle(canvas, game_state->cactus_position, 64 - BACKGROUND_H + CACTUS_W, CACTUS_W, CACTUS_H, CanvasDirectionBottomToTop);
             //canvas_draw_triangle(canvas, game_state->cactus_position, 64 - BACKGROUND_H + CACTUS_W, CACTUS_W, CACTUS_H, CanvasDirectionBottomToTop);
-            canvas_draw_icon(canvas, game_state->cactus_position, 64 - BACKGROUND_H/2 - CACTUS_H - 2, &I_Cactus);
+            canvas_draw_icon(
+                canvas,
+                game_state->cactus_position,
+                64 - BACKGROUND_H / 2 - CACTUS_H - 2,
+                &I_Cactus);
 
 
         // Show score
         // Show score
-        if(game_state->score == 0)
-            canvas_set_font(canvas, FontSecondary);
+        if(game_state->score == 0) canvas_set_font(canvas, FontSecondary);
         snprintf(score_string, 12, "Score: %d", game_state->score);
         snprintf(score_string, 12, "Score: %d", game_state->score);
         canvas_draw_str_aligned(canvas, 85, 5, AlignLeft, AlignTop, score_string);
         canvas_draw_str_aligned(canvas, 85, 5, AlignLeft, AlignTop, score_string);
 
 
@@ -171,11 +183,11 @@ static void render_callback(Canvas *const canvas, void *ctx) {
         canvas_set_font(canvas, FontPrimary);
         canvas_set_font(canvas, FontPrimary);
         canvas_draw_str_aligned(canvas, 64, 32, AlignCenter, AlignBottom, "You lost :c");
         canvas_draw_str_aligned(canvas, 64, 32, AlignCenter, AlignBottom, "You lost :c");
     }
     }
-    
+
     furi_mutex_release(game_state->mutex);
     furi_mutex_release(game_state->mutex);
 }
 }
 
 
-static void game_state_init(GameState *const game_state) {
+static void game_state_init(GameState* const game_state) {
     game_state->last_tick = furi_get_tick();
     game_state->last_tick = furi_get_tick();
     game_state->dino_frame_ms = 0;
     game_state->dino_frame_ms = 0;
     game_state->dino_icon = &I_Dino;
     game_state->dino_icon = &I_Dino;
@@ -189,14 +201,24 @@ static void game_state_init(GameState *const game_state) {
     game_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
     game_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
 }
 }
 
 
-int32_t trexrunner_app() {
+static void game_state_reinit(GameState* const game_state) {
+    game_state->last_tick = furi_get_tick();
+    game_state->y_acceleration = game_state->y_speed = 0;
+    game_state->y_position = DINO_START_Y;
+    game_state->has_cactus = 0;
+    game_state->background_position = 0;
+    game_state->lost = 0;
+    game_state->x_speed = START_x_speed;
+    game_state->score = 0;
+}
 
 
-    FuriMessageQueue *event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent));
+int32_t trexrunner_app() {
+    FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent));
 
 
-    GameState *game_state = malloc(sizeof(GameState));
+    GameState* game_state = malloc(sizeof(GameState));
     game_state_init(game_state);
     game_state_init(game_state);
 
 
-    if (!game_state->mutex) { 
+    if(!game_state->mutex) {
         FURI_LOG_E("T-rex runner", "cannot create mutex\r\n");
         FURI_LOG_E("T-rex runner", "cannot create mutex\r\n");
         free(game_state);
         free(game_state);
         return 255;
         return 255;
@@ -204,55 +226,54 @@ int32_t trexrunner_app() {
     // BEGIN IMPLEMENTATION
     // BEGIN IMPLEMENTATION
 
 
     // Set system callbacks
     // Set system callbacks
-    ViewPort *view_port = view_port_alloc();
+    ViewPort* view_port = view_port_alloc();
     view_port_draw_callback_set(view_port, render_callback, game_state);
     view_port_draw_callback_set(view_port, render_callback, game_state);
     view_port_input_callback_set(view_port, input_callback, event_queue);
     view_port_input_callback_set(view_port, input_callback, event_queue);
     game_state->timer = furi_timer_alloc(timer_callback, FuriTimerTypePeriodic, game_state);
     game_state->timer = furi_timer_alloc(timer_callback, FuriTimerTypePeriodic, game_state);
 
 
-    furi_timer_start(game_state->timer, (uint32_t) furi_kernel_get_tick_frequency() / FPS);
+    furi_timer_start(game_state->timer, (uint32_t)furi_kernel_get_tick_frequency() / FPS);
 
 
     // Open GUI and register view_port
     // Open GUI and register view_port
-    Gui *gui = furi_record_open("gui");
+    Gui* gui = furi_record_open("gui");
     gui_add_view_port(gui, view_port, GuiLayerFullscreen);
     gui_add_view_port(gui, view_port, GuiLayerFullscreen);
 
 
     PluginEvent event;
     PluginEvent event;
-    for (bool processing = true; processing && !game_state->lost;) {
+    for(bool processing = true; processing;) {
         FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
         FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
-        if (event_status == FuriStatusOk) {
+        if(event_status == FuriStatusOk) {
             // press events
             // press events
-            if (event.type == EventTypeKey) {
-                if (event.input.type == InputTypeShort) {
-                    switch (event.input.key) {
-                        case InputKeyUp:
-                            break;
-                        case InputKeyDown:
-                            break;
-                        case InputKeyLeft:
-                            break;
-                        case InputKeyRight:
-                            break;
-                        case InputKeyOk:
-                            if (game_state->y_position == DINO_START_Y)
-                                game_state->y_speed = JUMP_SPEED;       
-                            break;
-                        case InputKeyMAX:
-                            break;
-                        case InputKeyBack:
-                            // Exit the app
-                            processing = false;
+            if(event.type == EventTypeKey) {
+                if(event.input.type == InputTypeShort) {
+                    switch(event.input.key) {
+                    case InputKeyUp:
+                        break;
+                    case InputKeyDown:
+                        break;
+                    case InputKeyLeft:
+                        break;
+                    case InputKeyRight:
+                        break;
+                    case InputKeyOk:
+                        if(game_state->lost) {
+                            game_state_reinit(game_state);
                             break;
                             break;
+                        }
+                        if(game_state->y_position == DINO_START_Y)
+                            game_state->y_speed = JUMP_SPEED;
+                        break;
+                    case InputKeyMAX:
+                        break;
+                    case InputKeyBack:
+                        // Exit the app
+                        processing = false;
+                        break;
                     }
                     }
                 }
                 }
             }
             }
-        } else {
-            // event timeout
-            ;
-        }
-        if (game_state->lost){
-            furi_message_queue_get(event_queue, &event, 1500); //Sleep to show  the "you lost" message
         }
         }
-        view_port_update(view_port);
+
         furi_mutex_release(game_state->mutex);
         furi_mutex_release(game_state->mutex);
+        view_port_update(view_port);
     }
     }
 
 
     view_port_enabled_set(view_port, false);
     view_port_enabled_set(view_port, false);