Commit 92e51426 authored by Florian Oetke's avatar Florian Oetke
Browse files

game screen placeholders and transitions

parent 09d7e506
Pipeline #3248 passed with stage
in 2 minutes and 15 seconds
#include "game_screen.hpp"
#include "game_engine.hpp"
#include "gameover_screen.hpp"
#include "messages.hpp"
#include "meta_system.hpp"
#include "win_screen.hpp"
#include <mirrage/renderer/animation_comp.hpp>
#include <mirrage/renderer/light_comp.hpp>
......@@ -45,6 +48,15 @@ namespace phase_shifter {
break;
}
});
_mailbox.subscribe_to([&](Win_msg& e) {
// TODO: fade out...
_engine.screens().enter<Win_screen>();
});
_mailbox.subscribe_to([&](Lose_msg& e) {
// TODO: fade out...
_engine.screens().enter<Gameover_screen>();
});
}
Game_screen::~Game_screen() noexcept = default;
......
#include "gameover_screen.hpp"
#include "game_engine.hpp"
#include "game_screen.hpp"
#include "sync_screen.hpp"
#include <mirrage/gui/gui.hpp>
#include <mirrage/input/input_manager.hpp>
#include <mirrage/renderer/pass/clear_pass.hpp>
#include <mirrage/utils/log.hpp>
#include <mirrage/utils/maybe.hpp>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <chrono>
#include <cstdlib>
#include <iomanip>
#include <sstream>
#include <thread>
namespace phase_shifter {
using namespace mirrage;
using namespace ecs::components;
using namespace mirrage::input;
using namespace mirrage::util::unit_literals;
using namespace graphic;
Gameover_screen::Gameover_screen(Engine& engine)
: Screen(engine)
, _mailbox(engine.bus())
, _renderer(dynamic_cast<Game_engine&>(engine).renderer_factory().create_renderer(
mirrage::util::nothing, {renderer::render_pass_id_of<renderer::Clear_pass_factory>()}))
{
_mailbox.subscribe_to([&](Once_action& e) {
switch(e.id) {
case "quit"_strid:
// TODO: show pause menu, instead
_engine.screens().leave();
break;
}
});
}
Gameover_screen::~Gameover_screen() noexcept = default;
void Gameover_screen::_on_enter(mirrage::util::maybe<Screen&>) { _mailbox.enable(); }
void Gameover_screen::_on_leave(mirrage::util::maybe<Screen&>) { _mailbox.disable(); }
void Gameover_screen::_update(mirrage::util::Time dt)
{
std::this_thread::sleep_for(std::chrono::milliseconds(8));
_mailbox.update_subscriptions();
_renderer->update(dt);
}
void Gameover_screen::_draw()
{
_renderer->draw(); //< clear screen
ImGui::PositionNextWindow(
glm::vec2(500, 500), ImGui::WindowPosition_X::center, ImGui::WindowPosition_Y::center);
if(ImGui::Begin("Gameover")) {
ImGui::TextUnformatted("TODO");
if(ImGui::Button("Start")) {
_engine.screens().enter<Game_screen>();
}
if(ImGui::Button("Sync")) {
_engine.screens().enter<Sync_screen>();
}
if(ImGui::Button("Quit")) {
_engine.screens().leave();
}
}
ImGui::End();
}
} // namespace phase_shifter
#pragma once
#include <mirrage/engine.hpp>
#include <mirrage/gui/gui.hpp>
#include <mirrage/renderer/deferred_renderer.hpp>
#include <mirrage/utils/console_command.hpp>
#include <mirrage/utils/maybe.hpp>
namespace phase_shifter {
class Gameover_screen : public mirrage::Screen {
public:
Gameover_screen(mirrage::Engine& engine);
~Gameover_screen() noexcept override;
auto name() const -> std::string override { return "Gameover"; }
protected:
void _update(mirrage::util::Time delta_time) override;
void _draw() override;
void _on_enter(mirrage::util::maybe<Screen&> prev) override;
void _on_leave(mirrage::util::maybe<Screen&> next) override;
auto _prev_screen_policy() const noexcept -> mirrage::Prev_screen_policy override
{
return mirrage::Prev_screen_policy::discard;
}
protected:
mirrage::util::Mailbox_collection _mailbox;
std::unique_ptr<mirrage::renderer::Deferred_renderer> _renderer;
};
} // namespace phase_shifter
#include "beat_system.hpp"
#include "../messages.hpp"
#include <mirrage/utils/log.hpp>
namespace phase_shifter::gameplay {
......@@ -8,6 +10,8 @@ namespace phase_shifter::gameplay {
constexpr auto beat_time = 1.f;
}
Beat_system::Beat_system(mirrage::util::Message_bus& bus) : _bus(bus) {}
void Beat_system::update(mirrage::util::Time dt)
{
_acc += dt.value();
......@@ -16,6 +20,10 @@ namespace phase_shifter::gameplay {
_state.beats_left--;
LOG(plog::debug) << "beat";
_acc = 0;
if(_state.beats_left == 0) {
_bus.send<Lose_msg>();
}
}
_state = {beat, _acc, beat_time - _acc, beat_time, _state.beats_left};
......
#pragma once
#include <mirrage/utils/messagebus.hpp>
#include <mirrage/utils/units.hpp>
namespace phase_shifter::gameplay {
......@@ -10,13 +11,13 @@ namespace phase_shifter::gameplay {
float time_to_beat = 0.f;
float avg_beat_time = 1.f;
int beats_left = 9999.f;
int beats_left = 999.f;
};
// TODO: replace placeholder logic with actual beat detection
class Beat_system {
public:
Beat_system() = default;
Beat_system(mirrage::util::Message_bus&);
void update(mirrage::util::Time);
......@@ -25,8 +26,9 @@ namespace phase_shifter::gameplay {
void decrease_beats_left(int count);
private:
Beat_state _state;
float _acc = 0.f;
mirrage::util::Message_bus& _bus;
Beat_state _state;
float _acc = 0.f;
};
} // namespace phase_shifter::gameplay
#include "intro_screen.hpp"
#include "game_engine.hpp"
#include "game_screen.hpp"
#include "sync_screen.hpp"
#include <mirrage/gui/gui.hpp>
#include <mirrage/input/input_manager.hpp>
#include <mirrage/renderer/pass/clear_pass.hpp>
#include <mirrage/utils/log.hpp>
#include <mirrage/utils/maybe.hpp>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <chrono>
#include <cstdlib>
#include <iomanip>
#include <sstream>
#include <thread>
namespace phase_shifter {
using namespace mirrage;
using namespace ecs::components;
using namespace mirrage::input;
using namespace mirrage::util::unit_literals;
using namespace graphic;
Intro_screen::Intro_screen(Engine& engine)
: Screen(engine)
, _mailbox(engine.bus())
, _renderer(dynamic_cast<Game_engine&>(engine).renderer_factory().create_renderer(
mirrage::util::nothing, {renderer::render_pass_id_of<renderer::Clear_pass_factory>()}))
{
_mailbox.subscribe_to([&](Once_action& e) {
switch(e.id) {
case "quit"_strid:
// TODO: show pause menu, instead
_engine.screens().leave();
break;
}
});
}
Intro_screen::~Intro_screen() noexcept = default;
void Intro_screen::_on_enter(mirrage::util::maybe<Screen&>) { _mailbox.enable(); }
void Intro_screen::_on_leave(mirrage::util::maybe<Screen&>) { _mailbox.disable(); }
void Intro_screen::_update(mirrage::util::Time dt)
{
std::this_thread::sleep_for(std::chrono::milliseconds(8));
_mailbox.update_subscriptions();
_renderer->update(dt);
}
void Intro_screen::_draw()
{
_renderer->draw(); //< clear screen
ImGui::PositionNextWindow(
glm::vec2(500, 500), ImGui::WindowPosition_X::center, ImGui::WindowPosition_Y::center);
if(ImGui::Begin("Intro")) {
ImGui::TextUnformatted("TODO");
if(ImGui::Button("Start")) {
_engine.screens().enter<Game_screen>();
}
if(ImGui::Button("Sync")) {
_engine.screens().enter<Sync_screen>();
}
if(ImGui::Button("Quit")) {
_engine.screens().leave();
}
}
ImGui::End();
}
} // namespace phase_shifter
#pragma once
#include <mirrage/engine.hpp>
#include <mirrage/gui/gui.hpp>
#include <mirrage/renderer/deferred_renderer.hpp>
#include <mirrage/utils/console_command.hpp>
#include <mirrage/utils/maybe.hpp>
namespace phase_shifter {
class Intro_screen : public mirrage::Screen {
public:
Intro_screen(mirrage::Engine& engine);
~Intro_screen() noexcept override;
auto name() const -> std::string override { return "Gameover"; }
protected:
void _update(mirrage::util::Time delta_time) override;
void _draw() override;
void _on_enter(mirrage::util::maybe<Screen&> prev) override;
void _on_leave(mirrage::util::maybe<Screen&> next) override;
auto _prev_screen_policy() const noexcept -> mirrage::Prev_screen_policy override
{
return mirrage::Prev_screen_policy::discard;
}
protected:
mirrage::util::Mailbox_collection _mailbox;
std::unique_ptr<mirrage::renderer::Deferred_renderer> _renderer;
};
} // namespace phase_shifter
......@@ -9,6 +9,10 @@
#include "game_engine.hpp"
#include "game_screen.hpp"
#include "gameover_screen.hpp"
#include "intro_screen.hpp"
#include "sync_screen.hpp"
#include "win_screen.hpp"
#include <mirrage/info.hpp>
......@@ -25,8 +29,8 @@
#include <exception>
#include <iostream>
using namespace mirrage; // import engine namespace
using namespace phase_shifter; // import game namespace
using namespace mirrage; // import engine namespace
using namespace phase_shifter; // import game namespace
using namespace std::string_literals;
......@@ -145,6 +149,14 @@ namespace {
global_commands->add("screen.enter.game | Enters the game screen",
[&]() { engine->screens().enter<Game_screen>(); });
global_commands->add("screen.enter.gameover | Enters the gameover screen",
[&]() { engine->screens().enter<Gameover_screen>(); });
global_commands->add("screen.enter.intro | Enters the intro screen",
[&]() { engine->screens().enter<Intro_screen>(); });
global_commands->add("screen.enter.sync | Enters the sync screen",
[&]() { engine->screens().enter<Sync_screen>(); });
global_commands->add("screen.enter.win | Enters the win screen",
[&]() { engine->screens().enter<Win_screen>(); });
if(argc > 1 && argv[1] == "game"s)
engine->screens().enter<Game_screen>();
......
#pragma once
namespace phase_shifter {
struct Win_msg {
};
struct Lose_msg {
};
} // namespace phase_shifter
......@@ -28,7 +28,7 @@ namespace phase_shifter {
, _audio()
, _renderer(engine.renderer_factory().create_renderer(_entities, engine.render_pass_mask()))
, _model_loading(std::make_unique<renderer::Loading_system>(_entities, engine.assets()))
, _beat_system(std::make_unique<gameplay::Beat_system>())
, _beat_system(std::make_unique<gameplay::Beat_system>(engine.bus()))
, _movement_system(std::make_unique<gameplay::Movement_system>(engine.bus(), _entities, *_beat_system))
, _input_system(std::make_unique<input::Input_system>(engine.bus(), _entities))
, _combat_system(std::make_unique<gameplay::Combat_system>(engine.bus(), _entities, *_beat_system))
......
#include "sync_screen.hpp"
#include "game_engine.hpp"
#include "intro_screen.hpp"
#include <mirrage/gui/gui.hpp>
#include <mirrage/input/input_manager.hpp>
#include <mirrage/renderer/pass/clear_pass.hpp>
#include <mirrage/utils/log.hpp>
#include <mirrage/utils/maybe.hpp>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <chrono>
#include <cstdlib>
#include <iomanip>
#include <sstream>
#include <thread>
namespace phase_shifter {
using namespace mirrage;
using namespace ecs::components;
using namespace mirrage::input;
using namespace mirrage::util::unit_literals;
using namespace graphic;
Sync_screen::Sync_screen(Engine& engine)
: Screen(engine)
, _mailbox(engine.bus())
, _renderer(dynamic_cast<Game_engine&>(engine).renderer_factory().create_renderer(
mirrage::util::nothing, {renderer::render_pass_id_of<renderer::Clear_pass_factory>()}))
{
_mailbox.subscribe_to([&](Once_action& e) {
switch(e.id) {
case "quit"_strid:
// TODO: show pause menu, instead
_engine.screens().leave();
break;
}
});
}
Sync_screen::~Sync_screen() noexcept = default;
void Sync_screen::_on_enter(mirrage::util::maybe<Screen&>) { _mailbox.enable(); }
void Sync_screen::_on_leave(mirrage::util::maybe<Screen&>) { _mailbox.disable(); }
void Sync_screen::_update(mirrage::util::Time dt)
{
std::this_thread::sleep_for(std::chrono::milliseconds(8));
_mailbox.update_subscriptions();
_renderer->update(dt);
}
void Sync_screen::_draw()
{
_renderer->draw(); //< clear screen
ImGui::PositionNextWindow(
glm::vec2(500, 500), ImGui::WindowPosition_X::center, ImGui::WindowPosition_Y::center);
if(ImGui::Begin("Sync")) {
ImGui::TextUnformatted("TODO");
if(ImGui::Button("OK")) {
_engine.screens().enter<Intro_screen>();
}
}
ImGui::End();
}
} // namespace phase_shifter
#pragma once
#include <mirrage/engine.hpp>
#include <mirrage/gui/gui.hpp>
#include <mirrage/renderer/deferred_renderer.hpp>
#include <mirrage/utils/console_command.hpp>
#include <mirrage/utils/maybe.hpp>
namespace phase_shifter {
class Sync_screen : public mirrage::Screen {
public:
Sync_screen(mirrage::Engine& engine);
~Sync_screen() noexcept override;
auto name() const -> std::string override { return "Gameover"; }
protected:
void _update(mirrage::util::Time delta_time) override;
void _draw() override;
void _on_enter(mirrage::util::maybe<Screen&> prev) override;
void _on_leave(mirrage::util::maybe<Screen&> next) override;
auto _prev_screen_policy() const noexcept -> mirrage::Prev_screen_policy override
{
return mirrage::Prev_screen_policy::discard;
}
protected:
mirrage::util::Mailbox_collection _mailbox;
std::unique_ptr<mirrage::renderer::Deferred_renderer> _renderer;
};
} // namespace phase_shifter
#include "win_screen.hpp"
#include "game_engine.hpp"
#include "game_screen.hpp"
#include "sync_screen.hpp"
#include <mirrage/gui/gui.hpp>
#include <mirrage/input/input_manager.hpp>
#include <mirrage/renderer/pass/clear_pass.hpp>
#include <mirrage/utils/log.hpp>
#include <mirrage/utils/maybe.hpp>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <chrono>
#include <cstdlib>
#include <iomanip>
#include <sstream>
#include <thread>
namespace phase_shifter {
using namespace mirrage;
using namespace ecs::components;
using namespace mirrage::input;
using namespace mirrage::util::unit_literals;
using namespace graphic;
Win_screen::Win_screen(Engine& engine)
: Screen(engine)
, _mailbox(engine.bus())
, _renderer(dynamic_cast<Game_engine&>(engine).renderer_factory().create_renderer(
mirrage::util::nothing, {renderer::render_pass_id_of<renderer::Clear_pass_factory>()}))
{
_mailbox.subscribe_to([&](Once_action& e) {
switch(e.id) {
case "quit"_strid:
// TODO: show pause menu, instead
_engine.screens().leave();
break;
}
});
}
Win_screen::~Win_screen() noexcept = default;
void Win_screen::_on_enter(mirrage::util::maybe<Screen&>) { _mailbox.enable(); }
void Win_screen::_on_leave(mirrage::util::maybe<Screen&>) { _mailbox.disable(); }
void Win_screen::_update(mirrage::util::Time dt)
{
std::this_thread::sleep_for(std::chrono::milliseconds(8));
_mailbox.update_subscriptions();
_renderer->update(dt);
}
void Win_screen::_draw()
{
_renderer->draw(); //< clear screen
ImGui::PositionNextWindow(
glm::vec2(500, 500), ImGui::WindowPosition_X::center, ImGui::WindowPosition_Y::center);
if(ImGui::Begin("Win")) {
ImGui::TextUnformatted("TODO");
if(ImGui::Button("Start")) {
_engine.screens().enter<Game_screen>();
}
if(ImGui::Button("Sync")) {
_engine.screens().enter<Sync_screen>();
}
if(ImGui::Button("Quit")) {
_engine.screens().leave();
}
}
ImGui::End();
}
} // namespace phase_shifter
#pragma once
#include <mirrage/engine.hpp>
#include <mirrage/gui/gui.hpp>
#include <mirrage/renderer/deferred_renderer.hpp>
#include <mirrage/utils/console_command.hpp>
#include <mirrage/utils/maybe.hpp>
namespace phase_shifter {
class Win_screen : public mirrage::Screen {
public:
Win_screen(mirrage::Engine& engine);
~Win_screen() noexcept override;
auto name() const -> std::string override { return "Gameover"; }
protected:
void _update(mirrage::util::Time delta_time) override;
void _draw() override;
void _on_enter(mirrage::util::maybe<Screen&> prev) override;
void _on_leave(mirrage::util::maybe<Screen&> next) override;
auto _prev_screen_policy() const noexcept -> mirrage::Prev_screen_policy override
{
return mirrage::Prev_screen_policy::discard;
}
protected:
mirrage::util::Mailbox_collection _mailbox;
std::unique_ptr<mirrage::renderer::Deferred_renderer> _renderer;
};
} // namespace phase_shifter