final cpommit

This commit is contained in:
2026-07-20 20:28:52 +01:00
parent e7407ce319
commit 8feb32ae75
10 changed files with 146 additions and 17 deletions
+4
View File
@@ -0,0 +1,4 @@
BasedOnStyle: LLVM
IndentWidth: 4
TabWidth: 4
UseTab: Never
+2
View File
@@ -1,5 +1,7 @@
assets/
bin/
web/
web*
debug/
external/
compile_commands.json
+1 -1
View File
@@ -1,7 +1,7 @@
#pragma once
struct Player{};
struct PlayerBody{ unsigned int idx;};
struct PlayerBody{};
struct Fruit{};
+4
View File
@@ -3,6 +3,7 @@
#include "engine/core/service-locator.hpp"
#include "engine/scene/scene.hpp"
#include "game/scenes/game-over-scene/game-over.hpp"
#include "game/scenes/main-scene/main-scene.hpp"
#include "game/scenes/menu-scene/menu.hpp"
@@ -19,6 +20,9 @@ class Game : public varicle::Application{
scene_manager.register_scene("menu", []() { return std::make_unique<MenuScene>(); });
scene_manager.register_scene("game-over", []() { return std::make_unique<GameOverScene>(); });
change_scene("menu");
}
@@ -0,0 +1,61 @@
#include "game-over.hpp"
#include "engine/core/service-locator.hpp"
#include "raylib.h"
#include <imgui.h>
void GameOverScene::init() {}
void GameOverScene::update(float dt) {
}
void GameOverScene::render() {
ClearBackground(BLACK);
DrawText("GAME OVER",400,0,48,RED);
}
void GameOverScene::ui() {
// Get the current screen/viewport size
ImVec2 screen_size = ImGui::GetIO().DisplaySize;
// size of button container
ImVec2 vbox_size = ImVec2(200.0f, 250.0f);
// set next container to be center of the screen
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::SetNextWindowSize(vbox_size);
// remove sub window decoration
ImGuiWindowFlags flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoBackground;
ImGui::Begin("VBoxContainer", nullptr, flags);
// set button width to be size fill container
ImVec2 button_size = ImVec2(ImGui::GetContentRegionAvail().x, 50.0f);
// ImGui::SetCursorPos(centeredPos);
if (ImGui::Button("Play Again",button_size)){
v::ServiceLocator::get<v::SceneManager>().switch_to_scene("main");
}
ImGui::Dummy(ImVec2(0, 10)); // Gap
if (ImGui::Button("Menu",button_size)){
v::ServiceLocator::get<v::SceneManager>().switch_to_scene("menu");
}
ImGui::Dummy(ImVec2(0, 10)); // Gap
if (ImGui::Button("Quit",button_size)){
v::ServiceLocator::get<v::SceneManager>().quit();
}
ImGui::End();
// ImGui::Begin("Debug");
// ImGui::Button("Hello",button_size);
// ImGui::TextUnformatted(std::format("window size: {} {} ", screen_size.x,screen_size.y).c_str());
// ImGui::End();
}
@@ -0,0 +1,13 @@
#pragma once
#include "engine/scene/scene.hpp"
namespace v = varicle;
class GameOverScene : public v::Scene{
public:
void init() override;
void update(float dt) override;
void render() override;
void ui() override ;
};
+36 -13
View File
@@ -12,18 +12,22 @@
namespace v = varicle;
void create_body(entt::registry& registry,unsigned int idx){
entt::entity create_body(entt::registry& registry,unsigned int idx){
auto& asset_loader = v::ServiceLocator::get<v::RaylibAssetLoader>();
auto& body_manager = v::ServiceLocator::get<BodyManager>();
auto body_texture = asset_loader.get_texture("assets/snake_body.png");
const auto entity = registry.create();
registry.emplace<v::Position>(entity,-10000.0f,-10000.0f);
registry.emplace<PlayerBody>(entity,idx);
registry.emplace<v::Sprite>(entity,body_texture,0.0f,0.0f,70.0f,70.0f,false,false,0.0f);
// registry.emplace<v::Position>(entity,100.0f,100.0f);
registry.emplace<PlayerBody>(entity);
registry.emplace_or_replace<v::Sprite>(entity,body_texture,0.0f,0.0f,70.0f,70.0f,false,false,0.0f);
return entity;
}
void BodyManager::add_body(entt::registry& registry)
{
create_body(registry,parts_position_stack.size());
auto body_entity =create_body(registry,parts_position_stack.size());
body_parts.push_back(body_entity);
parts_position_stack.push_back( v::Position{});
}
@@ -46,22 +50,41 @@ void BodyManager::update_body_positions(v::Position player_head_position){
v::Position BodyManager::get_body_position(unsigned int part_idx){
return parts_position_stack[part_idx];
}
bool BodyManager::dectect_collision(entt::registry& registry) {
auto player_view = registry.view<const Player, v::Position>();
float radius = 50;
auto player_entity = player_view.front();
if (player_entity == entt::null) return false;
auto player_head_position = player_view.get<v::Position>(player_entity);
for (auto body_part_position : parts_position_stack) {
float x = abs(player_head_position.x - body_part_position.x);
float y = abs(player_head_position.y - body_part_position.y);
float distance = x*x + y*y;
if (distance < (radius * radius)) {
return true;
}
}
return false;
}
void BodyManager::update_body_positions(entt::registry& registry) {
for (int i = 0; i < body_parts.size() ;i++) {
auto body_part = body_parts[i];
auto& body_pos = registry.get<v::Position>(body_part);
auto new_pos = parts_position_stack[i];
body_pos.x = new_pos.x;
body_pos.y = new_pos.y;
}
}
void update_body_system(entt::registry& registry){
auto& body_manager = v::ServiceLocator::get<BodyManager>();
auto player_view = registry.view<const Player, v::Position>();
auto player_entity = player_view.front();
if (player_entity == entt::null) return;
body_manager.update_body_positions(player_view.get<v::Position>(player_entity));
auto body_view = registry.view<const PlayerBody, v::Position>();
body_view.each([&body_manager](const auto entity, const PlayerBody& pb, v::Position& pos){
auto new_pos = body_manager.get_body_position(pb.idx);
pos.x = new_pos.x;
pos.y = new_pos.y;
});
body_manager.update_body_positions(registry);
}
+4 -1
View File
@@ -11,6 +11,7 @@ namespace v = varicle;
class BodyManager{
private:
std::vector<v::Position> parts_position_stack = {};
std::vector<entt::entity> body_parts = {};
public:
Texture* body_texture;
BodyManager() = default;
@@ -19,8 +20,10 @@ class BodyManager{
void add_body(entt::registry& registry);
void pop_body();
void update_body_positions(v::Position player_head_position);
void update_body_positions(entt::registry& registry);
bool dectect_collision(entt::registry& registry);
v::Position get_body_position(unsigned int part_idx);
};
void create_body(entt::registry& registry,unsigned int idx);
entt::entity create_body(entt::registry& registry,unsigned int idx);
void update_body_system(entt::registry& registry);
@@ -43,6 +43,11 @@ void MainScene::update(float dt) {
tick_timer -= TICK_INTERVAL;
update_body_system(registry);
update_movement_system(registry,dt);
auto bm = v::ServiceLocator::get<BodyManager>();
if (bm.dectect_collision(registry)) {
v::ServiceLocator::get<v::SceneManager>().switch_to_scene("game-over");
}
}
}
+16 -2
View File
@@ -3,6 +3,7 @@
#include "engine/core/service-locator.hpp"
#include "engine/asset/raylib-asset.hpp"
#include "game/ecs/components.hpp"
#include "raylib.h"
#include <entt/entt.hpp>
@@ -27,10 +28,10 @@ void create_player(entt::registry &registry){
void update_player_system(entt::registry& registry,float dt){
using namespace varicle;
auto view = registry.view<const Position,Velocity,Sprite>();
auto view = registry.view<Position,Velocity,Sprite>();
// for (entt::entity entity : view){
view.each([](const auto entity, const Position& pos, Velocity& vel, Sprite& sprite){
view.each([](const auto entity, Position& pos, Velocity& vel, Sprite& sprite){
if (IsKeyPressed(KEY_W) && vel.dy <= 0.0f){
@@ -52,6 +53,19 @@ void update_player_system(entt::registry& registry,float dt){
float radians = std::atan2(vel.dy, vel.dx);
sprite.rotation = radians * (180.0f / 3.14159265f);
}
if (pos.x > GetScreenWidth()) {
pos.x = 45;
} else if (pos.x < 0) {
pos.x = GetScreenWidth() - 45;
}
if (pos.y > GetScreenHeight()) {
pos.y = 45;
} else if (pos.y < 0) {
pos.y = GetScreenHeight() - 45;
}
});
}