mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 12:22:44 +00:00 
			
		
		
		
	 3f3f45580a
			
		
	
	
		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.
		
			
				
	
	
		
			183 lines
		
	
	
	
		
			5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			183 lines
		
	
	
	
		
			5 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);
 | |
| };
 | |
| 
 | |
| }
 |