2018-04-21 21:24:46 +08:00
# include "..\e2dbase.h"
2018-08-15 23:30:23 +08:00
# include "..\e2dnode.h"
# include "..\e2dtransition.h"
2018-04-21 21:24:46 +08:00
# include "..\e2dmanager.h"
2018-04-24 09:02:06 +08:00
# include "..\e2dtool.h"
2018-07-21 22:57:21 +08:00
# include <thread>
2018-01-30 16:45:38 +08:00
2018-07-03 01:49:20 +08:00
e2d : : Game : : Game ( )
2018-07-24 12:49:32 +08:00
: _quit ( true )
2018-07-03 01:49:20 +08:00
, _paused ( false )
2018-07-24 12:49:32 +08:00
, _config ( )
2018-08-15 00:06:03 +08:00
, _window ( nullptr )
, _input ( nullptr )
, _renderer ( nullptr )
2018-08-15 23:30:23 +08:00
, _currScene ( nullptr )
, _nextScene ( nullptr )
, _transition ( nullptr )
, _scenes ( )
2018-07-03 01:49:20 +08:00
{
2018-07-04 15:33:09 +08:00
CoInitialize ( nullptr ) ;
2018-08-15 00:06:03 +08:00
_input = new ( std : : nothrow ) Input ;
_renderer = new ( std : : nothrow ) Renderer ;
2018-07-03 01:49:20 +08:00
}
2018-07-03 18:16:26 +08:00
e2d : : Game : : ~ Game ( )
{
2018-08-15 00:06:03 +08:00
if ( _renderer )
delete _renderer ;
if ( _input )
delete _input ;
if ( _window )
delete _window ;
2018-07-04 15:33:09 +08:00
CoUninitialize ( ) ;
2018-07-03 18:16:26 +08:00
}
2018-07-03 01:49:20 +08:00
e2d : : Game * e2d : : Game : : getInstance ( )
{
2018-08-15 00:06:03 +08:00
static Game instance ;
return & instance ;
2018-07-03 18:16:26 +08:00
}
2018-07-21 22:57:21 +08:00
void e2d : : Game : : start ( )
2018-01-30 16:45:38 +08:00
{
2018-08-02 00:27:45 +08:00
_quit = false ;
2018-07-29 13:44:53 +08:00
2018-08-02 00:27:45 +08:00
const int minInterval = 5 ;
Time last = Time : : now ( ) ;
2018-08-15 00:06:03 +08:00
HWND hWnd = _window - > getHWnd ( ) ;
2018-08-02 00:27:45 +08:00
2018-07-21 22:57:21 +08:00
: : ShowWindow ( hWnd , SW_SHOWNORMAL ) ;
: : UpdateWindow ( hWnd ) ;
2018-08-15 00:06:03 +08:00
_window - > poll ( ) ;
2018-08-15 23:30:23 +08:00
updateScene ( ) ;
2018-07-29 01:43:15 +08:00
2018-07-24 12:49:32 +08:00
while ( ! _quit )
2018-01-30 16:45:38 +08:00
{
2018-08-02 00:27:45 +08:00
auto now = Time : : now ( ) ;
auto dur = now - last ;
2018-01-30 16:45:38 +08:00
2018-08-02 00:27:45 +08:00
if ( dur . milliseconds ( ) > minInterval )
2018-01-30 16:45:38 +08:00
{
2018-08-02 00:27:45 +08:00
last = now ;
2018-08-15 00:06:03 +08:00
_input - > update ( ) ;
2018-07-29 01:43:15 +08:00
Timer : : getInstance ( ) - > update ( ) ;
ActionManager : : getInstance ( ) - > update ( ) ;
2018-08-15 23:30:23 +08:00
updateScene ( ) ;
drawScene ( ) ;
2018-08-15 00:06:03 +08:00
_window - > poll ( ) ;
2018-07-29 01:43:15 +08:00
GC : : getInstance ( ) - > flush ( ) ;
2018-01-30 16:45:38 +08:00
}
else
{
2018-08-12 14:05:12 +08:00
// ID2D1HwndRenderTarget <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ˴ <EFBFBD> ֱͬ<D6B1> <CDAC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ⱦʱ<C8BE> <CAB1> <EFBFBD> ȴ<EFBFBD> <C8B4> <EFBFBD> ʾ <EFBFBD> <CABE> ˢ<EFBFBD> £<EFBFBD>
2018-07-29 13:44:53 +08:00
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ˷dz<CBB7> <C7B3> ȶ<EFBFBD> <C8B6> <EFBFBD> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> ã<EFBFBD> <C3A3> <EFBFBD> <EFBFBD> Դ<D4B4> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> ֶ<EFBFBD> <D6B6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߳̽<DFB3> <CCBD> <EFBFBD> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1>
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ĵ<EFBFBD> <C4B4> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ Щ<D2BB> <D0A9> <EFBFBD> <EFBFBD> <EFBFBD> £<EFBFBD> <C2A3> <EFBFBD> <EFBFBD> 細<EFBFBD> <E7B4B0> <EFBFBD> <EFBFBD> С <EFBFBD> <D0A1> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ̣߳<DFB3> <CCA3> <EFBFBD> ֹռ <D6B9> ù<EFBFBD> <C3B9> <EFBFBD> CPU <20> <>
2018-08-02 00:27:45 +08:00
int wait = minInterval - dur . milliseconds ( ) ;
2018-07-29 13:44:53 +08:00
if ( wait > 1 )
{
std : : this_thread : : sleep_for ( std : : chrono : : milliseconds ( wait ) ) ;
}
2018-01-30 16:45:38 +08:00
}
}
}
2018-02-07 16:37:12 +08:00
void e2d : : Game : : pause ( )
2018-01-30 16:45:38 +08:00
{
2018-07-03 01:49:20 +08:00
_paused = true ;
2018-01-30 16:45:38 +08:00
}
2018-02-07 16:37:12 +08:00
void e2d : : Game : : resume ( )
2018-01-30 16:45:38 +08:00
{
2018-07-24 12:49:32 +08:00
if ( _paused & & ! _quit )
2018-05-24 00:58:16 +08:00
{
2018-07-21 22:57:21 +08:00
Timer : : getInstance ( ) - > updateTime ( ) ;
ActionManager : : getInstance ( ) - > updateTime ( ) ;
2018-05-24 00:58:16 +08:00
}
2018-07-05 16:44:47 +08:00
_paused = false ;
2018-05-10 18:18:02 +08:00
}
2018-02-07 16:37:12 +08:00
bool e2d : : Game : : isPaused ( )
2018-01-30 16:45:38 +08:00
{
2018-07-03 01:49:20 +08:00
return _paused ;
2018-01-30 16:45:38 +08:00
}
2018-07-24 12:49:32 +08:00
void e2d : : Game : : setConfig ( const Config & config )
2018-07-04 17:00:21 +08:00
{
2018-07-24 20:21:25 +08:00
_config = config ;
2018-07-04 17:00:21 +08:00
}
2018-08-15 00:06:03 +08:00
const e2d : : Config & e2d : : Game : : getConfig ( ) const
2018-07-04 17:00:21 +08:00
{
return _config ;
}
2018-08-15 00:06:03 +08:00
void e2d : : Game : : setWindow ( Window * window )
{
_window = window ;
_renderer - > init ( _window ) ;
_input - > init ( _window ) ;
}
2018-02-07 16:37:12 +08:00
void e2d : : Game : : quit ( )
2018-01-30 16:45:38 +08:00
{
2018-07-24 12:49:32 +08:00
_quit = true ;
2018-01-30 16:45:38 +08:00
}
2018-08-15 23:30:23 +08:00
void e2d : : Game : : pushScene ( Scene * scene , bool saveCurrentScene )
2018-01-30 16:45:38 +08:00
{
2018-08-15 23:30:23 +08:00
if ( ! scene )
return ;
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> <D2BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ָ<EFBFBD> <D6B8>
if ( _nextScene ) _nextScene - > release ( ) ;
_nextScene = scene ;
_nextScene - > retain ( ) ;
if ( saveCurrentScene & & _currScene )
{
_scenes . push ( _currScene ) ;
}
}
void e2d : : Game : : pushScene ( Transition * transition , bool saveCurrentScene )
{
if ( ! transition )
return ;
pushScene ( transition - > _inScene , saveCurrentScene ) ;
if ( _transition )
{
_transition - > _stop ( ) ;
_transition - > release ( ) ;
}
_transition = transition ;
_transition - > retain ( ) ;
// <20> <> ʼ <EFBFBD> <CABC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> л<EFBFBD> <D0BB> <EFBFBD> <EFBFBD> <EFBFBD>
if ( ! _transition - > _init ( _currScene ) )
{
WARN ( " Transition initialize failed! " ) ;
_transition - > release ( ) ;
_transition = nullptr ;
}
}
e2d : : Scene * e2d : : Game : : popScene ( )
{
// ջΪ<D5BB> <CEAA> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD> <EFBFBD> ÷<EFBFBD> <C3B7> س<EFBFBD> <D8B3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʧ<EFBFBD> <CAA7>
if ( _scenes . size ( ) = = 0 )
{
WARN ( " Scene stack is empty! " ) ;
return nullptr ;
}
_nextScene = _scenes . top ( ) ;
_nextScene - > release ( ) ;
_scenes . pop ( ) ;
return _nextScene ;
}
e2d : : Scene * e2d : : Game : : popScene ( Transition * transition )
{
if ( ! transition )
return nullptr ;
auto scene = popScene ( ) ;
if ( scene )
{
if ( _transition )
{
_transition - > _stop ( ) ;
_transition - > release ( ) ;
}
_transition = transition ;
_transition - > retain ( ) ;
_transition - > _inScene = scene ;
_transition - > _inScene - > retain ( ) ;
// <20> <> ʼ <EFBFBD> <CABC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> л<EFBFBD> <D0BB> <EFBFBD> <EFBFBD> <EFBFBD>
if ( ! _transition - > _init ( _currScene ) )
{
WARN ( " Transition initialize failed! " ) ;
_transition - > release ( ) ;
_transition = nullptr ;
}
}
return scene ;
}
void e2d : : Game : : clearAllScenes ( )
{
while ( ! _scenes . empty ( ) )
{
_scenes . top ( ) - > release ( ) ;
_scenes . pop ( ) ;
}
}
e2d : : Scene * e2d : : Game : : getCurrentScene ( )
{
return _currScene ;
}
const std : : stack < e2d : : Scene * > & e2d : : Game : : getSceneStack ( )
{
return _scenes ;
}
bool e2d : : Game : : isTransitioning ( ) const
{
return _transition ! = nullptr ;
}
void e2d : : Game : : updateScene ( )
{
if ( _transition )
{
_transition - > _update ( ) ;
if ( _transition - > isDone ( ) )
{
_transition - > release ( ) ;
_transition = nullptr ;
}
else
{
return ;
}
}
if ( _nextScene )
{
if ( _currScene )
{
_currScene - > onExit ( ) ;
if ( _scenes . empty ( ) | | _scenes . top ( ) ! = _currScene )
{
_currScene - > release ( ) ;
}
}
_nextScene - > onEnter ( ) ;
_currScene = _nextScene ;
_nextScene = nullptr ;
}
}
void e2d : : Game : : drawScene ( )
{
// <20> <> Ⱦ<EFBFBD> <C8BE> <EFBFBD> <EFBFBD>
_renderer - > beginDraw ( ) ;
{
if ( _transition )
{
_transition - > _render ( ) ;
}
else if ( _currScene )
{
_currScene - > visit ( _renderer ) ;
if ( _config . isOutlineVisible ( ) )
{
auto brush = _renderer - > getSolidColorBrush ( ) ;
brush - > SetColor ( D2D1 : : ColorF ( D2D1 : : ColorF : : Red , 0.6f ) ) ;
brush - > SetOpacity ( 1.f ) ;
_currScene - > drawOutline ( _renderer ) ;
}
if ( _config . isColliderVisible ( ) )
{
_renderer - > getRenderTarget ( ) - > SetTransform ( D2D1 : : Matrix3x2F : : Identity ( ) ) ;
_currScene - > drawCollider ( ) ;
}
}
if ( _config . isFpsShow ( ) )
{
_renderer - > drawFps ( ) ;
}
}
_renderer - > endDraw ( ) ;
2018-01-30 16:45:38 +08:00
}