1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-25 04:55:07 +00:00
serenity/Userland/Games/FlappyBug/Game.cpp
Mim Hufford 28e08f08c2 FlappyBug: Add new graphics and tweak colors
This adds some actual graphics to the game, and tweaks the obstacle and
sky colors. Eventually there will be graphics for those elements too.
2021-06-20 10:54:27 +01:00

120 lines
2.7 KiB
C++

/*
* Copyright (c) 2021, Mim Hufford <mim@hotmail.co.uk>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "Game.h"
namespace FlappyBug {
Game::Game()
{
set_override_cursor(Gfx::StandardCursor::Hidden);
start_timer(16);
reset();
}
void Game::reset()
{
m_active = false;
m_last_score = m_difficulty;
m_difficulty = 1;
m_restart_cooldown = 3;
m_bug.reset();
m_obstacle.reset();
}
void Game::game_over()
{
if (m_highscore.value_or(0) < m_difficulty) {
m_highscore = m_difficulty;
}
reset();
}
bool Game::ready_to_start() const
{
if (!m_highscore.has_value()) {
return true;
}
if (m_restart_cooldown <= 0) {
return true;
}
return false;
}
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(), m_sky_color);
painter.fill_rect(enclosing_int_rect(m_obstacle.top_rect()), m_obstacle.color);
painter.fill_rect(enclosing_int_rect(m_obstacle.bottom_rect()), m_obstacle.color);
painter.draw_scaled_bitmap(enclosing_int_rect(m_bug.rect()), *m_bug.current_bitmap(), m_bug.flapping_bitmap->rect());
if (m_active) {
painter.draw_text({ 10, 10, 100, 100 }, String::formatted("{:.0}", m_difficulty), Gfx::TextAlignment::TopLeft, Color::White);
} else if (m_highscore.has_value()) {
auto message = String::formatted("Your score: {:.0}\nHighscore: {:.0}\n\n{}", m_last_score, m_highscore.value(), m_restart_cooldown < 0 ? "Press any key to play again" : " ");
painter.draw_text(rect(), message, Gfx::TextAlignment::Center, Color::White);
} else {
painter.draw_text(rect(), "Press any key to start", Gfx::TextAlignment::Center, Color::White);
}
}
void Game::keydown_event(GUI::KeyEvent& event)
{
switch (event.key()) {
case Key_Escape:
GUI::Application::the()->quit();
break;
default:
if (ready_to_start()) {
m_active = true;
}
if (m_active) {
m_bug.flap();
}
break;
}
}
void Game::tick()
{
if (m_active) {
m_difficulty += 1.0f / 16.0f;
m_bug.fall();
m_bug.apply_velocity();
m_obstacle.x -= 4 + m_difficulty / 16.0f;
if (m_bug.y > game_height || m_bug.y < 0) {
game_over();
}
if (m_bug.rect().intersects(m_obstacle.top_rect()) || m_bug.rect().intersects(m_obstacle.bottom_rect())) {
game_over();
}
if (m_obstacle.x < 0) {
m_obstacle.reset();
}
}
m_restart_cooldown -= 1.0f / 16.0f;
update();
}
}