diff --git a/framework/platform-dx/game.cpp b/framework/platform-dx/game.cpp index ec10b7d..da44a36 100644 --- a/framework/platform-dx/game.cpp +++ b/framework/platform-dx/game.cpp @@ -5,8 +5,8 @@ namespace xna { impl = unew(); services = snew(); auto iservice = reinterpret_pointer_cast(services); - _contentManager = snew(services, ""); - _contentManager->mainGameService = iservice; + contentManager = snew(services, ""); + contentManager->mainGameService = iservice; _gameWindow = snew(); _gameWindow->impl->Color(146, 150, 154); @@ -16,6 +16,9 @@ namespace xna { GraphicsDeviceManager::DefaultBackBufferHeight, false); _gameComponents = snew(); + + IsFixedTimeStep(isFixedTimeStep); + TargetElapsedTime(targetElapsedTime); } void Game::Exit() { @@ -34,7 +37,7 @@ namespace xna { DispatchMessage(&msg); } else { - Step(); + Tick(); } } while (msg.message != WM_QUIT); @@ -42,7 +45,7 @@ namespace xna { return static_cast(msg.wParam); } - void Game::Step() + void Game::Tick() { impl->_stepTimer.Tick([&]() { @@ -59,6 +62,9 @@ namespace xna { } int Game::Run() { + if (isRunning) + return EXIT_FAILURE; + try { if (!_gameWindow->impl->Create()) { Exception::Throw(Exception::FAILED_TO_CREATE); @@ -72,6 +78,7 @@ namespace xna { return EXIT_FAILURE; } + isRunning = true; return StartGameLoop(); } catch (std::exception& e) { @@ -138,10 +145,10 @@ namespace xna { } sptr Game::Window() { return _gameWindow; } - sptr Game::GetGraphicsDevice() { return graphicsDevice; } - sptr Game::Components() { return _gameComponents; } + sptr Game::Device() const { return graphicsDevice; } + sptr Game::Components() const { return _gameComponents; } sptr Game::Services() { return services; } - sptr Game::Content() { return _contentManager; } + sptr Game::Content() const { return contentManager; } void Game::EnableGameComponents(bool value) { _enabledGameComponents = value; } void Game::AttachGraphicsDevice(sptr const& device) { @@ -158,4 +165,44 @@ namespace xna { _gameWindow->impl->Update(); } } + + void Game::Content(sptr const& value) { + contentManager = value; + auto iservice = reinterpret_pointer_cast(services); + contentManager->mainGameService = iservice; + } + + void Game::IsFixedTimeStep(bool value) { + isFixedTimeStep = value; + impl->_stepTimer.SetFixedTimeStep(value); + } + + bool Game::IsMouseVisible() const { + if (!Mouse::impl) + return false; + + return Mouse::impl->_dxMouse->IsVisible(); + } + + void Game::IsMouseVisible(bool value) { + if (!Mouse::impl) + return; + + Mouse::impl->_dxMouse->SetVisible(value); + } + void Game::TargetElapsedTime(TimeSpan const& value) { + if (!isFixedTimeStep) + return; + + const auto ticks = targetElapsedTime.Ticks(); + impl->_stepTimer.SetTargetElapsedTicks(ticks); + } + + void Game::ResetElapsedTime() const { + impl->_stepTimer.ResetElapsedTime(); + } + + void Game::RunOneFrame() { + Tick(); + } } diff --git a/inc/xna/game/game.hpp b/inc/xna/game/game.hpp index 6f67ee5..1749ddd 100644 --- a/inc/xna/game/game.hpp +++ b/inc/xna/game/game.hpp @@ -5,18 +5,50 @@ #include "time.hpp" namespace xna { + //Provides basic graphics device initialization, game logic, and rendering code. class Game : public std::enable_shared_from_this { public: Game(); - void Exit(); - int Run(); - sptr Window(); - sptr GetGraphicsDevice(); - sptr Components(); - sptr Services(); - sptr Content(); - void EnableGameComponents(bool value); + //Gets the collection of GameComponents owned by the game. + sptr Components() const; + //Gets or sets the current ContentManager. + sptr Content() const; + //Gets or sets the current ContentManager. + void Content(sptr const& value); + //Gets the current GraphicsDevice. + sptr Device() const; + //Gets or sets a value indicating whether to use fixed time steps. + //The default value for IsFixedTimeStep is true. + constexpr bool IsFixedTimeStep() const { return isFixedTimeStep; } + //Gets or sets a value indicating whether to use fixed time steps. + //The default value for IsFixedTimeStep is true. + void IsFixedTimeStep(bool value); + //Gets or sets a value indicating whether the mouse cursor should be visible. + bool IsMouseVisible() const; + //Gets or sets a value indicating whether the mouse cursor should be visible. + void IsMouseVisible(bool value); + //Gets the GameServiceContainer holding all the service providers attached to the Game. + sptr Services(); + //Gets or sets the target time between calls to Update when IsFixedTimeStep is true. + constexpr TimeSpan TargetElapsedTime() const { return targetElapsedTime; } + //Gets or sets the target time between calls to Update when IsFixedTimeStep is true. + void TargetElapsedTime(TimeSpan const& value); + //Gets the underlying operating system window. + sptr Window(); + + //Exits the game. + void Exit(); + //Resets the elapsed time counter. + void ResetElapsedTime() const; + //Call this method to initialize the game, begin running the game loop, and start processing events for the game. + int Run(); + //Run the game through what would happen in a single tick of the game clock; this method is designed for debugging only. + void RunOneFrame(); + //Updates the game's clock and calls Update and Draw. + void Tick(); + + void EnableGameComponents(bool value); void AttachGraphicsDevice(sptr const& graphicsDevice); void ResizeWindow(int width, int heigth); @@ -25,8 +57,7 @@ namespace xna { virtual void Initialize(); virtual void LoadContent(){} virtual void Update(GameTime const& gameTime); - int StartGameLoop(); - void Step(); + int StartGameLoop(); public: sptr graphicsDevice = nullptr; @@ -38,11 +69,14 @@ namespace xna { sptr _gameComponents = nullptr; sptr _gameWindow{ nullptr }; sptr _audioEngine = nullptr; - sptr _contentManager; + sptr contentManager; std::vector> _drawableGameComponents; size_t _drawableGameComponentsCount{ 0 }; bool _enabledGameComponents{ false }; GameTime _currentGameTime{}; + bool isFixedTimeStep{ true }; + TimeSpan targetElapsedTime{ TimeSpan::FromTicks(166667L) }; + bool isRunning{ false }; public: struct PlatformImplementation; diff --git a/samples/02_PlatfformerStarterKit/game.cpp b/samples/02_PlatfformerStarterKit/game.cpp index cd3d5fd..fc96f09 100644 --- a/samples/02_PlatfformerStarterKit/game.cpp +++ b/samples/02_PlatfformerStarterKit/game.cpp @@ -73,7 +73,7 @@ namespace PlatformerStarterKit { auto keyboardState = Keyboard::GetState(); auto gamepadState = GamePad::GetState(PlayerIndex::One); - if (gamepadState.Buttons.Back == ButtonState::Pressed) + if (gamepadState.Buttons().Back() == ButtonState::Pressed) Exit(); bool continuePressed = diff --git a/samples/02_PlatfformerStarterKit/player.cpp b/samples/02_PlatfformerStarterKit/player.cpp index 9d98c5b..e2b7961 100644 --- a/samples/02_PlatfformerStarterKit/player.cpp +++ b/samples/02_PlatfformerStarterKit/player.cpp @@ -92,7 +92,7 @@ namespace PlatformerStarterKit { auto gamePadState = xna::GamePad::GetState(xna::PlayerIndex::One); auto keyboardState = xna::Keyboard::GetState(); - movement = gamePadState.ThumbSticks.Left().X * MoveStickScale; + movement = gamePadState.ThumbSticks().Left().X * MoveStickScale; if (std::abs(movement) < 0.5f) movement = 0.0f;