2021-06-01 13:16:19 -03:00
/*
* 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 ;
2021-06-01 13:59:01 -03:00
m_last_score = m_difficulty ;
2021-06-01 13:16:19 -03:00
m_difficulty = 1 ;
2021-06-02 06:37:00 -03:00
m_restart_cooldown = 3 ;
2021-06-01 13:16:19 -03:00
m_bug . reset ( ) ;
m_obstacle . reset ( ) ;
}
2021-06-01 13:59:01 -03:00
void Game : : game_over ( )
{
2021-06-22 11:50:54 -03:00
if ( on_game_end )
2021-06-22 11:54:42 -03:00
m_high_score = on_game_end ( static_cast < u32 > ( m_difficulty ) ) ;
2021-06-22 11:50:54 -03:00
2021-06-01 13:59:01 -03:00
reset ( ) ;
}
2021-06-02 06:37:00 -03:00
bool Game : : ready_to_start ( ) const
{
2021-06-22 11:54:42 -03:00
if ( ! m_high_score . has_value ( ) ) {
2021-06-02 06:37:00 -03:00
return true ;
}
if ( m_restart_cooldown < = 0 ) {
return true ;
}
return false ;
}
2021-06-01 13:16:19 -03:00
void Game : : timer_event ( Core : : TimerEvent & )
{
tick ( ) ;
}
void Game : : paint_event ( GUI : : PaintEvent & event )
{
2021-06-21 16:53:50 -03:00
GUI : : Frame : : paint_event ( event ) ;
2021-06-01 13:16:19 -03:00
GUI : : Painter painter ( * this ) ;
2021-06-21 16:53:50 -03:00
painter . add_clip_rect ( frame_inner_rect ( ) ) ;
2021-06-01 13:16:19 -03:00
painter . add_clip_rect ( event . rect ( ) ) ;
2021-06-21 16:53:50 -03:00
painter . draw_tiled_bitmap ( frame_inner_rect ( ) , * m_background_bitmap ) ;
2021-06-07 07:03:01 -03:00
painter . draw_scaled_bitmap ( m_cloud . rect ( ) , * m_cloud . bitmap ( ) , m_cloud . bitmap ( ) - > rect ( ) , 0.2f ) ;
2021-06-01 13:16:19 -03:00
2021-06-02 08:18:57 -03:00
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 ( ) ) ;
2021-06-01 13:16:19 -03:00
2021-06-01 13:59:01 -03:00
if ( m_active ) {
2021-07-10 18:15:38 -03:00
painter . draw_text ( m_score_rect , String : : formatted ( " {:.0} " , m_difficulty ) , Gfx : : TextAlignment : : TopLeft , Color : : White ) ;
2021-06-22 11:54:42 -03:00
} else if ( m_high_score . has_value ( ) ) {
auto message = String : : formatted ( " Your score: {:.0} \n High score: {:.0} \n \n {} " , m_last_score , m_high_score . value ( ) , m_restart_cooldown < 0 ? " Press any key to play again " : " " ) ;
2021-07-10 18:15:38 -03:00
painter . draw_text ( m_text_rect , message , Gfx : : TextAlignment : : Center , Color : : White ) ;
2021-06-01 13:59:01 -03:00
} else {
2021-07-10 18:15:38 -03:00
painter . draw_text ( m_text_rect , " Press any key to start " , Gfx : : TextAlignment : : Center , Color : : White ) ;
2021-06-01 13:59:01 -03:00
}
2021-06-01 13:16:19 -03:00
}
void Game : : keydown_event ( GUI : : KeyEvent & event )
{
switch ( event . key ( ) ) {
case Key_Escape :
GUI : : Application : : the ( ) - > quit ( ) ;
break ;
default :
2021-06-02 06:37:00 -03:00
if ( ready_to_start ( ) ) {
m_active = true ;
}
if ( m_active ) {
m_bug . flap ( ) ;
}
2021-06-01 13:16:19 -03:00
break ;
}
}
void Game : : tick ( )
{
2021-07-10 18:15:38 -03:00
auto queue_update = [ & ] ( ) {
update ( m_score_rect ) ;
update ( m_text_rect ) ;
update ( enclosing_int_rect ( m_bug . rect ( ) ) ) ;
update ( enclosing_int_rect ( m_obstacle . top_rect ( ) ) ) ;
update ( enclosing_int_rect ( m_obstacle . bottom_rect ( ) ) ) ;
update ( m_cloud . rect ( ) ) ;
} ;
2021-06-01 13:16:19 -03:00
if ( m_active ) {
2021-07-10 18:15:38 -03:00
queue_update ( ) ;
2021-06-01 13:59:01 -03:00
m_difficulty + = 1.0f / 16.0f ;
2021-06-01 13:16:19 -03:00
m_bug . fall ( ) ;
m_bug . apply_velocity ( ) ;
2021-06-01 13:59:01 -03:00
m_obstacle . x - = 4 + m_difficulty / 16.0f ;
2021-06-07 07:03:01 -03:00
m_cloud . x - = m_difficulty / 16.0f ;
2021-06-01 13:16:19 -03:00
if ( m_bug . y > game_height | | m_bug . y < 0 ) {
2021-06-01 13:59:01 -03:00
game_over ( ) ;
2021-06-01 13:16:19 -03:00
}
if ( m_bug . rect ( ) . intersects ( m_obstacle . top_rect ( ) ) | | m_bug . rect ( ) . intersects ( m_obstacle . bottom_rect ( ) ) ) {
2021-06-01 13:59:01 -03:00
game_over ( ) ;
2021-06-01 13:16:19 -03:00
}
if ( m_obstacle . x < 0 ) {
m_obstacle . reset ( ) ;
}
2021-06-07 07:03:01 -03:00
if ( m_cloud . x < 0 ) {
m_cloud . reset ( ) ;
}
2021-06-01 13:16:19 -03:00
}
2021-06-02 06:37:00 -03:00
m_restart_cooldown - = 1.0f / 16.0f ;
2021-07-10 18:15:38 -03:00
queue_update ( ) ;
2021-06-01 13:16:19 -03:00
}
}