Compare commits
6 Commits
8bdcffcfa6
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
f879c5fe8f
|
|||
|
b5ff44d793
|
|||
|
24252896c7
|
|||
|
4c0078a5f2
|
|||
|
4072e49b32
|
|||
|
e0080fa50c
|
3
README.md
Normal file
3
README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# (CubeCraft) Tower Defense
|
||||||
|
|
||||||
|
## Currently in contruction 🏗️👷⚙️
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <client/ClientState.h>
|
#include <client/ClientState.h>
|
||||||
#include <td/game/World.h>
|
#include <td/game/World.h>
|
||||||
#include <td/simulation/ServerSimulation.h>
|
#include <td/simulation/ClientSimulation.h>
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
namespace client {
|
namespace client {
|
||||||
@@ -10,14 +10,19 @@ namespace client {
|
|||||||
class GameState : public ClientState {
|
class GameState : public ClientState {
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<game::World> m_World;
|
std::shared_ptr<game::World> m_World;
|
||||||
// sim::ClientSimulation m_Simulation;
|
sim::ClientSimulation m_Simulation;
|
||||||
|
float m_CurrentLerp;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GameState(Client& a_Client, const std::shared_ptr<game::World>& a_World);
|
GameState(Client& a_Client, const std::shared_ptr<game::World>& a_World, std::uint64_t a_StepTime);
|
||||||
~GameState() {}
|
~GameState() {}
|
||||||
|
|
||||||
virtual void Update(float a_Delta) override;
|
virtual void Update(float a_Delta) override;
|
||||||
|
|
||||||
|
float GetCurrentLerp() const {
|
||||||
|
return m_CurrentLerp;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void HandlePacket(const protocol::PacketBase& a_Packet) override;
|
virtual void HandlePacket(const protocol::PacketBase& a_Packet) override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
@@ -15,6 +15,11 @@ class StateMachine {
|
|||||||
|
|
||||||
virtual TReturn Update(TArgs... args) = 0;
|
virtual TReturn Update(TArgs... args) = 0;
|
||||||
|
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
T* ChangeState(Args&&... args) {
|
||||||
|
return m_StateMachine.template ChangeState<T>(std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TDerived& m_StateMachine;
|
TDerived& m_StateMachine;
|
||||||
};
|
};
|
||||||
@@ -29,8 +34,9 @@ class StateMachine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
void ChangeState(Args&&... args) {
|
T* ChangeState(Args&&... args) {
|
||||||
m_State = std::make_unique<T>(static_cast<TDerived&>(*this), std::forward<Args>(args)...);
|
m_State = std::make_unique<T>(static_cast<TDerived&>(*this), std::forward<Args>(args)...);
|
||||||
|
return static_cast<T*>(m_State.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
69
include/td/common/StateStack.h
Normal file
69
include/td/common/StateStack.h
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
template <typename TDerived, typename TReturn, typename... TArgs>
|
||||||
|
class StateStack {
|
||||||
|
public:
|
||||||
|
class State {
|
||||||
|
public:
|
||||||
|
State(TDerived& a_StateStack) : m_StateStack(a_StateStack) {}
|
||||||
|
virtual ~State() {}
|
||||||
|
|
||||||
|
virtual TReturn Update(TArgs... args) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* \brief Called when enabled (can be used to connect signals)
|
||||||
|
*/
|
||||||
|
virtual void OnEnable() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Called when disabled (can be used to disconnect signals)
|
||||||
|
*/
|
||||||
|
virtual void OnDisable() {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
TDerived& m_StateStack;
|
||||||
|
|
||||||
|
friend class StateStack;
|
||||||
|
};
|
||||||
|
|
||||||
|
StateStack() {}
|
||||||
|
StateStack(StateStack&&) = default;
|
||||||
|
virtual ~StateStack() {}
|
||||||
|
|
||||||
|
virtual TReturn Update(TArgs... args) {
|
||||||
|
assert(!m_States.empty() && "You must push at least one state before updating !");
|
||||||
|
return m_States.back()->Update(args...);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PopState() {
|
||||||
|
assert(!m_States.empty() && "You must push at least one state before poping !");
|
||||||
|
m_States.back()->OnDisable();
|
||||||
|
m_States.pop_back();
|
||||||
|
if (m_States.empty())
|
||||||
|
return;
|
||||||
|
m_States.back()->OnEnable();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
T* PushState(Args&&... args) {
|
||||||
|
if (!m_States.empty())
|
||||||
|
m_States.back()->OnDisable();
|
||||||
|
auto newState = std::make_unique<T>(static_cast<TDerived&>(*this), std::forward<Args>(args)...);
|
||||||
|
newState->OnEnable();
|
||||||
|
m_States.push_back(std::move(newState));
|
||||||
|
return static_cast<T*>(newState.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<std::unique_ptr<State>> m_States;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace td
|
||||||
15
include/td/display/menu/CreatePartyMenu.h
Normal file
15
include/td/display/menu/CreatePartyMenu.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <td/display/state/MainMenuState.h>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
class CreatePartyMenu : public MainMenuState::Menu {
|
||||||
|
public:
|
||||||
|
CreatePartyMenu(MainMenuState& a_MainMenu);
|
||||||
|
~CreatePartyMenu();
|
||||||
|
|
||||||
|
virtual void Update() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace td
|
||||||
15
include/td/display/menu/JoinPartyMenu.h
Normal file
15
include/td/display/menu/JoinPartyMenu.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <td/display/state/MainMenuState.h>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
class JoinPartyMenu : public MainMenuState::Menu {
|
||||||
|
public:
|
||||||
|
JoinPartyMenu(MainMenuState& a_MainMenu);
|
||||||
|
~JoinPartyMenu();
|
||||||
|
|
||||||
|
virtual void Update() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace td
|
||||||
15
include/td/display/menu/MainMenu.h
Normal file
15
include/td/display/menu/MainMenu.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <td/display/state/MainMenuState.h>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
class MainMenu : public MainMenuState::Menu {
|
||||||
|
public:
|
||||||
|
MainMenu(MainMenuState& a_MainMenu);
|
||||||
|
~MainMenu();
|
||||||
|
|
||||||
|
virtual void Update() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace td
|
||||||
15
include/td/display/menu/SettingsMenu.h
Normal file
15
include/td/display/menu/SettingsMenu.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <td/display/state/MainMenuState.h>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
class SettingsMenu : public MainMenuState::Menu {
|
||||||
|
public:
|
||||||
|
SettingsMenu(MainMenuState& a_MainMenu);
|
||||||
|
~SettingsMenu();
|
||||||
|
|
||||||
|
virtual void Update() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace td
|
||||||
@@ -5,19 +5,17 @@
|
|||||||
#include <td/display/DisplayState.h>
|
#include <td/display/DisplayState.h>
|
||||||
#include <td/render/Renderer.h>
|
#include <td/render/Renderer.h>
|
||||||
#include <td/simulation/ClientSimulation.h>
|
#include <td/simulation/ClientSimulation.h>
|
||||||
|
#include <client/state/GameState.h>
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
class ClientHandler;
|
|
||||||
|
|
||||||
class DebugWorldState : public DisplayState {
|
class DebugWorldState : public DisplayState {
|
||||||
private:
|
private:
|
||||||
render::RenderPipeline m_Renderer;
|
render::RenderPipeline m_Renderer;
|
||||||
|
render::Camera m_Camera;
|
||||||
std::unique_ptr<client::Client> m_Client;
|
std::unique_ptr<client::Client> m_Client;
|
||||||
std::unique_ptr<server::Server> m_Server;
|
std::unique_ptr<server::Server> m_Server;
|
||||||
std::unique_ptr<sim::ClientSimulation> m_Simulation;
|
client::GameState* m_ClientState;
|
||||||
render::Camera m_Camera;
|
|
||||||
std::unique_ptr<ClientHandler> m_ClientHandler;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DebugWorldState(Display& a_Display);
|
DebugWorldState(Display& a_Display);
|
||||||
|
|||||||
27
include/td/display/state/MainMenuState.h
Normal file
27
include/td/display/state/MainMenuState.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <td/common/StateStack.h>
|
||||||
|
#include <td/display/DisplayState.h>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
class MainMenuState;
|
||||||
|
|
||||||
|
using MainMenuStateStack = StateStack<MainMenuState, void>;
|
||||||
|
|
||||||
|
class MainMenuState : public DisplayState, public MainMenuStateStack {
|
||||||
|
public:
|
||||||
|
using Menu = MainMenuStateStack::State;
|
||||||
|
|
||||||
|
MainMenuState(Display& a_Display);
|
||||||
|
~MainMenuState();
|
||||||
|
|
||||||
|
virtual void Update(float a_Delta) override;
|
||||||
|
|
||||||
|
void RenderBackButton();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void OnKeyDown(SDL_Keycode a_Key) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace td
|
||||||
@@ -14,7 +14,7 @@ using GameBuffer = std::vector<std::optional<td::protocol::LockStep>>;
|
|||||||
class ClientSimulation : public protocol::PacketHandler {
|
class ClientSimulation : public protocol::PacketHandler {
|
||||||
private:
|
private:
|
||||||
std::uint64_t m_StepTime;
|
std::uint64_t m_StepTime;
|
||||||
game::World& m_World;
|
std::shared_ptr<game::World> m_World;
|
||||||
GameBuffer m_History;
|
GameBuffer m_History;
|
||||||
float m_CurrentTime;
|
float m_CurrentTime;
|
||||||
StepTime m_CurrentStep;
|
StepTime m_CurrentStep;
|
||||||
@@ -33,13 +33,13 @@ class ClientSimulation : public protocol::PacketHandler {
|
|||||||
* \brief Replay constructor
|
* \brief Replay constructor
|
||||||
* \param a_StepTime in ms
|
* \param a_StepTime in ms
|
||||||
*/
|
*/
|
||||||
ClientSimulation(game::World& a_World, GameHistory&& a_History, std::uint64_t a_StepTime);
|
ClientSimulation(std::shared_ptr<game::World> a_World, GameHistory&& a_History, std::uint64_t a_StepTime);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Live update constructor (continuous game updates)
|
* \brief Live update constructor (continuous game updates)
|
||||||
* \param a_StepTime in ms
|
* \param a_StepTime in ms
|
||||||
*/
|
*/
|
||||||
ClientSimulation(game::World& a_World, std::uint64_t a_StepTime);
|
ClientSimulation(std::shared_ptr<game::World> a_World, std::uint64_t a_StepTime);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \return the progress [0-1] between two steps
|
* \return the progress [0-1] between two steps
|
||||||
|
|||||||
@@ -3,9 +3,39 @@
|
|||||||
namespace td {
|
namespace td {
|
||||||
namespace client {
|
namespace client {
|
||||||
|
|
||||||
GameState::GameState(Client& a_Client, const std::shared_ptr<game::World>& a_World) : ClientState(a_Client), m_World(a_World) {}
|
class ClientHandler : public protocol::PacketHandler {
|
||||||
void GameState::HandlePacket(const protocol::PacketBase& a_Packet) {}
|
private:
|
||||||
void GameState::Update(float a_Delta) {}
|
sim::ClientSimulation& m_Simulation;
|
||||||
|
|
||||||
|
using protocol::PacketHandler::Handle;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ClientHandler(sim::ClientSimulation& a_Simulation) : m_Simulation(a_Simulation) {}
|
||||||
|
|
||||||
|
void Handle(const protocol::packets::LockStepsPacket& a_LockStep) {
|
||||||
|
m_Simulation.Handle(a_LockStep);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Handle(const protocol::packets::LockStepResponsePacket& a_LockStep) {
|
||||||
|
m_Simulation.Handle(a_LockStep);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
GameState::GameState(Client& a_Client, const std::shared_ptr<game::World>& a_World, std::uint64_t a_StepTime) :
|
||||||
|
ClientState(a_Client), m_World(a_World), m_Simulation(a_World, a_StepTime) {
|
||||||
|
m_Simulation.OnMissingLockSteps.Connect([this](const std::vector<td::StepTime>& a_MissingSteps) {
|
||||||
|
SendPacket(protocol::packets::LockStepRequestPacket(a_MissingSteps));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameState::HandlePacket(const protocol::PacketBase& a_Packet) {
|
||||||
|
ClientHandler handler(m_Simulation);
|
||||||
|
a_Packet.Dispatch(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameState::Update(float a_Delta) {
|
||||||
|
m_CurrentLerp = m_Simulation.Update(a_Delta);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace client
|
} // namespace client
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <td/display/state/DebugWorldState.h>
|
#include <td/display/state/MainMenuState.h>
|
||||||
|
|
||||||
float GetDelta() {
|
float GetDelta() {
|
||||||
static std::chrono::time_point<std::chrono::system_clock> m_LastTime = std::chrono::system_clock::now();
|
static std::chrono::time_point<std::chrono::system_clock> m_LastTime = std::chrono::system_clock::now();
|
||||||
@@ -13,7 +13,7 @@ int main(int argc, char** argv) {
|
|||||||
// init GL context
|
// init GL context
|
||||||
td::Display display(1920, 1080, "Tower-Defense 2");
|
td::Display display(1920, 1080, "Tower-Defense 2");
|
||||||
|
|
||||||
display.ChangeState<td::DebugWorldState>();
|
display.ChangeState<td::MainMenuState>();
|
||||||
|
|
||||||
while (!display.IsCloseRequested()) {
|
while (!display.IsCloseRequested()) {
|
||||||
display.PollEvents();
|
display.PollEvents();
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ void GameState::HandlePacket(PlayerID a_Id, const protocol::PacketBase& a_Packet
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GameState::Update(float a_Delta) {
|
void GameState::Update(float a_Delta) {
|
||||||
|
// TODO: don't make STEP_TIME constant
|
||||||
static const float stepTimeSecond = static_cast<float>(STEP_TIME) / 1000.0f;
|
static const float stepTimeSecond = static_cast<float>(STEP_TIME) / 1000.0f;
|
||||||
m_Time += a_Delta;
|
m_Time += a_Delta;
|
||||||
if (m_Time > stepTimeSecond) {
|
if (m_Time > stepTimeSecond) {
|
||||||
|
|||||||
@@ -80,8 +80,7 @@ Display::Display(int a_Width, int a_Height, const std::string& a_Title) :
|
|||||||
utils::LOG(utils::Format(
|
utils::LOG(utils::Format(
|
||||||
"GL Context : %i.%i %s, Color : R:%i G:%i B:%i A:%i, Depth bits : %i", major, minor, mask_desc, r, g, b, a, depth));
|
"GL Context : %i.%i %s, Color : R:%i G:%i B:%i A:%i, Depth bits : %i", major, minor, mask_desc, r, g, b, a, depth));
|
||||||
|
|
||||||
utils::LOG(utils::Format(
|
utils::LOG(utils::Format("MultiSamples : Buffers : %i, Samples : %i", mBuffers, mSamples));
|
||||||
"MultiSamples : Buffers : %i, Samples : %i", mBuffers, mSamples));
|
|
||||||
|
|
||||||
SDL_GL_MakeCurrent(m_Window, m_GLContext);
|
SDL_GL_MakeCurrent(m_Window, m_GLContext);
|
||||||
|
|
||||||
@@ -166,6 +165,9 @@ void Display::PollEvents() {
|
|||||||
|
|
||||||
void Display::Update(float a_Delta) {
|
void Display::Update(float a_Delta) {
|
||||||
StateMachine::Update(a_Delta);
|
StateMachine::Update(a_Delta);
|
||||||
|
#ifndef NDEBUG
|
||||||
|
ImGui::ShowDemoWindow();
|
||||||
|
#endif
|
||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
|
glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
|
||||||
|
|||||||
16
src/td/display/menu/CreatePartyMenu.cpp
Normal file
16
src/td/display/menu/CreatePartyMenu.cpp
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#include <td/display/menu/CreatePartyMenu.h>
|
||||||
|
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
CreatePartyMenu::CreatePartyMenu(MainMenuState& a_MainMenu) : MainMenuState::Menu(a_MainMenu) {}
|
||||||
|
|
||||||
|
CreatePartyMenu::~CreatePartyMenu() {}
|
||||||
|
|
||||||
|
void CreatePartyMenu::Update() {
|
||||||
|
ImGui::Text("CreatePartyMenu");
|
||||||
|
m_StateStack.RenderBackButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace td
|
||||||
16
src/td/display/menu/JoinPartyMenu.cpp
Normal file
16
src/td/display/menu/JoinPartyMenu.cpp
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#include <td/display/menu/JoinPartyMenu.h>
|
||||||
|
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
JoinPartyMenu::JoinPartyMenu(MainMenuState& a_MainMenu) : MainMenuState::Menu(a_MainMenu) {}
|
||||||
|
|
||||||
|
JoinPartyMenu::~JoinPartyMenu() {}
|
||||||
|
|
||||||
|
void JoinPartyMenu::Update() {
|
||||||
|
ImGui::Text("JoinPartyMenu");
|
||||||
|
m_StateStack.RenderBackButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace td
|
||||||
28
src/td/display/menu/MainMenu.cpp
Normal file
28
src/td/display/menu/MainMenu.cpp
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#include <td/display/menu/MainMenu.h>
|
||||||
|
|
||||||
|
#include <imgui.h>
|
||||||
|
#include <td/display/menu/CreatePartyMenu.h>
|
||||||
|
#include <td/display/menu/JoinPartyMenu.h>
|
||||||
|
#include <td/display/menu/SettingsMenu.h>
|
||||||
|
#include <td/display/state/DebugWorldState.h>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
MainMenu::MainMenu(MainMenuState& a_MainMenu) : MainMenuState::Menu(a_MainMenu) {}
|
||||||
|
|
||||||
|
MainMenu::~MainMenu() {}
|
||||||
|
|
||||||
|
void MainMenu::Update() {
|
||||||
|
if (ImGui::Button("Create Party"))
|
||||||
|
m_StateStack.PushState<CreatePartyMenu>();
|
||||||
|
if (ImGui::Button("Join Party"))
|
||||||
|
m_StateStack.PushState<JoinPartyMenu>();
|
||||||
|
if (ImGui::Button("Settings"))
|
||||||
|
m_StateStack.PushState<SettingsMenu>();
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if (ImGui::Button("Debug world"))
|
||||||
|
m_StateStack.ChangeState<DebugWorldState>();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace td
|
||||||
16
src/td/display/menu/SettingsMenu.cpp
Normal file
16
src/td/display/menu/SettingsMenu.cpp
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#include <td/display/menu/SettingsMenu.h>
|
||||||
|
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
SettingsMenu::SettingsMenu(MainMenuState& a_MainMenu) : MainMenuState::Menu(a_MainMenu) {}
|
||||||
|
|
||||||
|
SettingsMenu::~SettingsMenu() {}
|
||||||
|
|
||||||
|
void SettingsMenu::Update() {
|
||||||
|
ImGui::Text("SettingsMenu");
|
||||||
|
m_StateStack.RenderBackButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace td
|
||||||
@@ -10,7 +10,6 @@
|
|||||||
#include <td/render/renderer/EntityRenderer.h>
|
#include <td/render/renderer/EntityRenderer.h>
|
||||||
#include <td/render/renderer/TowerRenderer.h>
|
#include <td/render/renderer/TowerRenderer.h>
|
||||||
#include <td/render/renderer/WorldRenderer.h>
|
#include <td/render/renderer/WorldRenderer.h>
|
||||||
#include <td/simulation/ClientSimulation.h>
|
|
||||||
|
|
||||||
#include <sp/common/DataBuffer.h>
|
#include <sp/common/DataBuffer.h>
|
||||||
#include <sp/extensions/Compress.h>
|
#include <sp/extensions/Compress.h>
|
||||||
@@ -30,24 +29,7 @@
|
|||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
class ClientHandler : public protocol::PacketHandler {
|
// TODO: get rid of this class
|
||||||
private:
|
|
||||||
sim::ClientSimulation& m_Simulation;
|
|
||||||
|
|
||||||
using protocol::PacketHandler::Handle;
|
|
||||||
|
|
||||||
public:
|
|
||||||
ClientHandler(sim::ClientSimulation& a_Simulation) : m_Simulation(a_Simulation) {}
|
|
||||||
|
|
||||||
void Handle(const protocol::packets::LockStepsPacket& a_LockStep) {
|
|
||||||
m_Simulation.Handle(a_LockStep);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Handle(const protocol::packets::LockStepResponsePacket& a_LockStep) {
|
|
||||||
m_Simulation.Handle(a_LockStep);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class WorldApply : public protocol::PacketHandler {
|
class WorldApply : public protocol::PacketHandler {
|
||||||
private:
|
private:
|
||||||
game::World& m_World;
|
game::World& m_World;
|
||||||
@@ -103,45 +85,35 @@ game::WorldPtr GetWorld() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DebugWorldState::DebugWorldState(Display& a_Display) : DisplayState(a_Display) {
|
DebugWorldState::DebugWorldState(Display& a_Display) : DisplayState(a_Display) {
|
||||||
game::WorldPtr serverWorld = GetWorld();
|
|
||||||
|
|
||||||
// server
|
// server
|
||||||
|
game::WorldPtr serverWorld = GetWorld();
|
||||||
auto serverFakeSocket = std::make_shared<server::FakeSocket>();
|
auto serverFakeSocket = std::make_shared<server::FakeSocket>();
|
||||||
m_Server = std::make_unique<server::Server>(serverFakeSocket);
|
m_Server = std::make_unique<server::Server>(serverFakeSocket);
|
||||||
|
|
||||||
// client
|
// client
|
||||||
|
game::WorldPtr clientWorld = GetWorld();
|
||||||
auto clientFakeSocket = client::FakeSocket::Connect(serverFakeSocket);
|
auto clientFakeSocket = client::FakeSocket::Connect(serverFakeSocket);
|
||||||
m_Client = std::make_unique<client::Client>(clientFakeSocket);
|
m_Client = std::make_unique<client::Client>(clientFakeSocket);
|
||||||
|
|
||||||
game::WorldPtr clientWorld = GetWorld();
|
// render
|
||||||
|
|
||||||
m_Renderer.AddRenderer<render::WorldRenderer>(m_Camera, *clientWorld);
|
m_Renderer.AddRenderer<render::WorldRenderer>(m_Camera, *clientWorld);
|
||||||
m_Renderer.AddRenderer<render::EntityRenderer>(m_Camera, *clientWorld);
|
m_Renderer.AddRenderer<render::EntityRenderer>(m_Camera, *clientWorld);
|
||||||
m_Renderer.AddRenderer<render::TowerRenderer>(m_Camera, *clientWorld);
|
m_Renderer.AddRenderer<render::TowerRenderer>(m_Camera, *clientWorld);
|
||||||
|
|
||||||
|
// camera
|
||||||
m_Camera.SetCamPos({77, 7, 13});
|
m_Camera.SetCamPos({77, 7, 13});
|
||||||
m_Camera.UpdatePerspective(m_StateMachine.GetAspectRatio());
|
m_Camera.UpdatePerspective(m_StateMachine.GetAspectRatio());
|
||||||
|
|
||||||
m_Simulation = std::make_unique<sim::ClientSimulation>(*clientWorld, STEP_TIME);
|
// states
|
||||||
|
m_ClientState = m_Client->ChangeState<client::GameState>(clientWorld, STEP_TIME);
|
||||||
m_ClientHandler = std::make_unique<ClientHandler>(*m_Simulation);
|
|
||||||
|
|
||||||
// packets from the server to the client
|
|
||||||
clientFakeSocket->OnReceive.Connect([this](const protocol::PacketBase& a_Packet) { a_Packet.Dispatch(*m_ClientHandler); });
|
|
||||||
|
|
||||||
m_Simulation->OnMissingLockSteps.Connect([clientFakeSocket](const std::vector<td::StepTime>& a_MissingSteps) {
|
|
||||||
clientFakeSocket->Send(protocol::packets::LockStepRequestPacket(a_MissingSteps));
|
|
||||||
});
|
|
||||||
|
|
||||||
m_Server->ChangeState<server::GameState>(serverWorld);
|
m_Server->ChangeState<server::GameState>(serverWorld);
|
||||||
m_Client->ChangeState<client::GameState>(clientWorld);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugWorldState::Update(float a_Delta) {
|
void DebugWorldState::Update(float a_Delta) {
|
||||||
m_Server->Update(a_Delta);
|
m_Server->Update(a_Delta);
|
||||||
m_Client->Update(a_Delta);
|
m_Client->Update(a_Delta);
|
||||||
float lerp = m_Simulation->Update(a_Delta);
|
// TODO: m_ClientState might be invalid !
|
||||||
m_Renderer.Render(lerp);
|
m_Renderer.Render(m_ClientState->GetCurrentLerp());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugWorldState::OnAspectRatioChange(float a_Ratio) {
|
void DebugWorldState::OnAspectRatioChange(float a_Ratio) {
|
||||||
|
|||||||
31
src/td/display/state/MainMenuState.cpp
Normal file
31
src/td/display/state/MainMenuState.cpp
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#include <td/display/state/MainMenuState.h>
|
||||||
|
|
||||||
|
#include <imgui.h>
|
||||||
|
#include <td/display/menu/MainMenu.h>
|
||||||
|
#include <td/display/state/DebugWorldState.h>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
MainMenuState::MainMenuState(Display& a_Display) : DisplayState(a_Display) {
|
||||||
|
PushState<MainMenu>();
|
||||||
|
}
|
||||||
|
|
||||||
|
MainMenuState::~MainMenuState() {}
|
||||||
|
|
||||||
|
void MainMenuState::Update(float a_Delta) {
|
||||||
|
ImGui::Begin("MainWindow");
|
||||||
|
MainMenuStateStack::Update();
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainMenuState::RenderBackButton() {
|
||||||
|
if (ImGui::Button("Back"))
|
||||||
|
PopState();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainMenuState::OnKeyDown(SDL_Keycode a_Key) {
|
||||||
|
if (a_Key == SDLK_ESCAPE)
|
||||||
|
PopState();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace td
|
||||||
@@ -16,7 +16,6 @@ WorldRenderer::~WorldRenderer() {}
|
|||||||
void WorldRenderer::Render(float a_Lerp) {
|
void WorldRenderer::Render(float a_Lerp) {
|
||||||
m_Shader->Start();
|
m_Shader->Start();
|
||||||
Renderer::Render(*m_WorldVao);
|
Renderer::Render(*m_WorldVao);
|
||||||
ImGui::ShowDemoWindow();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace render
|
} // namespace render
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ std::uint64_t GetTime() {
|
|||||||
std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock().now().time_since_epoch()).count());
|
std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock().now().time_since_epoch()).count());
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientSimulation::ClientSimulation(game::World& a_World, GameHistory&& a_History, std::uint64_t a_StepTime) :
|
ClientSimulation::ClientSimulation(std::shared_ptr<game::World> a_World, GameHistory&& a_History, std::uint64_t a_StepTime) :
|
||||||
m_StepTime(a_StepTime),
|
m_StepTime(a_StepTime),
|
||||||
m_World(a_World),
|
m_World(a_World),
|
||||||
m_CurrentTime(0),
|
m_CurrentTime(0),
|
||||||
@@ -30,7 +30,7 @@ ClientSimulation::ClientSimulation(game::World& a_World, GameHistory&& a_History
|
|||||||
Step();
|
Step();
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientSimulation::ClientSimulation(game::World& a_World, std::uint64_t a_StepTime) :
|
ClientSimulation::ClientSimulation(std::shared_ptr<game::World> a_World, std::uint64_t a_StepTime) :
|
||||||
m_StepTime(a_StepTime),
|
m_StepTime(a_StepTime),
|
||||||
m_World(a_World),
|
m_World(a_World),
|
||||||
m_History(std::numeric_limits<StepTime>::max()),
|
m_History(std::numeric_limits<StepTime>::max()),
|
||||||
@@ -41,7 +41,7 @@ ClientSimulation::ClientSimulation(game::World& a_World, std::uint64_t a_StepTim
|
|||||||
|
|
||||||
float ClientSimulation::Update(float a_Delta) {
|
float ClientSimulation::Update(float a_Delta) {
|
||||||
// TODO: handle freezes (m_CurrentTime > 2 * m_StepTime)
|
// TODO: handle freezes (m_CurrentTime > 2 * m_StepTime)
|
||||||
static const float stepTimeSecond = static_cast<float>(STEP_TIME) / 1000.0f;
|
static const float stepTimeSecond = static_cast<float>(m_StepTime) / 1000.0f;
|
||||||
m_CurrentTime += a_Delta;
|
m_CurrentTime += a_Delta;
|
||||||
if (m_CurrentTime > stepTimeSecond) {
|
if (m_CurrentTime > stepTimeSecond) {
|
||||||
m_CurrentTime = std::fmod(m_CurrentTime, stepTimeSecond);
|
m_CurrentTime = std::fmod(m_CurrentTime, stepTimeSecond);
|
||||||
@@ -53,13 +53,13 @@ float ClientSimulation::Update(float a_Delta) {
|
|||||||
bool ClientSimulation::Step() {
|
bool ClientSimulation::Step() {
|
||||||
const auto& step = m_History[m_CurrentStep];
|
const auto& step = m_History[m_CurrentStep];
|
||||||
if (step.has_value()) {
|
if (step.has_value()) {
|
||||||
auto snapshot = m_World.Tick(step.value(), FpFloat(m_StepTime) / FpFloat(1000));
|
auto snapshot = m_World->Tick(step.value(), FpFloat(m_StepTime) / FpFloat(1000));
|
||||||
if (m_LastValidStep + 1 == m_CurrentStep) {
|
if (m_LastValidStep + 1 == m_CurrentStep) {
|
||||||
m_LastValidStep = m_CurrentStep;
|
m_LastValidStep = m_CurrentStep;
|
||||||
m_LastSnapshot = snapshot;
|
m_LastSnapshot = snapshot;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
m_World.Tick(EMPTY_LOCKSTEP, FpFloat(m_StepTime) / FpFloat(1000));
|
m_World->Tick(EMPTY_LOCKSTEP, FpFloat(m_StepTime) / FpFloat(1000));
|
||||||
std::cout << "Empty tick (" << m_CurrentStep << ") !\n";
|
std::cout << "Empty tick (" << m_CurrentStep << ") !\n";
|
||||||
}
|
}
|
||||||
m_CurrentStep++;
|
m_CurrentStep++;
|
||||||
@@ -103,7 +103,7 @@ void ClientSimulation::FastReplay() {
|
|||||||
if (m_LastValidStep + 1 >= m_CurrentStep)
|
if (m_LastValidStep + 1 >= m_CurrentStep)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_World.ResetSnapshots(m_LastSnapshot, m_LastSnapshot);
|
m_World->ResetSnapshots(m_LastSnapshot, m_LastSnapshot);
|
||||||
|
|
||||||
const std::size_t stepCount = m_CurrentStep - m_LastValidStep;
|
const std::size_t stepCount = m_CurrentStep - m_LastValidStep;
|
||||||
m_CurrentStep = m_LastValidStep;
|
m_CurrentStep = m_LastValidStep;
|
||||||
|
|||||||
@@ -3,8 +3,7 @@ add_rules("mode.debug", "mode.release")
|
|||||||
add_repositories("persson-repo https://git.ale-pri.com/Persson-dev/xmake-repo.git")
|
add_repositories("persson-repo https://git.ale-pri.com/Persson-dev/xmake-repo.git")
|
||||||
|
|
||||||
add_requires("imgui 1.92.0", {configs = {sdl3 = true, opengl3 = true}})
|
add_requires("imgui 1.92.0", {configs = {sdl3 = true, opengl3 = true}})
|
||||||
add_requires("splib 2.3.0", "zlib")
|
add_requires("libsdl3 3.2.16", "splib 2.3.0", "zlib", "glew", "fpm", "enet6")
|
||||||
add_requires("libsdl3 3.2.16", "glew", "fpm", "enet6")
|
|
||||||
|
|
||||||
set_languages("c++17")
|
set_languages("c++17")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user