From f12d5105c166fc170dc2d0c51ae7740efbd882fd Mon Sep 17 00:00:00 2001 From: Boteium Date: Mon, 3 Jul 2023 22:52:44 +0800 Subject: [PATCH] new game: bird and cactus --- src/CMakeLists.txt | 1 + src/displayapp/Apps.h | 1 + src/displayapp/DisplayApp.cpp | 4 + src/displayapp/fonts/fonts.json | 2 +- src/displayapp/screens/ApplicationList.h | 2 +- src/displayapp/screens/Bird.cpp | 141 +++++++++++++++++++++++ src/displayapp/screens/Bird.h | 52 +++++++++ src/displayapp/screens/Symbols.h | 1 + 8 files changed, 202 insertions(+), 2 deletions(-) create mode 100644 src/displayapp/screens/Bird.cpp create mode 100644 src/displayapp/screens/Bird.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d903629b..d1e8bcfb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -375,6 +375,7 @@ list(APPEND SOURCE_FILES displayapp/screens/Screen.cpp displayapp/screens/Clock.cpp displayapp/screens/Tile.cpp + displayapp/screens/Bird.cpp displayapp/screens/InfiniPaint.cpp displayapp/screens/Paddle.cpp displayapp/screens/StopWatch.cpp diff --git a/src/displayapp/Apps.h b/src/displayapp/Apps.h index f253bc03..919d9bc4 100644 --- a/src/displayapp/Apps.h +++ b/src/displayapp/Apps.h @@ -16,6 +16,7 @@ namespace Pinetime { FlashLight, BatteryInfo, Music, + Bird, Paint, Paddle, Twos, diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index a930fe96..6188c11a 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -16,6 +16,7 @@ #include "displayapp/screens/FirmwareValidation.h" #include "displayapp/screens/InfiniPaint.h" #include "displayapp/screens/Paddle.h" +#include "displayapp/screens/Bird.h" #include "displayapp/screens/StopWatch.h" #include "displayapp/screens/Metronome.h" #include "displayapp/screens/Music.h" @@ -528,6 +529,9 @@ void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections directio case Apps::Paddle: currentScreen = std::make_unique(lvgl); break; + case Apps::Bird: + currentScreen = std::make_unique(lvgl); + break; case Apps::Music: currentScreen = std::make_unique(systemTask->nimble().music()); break; diff --git a/src/displayapp/fonts/fonts.json b/src/displayapp/fonts/fonts.json index e65f6dd4..e31e39dc 100644 --- a/src/displayapp/fonts/fonts.json +++ b/src/displayapp/fonts/fonts.json @@ -7,7 +7,7 @@ }, { "file": "FontAwesome5-Solid+Brands+Regular.woff", - "range": "0xf294, 0xf242, 0xf54b, 0xf21e, 0xf1e6, 0xf017, 0xf129, 0xf03a, 0xf185, 0xf560, 0xf001, 0xf3fd, 0xf1fc, 0xf45d, 0xf59f, 0xf5a0, 0xf027, 0xf028, 0xf6a9, 0xf04b, 0xf04c, 0xf048, 0xf051, 0xf095, 0xf3dd, 0xf04d, 0xf2f2, 0xf024, 0xf252, 0xf569, 0xf06e, 0xf015, 0xf00c" + "range": "0xf294, 0xf242, 0xf54b, 0xf21e, 0xf1e6, 0xf017, 0xf129, 0xf03a, 0xf185, 0xf560, 0xf001, 0xf3fd, 0xf1fc, 0xf45d, 0xf59f, 0xf5a0, 0xf027, 0xf028, 0xf6a9, 0xf04b, 0xf04c, 0xf048, 0xf051, 0xf095, 0xf3dd, 0xf04d, 0xf2f2, 0xf024, 0xf252, 0xf569, 0xf06e, 0xf015, 0xf00c, 0xf4ba" } ], "bpp": 1, diff --git a/src/displayapp/screens/ApplicationList.h b/src/displayapp/screens/ApplicationList.h index 7bdd1154..c3a8f4b0 100644 --- a/src/displayapp/screens/ApplicationList.h +++ b/src/displayapp/screens/ApplicationList.h @@ -52,7 +52,7 @@ namespace Pinetime { {"2", Apps::Twos}, {Symbols::drum, Apps::Metronome}, {Symbols::map, Apps::Navigation}, - {Symbols::none, Apps::None}, + {Symbols::dove, Apps::Bird}, // {"M", Apps::Motion}, }}; diff --git a/src/displayapp/screens/Bird.cpp b/src/displayapp/screens/Bird.cpp new file mode 100644 index 00000000..49d714b4 --- /dev/null +++ b/src/displayapp/screens/Bird.cpp @@ -0,0 +1,141 @@ +#include "displayapp/screens/Bird.h" +#include "displayapp/DisplayApp.h" +#include "displayapp/LittleVgl.h" +#include "displayapp/screens/Symbols.h" + +#include // for rand() + +using namespace Pinetime::Applications::Screens; + +Bird::Bird(Pinetime::Components::LittleVgl& lvgl) : lvgl {lvgl} { + + lv_obj_t* background = lv_obj_create(lv_scr_act(), nullptr); + lv_obj_set_size(background, LV_HOR_RES, LV_VER_RES); + lv_obj_set_style_local_radius(background, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0); + lv_obj_set_style_local_bg_color(background, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x2874a6)); + + cactus_top = lv_obj_create(lv_scr_act(), nullptr); + lv_obj_set_size(cactus_top, CACTUS_WIDTH, CACTUS_HEIGHT); + lv_obj_set_style_local_bg_color(cactus_top, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GREEN); + lv_obj_set_style_local_border_color(cactus_top, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK); + lv_obj_set_style_local_border_width(cactus_top, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 1); + + cactus_bottom = lv_obj_create(lv_scr_act(), nullptr); + lv_obj_set_size(cactus_bottom, CACTUS_WIDTH, CACTUS_HEIGHT); + lv_obj_set_style_local_bg_color(cactus_bottom, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GREEN); + lv_obj_set_style_local_border_color(cactus_bottom, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK); + lv_obj_set_style_local_border_width(cactus_bottom, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 1); + + MovePipe(); + + points = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_text_static(points, " "); + lv_obj_align(points, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, -10, 5); + + info = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_text_static(info, "touch to start"); + lv_obj_align(info, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 0, 40); + + bird = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_text_static(bird, Symbols::dove); + lv_obj_set_style_local_text_color(bird, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_YELLOW); + lv_obj_set_pos(bird, BIRD_X, pos); + + taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); +} + +Bird::~Bird() { + lv_task_del(taskRefresh); + lv_obj_clean(lv_scr_act()); +} + +void Bird::MovePipe() { + lv_obj_set_pos(cactus_top, cactus_x, -cactus_y_offset); + lv_obj_set_pos(cactus_bottom, cactus_x, CACTUS_HEIGHT + CACTUS_GAP - cactus_y_offset); + return; +} + +void Bird::Refresh() { + if (is_stopped) { + return; + } + + pos += accel / 6; + + if (is_ascending) { + if (accel >= -18) { + accel -= 3; + } + } else { + if (accel <= 42) { + accel++; + } + } + + // checks if it has hit the floor or ceiling + if (pos <= 1 || pos >= LV_VER_RES - BIRD_SIZE) { + GameOver(); + return; + } + + // checks if it has rammed into cacti + // BIRD_X-CACTUS_WIDTH to BIRD_X+BIRD_SIZE + if (90 < cactus_x && cactus_x < 130) { + if (pos < CACTUS_HEIGHT - cactus_y_offset || pos > CACTUS_HEIGHT + CACTUS_GAP - BIRD_SIZE - cactus_y_offset) { + GameOver(); + return; + } + } + + lv_obj_set_pos(bird, BIRD_X, pos); + + lv_label_set_text_fmt(points, "%04d", score / 10); + is_ascending = false; + + score++; + if (cactus_x == 0) { + while (true) { + uint8_t new_offset = rand() % 5 * 40; + if (new_offset != cactus_y_offset) { + cactus_y_offset = new_offset; + break; + } + } + cactus_x = 240; + } + cactus_x--; + if (cactus_x % 4 == 0) { + MovePipe(); + } +} + +void Bird::GameOver() { + lv_label_set_text_static(info, "Game Over"); + lv_obj_align(info, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 0, 40); + is_stopped = true; + return; +} + +bool Bird::OnTouchEvent(Pinetime::Applications::TouchEvents /*event*/) { + if (is_stopped) { + if (pos != 120) { + pos = 120; + lv_label_set_text_static(info, "Touch to Start"); + lv_obj_align(info, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 0, 40); + return true; + } + // reset + cactus_x = 240; + accel = 0; + score = 0; + is_stopped = false; + lv_label_set_text_static(info, ""); + } + is_ascending = true; + return true; +} + +bool Bird::OnTouchEvent(uint16_t /*x*/, uint16_t /*y*/) { + is_ascending = true; + return true; +} diff --git a/src/displayapp/screens/Bird.h b/src/displayapp/screens/Bird.h new file mode 100644 index 00000000..87b46ba5 --- /dev/null +++ b/src/displayapp/screens/Bird.h @@ -0,0 +1,52 @@ +#pragma once + +#include +#include +#include "displayapp/screens/Screen.h" + +#define BIRD_X 110 +#define BIRD_SIZE 20 +#define CACTUS_HEIGHT 160 +#define CACTUS_WIDTH 30 +#define CACTUS_GAP 80 + +namespace Pinetime { + namespace Components { + class LittleVgl; + } + + namespace Applications { + namespace Screens { + + class Bird : public Screen { + public: + Bird(Pinetime::Components::LittleVgl& lvgl); + ~Bird() override; + + void Refresh() override; + + bool OnTouchEvent(TouchEvents event) override; + bool OnTouchEvent(uint16_t x, uint16_t y) override; + + private: + void GameOver(); + void MovePipe(); + Pinetime::Components::LittleVgl& lvgl; + + bool is_stopped = true; + bool is_ascending = false; + + uint8_t cactus_x = 240; + uint8_t cactus_y_offset = 40; + + int8_t accel = 0; + uint8_t pos = 120; + uint16_t score = 0; + + lv_obj_t *info, *points, *bird, *cactus_top, *cactus_bottom; + + lv_task_t* taskRefresh; + }; + } + } +} diff --git a/src/displayapp/screens/Symbols.h b/src/displayapp/screens/Symbols.h index 7154ff44..bf63d398 100644 --- a/src/displayapp/screens/Symbols.h +++ b/src/displayapp/screens/Symbols.h @@ -20,6 +20,7 @@ namespace Pinetime { static constexpr const char* paintbrush = "\xEF\x87\xBC"; static constexpr const char* paddle = "\xEF\x91\x9D"; static constexpr const char* map = "\xEF\x96\xa0"; + static constexpr const char* dove = "\xEF\x92\xBA"; static constexpr const char* phone = "\xEF\x82\x95"; static constexpr const char* phoneSlash = "\xEF\x8F\x9D"; static constexpr const char* volumMute = "\xEF\x9A\xA9";