Implement Quit Button

This commit is contained in:
2024-11-12 18:51:58 -05:00
parent 9fae3eb882
commit 0be127260e
19 changed files with 398 additions and 67 deletions

View File

@@ -18,6 +18,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(cmake/CPM.cmake)
CPMAddPackage(
NAME J3ML
URL https://git.redacted.cc/josh/j3ml/archive/Release-3.2.zip

View File

@@ -10,8 +10,14 @@
namespace CaveGame::Client
{
struct SingleplayerSessionInfo {
};
class MainMenu : public Scene {
public:
Event<SingleplayerSessionInfo> RequestWorld;
Event<> RequestQuit;
MainMenu();
void Update(float elapsed) override;
void Draw() override;
@@ -20,6 +26,8 @@ namespace CaveGame::Client
void PassFont(JGL::Font font);
void PassWindowSize(const J3ML::LinearAlgebra::Vector2 &size) override;
void PassMouseInput(unsigned int, bool) override;
void PassMouseMovement(const J3ML::LinearAlgebra::Vector2 &pos) override;
protected:
JUI::Scene* scene;
JUI::TextRect* title;

View File

@@ -1,9 +1,12 @@
#pragma once
#include <J3ML/LinearAlgebra/Vector2.hpp>
#include "SceneManager.hpp"
namespace CaveGame::Client
{
class SceneManager;
class Scene
{
public:
@@ -17,9 +20,9 @@ namespace CaveGame::Client
virtual void PassWindowSize(const Vector2& size);
//virtual void PassMouseInput(int mouse_btn, bool pressed) = 0;
//virtual void PassKeyInput(char keyCode, bool pressed) = 0;
//virtual void PassMouseMovement(const Vector2& pos) = 0;
virtual void PassMouseInput(unsigned int mouse_btn, bool pressed) {}
virtual void PassKeyInput(char keyCode, bool pressed) {}
virtual void PassMouseMovement(const Vector2& pos) {}
[[nodiscard]] bool Active() const;
protected:
bool active;

View File

@@ -0,0 +1,16 @@
#pragma once
namespace CaveGame::Client
{
class Scene;
class SceneManager
{
public:
void ChangeScene(Scene* new_scene);
Scene* CurrentScene();
protected:
Scene* current_scene = nullptr;
private:
};
}

View File

@@ -42,8 +42,11 @@ JUI::TextButton* CaveGame::Client::MainMenu::create_mainmenu_btn(const std::stri
btn->SetTextSize(24);
btn->SetTextColor(Colors::White);
btn->BaseBGColor(Colors::LightGray);
btn->HoveredBGColor(Colors::Blues::LightSteelBlue);
btn->BGColor(btn->BaseBGColor());
btn->Size({0, 40, 1.f, 0});
btn->Enable();
btn->Center();
btn->SetContent(content);
return btn;
@@ -60,36 +63,49 @@ void CaveGame::Client::MainMenu::PassFont(JGL::Font passed) {
title->SetContent("CaveGame");
title->SetTextColor(Colors::White);
title->SetTextSize(64);
title->Position({0,0,0.5f,0.2f});
title->Size({0,0, 0.3f,0.15f});
title->Position({0, 0, 0.5f, 0.2f});
title->Size({0, 0, 0.3f, 0.15f});
title->AnchorPoint({0.5f, 0.5f});
title->Center();
title->BGColor(Colors::Black);
title->SetBorderStyling(Colors::Cyans::Cyan, 1);
button_group = new Rect(scene);
button_group->Size({250,400,0,0});
button_group->Size({250, 400, 0, 0});
button_group->Position({0, 0, 0.5f, 0.3f});
button_group->AnchorPoint({0.5f, 0.f});
button_group->BGColor(Colors::Black);
button_group->SetBorderStyling(Colors::Cyans::Cyan, 1);
auto* button_list = new JUI::VerticalListLayout(button_group);
auto *button_list = new JUI::VerticalListLayout(button_group);
button_list->PaddingBottom(5_px);
auto* sp_btn = create_mainmenu_btn("Singleplayer", button_list);
auto* mp_btn = create_mainmenu_btn("Multiplayer", button_list);
auto* credits_btn = create_mainmenu_btn("Credits", button_list);
auto *ur_black = create_mainmenu_btn("ur black", button_list);
credits_btn->OnReleaseEvent += [] (Vector2 pos, MouseButton btn, bool b)
{
auto *sp_btn = create_mainmenu_btn("Singleplayer", button_list);
sp_btn->OnReleaseEvent += [this](Vector2 pos, MouseButton btn, bool b) {
if (b)
RequestWorld.Invoke({});
};
auto *mp_btn = create_mainmenu_btn("Multiplayer", button_list);
auto *credits_btn = create_mainmenu_btn("Credits", button_list);
credits_btn->OnReleaseEvent += [](Vector2 pos, MouseButton btn, bool b) {
};
// TODO: Replace with IconButton with steam logo
auto* steam_community_btn = create_mainmenu_btn("Steam Community", button_list);
auto* quit_btn = create_mainmenu_btn("Quit", button_list);
auto *steam_community_btn = create_mainmenu_btn("Steam Community", button_list);
auto *quit_btn = create_mainmenu_btn("Quit", button_list);
quit_btn->OnReleaseEvent += [this](Vector2 pos, MouseButton btn, bool b)
{
if (b)
RequestQuit.Invoke();
};
}
void CaveGame::Client::MainMenu::PassWindowSize(const Vector2 &size) {
@@ -97,3 +113,11 @@ void CaveGame::Client::MainMenu::PassWindowSize(const Vector2 &size) {
scene->SetViewportSize(window_size.x, window_size.y);
}
void CaveGame::Client::MainMenu::PassMouseInput(unsigned int btn, bool down) {
scene->ObserveMouseInput(static_cast<JUI::MouseButton>(btn), down);
}
void CaveGame::Client::MainMenu::PassMouseMovement(const Vector2 &pos) {
scene->ObserveMouseMovement(pos);
}

View File

@@ -1,5 +1,5 @@
#include <Client/Scene.hpp>
#include <Client/SceneManager.hpp>
bool CaveGame::Client::Scene::Active() const { return active;}

View File

@@ -0,0 +1,17 @@
#include <Client/SceneManager.hpp>
#include "Client/Scene.hpp"
namespace CaveGame::Client
{
void SceneManager::ChangeScene(Scene* new_scene)
{
if (current_scene != nullptr)
current_scene->Unload();
current_scene = new_scene;
current_scene->Load();
}
Scene* SceneManager::CurrentScene() { return current_scene; }
}

View File

@@ -5,6 +5,15 @@ file(GLOB_RECURSE CaveClientApp_SRC "src/*.cpp")
file(COPY "assets" DESTINATION "${PROJECT_BINARY_DIR}/ClientApp")
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/steam_appid.txt
DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
file(COPY ${STEAMAPI_SHARED_DIR}
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
)
add_executable(CaveClientApp main.cpp ${CaveClientApp_SRC})
target_include_directories(CaveClientApp PUBLIC
@@ -13,6 +22,9 @@ target_include_directories(CaveClientApp PUBLIC
${J3ML_SOURCE_DIR}/include
${JGL_SOURCE_DIR}/include)
target_include_directories(CaveClientApp PUBLIC "include")
add_library(SteamworksSDK SHARED IMPORTED)
set_target_properties(SteamworksSDK PROPERTIES IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/assets/steamworks_sdk/linux64/libsteam_api.so")
target_link_libraries(CaveClientApp PUBLIC CaveClient ReWindowLibrary J3ML JGL)
target_include_directories(CaveClientApp PUBLIC "include")
target_include_directories(CaveClientApp PUBLIC "../Steam/")
target_link_libraries(CaveClientApp PUBLIC CaveClient ReWindowLibrary J3ML JGL SteamworksSDK)

View File

@@ -1,25 +1,26 @@
#pragma once
#include <J3ML/Geometry.hpp>
#include <Client/Splash.hpp>
#include <Client/MainMenu.hpp>
#include <Client/GameSession.hpp>
#include <Client/WindowWidgetManager.hpp>
#include <JUI/Widgets/ListLayout.hpp>
#include <JUI/UDim.hpp>
#include <rewindow/types/window.h>
#include <JUI/Widgets/Window.hpp>
#include <Client/Scene.hpp>
#include "J3ML/Geometry.hpp"
#include "Client/Splash.hpp"
#include "Client/MainMenu.hpp"
#include "Client/GameSession.hpp"
#include "Client/WindowWidgetManager.hpp"
#include "JUI/Widgets/ListLayout.hpp"
#include "JUI/UDim.hpp"
#include "rewindow/types/window.h"
#include "JUI/Widgets/Window.hpp"
#include "Client/Scene.hpp"
#include "Client/SceneManager.hpp"
namespace CaveGame::ClientApp
{
using CaveGame::Client::Scene;
using CaveGame::Client::SceneManager;
class CaveGameWindow : public ReWindow::RWindow
class CaveGameWindow : public ReWindow::RWindow, public SceneManager
{
public:
bool wanna_die = false;
CaveGame::Client::Splash* splash_ctx;
CaveGame::Client::MainMenu* menu_ctx;
CaveGame::Client::GameSession* game_ctx;
@@ -30,7 +31,7 @@ namespace CaveGame::ClientApp
JUI::Window* console_window;
JUI::Window* stats_window;
Scene* current_scene = nullptr;
//Scene* current_scene = nullptr;
bool render_grid = true;
bool generate_grid = true;
@@ -44,7 +45,7 @@ namespace CaveGame::ClientApp
void Run();
void ChangeScene(Scene* new_scene);
void Die();
void create_console_window()
{
@@ -83,5 +84,8 @@ namespace CaveGame::ClientApp
void OnMouseMove(const ReWindow::WindowEvents::MouseMoveEvent &ev) override;
bool OnResizeRequest(const ReWindow::WindowEvents::WindowResizeRequestEvent &ev) override;
protected:
void CreateMenuWindows();
void CreateContexts();
};
}

View File

@@ -6,22 +6,17 @@
/// @file main.cpp
/// @desc The Client App's main file. Creates and runs the Client App window.
/// @edit 10/1/2024
/// @edit 11/1/2024
/// @auth Josh O'Leary
#include <iostream>
#include <JGL/JGL.h>
#include <Core/Perlin.hpp>
#include <ClientApp/ClientApp.hpp>
#include <steam_api.h>
#include "ClientApp/CaveGameWindow.hpp"
CaveGame::Core::PerlinNoise noise(0);
constexpr int test_grid_size = 256;
constexpr float test_grid_scale = 2;
@@ -29,12 +24,16 @@ int test_tiles[test_grid_size][test_grid_size];
float z = 0;
int main(int argc, char** argv) {
bool steam_success = SteamAPI_Init();
srand(0);
auto* window = new CaveGame::ClientApp::CaveGameWindow("Re-CaveGame", 1280, 720);
auto* window = new CaveGame::ClientApp::CaveGameWindow("Re-CaveGame", 800, 600);
window->Run();
SteamAPI_Shutdown();
return 0;
}

View File

@@ -1,12 +1,30 @@
#include <ClientApp/ClientApp.hpp>
#include "ClientApp/CaveGameWindow.hpp"
namespace CaveGame::ClientApp
{
CaveGameWindow::CaveGameWindow(const std::string& title, int width, int height): ReWindow::RWindow(title, width, height)
{
CreateContexts();
CreateMenuWindows();
}
void CaveGameWindow::CreateContexts()
{
splash_ctx = new CaveGame::Client::Splash();
menu_ctx = new CaveGame::Client::MainMenu();
game_ctx = new CaveGame::Client::GameSession();
menu_ctx->RequestWorld += [this](Client::SingleplayerSessionInfo info) {
// TODO: Parse Info to construct gameworld files.
ChangeScene(game_ctx);
};
menu_ctx->RequestQuit += [this]() {
Die();
};
}
void CaveGameWindow::CreateMenuWindows()
{
wm = new JUI::Scene();
}
@@ -18,28 +36,17 @@ namespace CaveGame::ClientApp
this->setResizable(true);
this->setVsyncEnabled(false);
this->splash_ctx->PassFont(Jupiteroid);
this->menu_ctx->PassFont(Jupiteroid);
this->ChangeScene(this->splash_ctx);
while (this->isAlive()) {
while (!this->wanna_die) {
this->pollEvents();
this->refresh();
}
}
void CaveGameWindow::ChangeScene(Scene* new_scene)
{
if (current_scene != nullptr)
current_scene->Unload();
current_scene = new_scene;
current_scene->Load();
}
JUI::TextRect* CaveGameWindow::line_item(const std::string& content, int size, JUI::Widget* parent)
{
auto* item = new JUI::TextRect(parent);
@@ -176,12 +183,12 @@ namespace CaveGame::ClientApp
wm->Draw();
draw_debug_info({
"Re-CaveGame - Redacted Software",
std::format("frame: {}", refresh_count),
std::format("delta: {}ms", J3ML::Math::Round(delta_time*1000)),
std::format("fps: {}", J3ML::Math::Round(refresh_rate)),
std::format("avg: {}", J3ML::Math::Round(avg_refresh_rate))
});
"Re-CaveGame - Redacted Software",
std::format("frame: {}", refresh_count),
std::format("delta: {}ms", J3ML::Math::Round(delta_time*1000)),
std::format("fps: {}", J3ML::Math::Round(refresh_rate)),
std::format("avg: {}", J3ML::Math::Round(avg_refresh_rate))
});
}
void CaveGameWindow::procgen()
@@ -219,10 +226,8 @@ namespace CaveGame::ClientApp
void CaveGameWindow::OnMouseButtonDown(const ReWindow::WindowEvents::MouseButtonDownEvent& ev)
{
std::cout << "This Dick" << std::endl;
//if (current_scene != nullptr)
//current_scene->PassMouseInput(ev.Button.ButtonIndex, true);
if (current_scene != nullptr)
current_scene->PassMouseInput(ev.Button.ButtonIndex, true);
if (ev.Button == MouseButtons::Left)
@@ -249,8 +254,8 @@ namespace CaveGame::ClientApp
void CaveGameWindow::OnMouseButtonUp(const ReWindow::WindowEvents::MouseButtonUpEvent& ev)
{
//if (current_scene != nullptr)
//current_scene->PassMouseInput(ev.Button.ButtonIndex, false);
if (current_scene != nullptr)
current_scene->PassMouseInput(ev.Button.ButtonIndex, false);
if (ev.Button == MouseButtons::Left)
wm->ObserveMouseInput(JUI::MouseButton::Left, false);
@@ -264,6 +269,10 @@ namespace CaveGame::ClientApp
void CaveGameWindow::OnMouseMove(const ReWindow::WindowEvents::MouseMoveEvent& ev)
{
if (current_scene != nullptr)
current_scene->PassMouseMovement(ev.Position);
wm->ObserveMouseMovement(ev.Position);
RWindow::OnMouseMove(ev);
@@ -273,6 +282,8 @@ namespace CaveGame::ClientApp
{
return true;
}
void CaveGameWindow::Die() { wanna_die = true; }
}

View File

@@ -0,0 +1 @@
666

View File

@@ -0,0 +1,133 @@
/// CaveGame - A procedural 2D platformer sandbox.
/// Created by Josh O'Leary @ Redacted Software, 2020-2024
/// Contact: josh@redacted.cc
/// Contributors: william@redacted.cc maxi@redacted.cc
/// This work is dedicated to the public domain.
/// @file ConcurrentQueue.hpp
/// @desc A simple C++11 Concurrent Queue based on std::queue.
/// @ref https://github.com/jlim262/concurrent_queue
/// @edit 11/11/2024
/// @auth JongYoon Lim
#pragma once
#include <queue>
#include <atomic>
#include <mutex>
#include <condition_variable>
#include <type_traits>
#include <wait.h>
namespace CaveGame::Core
{
/// A simple C++11 Concurrent Queue based on std::queue.
/// Supports waiting operations for retrieving an element when it's empty.
/// It's interrupted by calling interrupt.
template <typename T, typename Container = std::deque<T> >
class ConcurrentQueue
{
public:
typedef typename std::queue<T>::size_type size_type;
typedef typename std::queue<T>::reference reference;
typedef typename std::queue<T>::const_reference const_reference;
~ConcurrentQueue() {
interrupt();
}
void interrupt()
{
interrupted = true;
condition_variable.notify_one();
}
void push(const T& e)
{
std::unique_lock<std::mutex> lock(mutex);
queue.push(e);
condition_variable.notify_one();
}
template <typename... Args>
void emplace(Args&&... args)
{
std::unique_lock<std::mutex> lock(this->mutex);
queue.emplace(std::forward<Args>(args)...);
condition_variable.notify_one();
}
bool empty() {
std::unique_lock<std::mutex> lock(this->mutex);
return queue.empty();
}
void pop() {
std::unique_lock<std::mutex> lock(this->mutex);
if (!queue.empty())
queue.pop();
}
void front_pop(T& ret) {
std::unique_lock<std::mutex> lock(this->mutex);
wait(lock);
ret = queue.front();
queue.pop();
}
size_type size() const {
//std::unique_lock<std::mutex> lock(this->mutex);
return queue.size();
}
reference front() {
std::unique_lock<std::mutex> lock(this->mutex);
wait(lock);
return queue.front();
}
/*const_reference front() const {
std::unique_lock<std::mutex> lock(this->mutex);
wait(lock);
return queue.front();
}*/
reference back() {
std::unique_lock<std::mutex> lock(this->mutex);
wait(lock);
return queue.back();
}
/*const_reference back() const {
std::unique_lock<std::mutex> lock(this->mutex);
wait(lock);
return queue.back();
}*/
void swap(ConcurrentQueue& q) {
throw std::runtime_error("Not supported");
}
protected:
std::queue<T, Container> queue;
std::mutex mutex;
std::condition_variable condition_variable;
std::atomic_bool interrupted;
private:
void wait(std::unique_lock<std::mutex>& lock) {
interrupted = false;
while (queue.empty()) {
condition_variable.wait(lock);
if (interrupted)
throw std::runtime_error("Interrupted");
}
}
};
}

View File

@@ -0,0 +1,8 @@
//
// Created by dawsh on 11/10/24.
//
#ifndef RECAVEGAME_GAMEPROTOCOL_HPP
#define RECAVEGAME_GAMEPROTOCOL_HPP
#endif //RECAVEGAME_GAMEPROTOCOL_HPP

View File

@@ -0,0 +1,75 @@
#pragma once
#include "ConcurrentQueue.hpp"
namespace CaveGame::Core
{
enum PacketType : unsigned int
{
Ping = 0,
PlrDamageTile, SrvDamageTile,
PlrPlaceTile, SrvPlaceTile,
PlrDamageWall, SrvDamageWall,
PlrPlaceWall, SrvPlaceWall,
PlrUseItem,
OpenDoor, CloseDoor,
PlaceFurniture, BreakFurniture,
EntityPhysicsTic,
ClientHandshake,
ClientRequestSession,
ClientConfirmSection,
ClientLogout,
ClientSendMsg,
ClientAdminCommand,
ClientThrowItem,
SrvHandshakeResponse,
SrvDownloadChunk,
SrvChatMessage,
SrvKick,
SrvUpdateTile,
SrvUpdateWall,
SrvAcceptLogin,
SrvRejectLogin,
SrvSpawnEntity,
SrvPeerJoin,
SrvPeerLeft,
SrvRemoveEntity,
SrvTime,
};
class Packet
{
public:
PacketType Type;
virtual const void* onSend(std::size_t& size)
{
}
virtual void onRecieve(const void* data, std::size_t size)
{
}
};
class NetMsg
{
Packet Payload;
//IPAddress Target;
//IPAddress Source;
};
class SharedNetworkSubsystem
{
public:
std::atomic<bool> running;
ConcurrentQueue<NetMsg> Outgoing;
ConcurrentQueue<NetMsg> Incoming;
};
}

View File

@@ -0,0 +1,7 @@
#include <Core/ConcurrentQueue.hpp>
namespace CaveGame::Core
{
}

View File

@@ -0,0 +1 @@
#include <Core/SharedNetworkSubsystem.hpp>

View File

@@ -0,0 +1,8 @@
//
// Created by dawsh on 11/12/24.
//
#ifndef RECAVEGAME_GAMESERVER_HPP
#define RECAVEGAME_GAMESERVER_HPP
#endif //RECAVEGAME_GAMESERVER_HPP

View File

@@ -0,0 +1,3 @@
//
// Created by dawsh on 11/12/24.
//