mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-01-09 04:37:52 +03:00
3f3f45580a
Each of these strings would previously rely on StringView's char const* constructor overload, which would call __builtin_strlen on the string. Since we now have operator ""sv, we can replace these with much simpler versions. This opens the door to being able to remove StringView(char const*). No functional changes.
184 lines
5.0 KiB
C++
184 lines
5.0 KiB
C++
/*
|
|
* Copyright (c) 2021, Mim Hufford <mim@hotmail.co.uk>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <AK/Optional.h>
|
|
#include <AK/Random.h>
|
|
#include <AK/Vector.h>
|
|
#include <LibGUI/Application.h>
|
|
#include <LibGUI/Frame.h>
|
|
#include <LibGUI/Painter.h>
|
|
#include <LibGfx/Bitmap.h>
|
|
#include <LibGfx/Font/Font.h>
|
|
#include <LibGfx/StandardCursor.h>
|
|
|
|
namespace FlappyBug {
|
|
|
|
class Game final : public GUI::Frame {
|
|
C_OBJECT(Game);
|
|
|
|
public:
|
|
static constexpr int game_width = 560;
|
|
static constexpr int game_height = 480;
|
|
|
|
Function<u32(u32)> on_game_end;
|
|
|
|
private:
|
|
virtual void paint_event(GUI::PaintEvent&) override;
|
|
virtual void keydown_event(GUI::KeyEvent&) override;
|
|
virtual void mousedown_event(GUI::MouseEvent&) override;
|
|
virtual void timer_event(Core::TimerEvent&) override;
|
|
|
|
void tick();
|
|
void reset();
|
|
void game_over();
|
|
bool ready_to_start() const;
|
|
void player_input();
|
|
|
|
public:
|
|
struct Bug {
|
|
float const x { 50 };
|
|
float const radius { 16 };
|
|
float const starting_y { 200 };
|
|
NonnullRefPtr<Gfx::Bitmap> falling_bitmap;
|
|
NonnullRefPtr<Gfx::Bitmap> flapping_bitmap;
|
|
float y {};
|
|
float velocity {};
|
|
|
|
private:
|
|
Bug(NonnullRefPtr<Gfx::Bitmap> falling_bitmap_value, NonnullRefPtr<Gfx::Bitmap> flapping_bitmap_value)
|
|
: falling_bitmap(move(falling_bitmap_value))
|
|
, flapping_bitmap(move(flapping_bitmap_value))
|
|
{
|
|
}
|
|
|
|
public:
|
|
static ErrorOr<Bug> construct()
|
|
{
|
|
NonnullRefPtr<Gfx::Bitmap> falling_bitmap = TRY(Gfx::Bitmap::try_load_from_file("/res/icons/flappybug/falling.png"sv));
|
|
NonnullRefPtr<Gfx::Bitmap> flapping_bitmap = TRY(Gfx::Bitmap::try_load_from_file("/res/icons/flappybug/flapping.png"sv));
|
|
return Bug(move(falling_bitmap), move(flapping_bitmap));
|
|
}
|
|
|
|
void reset()
|
|
{
|
|
y = starting_y;
|
|
}
|
|
|
|
NonnullRefPtr<Gfx::Bitmap> current_bitmap() const
|
|
{
|
|
return velocity < 0 ? falling_bitmap : flapping_bitmap;
|
|
}
|
|
|
|
Gfx::FloatRect rect() const
|
|
{
|
|
return { x - radius, y - radius, radius * 2, radius * 2 };
|
|
}
|
|
|
|
void flap()
|
|
{
|
|
float const flap_strength = 10.0f;
|
|
velocity = -flap_strength;
|
|
}
|
|
|
|
void fall()
|
|
{
|
|
float const gravity = 1.0f;
|
|
velocity += gravity;
|
|
}
|
|
|
|
void apply_velocity()
|
|
{
|
|
y += velocity;
|
|
}
|
|
};
|
|
|
|
struct Obstacle {
|
|
float const width { 20 };
|
|
Color color { Color::DarkGray };
|
|
float x {};
|
|
float gap_top_y { 200 };
|
|
float gap_height { 175 };
|
|
|
|
void reset()
|
|
{
|
|
x = game_width + width;
|
|
gap_top_y = get_random_uniform(game_height - gap_height);
|
|
}
|
|
|
|
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 };
|
|
}
|
|
};
|
|
|
|
struct Cloud {
|
|
Vector<NonnullRefPtr<Gfx::Bitmap>> const cloud_bitmaps;
|
|
float x {};
|
|
float y {};
|
|
int bitmap_id {};
|
|
|
|
private:
|
|
Cloud(Vector<NonnullRefPtr<Gfx::Bitmap>> const cloud_bitmaps_value)
|
|
: cloud_bitmaps(move(cloud_bitmaps_value))
|
|
{
|
|
reset();
|
|
x = get_random_uniform(game_width);
|
|
}
|
|
|
|
public:
|
|
static ErrorOr<Cloud> construct()
|
|
{
|
|
Vector<NonnullRefPtr<Gfx::Bitmap>> const cloud_bitmaps {
|
|
TRY(Gfx::Bitmap::try_load_from_file("/res/icons/flappybug/cloud_0.png"sv)),
|
|
TRY(Gfx::Bitmap::try_load_from_file("/res/icons/flappybug/cloud_1.png"sv)),
|
|
TRY(Gfx::Bitmap::try_load_from_file("/res/icons/flappybug/cloud_2.png"sv)),
|
|
};
|
|
return Cloud(move(cloud_bitmaps));
|
|
}
|
|
|
|
void reset()
|
|
{
|
|
bitmap_id = get_random_uniform(cloud_bitmaps.size());
|
|
x = game_width + bitmap()->width();
|
|
y = get_random_uniform(game_height / 2) + bitmap()->height();
|
|
}
|
|
|
|
NonnullRefPtr<Gfx::Bitmap> bitmap() const
|
|
{
|
|
return cloud_bitmaps[bitmap_id];
|
|
}
|
|
|
|
Gfx::IntRect rect() const
|
|
{
|
|
return { (int)x - bitmap()->width(), (int)y - bitmap()->height(), bitmap()->width(), bitmap()->height() };
|
|
}
|
|
};
|
|
|
|
private:
|
|
Bug m_bug;
|
|
Obstacle m_obstacle;
|
|
Cloud m_cloud;
|
|
bool m_active;
|
|
Optional<float> m_high_score {};
|
|
float m_last_score {};
|
|
float m_difficulty {};
|
|
float m_restart_cooldown {};
|
|
NonnullRefPtr<Gfx::Bitmap> m_background_bitmap { Gfx::Bitmap::try_load_from_file("/res/icons/flappybug/background.png"sv).release_value_but_fixme_should_propagate_errors() };
|
|
const Gfx::IntRect m_score_rect { 10, 10, 20, 20 };
|
|
const Gfx::IntRect m_text_rect { game_width / 2 - 80, game_height / 2 - 40, 160, 80 };
|
|
|
|
Game(Bug, Cloud);
|
|
};
|
|
|
|
}
|