second commit

This commit is contained in:
2026-07-09 12:30:40 +01:00
parent 06bcac9bf7
commit 1bf565b543
22 changed files with 969 additions and 792 deletions
+5 -5
View File
@@ -1,5 +1,5 @@
assets/ assets/
bin/ bin/
debug/ debug/
external/ external/
compile_commands.json compile_commands.json
+8 -8
View File
@@ -1,8 +1,8 @@
[Window][Debug##Default] [Window][Debug##Default]
Pos=60,60 Pos=60,60
Size=400,400 Size=400,400
[Window][VBoxContainer] [Window][VBoxContainer]
Pos=540,275 Pos=540,275
Size=200,250 Size=200,250
+34 -33
View File
@@ -1,34 +1,35 @@
{ {
// Use IntelliSense to learn about possible attributes. // Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes. // Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{ {
"name": "(gdb) Launch", "name": "(gdb) Launch",
"type": "cppdbg", "type": "cppdbg",
"request": "launch", "request": "launch",
"program": "${workspaceFolder}/debug/d.exe", "program": "${workspaceFolder}/debug/d.exe",
"args": [], "args": [],
"stopAtEntry": false, "stopAtEntry": false,
"cwd": "${fileDirname}", // "cwd": "${fileDirname}",
"environment": [], "cwd": "${workspaceFolder}",
"externalConsole": false, "environment": [],
"MIMode": "gdb", "externalConsole": false,
"miDebuggerPath": "gdb", "MIMode": "gdb",
"setupCommands": [ "miDebuggerPath": "gdb",
{ "setupCommands": [
"description": "Enable pretty-printing for gdb", {
"text": "-enable-pretty-printing", "description": "Enable pretty-printing for gdb",
"ignoreFailures": true "text": "-enable-pretty-printing",
}, "ignoreFailures": true
{ },
"description": "Set Disassembly Flavor to Intel", {
"text": "-gdb-set disassembly-flavor intel", "description": "Set Disassembly Flavor to Intel",
"ignoreFailures": true "text": "-gdb-set disassembly-flavor intel",
} "ignoreFailures": true
] }
} ]
}
]
]
} }
+25 -21
View File
@@ -1,21 +1,25 @@
[Window][Debug##Default] [Window][Debug##Default]
Pos=143,124 Pos=952,-6
Size=400,400 Size=400,400
[Window][CenterWindow] [Window][CenterWindow]
Pos=0,0 Pos=0,0
Size=1280,800 Size=1280,800
Collapsed=1 Collapsed=1
[Window][VBoxContainer] [Window][VBoxContainer]
Pos=540,275 Pos=540,275
Size=200,250 Size=200,250
[Window][Box] [Window][Box]
Pos=156,64 Pos=156,64
Size=180,105 Size=180,105
[Window][Debug] [Window][Debug]
Pos=882,174 Pos=882,174
Size=320,170 Size=320,170
[Window][Exit]
Pos=1132,60
Size=40,40
+114 -103
View File
@@ -1,103 +1,114 @@
.PHONY: all build-gui build-game run .PHONY: all build-gui build-game run
CXX = g++ CXX = g++
LDFLAGS = -L./external/raylib/lib \ LDFLAGS = -L./external/raylib/lib \
-L./external/box2d/build/src \ -L./external/box2d/build/src \
-L./external/asset_packer/bin \ -L./external/asset_packer/bin \
LIBS = -lraylib -lwinmm -lgdi32 -lbox2d -lassetpacker LIBS = -lraylib -lwinmm -lgdi32 -lbox2d -lassetpacker
CXXFLAGS = -std=c++20 -O2 \ CXXFLAGS = -std=c++20 -O2 \
-MMD -MP -MMD -MP
DEBUGFLAGS = -std=c++20 -g -Og DEBUGFLAGS = -std=c++20 -g -O0
INCLUDES = -I./external/raylib/include \ INCLUDES = -I./external/raylib/include \
-I./external/entt/single_include \ -I./external/entt/single_include \
-I./src/include \ -I./src/include \
-I./external/imgui \ -I./external/imgui \
-I./external/rlImGui \ -I./external/rlImGui \
-I./external/box2d/include \ -I./external/box2d/include \
-I./external/nhlohmann_json_3.12.0/ \ -I./external/nhlohmann_json_3.12.0/ \
-I./external/asset_packer/bin/include \ -I./external/asset_packer/bin/include \
IMGUI_SRCS = ./external/imgui/imgui.cpp \ IMGUI_SRCS = ./external/imgui/imgui.cpp \
./external/imgui/imgui_demo.cpp \ ./external/imgui/imgui_demo.cpp \
./external/imgui/imgui_draw.cpp \ ./external/imgui/imgui_draw.cpp \
./external/imgui/imgui_tables.cpp \ ./external/imgui/imgui_tables.cpp \
./external/imgui/imgui_widgets.cpp \ ./external/imgui/imgui_widgets.cpp \
IMGUI_BACKEND = ./external/rlImGui/rlImGui.cpp IMGUI_BACKEND = ./external/rlImGui/rlImGui.cpp
SRC_FILES = ./src/main.cpp \ SRC_FILES = ./src/asset.cpp \
./src/asset.cpp \ ./src/movement.cpp \
./src/movement.cpp \ ./src/player.cpp \
./src/player.cpp \ ./src/render.cpp \
./src/render.cpp \ ./src/scenes/scene.cpp \
./src/scenes/scene.cpp \ ./src/scenes/game_play_scene.cpp \
./src/scenes/game_play_scene.cpp \ ./src/scenes/menu_scene.cpp
./src/scenes/menu_scene.cpp
ENTRY_POINT = ./src/main.cpp
IMGUI_OBJS = $(patsubst ./external/imgui/%.cpp,./bin/%.o,$(IMGUI_SRCS)) TEST_ENTRY_POINT = ./src/test.cpp
IMGUI_BACKEND_OBJS = $(patsubst ./external/rlImGui/%.cpp,./bin/%.o,$(IMGUI_BACKEND))
OBJS_FILES = $(patsubst ./src/%.cpp,./bin/%.o,$(SRC_FILES)) IMGUI_OBJS = $(patsubst ./external/imgui/%.cpp,./bin/%.o,$(IMGUI_SRCS))
IMGUI_BACKEND_OBJS = $(patsubst ./external/rlImGui/%.cpp,./bin/%.o,$(IMGUI_BACKEND))
DEP_FILES = $(patsubst ./bin/%.o,./bin/%.d,$(OBJS_FILES)) OBJS_FILES = $(patsubst ./src/%.cpp,./bin/%.o,$(SRC_FILES))
DEP_FILES = $(patsubst ./bin/%.o,./bin/%.d,$(OBJS_FILES))
all: build-game run
./bin/%.o: ./external/imgui/%.cpp all: build-game run
@mkdir -p bin
$(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@ ./bin/%.o: ./external/imgui/%.cpp
@mkdir -p bin
./bin/%.o: ./external/rlImGui/%.cpp $(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@
@mkdir -p bin
$(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@ ./bin/%.o: ./external/rlImGui/%.cpp
@mkdir -p bin
./bin/%.o: ./src/%.cpp $(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@
@mkdir -p bin
@mkdir -p $(dir $@) ./bin/%.o: ./src/%.cpp
$(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@ @mkdir -p bin
@mkdir -p $(dir $@)
compile_commands.json: clean $(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@
@echo "Generating compile_commands.json..."
bear -- $(MAKE) compile_commands.json: clean
@echo "Generating compile_commands.json..."
-include $(DEP_FILES) bear -- $(MAKE)
build-gui: $(IMGUI_OBJS) -include $(DEP_FILES)
build-gui-backend: $(IMGUI_BACKEND_OBJS) build-gui: $(IMGUI_OBJS)
build-core: $(OBJS_FILES) build-gui-backend: $(IMGUI_BACKEND_OBJS)
build-game: $(OBJS_FILES) $(IMGUI_OBJS) $(IMGUI_BACKEND_OBJS) build-core: $(OBJS_FILES)
@mkdir -p bin
$(CXX) $(CXXFLAGS) $(OBJS_FILES) $(IMGUI_OBJS) $(IMGUI_BACKEND_OBJS) $(LDFLAGS) $(LIBS) -o ./bin/main.exe build-game: $(OBJS_FILES) $(IMGUI_OBJS) $(IMGUI_BACKEND_OBJS)
cp ./assets ./bin -rf @mkdir -p bin
$(CXX) $(CXXFLAGS) $(INCLUDES) $(ENTRY_POINT) $(OBJS_FILES) $(IMGUI_OBJS) $(IMGUI_BACKEND_OBJS) $(LDFLAGS) $(LIBS) -o ./bin/main.exe
build-debug: cp ./assets ./bin -rf
@mkdir -p debug
$(CXX) $(DEBUGFLAGS) $(INCLUDES) $(SRC_FILES) $(IMGUI_SRCS) $(IMGUI_BACKEND) $(LDFLAGS) $(LIBS) -o ./debug/d.exe build-test: $(OBJS_FILES) $(IMGUI_OBJS) $(IMGUI_BACKEND_OBJS)
cp ./assets ./debug -rf @mkdir -p bin
$(CXX) $(CXXFLAGS) $(INCLUDES) $(TEST_ENTRY_POINT) $(OBJS_FILES) $(IMGUI_OBJS) $(IMGUI_BACKEND_OBJS) $(LDFLAGS) $(LIBS) -o ./bin/test.exe
cp ./assets ./bin -rf
clean:
@rm -r -f ./bin build-debug:
@rm -f compile_commands.json @mkdir -p debug
$(CXX) $(DEBUGFLAGS) $(INCLUDES) $(ENTRY_POINT) $(SRC_FILES) $(IMGUI_OBJS) $(IMGUI_BACKEND_OBJS) $(LDFLAGS) $(LIBS) -o ./debug/d.exe
clean-debug: cp ./data.dat ./debug -rf
@rm -r -f ./debug
clean-all: clean clean-debug
clean:
run: @rm -r -f ./bin
./bin/main.exe @rm -f compile_commands.json
run-debug: clean-debug:
./debug/d.exe @rm -r -f ./debug
clean-all: clean clean-debug
run:
./bin/main.exe
run-debug:
./debug/d.exe
run-test: build-test
./bin/test.exe
+182 -132
View File
@@ -1,132 +1,182 @@
#include <asset_packer/asset.hpp> #include <asset_packer/asset.hpp>
#include <asset/asset.hpp> #include <asset/asset.hpp>
#include <asset/raylib_asset.hpp> #include <asset/raylib_asset.hpp>
#include <raylib.h> #include <raylib.h>
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <filesystem> #include <filesystem>
#include <variant> #include <variant>
namespace fs = std::filesystem; namespace fs = std::filesystem;
AssetLoader::AssetLoader(std::string asset_data) : asset_reader(asset_data){ // Helper to determine if the asset path implies streaming music
if (!asset_reader.load_index()){ bool should_stream_as_music(const std::filesystem::path& asset_path) {
std::cerr << "Failed to load assets!!!" << std::endl; for (const auto& part : asset_path) {
} if (part == "music" || part == "bgm") {
} return true;
}
AssetReader AssetLoader::get_reader(){ }
return asset_reader; return false;
} }
RaylibAssetLoader::RaylibAssetLoader(std::string asset_data) : AssetLoader(asset_data) { AssetLoader::AssetLoader(std::string asset_data) : asset_reader(asset_data){
if (!asset_reader.load_index()){
} std::cerr << "Failed to load assets!!!" << std::endl;
}
RaylibAssetLoader::~RaylibAssetLoader(){ }
unload_all_assets();
} AssetReader AssetLoader::get_reader(){
return asset_reader;
}
void RaylibAssetLoader::load_asset(std::string path){
fs::path file_path(path); RaylibAssetLoader::RaylibAssetLoader(std::string asset_data) : AssetLoader(asset_data) {
Asset new_asset;
new_asset.name = file_path.filename().string() ; }
std::cout << file_path.extension() << std::endl; RaylibAssetLoader::~RaylibAssetLoader(){
unload_all_assets();
if (file_path.extension() == ".png"){ }
auto texture_data = get_reader().extract_asset(path);
Image img = LoadImageFromMemory(".png", texture_data.data(), texture_data.size());
auto texture = LoadTextureFromImage(img);
UnloadImage(img); void RaylibAssetLoader::load_asset(std::string path){
new_asset.data = ImageData { new Texture(texture)}; fs::path file_path(path);
Asset new_asset;
new_asset.name = file_path.filename().string() ;
}else if(file_path.extension() == ".ogg"){
// std::cout << file_path.extension() << std::endl;
}else if(file_path.extension() == ".wav"){ auto bytes = get_reader().extract_asset(path);
}else if(file_path.extension() == ".json"){ if (file_path.extension() == ".png"){
Image img = LoadImageFromMemory(".png", bytes.data(), bytes.size());
} auto texture = LoadTextureFromImage(img);
UnloadImage(img);
new_asset.data = ImageData { new Texture(texture)};
assets[path] = new_asset;
} }else if(file_path.extension() == ".ogg"){
void RaylibAssetLoader::unload_asset(std::string path){ if (should_stream_as_music(file_path)){
Asset asset = assets[path]; auto music = LoadMusicStreamFromMemory(".ogg",bytes.data(),bytes.size());
new_asset.data = MusicData{new Music(music)};
std::visit([](auto&& arg) { }else{
using T = std::decay_t<decltype(arg)>; auto wave = LoadWaveFromMemory(".ogg", bytes.data(),bytes.size());
auto sound = LoadSoundFromWave(wave);
if constexpr (std::is_same_v<T, ImageData>) { UnloadWave(wave);
new_asset.data = SoundData{new Sound(sound)};
UnloadTexture(*((Texture*) arg.texture)); }
delete (Texture*) arg.texture;
} }
else if constexpr (std::is_same_v<T, SoundData>) { else if(file_path.extension() == ".mp3"){
UnloadSound(*((Sound*) arg.sound)); if (should_stream_as_music(file_path)){
delete (Sound*) arg.sound; auto music = LoadMusicStreamFromMemory(".mp3",bytes.data(),bytes.size());
} new_asset.data = MusicData{new Music(music)};
else if constexpr (std::is_same_v<T, MusicData>) { }else{
UnloadMusicStream(*((Music*) arg.music)); auto wave = LoadWaveFromMemory(".mp3", bytes.data(),bytes.size());
delete (Music*) arg.music; auto sound = LoadSoundFromWave(wave);
} UnloadWave(wave);
// JsonData requires no manual step because std::string cleans itself up! new_asset.data = SoundData{new Sound(sound)};
}, asset.data); }
} }
else if(file_path.extension() == ".wav"){
if (should_stream_as_music(file_path)){
void RaylibAssetLoader::unload_all_assets(){ auto music = LoadMusicStreamFromMemory(".wav",bytes.data(),bytes.size());
for (auto [path,_] : assets){ new_asset.data = MusicData{new Music(music)};
unload_asset(path); }else{
} auto wave = LoadWaveFromMemory(".wav", bytes.data(),bytes.size());
} auto sound = LoadSoundFromWave(wave);
UnloadWave(wave);
Asset RaylibAssetLoader::get_asset(std::string path){ new_asset.data = SoundData{new Sound(sound)};
if (assets.contains(path)){ }
return assets[path]; }
}else{
return {}; else if(file_path.extension() == ".json"){
} auto json = std::string(bytes.begin(),bytes.end());
} new_asset.data = JsonData {json};
}
Texture* RaylibAssetLoader::get_texture(std::string path){ assets[path] = new_asset;
Asset asset = get_asset(path); }
if (auto* ptr = std::get_if<ImageData>(&asset.data)) {
return (Texture*)ptr->texture; void RaylibAssetLoader::unload_asset(std::string path){
} Asset asset = assets[path];
return nullptr;
} std::visit([](auto&& arg) {
using T = std::decay_t<decltype(arg)>;
Sound* RaylibAssetLoader::get_sound(std::string path){
Asset asset = get_asset(path); if constexpr (std::is_same_v<T, ImageData>) {
if (auto* ptr = std::get_if<SoundData>(&asset.data)) { Texture* tex = static_cast<Texture*>(arg.texture);
return (Sound*)ptr->sound; UnloadTexture(*tex);
} delete tex;
return nullptr; arg.texture = nullptr;
} }
Music* RaylibAssetLoader::get_music(std::string path){ else if constexpr (std::is_same_v<T, SoundData>) {
Asset asset = get_asset(path); Sound* sound = static_cast<Sound*>(arg.sound);
if (auto* ptr = std::get_if<MusicData>(&asset.data)) { UnloadSound(*sound);
return (Music*)ptr->music; delete sound;
} arg.sound = nullptr;
return nullptr; }
} else if constexpr (std::is_same_v<T, MusicData>) {
Music* music = static_cast<Music*>(arg.music);
std::string RaylibAssetLoader::get_json(std::string path){ UnloadMusicStream(*music);
Asset asset = get_asset(path); delete music;
if (auto* ptr = std::get_if<JsonData>(&asset.data)) { arg.music = nullptr;
return ptr->json; }
} // JsonData requires no manual step because std::string cleans itself up!
return "{}"; }, asset.data);
}
assets.erase(path);
}
void RaylibAssetLoader::unload_all_assets(){
for (auto [path,_] : assets){
unload_asset(path);
}
}
Asset RaylibAssetLoader::get_asset(std::string path){
if (assets.contains(path)){
return assets[path];
}else{
return {};
}
}
Texture* RaylibAssetLoader::get_texture(std::string path){
Asset asset = get_asset(path);
if (auto* ptr = std::get_if<ImageData>(&asset.data)) {
return (Texture*)ptr->texture;
}
return nullptr;
}
Sound* RaylibAssetLoader::get_sound(std::string path){
Asset asset = get_asset(path);
if (auto* ptr = std::get_if<SoundData>(&asset.data)) {
return (Sound*)ptr->sound;
}
return nullptr;
}
Music* RaylibAssetLoader::get_music(std::string path){
Asset asset = get_asset(path);
if (auto* ptr = std::get_if<MusicData>(&asset.data)) {
return (Music*)ptr->music;
}
return nullptr;
}
std::string RaylibAssetLoader::get_json(std::string path){
Asset asset = get_asset(path);
if (auto* ptr = std::get_if<JsonData>(&asset.data)) {
return ptr->json;
}
return "{}";
}
+8 -8
View File
@@ -1,8 +1,8 @@
[Window][Debug##Default] [Window][Debug##Default]
Pos=60,60 Pos=60,60
Size=400,400 Size=400,400
[Window][VBoxContainer] [Window][VBoxContainer]
Pos=540,275 Pos=540,275
Size=200,250 Size=200,250
+54 -54
View File
@@ -1,54 +1,54 @@
#pragma once #pragma once
#include <asset_packer/asset.hpp> #include <asset_packer/asset.hpp>
#include <string> #include <string>
#include <variant> #include <variant>
#include <unordered_map> #include <unordered_map>
struct ImageData { struct ImageData {
void* texture; void* texture;
}; };
struct SoundData { struct SoundData {
void* sound; void* sound;
}; };
struct MusicData { struct MusicData {
void* music; void* music;
}; };
struct JsonData { struct JsonData {
std::string json; std::string json;
}; };
struct Asset { struct Asset {
std::string name; std::string name;
std::variant<ImageData, SoundData, MusicData, JsonData> data; std::variant<ImageData, SoundData, MusicData, JsonData> data;
}; };
class AssetLoader{ class AssetLoader{
private: private:
AssetReader asset_reader; AssetReader asset_reader;
protected: protected:
std::unordered_map<std::string,Asset> assets; std::unordered_map<std::string,Asset> assets;
virtual void load_all_assets(std::string data_path) = 0; virtual void load_all_assets(std::string data_path) = 0;
virtual void unload_all_assets() = 0; virtual void unload_all_assets() = 0;
AssetReader get_reader(); AssetReader get_reader();
public: public:
AssetLoader(std::string asset_data); AssetLoader(std::string asset_data);
~AssetLoader() = default; ~AssetLoader() = default;
virtual void load_asset(std::string path) = 0; virtual void load_asset(std::string path) = 0;
virtual void unload_asset(std::string path) = 0; virtual void unload_asset(std::string path) = 0;
virtual Asset get_asset(std::string path) = 0;; virtual Asset get_asset(std::string path) = 0;;
}; };
+31 -31
View File
@@ -1,31 +1,31 @@
#pragma once #pragma once
#include "asset_packer/asset.hpp" #include "asset_packer/asset.hpp"
#include <asset/asset.hpp> #include <asset/asset.hpp>
#include <raylib.h> #include <raylib.h>
class RaylibAssetLoader : AssetLoader{ class RaylibAssetLoader : AssetLoader{
protected: protected:
void load_all_assets(std::string asset_list) override {}; void load_all_assets(std::string asset_list) override {};
void unload_all_assets() override; void unload_all_assets() override;
public: public:
RaylibAssetLoader(std::string asset_data = "data.dat"); RaylibAssetLoader(std::string asset_data = "data.dat");
~RaylibAssetLoader(); ~RaylibAssetLoader();
void load_asset(std::string path) override; void load_asset(std::string path) override;
void unload_asset(std::string path) override; void unload_asset(std::string path) override;
Asset get_asset(std::string path) override; Asset get_asset(std::string path) override;
Texture* get_texture(std::string path); Texture* get_texture(std::string path);
Sound* get_sound(std::string path); Sound* get_sound(std::string path);
Music* get_music(std::string path); Music* get_music(std::string path);
std::string get_json(std::string path); std::string get_json(std::string path);
}; };
extern RaylibAssetLoader asset_loader; extern RaylibAssetLoader asset_loader;
+18 -18
View File
@@ -1,18 +1,18 @@
#pragma once #pragma once
#include<raylib.h> #include<raylib.h>
struct Position{ struct Position{
float x; float x;
float y; float y;
}; };
struct Velocity{ struct Velocity{
float dx; float dx;
float dy; float dy;
}; };
struct Player{}; struct Player{};
struct Sprite{ struct Sprite{
Texture *texture; Texture *texture;
}; };
+4 -4
View File
@@ -1,4 +1,4 @@
#pragma once #pragma once
#include<entt/entt.hpp> #include<entt/entt.hpp>
void update_movement_system(entt::registry& registry, float dt); void update_movement_system(entt::registry& registry, float dt);
+6 -6
View File
@@ -1,6 +1,6 @@
#pragma once #pragma once
#include <entt/entt.hpp> #include <entt/entt.hpp>
#include<raylib.h> #include<raylib.h>
void create_player(entt::registry& registry,Texture* texture); void create_player(entt::registry& registry,Texture* texture);
void update_player_system(entt::registry& registry,float dt); void update_player_system(entt::registry& registry,float dt);
+5 -5
View File
@@ -1,5 +1,5 @@
#pragma once #pragma once
#include <entt/entt.hpp> #include <entt/entt.hpp>
void update_render_system(entt::registry &registry); void update_render_system(entt::registry &registry);
+86 -86
View File
@@ -1,86 +1,86 @@
#pragma once #pragma once
#include <functional> #include <functional>
#include <entt/entt.hpp> #include <entt/entt.hpp>
enum class SceneType{ enum class SceneType{
MENU, MENU,
GAMEPLAY GAMEPLAY
}; };
// Simple global data structure to hold the switch request // Simple global data structure to hold the switch request
struct EngineState { struct EngineState {
bool pendingSwitch = false; bool pendingSwitch = false;
SceneType nextScene; SceneType nextScene;
bool shouldQuit = false; bool shouldQuit = false;
void request_switch(SceneType type) { void request_switch(SceneType type) {
nextScene = type; nextScene = type;
pendingSwitch = true; pendingSwitch = true;
} }
void quit(){ void quit(){
shouldQuit = true; shouldQuit = true;
} }
}; };
// Expose the global state to any file that includes scene.hpp // Expose the global state to any file that includes scene.hpp
extern EngineState g_Engine; extern EngineState g_Engine;
class Scene{ class Scene{
public: public:
Scene() = default; Scene() = default;
virtual ~Scene() = default; virtual ~Scene() = default;
virtual void update(float dt) = 0; virtual void update(float dt) = 0;
virtual void render() = 0; virtual void render() = 0;
virtual void ui() = 0; virtual void ui() = 0;
}; };
class GamePlayScene : public Scene{ class GamePlayScene : public Scene{
private: private:
entt::registry registry; entt::registry registry;
public: public:
GamePlayScene(); GamePlayScene();
~GamePlayScene(); ~GamePlayScene();
void update(float dt) override; void update(float dt) override;
void render() override; void render() override;
void ui() override; void ui() override;
}; };
class MenuScene : public Scene{ class MenuScene : public Scene{
public: public:
MenuScene(); MenuScene();
~MenuScene() = default; ~MenuScene() = default;
void update(float dt) override; void update(float dt) override;
void render() override; void render() override;
void ui() override; void ui() override;
}; };
class SceneManager{ class SceneManager{
private: private:
Scene* current_scene = nullptr; Scene* current_scene = nullptr;
SceneType next_scene_type; SceneType next_scene_type;
bool should_switch = false; bool should_switch = false;
public: public:
SceneManager(); SceneManager();
~SceneManager(); ~SceneManager();
void update(float dt); void update(float dt);
void render(); void render();
void ui(); void ui();
void process_scene_switch(); void process_scene_switch();
}; };
+84 -84
View File
@@ -1,84 +1,84 @@
#include <asset/raylib_asset.hpp> #include <asset/raylib_asset.hpp>
#include <scene.hpp> #include <scene.hpp>
#include <components.hpp> #include <components.hpp>
#include <box2d/box2d.h> #include <box2d/box2d.h>
#include <box2d/types.h> #include <box2d/types.h>
#include <raylib.h> #include <raylib.h>
#include <rlImGui.h> #include <rlImGui.h>
#include <imgui.h> #include <imgui.h>
#include <entt/entt.hpp> #include <entt/entt.hpp>
#include <asset_packer/asset.hpp> #include <asset_packer/asset.hpp>
#include <iostream> #include <iostream>
// Globals // Globals
EngineState g_Engine; EngineState g_Engine;
RaylibAssetLoader asset_loader; RaylibAssetLoader asset_loader;
int main(){ int main(){
// //
int screen_width = 1280; int screen_width = 1280;
int screen_height = 800; int screen_height = 800;
// initialized scene manager // initialized scene manager
SceneManager scene_manager; SceneManager scene_manager;
entt::registry registry; entt::registry registry;
rlImGuiSetup(true); rlImGuiSetup(true);
ImGuiStyle& style = ImGui::GetStyle(); ImGuiStyle& style = ImGui::GetStyle();
// Rounded corners // Rounded corners
style.WindowRounding = 6.0f; style.WindowRounding = 6.0f;
style.ChildRounding = 4.0f; style.ChildRounding = 4.0f;
style.FrameRounding = 4.0f; style.FrameRounding = 4.0f;
style.PopupRounding = 4.0f; style.PopupRounding = 4.0f;
style.ScrollbarRounding = 9.0f; style.ScrollbarRounding = 9.0f;
style.GrabRounding = 4.0f; style.GrabRounding = 4.0f;
style.TabRounding = 4.0f; style.TabRounding = 4.0f;
// Sizes and Spacing // Sizes and Spacing
style.WindowPadding = ImVec2(15.0f, 15.0f); style.WindowPadding = ImVec2(15.0f, 15.0f);
style.FramePadding = ImVec2(6.0f, 6.0f); style.FramePadding = ImVec2(6.0f, 6.0f);
style.ItemSpacing = ImVec2(10.0f, 8.0f); style.ItemSpacing = ImVec2(10.0f, 8.0f);
style.ScrollbarSize = 15.0f; style.ScrollbarSize = 15.0f;
SetTargetFPS(60); SetTargetFPS(60);
SetTraceLogLevel(TraceLogLevel::LOG_NONE); SetTraceLogLevel(TraceLogLevel::LOG_NONE);
InitWindow(screen_width, screen_height, "Bullet bird"); InitWindow(screen_width, screen_height, "Bullet bird");
SetWindowState(FLAG_WINDOW_RESIZABLE); SetWindowState(FLAG_WINDOW_RESIZABLE);
while (!WindowShouldClose() && !g_Engine.shouldQuit){ while (!WindowShouldClose() && !g_Engine.shouldQuit){
float dt = GetFrameTime(); float dt = GetFrameTime();
if (dt > 0.1f) dt = 0.1f; // cap dt just for now if (dt > 0.1f) dt = 0.1f; // cap dt just for now
scene_manager.update(dt); scene_manager.update(dt);
BeginDrawing(); BeginDrawing();
ClearBackground(RAYWHITE); ClearBackground(RAYWHITE);
scene_manager.render(); scene_manager.render();
rlImGuiBegin(); rlImGuiBegin();
scene_manager.ui(); scene_manager.ui();
rlImGuiEnd(); rlImGuiEnd();
EndDrawing(); EndDrawing();
scene_manager.process_scene_switch(); // !!! After scene_manager is done with the current loop scene_manager.process_scene_switch(); // !!! After scene_manager is done with the current loop
} }
CloseWindow(); CloseWindow();
rlImGuiShutdown(); rlImGuiShutdown();
return 0; return 0;
} }
+14 -14
View File
@@ -1,14 +1,14 @@
// src\movement.cpp // src\movement.cpp
#include <entt/entt.hpp> #include <entt/entt.hpp>
#include <components.hpp> #include <components.hpp>
void update_movement_system(entt::registry& registry, float dt) { void update_movement_system(entt::registry& registry, float dt) {
// We get Position and Velocity, but EXCLUDE entities that have the Player tag // We get Position and Velocity, but EXCLUDE entities that have the Player tag
auto view = registry.view<Position, Velocity>(); auto view = registry.view<Position, Velocity>();
view.each([dt](Position &position, Velocity &velocity) { view.each([dt](Position &position, Velocity &velocity) {
// This will only run for pipes, enemies, or particles! // This will only run for pipes, enemies, or particles!
position.x += velocity.dx * dt; position.x += velocity.dx * dt;
position.y += velocity.dy * dt; position.y += velocity.dy * dt;
}); });
} }
+50 -34
View File
@@ -1,34 +1,50 @@
// src\player.cpp // src\player.cpp
#include<raylib.h> #include<raylib.h>
#include<entt/entt.hpp> #include<entt/entt.hpp>
#include<components.hpp> #include<components.hpp>
entt::entity player; entt::entity player;
void create_player(entt::registry& registry,Texture* texture){ void create_player(entt::registry& registry,Texture* texture){
const auto entity = registry.create(); const auto entity = registry.create();
registry.emplace<Position>(entity,100.0f,0.0f); registry.emplace<Position>(entity,100.0f,0.0f);
registry.emplace<Velocity>(entity,0.0f,0.0f); registry.emplace<Velocity>(entity,300.0f,0.0f);
registry.emplace<Player>(entity); registry.emplace<Player>(entity);
registry.emplace<Sprite>(entity,texture); registry.emplace<Sprite>(entity,texture);
} }
void update_player_system(entt::registry& registry,float dt){ void update_player_system(entt::registry& registry,float dt){
auto view = registry.view<const Player, Velocity>(); auto view = registry.view<const Player, const Position, Velocity>();
// Constants for fine-tuning game feel // Constants for fine-tuning game feel
const float GRAVITY = 900.0f; // Constant downward pull (pixels/sec^2) const float GRAVITY = 900.0f; // Constant downward pull (pixels/sec^2)
const float JUMP_FORCE = -350.0f; // Negative force to burst UPWARD const float JUMP_FORCE = -350.0f; // Negative force to burst UPWARD
view.each([dt,GRAVITY,JUMP_FORCE](const auto &player, auto &velocity){ for (entt::entity entity : view){
if (IsKeyPressed(KEY_SPACE)){ const Position& pos = view.get<Position>(entity);
velocity.dy = JUMP_FORCE; Velocity& vel = view.get<Velocity>(entity);
}
velocity.dy += GRAVITY * dt; if (pos.x < -50 && vel.dx < 0){
}); vel.dx *= -1;
} else if (pos.x > (GetScreenWidth()-250) && vel.dx > 0){
} vel.dx *= -1;
}
if (IsKeyPressed(KEY_SPACE)){
vel.dy = JUMP_FORCE;
}
vel.dy += GRAVITY * dt;
}
view.each([dt,GRAVITY,JUMP_FORCE](entt::entity entity,const Position &position, auto &velocity){
if (position.x > 100 && position.x < 120){
velocity.dx += 20;
}
});
}
+18 -18
View File
@@ -1,18 +1,18 @@
#include <render.hpp> #include <render.hpp>
#include <components.hpp> #include <components.hpp>
#include<raylib.h> #include<raylib.h>
#include <entt/entt.hpp> #include <entt/entt.hpp>
void update_render_system(entt::registry &registry){ void update_render_system(entt::registry &registry){
auto view = registry.view<const Sprite, const Position>(); auto view = registry.view<const Sprite, const Position>();
view.each([] (const auto &sprite, const auto &position){ view.each([] (const auto &sprite, const auto &position){
if (sprite.texture){ if (sprite.texture){
DrawTexture(*(sprite.texture),position.x,position.y,WHITE); DrawTexture(*(sprite.texture),position.x,position.y,WHITE);
}else{ }else{
DrawRectangle(position.x,position.y,50, 70,BLACK); DrawRectangle(position.x,position.y,50, 70,BLACK);
} }
}); });
} }
+53 -33
View File
@@ -1,33 +1,53 @@
#include <player.hpp> #include <imgui.h>
#include <movement.hpp> #include <player.hpp>
#include <scene.hpp> #include <movement.hpp>
#include <render.hpp> #include <scene.hpp>
#include <asset/raylib_asset.hpp> #include <render.hpp>
#include <asset/raylib_asset.hpp>
GamePlayScene::GamePlayScene() { #include <format>
registry = entt::registry();
GamePlayScene::GamePlayScene() {
asset_loader.load_asset("assets/bird.png"); registry = entt::registry();
create_player(registry,asset_loader.get_texture("assets/bird.png"));
asset_loader.load_asset("assets/bird.png");
} create_player(registry,asset_loader.get_texture("assets/bird.png"));
void GamePlayScene::update(float dt) { }
update_movement_system(registry, dt);
update_player_system(registry, dt); void GamePlayScene::update(float dt) {
} update_movement_system(registry, dt);
update_player_system(registry, dt);
}
void GamePlayScene::render() {
update_render_system(registry);
} void GamePlayScene::render() {
update_render_system(registry);
void GamePlayScene::ui() { }
}
void GamePlayScene::ui() {
GamePlayScene::~GamePlayScene(){ // Get the current screen/viewport size
asset_loader.unload_asset("assets/bird.png"); ImVec2 screen_size = ImGui::GetIO().DisplaySize;
// set next container to be center of the screen
} ImVec2 screen_center = ImVec2(screen_size.x * 0.9f, screen_size.y * 0.1f);
ImGui::SetNextWindowPos(screen_center, ImGuiCond_Always,ImVec2(0.5f, 0.5f));
ImGui::SetNextWindowSize({40.f,40.f});
// remove sub window decoration
ImGuiWindowFlags flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoBackground;
ImGui::Begin("Exit", nullptr, flags);
if (ImGui::Button("X",{40.f,40.f})){
g_Engine.request_switch(SceneType::MENU);
}
ImGui::End();
}
GamePlayScene::~GamePlayScene(){
asset_loader.unload_asset("assets/bird.png");
}
+56 -56
View File
@@ -1,56 +1,56 @@
#include <player.hpp> #include <player.hpp>
#include <movement.hpp> #include <movement.hpp>
#include <scene.hpp> #include <scene.hpp>
#include <imgui.h> #include <imgui.h>
// #include <format> // #include <format>
MenuScene::MenuScene() { MenuScene::MenuScene() {
} }
void MenuScene::update(float dt) { void MenuScene::update(float dt) {
} }
void MenuScene::render() {} void MenuScene::render() {}
void MenuScene::ui() { void MenuScene::ui() {
// Get the current screen/viewport size // Get the current screen/viewport size
ImVec2 screen_size = ImGui::GetIO().DisplaySize; ImVec2 screen_size = ImGui::GetIO().DisplaySize;
// size of button container // size of button container
ImVec2 vbox_size = ImVec2(200.0f, 250.0f); ImVec2 vbox_size = ImVec2(200.0f, 250.0f);
// set next container to be center of the screen // set next container to be center of the screen
ImVec2 screen_center = ImVec2(screen_size.x * 0.5f, screen_size.y * 0.5f); ImVec2 screen_center = ImVec2(screen_size.x * 0.5f, screen_size.y * 0.5f);
ImGui::SetNextWindowPos(screen_center, ImGuiCond_Always,ImVec2(0.5f, 0.5f)); ImGui::SetNextWindowPos(screen_center, ImGuiCond_Always,ImVec2(0.5f, 0.5f));
ImGui::SetNextWindowSize(vbox_size); ImGui::SetNextWindowSize(vbox_size);
// remove sub window decoration // remove sub window decoration
ImGuiWindowFlags flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoBackground; ImGuiWindowFlags flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoBackground;
ImGui::Begin("VBoxContainer", nullptr, flags); ImGui::Begin("VBoxContainer", nullptr, flags);
// set button width to be size fill container // set button width to be size fill container
ImVec2 button_size = ImVec2(ImGui::GetContentRegionAvail().x, 50.0f); ImVec2 button_size = ImVec2(ImGui::GetContentRegionAvail().x, 50.0f);
// ImGui::SetCursorPos(centeredPos); // ImGui::SetCursorPos(centeredPos);
if (ImGui::Button("Play",button_size)){ if (ImGui::Button("Play",button_size)){
g_Engine.request_switch(SceneType::GAMEPLAY); g_Engine.request_switch(SceneType::GAMEPLAY);
} }
ImGui::Dummy(ImVec2(0, 10)); // Gap ImGui::Dummy(ImVec2(0, 10)); // Gap
if (ImGui::Button("Quit",button_size)){ if (ImGui::Button("Quit",button_size)){
g_Engine.quit(); g_Engine.quit();
} }
ImGui::End(); ImGui::End();
// ImGui::Begin("Debug"); // ImGui::Begin("Debug");
// ImGui::Button("Hello",button_size); // ImGui::Button("Hello",button_size);
// ImGui::TextUnformatted(std::format("window size: {} {} ", screen_size.x,screen_size.y).c_str()); // ImGui::TextUnformatted(std::format("window size: {} {} ", screen_size.x,screen_size.y).c_str());
// ImGui::End(); // ImGui::End();
} }
+39 -39
View File
@@ -1,39 +1,39 @@
#include <scene.hpp> #include <scene.hpp>
SceneManager::SceneManager(){ SceneManager::SceneManager(){
current_scene = new MenuScene(); current_scene = new MenuScene();
} }
SceneManager::~SceneManager(){ SceneManager::~SceneManager(){
delete current_scene; delete current_scene;
} }
void SceneManager::process_scene_switch(){ void SceneManager::process_scene_switch(){
if (!g_Engine.pendingSwitch) return; if (!g_Engine.pendingSwitch) return;
delete current_scene; delete current_scene;
switch(g_Engine.nextScene){ switch(g_Engine.nextScene){
case SceneType::MENU: case SceneType::MENU:
current_scene = new MenuScene(); current_scene = new MenuScene();
break; break;
case SceneType::GAMEPLAY: case SceneType::GAMEPLAY:
current_scene = new GamePlayScene(); current_scene = new GamePlayScene();
break; break;
} }
g_Engine.pendingSwitch = false; g_Engine.pendingSwitch = false;
} }
void SceneManager::update(float dt){ void SceneManager::update(float dt){
if (current_scene){ if (current_scene){
current_scene->update(dt); current_scene->update(dt);
} }
} }
void SceneManager::render(){ void SceneManager::render(){
current_scene->render(); current_scene->render();
} }
void SceneManager::ui(){ void SceneManager::ui(){
current_scene->ui(); current_scene->ui();
} }
+75
View File
@@ -0,0 +1,75 @@
#include <asset/raylib_asset.hpp>
#include <scene.hpp>
#include <components.hpp>
#include <box2d/box2d.h>
#include <box2d/types.h>
#include <raylib.h>
#include <rlImGui.h>
#include <imgui.h>
#include <entt/entt.hpp>
#include <asset_packer/asset.hpp>
#include <chrono>
#include <thread>
#include <format>
#include <iostream>
// #include <windows.h>
// #include <psapi.h>
EngineState g_Engine;
RaylibAssetLoader asset_loader;
// size_t get_current_ram_usage() {
// PROCESS_MEMORY_COUNTERS pmc;
// if (GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))) {
// return pmc.WorkingSetSize;
// }
// return 0;
// }
void asset_thread(){
// for (int i = 0; i < 1000000; i++){
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
asset_loader.load_asset("assets/bird.png");
// asset_loader.unload_asset("assets/bird.png");
// if (WindowShouldClose()) break;
// }
}
int main() {
int* num = reinterpret_cast<int*>(new char[4]);
SetTraceLogLevel(LOG_NONE);
InitWindow(800,800,"test");
// std::cout << "Starting Test..." << std::endl;
// std::this_thread::sleep_for(std::chrono::milliseconds(5000));
// std::thread t(asset_thread);
// asset_loader.load_asset("assets/bird.png");
while(!WindowShouldClose()){
// size_t ram_bytes = get_current_ram_usage();
asset_loader.load_asset("assets/bird.png");
std::this_thread::sleep_for(std::chrono::milliseconds(10));
asset_loader.unload_asset("assets/bird.png");
BeginDrawing();
ClearBackground(RAYWHITE);
// auto tex = asset_loader.get_texture("assets/bird.png");
// if (tex != nullptr){
// DrawTexture(*tex, 0,0,WHITE);
// }
rlImGuiBegin();
ImGui::TextUnformatted(std::format("hello {}","world").c_str());
// ImGui::TextUnformatted(std::format("Memory usage: %.2f",ram_bytes/(1024*1024)).c_str());
rlImGuiEnd();
EndDrawing();
}
// t.join();
CloseWindow();
return 0;
}