diff options
author | Mim Hufford <mim@hotmail.co.uk> | 2021-06-01 17:16:19 +0100 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2021-06-20 10:54:27 +0100 |
commit | 811d9722f9107fb8e6a3611ebb5c40c1fe356c37 (patch) | |
tree | 09548c7670dc2a15d589a6a5b49eb603aaf372ae /Userland | |
parent | 24225df979e1976e89b7e18be71c14fbdcdbfc43 (diff) | |
download | serenity-811d9722f9107fb8e6a3611ebb5c40c1fe356c37.zip |
FlappyBug: Introduce a new Flappy Bug game
This introduces a Flappy Bug game. It's pretty simple currently, but is
playable.
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Games/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Userland/Games/FlappyBug/CMakeLists.txt | 7 | ||||
-rw-r--r-- | Userland/Games/FlappyBug/Game.cpp | 84 | ||||
-rw-r--r-- | Userland/Games/FlappyBug/Game.h | 99 | ||||
-rw-r--r-- | Userland/Games/FlappyBug/main.cpp | 62 |
5 files changed, 253 insertions, 0 deletions
diff --git a/Userland/Games/CMakeLists.txt b/Userland/Games/CMakeLists.txt index c1cd514220..07e860670f 100644 --- a/Userland/Games/CMakeLists.txt +++ b/Userland/Games/CMakeLists.txt @@ -1,6 +1,7 @@ add_subdirectory(2048) add_subdirectory(Breakout) add_subdirectory(Chess) +add_subdirectory(FlappyBug) add_subdirectory(GameOfLife) add_subdirectory(Hearts) add_subdirectory(Minesweeper) diff --git a/Userland/Games/FlappyBug/CMakeLists.txt b/Userland/Games/FlappyBug/CMakeLists.txt new file mode 100644 index 0000000000..dd77a434da --- /dev/null +++ b/Userland/Games/FlappyBug/CMakeLists.txt @@ -0,0 +1,7 @@ +set(SOURCES + main.cpp + Game.cpp +) + +serenity_app(FlappyBug ICON app-flappybug) +target_link_libraries(FlappyBug LibGUI) diff --git a/Userland/Games/FlappyBug/Game.cpp b/Userland/Games/FlappyBug/Game.cpp new file mode 100644 index 0000000000..4e05ba85d5 --- /dev/null +++ b/Userland/Games/FlappyBug/Game.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2021, Mim Hufford <mim@hotmail.co.uk> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "Game.h" +#include <AK/Random.h> + +namespace FlappyBug { + +Game::Game() +{ + set_override_cursor(Gfx::StandardCursor::Hidden); + start_timer(16); + reset(); +} + +void Game::reset() +{ + m_active = false; + m_difficulty = 1; + m_bug.reset(); + m_obstacle.reset(); +} + +void Game::timer_event(Core::TimerEvent&) +{ + tick(); +} + +void Game::paint_event(GUI::PaintEvent& event) +{ + GUI::Painter painter(*this); + painter.add_clip_rect(event.rect()); + + painter.fill_rect(rect(), Color::Black); + + painter.fill_rect(enclosing_int_rect(m_obstacle.top_rect()), Color::White); + painter.fill_rect(enclosing_int_rect(m_obstacle.bottom_rect()), Color::White); + painter.fill_ellipse(enclosing_int_rect(m_bug.rect()), Color::Red); + + painter.draw_text({ 10, 10, 100, 100 }, String::formatted("{}", m_difficulty), Gfx::TextAlignment::TopLeft, Color::Green); +} + +void Game::keydown_event(GUI::KeyEvent& event) +{ + switch (event.key()) { + case Key_Escape: + GUI::Application::the()->quit(); + break; + default: + m_active = true; + m_bug.flap(); + break; + } +} + +void Game::tick() +{ + if (m_active) { + m_difficulty += 0.0001f; + + m_bug.fall(); + m_bug.apply_velocity(); + m_obstacle.x -= 4 + m_difficulty; + + if (m_bug.y > game_height || m_bug.y < 0) { + reset(); + } + + if (m_bug.rect().intersects(m_obstacle.top_rect()) || m_bug.rect().intersects(m_obstacle.bottom_rect())) { + reset(); + } + + if (m_obstacle.x < 0) { + m_obstacle.reset(); + } + } + + update(); +} + +} diff --git a/Userland/Games/FlappyBug/Game.h b/Userland/Games/FlappyBug/Game.h new file mode 100644 index 0000000000..6df9b0b451 --- /dev/null +++ b/Userland/Games/FlappyBug/Game.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2021, Mim Hufford <mim@hotmail.co.uk> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <AK/Optional.h> +#include <LibGUI/Application.h> +#include <LibGUI/Painter.h> +#include <LibGUI/Widget.h> +#include <LibGfx/Bitmap.h> +#include <LibGfx/Font.h> +#include <LibGfx/StandardCursor.h> + +namespace FlappyBug { + +class Game final : public GUI::Widget { + C_OBJECT(Game); + +public: + static const int game_width = 560; + static const int game_height = 480; + +private: + Game(); + + virtual void paint_event(GUI::PaintEvent&) override; + virtual void keydown_event(GUI::KeyEvent&) override; + virtual void timer_event(Core::TimerEvent&) override; + + void tick(); + void reset(); + + struct Bug { + const float x { 50 }; + const float radius { 10 }; + const float starting_y { 200 }; + float y {}; + float velocity {}; + + void reset() + { + y = starting_y; + } + + Gfx::FloatRect rect() const + { + return { x - radius, y - radius, radius * 2, radius * 2 }; + } + + void flap() + { + const float flap_strength = 15.0f; + velocity = -flap_strength; + } + + void fall() + { + const float gravity = 1.0f; + velocity += gravity; + } + + void apply_velocity() + { + y += velocity; + } + }; + + struct Obstacle { + const float width { 20 }; + float x; + float gap_top_y { 200 }; + float gap_height { 175 }; + + void reset() + { + x = game_width; + } + + Gfx::FloatRect top_rect() const + { + return { x - width, 0, width, gap_top_y }; + } + + Gfx::FloatRect bottom_rect() const + { + return { x - width, gap_top_y + gap_height, width, game_height - gap_top_y - gap_height }; + } + }; + + Bug m_bug; + Obstacle m_obstacle; + bool m_active; + float m_difficulty; +}; + +} diff --git a/Userland/Games/FlappyBug/main.cpp b/Userland/Games/FlappyBug/main.cpp new file mode 100644 index 0000000000..1112889366 --- /dev/null +++ b/Userland/Games/FlappyBug/main.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2021, Mim Hufford <mim@hotmail.co.uk> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "Game.h" +#include <LibGUI/Application.h> +#include <LibGUI/Icon.h> +#include <LibGUI/Menu.h> +#include <LibGUI/Menubar.h> +#include <LibGUI/Window.h> +#include <unistd.h> + +int main(int argc, char** argv) +{ + if (pledge("stdio rpath wpath cpath recvfd sendfd cpath unix", nullptr) < 0) { + perror("pledge"); + return 1; + } + + auto app = GUI::Application::construct(argc, argv); + + if (pledge("stdio rpath wpath cpath recvfd sendfd", nullptr) < 0) { + perror("pledge"); + return 1; + } + + if (unveil("/res", "r") < 0) { + perror("unveil"); + return 1; + } + + if (unveil(nullptr, nullptr) < 0) { + perror("unveil"); + return 1; + } + + auto window = GUI::Window::construct(); + window->resize(FlappyBug::Game::game_width, FlappyBug::Game::game_height); + auto app_icon = GUI::Icon::default_icon("app-flappybug"); + window->set_icon(app_icon.bitmap_for_size(16)); + window->set_title("Flappy Bug"); + window->set_double_buffering_enabled(false); + window->set_resizable(false); + window->set_main_widget<FlappyBug::Game>(); + window->show(); + + auto menubar = GUI::Menubar::construct(); + + auto& game_menu = menubar->add_menu("&Game"); + game_menu.add_action(GUI::CommonActions::make_quit_action([](auto&) { + GUI::Application::the()->quit(); + })); + + auto& help_menu = menubar->add_menu("&Help"); + help_menu.add_action(GUI::CommonActions::make_about_action("Flappy Bug", app_icon, window)); + + window->set_menubar(move(menubar)); + + return app->exec(); +} |