Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d307bd5dbe |
@@ -8,7 +8,7 @@ Size=1280,800
|
||||
Collapsed=1
|
||||
|
||||
[Window][VBoxContainer]
|
||||
Pos=540,275
|
||||
Pos=540,235
|
||||
Size=200,250
|
||||
|
||||
[Window][Box]
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace varicle {
|
||||
scene_manager.render();
|
||||
|
||||
rlImGuiBegin();
|
||||
scene_manager.ui();
|
||||
rlImGuiEnd();
|
||||
|
||||
EndDrawing();
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
#pragma once
|
||||
#include <variant>
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
#include <iostream>
|
||||
|
||||
struct Vec2 {
|
||||
float x = 0.0f;
|
||||
float y = 0.0f;
|
||||
|
||||
bool operator==(const Vec2& o) const { return x == o.x && y == o.y; }
|
||||
bool operator!=(const Vec2& o) const { return !(*this == o); }
|
||||
Vec2 operator+(const Vec2& o) const { return { x + o.x, y + o.y }; }
|
||||
Vec2 operator-(const Vec2& o) const { return { x - o.x, y - o.y }; }
|
||||
Vec2 operator*(float scalar) const { return { x * scalar, y * scalar }; }
|
||||
};
|
||||
|
||||
struct Vec3 {
|
||||
float x = 0.0f;
|
||||
float y = 0.0f;
|
||||
float z = 0.0f;
|
||||
|
||||
bool operator==(const Vec3& o) const { return x == o.x && y == o.y && z == o.z; }
|
||||
bool operator!=(const Vec3& o) const { return !(*this == o); }
|
||||
Vec3 operator+(const Vec3& o) const { return { x + o.x, y + o.y, z + o.z }; }
|
||||
Vec3 operator-(const Vec3& o) const { return { x - o.x, y - o.y, z - o.z }; }
|
||||
Vec3 operator*(float scalar) const { return { x * scalar, y * scalar, z * scalar }; }
|
||||
};
|
||||
|
||||
struct Vec4 {
|
||||
float x = 0.0f;
|
||||
float y = 0.0f;
|
||||
float z = 0.0f;
|
||||
float w = 1.0f;
|
||||
|
||||
bool operator==(const Vec4& o) const { return x == o.x && y == o.y && z == o.z && w == o.w; }
|
||||
bool operator!=(const Vec4& o) const { return !(*this == o); }
|
||||
Vec4 operator+(const Vec4& o) const { return { x + o.x, y + o.y, z + o.z, w + o.w }; }
|
||||
Vec4 operator-(const Vec4& o) const { return { x - o.x, y - o.y, z - o.z, w - o.w }; }
|
||||
Vec4 operator*(float scalar) const { return { x * scalar, y * scalar, z * scalar, w * scalar }; }
|
||||
};
|
||||
|
||||
|
||||
// Standalone Interpolation Helpers
|
||||
inline Vec2 Vec2Lerp(const Vec2& s, const Vec2& e, float a) { return { s.x + (e.x - s.x) * a, s.y + (e.y - s.y) * a }; }
|
||||
inline Vec3 Vec3Lerp(const Vec3& s, const Vec3& e, float a) { return { s.x + (e.x - s.x) * a, s.y + (e.y - s.y) * a, s.z + (e.z - s.z) * a }; }
|
||||
inline Vec4 Vec4Lerp(const Vec4& s, const Vec4& e, float a) { return { s.x + (e.x - s.x) * a, s.y + (e.y - s.y) * a, s.z + (e.z - s.z) * a, s.w + (e.w - s.w) * a }; }
|
||||
|
||||
|
||||
|
||||
|
||||
enum class VariantType { Null, Float, Vector2, Vector3, Vector4, String };
|
||||
|
||||
class EngineVariant{
|
||||
|
||||
public:
|
||||
using InternalVariant = std::variant<std::monostate,float,Vec2,Vec3,Vec4,std::string>;
|
||||
|
||||
EngineVariant() : data(std::monostate{}), type(VariantType::Null){}
|
||||
EngineVariant(float v) : data(v), type(VariantType::Float){}
|
||||
EngineVariant(Vec2 v) : data(v), type(VariantType::Vector2){}
|
||||
EngineVariant(Vec3 v) : data(v), type(VariantType::Vector3){}
|
||||
EngineVariant(Vec4 v) : data(v), type(VariantType::Vector4){}
|
||||
EngineVariant(std::string v) : data(v), type(VariantType::String){}
|
||||
|
||||
VariantType GetType() const { return type; }
|
||||
|
||||
template<typename T>
|
||||
T Get() const {
|
||||
std::lock_guard<std::mutex> lock(v_mutex);
|
||||
return std::get<T>(data);
|
||||
}
|
||||
|
||||
void Print() const {
|
||||
|
||||
std::lock_guard<std::mutex> lock(v_mutex);
|
||||
std::cout << "[Variant " << TypeToString(type) << "]: ";
|
||||
std::visit([](auto &&arg){
|
||||
using T = std::decay_t<decltype(arg)>;
|
||||
if constexpr (std::is_same_v<T, std::monostate>) std::cout << "Null";
|
||||
else if constexpr (std::is_same_v<T, float>) std::cout << arg;
|
||||
else if constexpr (std::is_same_v<T, Vec2>) std::cout << "(" << arg.x << ", " << arg.y << ")";
|
||||
else if constexpr (std::is_same_v<T, Vec3>) std::cout << "(" << arg.x << ", " << arg.y << ", " << arg.z << ")";
|
||||
else if constexpr (std::is_same_v<T, Vec4>) std::cout << "(" << arg.x << ", " << arg.y << ", " << arg.z << ", " << arg.w << ")";
|
||||
else if constexpr (std::is_same_v<T, std::string>) std::cout << "\"" << arg << "\"";
|
||||
|
||||
},data);
|
||||
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
private:
|
||||
InternalVariant data;
|
||||
VariantType type;
|
||||
mutable std::mutex v_mutex;
|
||||
|
||||
static std::string TypeToString(VariantType t) {
|
||||
switch(t) {
|
||||
case VariantType::Float: return "Float";
|
||||
case VariantType::Vector2: return "Vector2";
|
||||
case VariantType::Vector3: return "Vector3";
|
||||
case VariantType::Vector4: return "Vector4";
|
||||
case VariantType::String: return "String";
|
||||
default: return "Null";
|
||||
}
|
||||
}
|
||||
|
||||
friend class VariantOpManager;
|
||||
};
|
||||
@@ -0,0 +1,74 @@
|
||||
#pragma once
|
||||
|
||||
#include <engine_variant.hpp>
|
||||
|
||||
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
|
||||
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
|
||||
|
||||
enum class OpType {
|
||||
Assign, // Replace the old value entirely
|
||||
Add, // Add to the current value
|
||||
Multiply, // Add to the current value
|
||||
Lerp // Smoothly blend toward a value
|
||||
};
|
||||
|
||||
struct VariantOpRequest {
|
||||
EngineVariant* target; // The variable we want to change
|
||||
OpType operation; // How we want to change it
|
||||
EngineVariant operand; // The value we are using to make the change
|
||||
float alpha; // Used ONLY for Lerp (0.0 to 1.0)
|
||||
};
|
||||
|
||||
class VariantOpManager{
|
||||
|
||||
public:
|
||||
VariantOpManager(){}
|
||||
void ExecuteOperation(const VariantOpRequest& req) {
|
||||
|
||||
if (req.target == nullptr) return;
|
||||
|
||||
switch (req.operation){
|
||||
|
||||
case OpType::Assign:
|
||||
req.target->data = req.operand.data;
|
||||
req.target->type = req.operand.type;
|
||||
break;
|
||||
case OpType::Add:
|
||||
req.target->data = std::visit(
|
||||
overloaded{
|
||||
[](float p, float n) -> EngineVariant::InternalVariant {return p + n;},
|
||||
[](Vec2 p, Vec2 n) -> EngineVariant::InternalVariant {return p + n;},
|
||||
[](Vec3 p, Vec3 n) -> EngineVariant::InternalVariant {return p + n;},
|
||||
[](Vec4 p, Vec4 n) -> EngineVariant::InternalVariant {return p + n;},
|
||||
|
||||
// Fallback
|
||||
[](auto p, auto n) -> EngineVariant::InternalVariant {return p;},
|
||||
},req.target->data,req.operand.data);
|
||||
break;
|
||||
|
||||
case OpType::Lerp:
|
||||
req.target->data = std::visit(overloaded{
|
||||
[&](float p, float n) -> EngineVariant::InternalVariant { return p + (n - p) * req.alpha; },
|
||||
[&](Vec2 p, Vec2 n) -> EngineVariant::InternalVariant { return Vec2Lerp(p, n, req.alpha); },
|
||||
[&](Vec3 p, Vec3 n) -> EngineVariant::InternalVariant { return Vec3Lerp(p, n, req.alpha); },
|
||||
[&](Vec4 p, Vec4 n) -> EngineVariant::InternalVariant { return Vec4Lerp(p, n, req.alpha); },
|
||||
[&](const std::string& p, const std::string& n) -> EngineVariant::InternalVariant {
|
||||
return req.alpha >= 0.5f ? n : p; // Discrete switch for strings
|
||||
},
|
||||
|
||||
// Fallback
|
||||
[](auto p, auto n) -> EngineVariant::InternalVariant { return p; }
|
||||
}, req.target->data, req.operand.data);
|
||||
break;
|
||||
|
||||
case OpType::Multiply:
|
||||
req.target->data = std::visit(overloaded{
|
||||
[](float p, float n) -> EngineVariant::InternalVariant { return p * n; },
|
||||
[](Vec2 p, float n) -> EngineVariant::InternalVariant { return p * n; }, // Scale a vector!
|
||||
[](auto p, auto n) -> EngineVariant::InternalVariant { return p; }
|
||||
}, req.target->data, req.operand.data);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
@@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include<vector>
|
||||
#include<algorithm>
|
||||
#include <memory>
|
||||
#include <typeindex>
|
||||
#include <unordered_map>
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <raylib.h>
|
||||
|
||||
namespace varicle{
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <random>
|
||||
|
||||
|
||||
namespace varicle {
|
||||
// Generate a random float between min and max
|
||||
inline float RandomRange(float min, float max) {
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
std::uniform_real_distribution<float> dist(min, max);
|
||||
return dist(gen);
|
||||
}
|
||||
|
||||
// Generate a random int between min and max
|
||||
inline int RandomRange(int min, int max) {
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
std::uniform_int_distribution<int> dist(min, max);
|
||||
return dist(gen);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
struct Player{};
|
||||
struct PlayerBody{ unsigned int idx;};
|
||||
|
||||
struct Fruit{};
|
||||
|
||||
|
||||
+4
-1
@@ -4,6 +4,7 @@
|
||||
#include "engine/scene/scene.hpp"
|
||||
|
||||
#include "game/scenes/main-scene/main-scene.hpp"
|
||||
#include "game/scenes/menu-scene/menu.hpp"
|
||||
|
||||
#include <raylib.h>
|
||||
|
||||
@@ -14,7 +15,9 @@ class Game : public varicle::Application{
|
||||
public:
|
||||
void on_init() override {
|
||||
auto& scene_manager = varicle::ServiceLocator::get<varicle::SceneManager>();
|
||||
scene_manager.register_scene("menu", []() { return std::make_unique<MainScene>(); });
|
||||
scene_manager.register_scene("main", []() { return std::make_unique<MainScene>(); });
|
||||
|
||||
scene_manager.register_scene("menu", []() { return std::make_unique<MenuScene>(); });
|
||||
|
||||
change_scene("menu");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
|
||||
#include "body.hpp"
|
||||
|
||||
#include "engine/ecs/components.hpp"
|
||||
#include "game/ecs/components.hpp"
|
||||
#include "engine/asset/raylib-asset.hpp"
|
||||
#include "engine/core/service-locator.hpp"
|
||||
|
||||
#include <raylib.h>
|
||||
#include <entt/entt.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace v = varicle;
|
||||
|
||||
void create_body(entt::registry& registry,unsigned int idx){
|
||||
auto& asset_loader = v::ServiceLocator::get<v::RaylibAssetLoader>();
|
||||
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);
|
||||
}
|
||||
|
||||
void BodyManager::add_body(entt::registry& registry)
|
||||
{
|
||||
create_body(registry,parts_position_stack.size());
|
||||
parts_position_stack.push_back( v::Position{});
|
||||
}
|
||||
|
||||
void BodyManager::pop_body(){
|
||||
parts_position_stack.pop_back();
|
||||
}
|
||||
|
||||
void BodyManager::update_body_positions(v::Position player_head_position){
|
||||
if (parts_position_stack.size() >= 2){
|
||||
for ( auto i = parts_position_stack.size()-1; i > 0 ;i--){
|
||||
parts_position_stack[i] = parts_position_stack[i-1];
|
||||
}
|
||||
}
|
||||
|
||||
if (parts_position_stack.size() >= 1){
|
||||
parts_position_stack[0] = player_head_position;
|
||||
}
|
||||
}
|
||||
|
||||
v::Position BodyManager::get_body_position(unsigned int part_idx){
|
||||
return parts_position_stack[part_idx];
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
// #include "game/ecs/components.hpp"
|
||||
#include "engine/ecs/components.hpp"
|
||||
|
||||
#include <raylib.h>
|
||||
#include <entt/entt.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace v = varicle;
|
||||
class BodyManager{
|
||||
private:
|
||||
std::vector<v::Position> parts_position_stack = {};
|
||||
public:
|
||||
Texture* body_texture;
|
||||
BodyManager() = default;
|
||||
~BodyManager() = default;
|
||||
|
||||
void add_body(entt::registry& registry);
|
||||
void pop_body();
|
||||
void update_body_positions(v::Position player_head_position);
|
||||
v::Position get_body_position(unsigned int part_idx);
|
||||
};
|
||||
|
||||
void create_body(entt::registry& registry,unsigned int idx);
|
||||
void update_body_system(entt::registry& registry);
|
||||
@@ -0,0 +1,57 @@
|
||||
#include "game/ecs/components.hpp"
|
||||
#include "body.hpp"
|
||||
#include "score-system.hpp"
|
||||
|
||||
#include "engine/ecs/components.hpp"
|
||||
#include "engine/util/math_util.hpp"
|
||||
#include "engine/asset/raylib-asset.hpp"
|
||||
#include "engine/core/service-locator.hpp"
|
||||
|
||||
#include <raylib.h>
|
||||
#include <entt/entt.hpp>
|
||||
|
||||
namespace v = varicle ;
|
||||
|
||||
void create_fruit(entt::registry& registry){
|
||||
auto& asset_loader = v::ServiceLocator::get<v::RaylibAssetLoader>();
|
||||
auto fruit_texture = asset_loader.get_texture("assets/fruit.png");
|
||||
|
||||
const auto entity = registry.create();
|
||||
registry.emplace<v::Position>(entity,640.0f,400.0f);
|
||||
registry.emplace<v::Sprite>(entity,fruit_texture,0.0f,0.0f,30.f,30.0f,false,false,0.0f);
|
||||
registry.emplace<Fruit>(entity);
|
||||
}
|
||||
|
||||
v::Position get_player_position(entt::registry& registry){
|
||||
auto player_view = registry.view<const Player>();
|
||||
if (player_view.empty()) return {};
|
||||
|
||||
entt::entity player_entity = player_view.front();
|
||||
return registry.get<v::Position>(player_entity);
|
||||
}
|
||||
|
||||
void change_position(v::Position& pos){
|
||||
pos.x = varicle::RandomRange(30, GetScreenWidth()-30);
|
||||
pos.y = varicle::RandomRange(30, GetScreenHeight()-30);
|
||||
};
|
||||
|
||||
|
||||
void update_fruit_system(entt::registry& registry,float dt){
|
||||
|
||||
auto view = registry.view<const Fruit, v::Position>();
|
||||
const v::Position player_pos = get_player_position(registry);
|
||||
|
||||
for (entt::entity entity : view){
|
||||
v::Position& pos = view.get<v::Position>(entity);
|
||||
if (abs(pos.x - player_pos.x) < 35 && abs(pos.y - player_pos.y) < 35 ){
|
||||
|
||||
auto& score_system = v::ServiceLocator::get<ScoreSystem>();
|
||||
auto& body_manager = v::ServiceLocator::get<BodyManager>();
|
||||
body_manager.add_body(registry);
|
||||
score_system.add_points(1);
|
||||
|
||||
change_position(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <raylib.h>
|
||||
#include <entt/entt.hpp>
|
||||
|
||||
void create_fruit(entt::registry& registry);
|
||||
void update_fruit_system(entt::registry& registry,float dt);
|
||||
@@ -1,58 +1,63 @@
|
||||
#include "main-scene.hpp"
|
||||
#include "fruit.hpp"
|
||||
#include "player.hpp"
|
||||
#include "body.hpp"
|
||||
|
||||
#include "score-system.hpp"
|
||||
|
||||
#include "engine/asset/raylib-asset.hpp"
|
||||
#include "engine/core/service-locator.hpp"
|
||||
#include "engine/render/render-system.hpp"
|
||||
#include "engine/ecs/components.hpp"
|
||||
#include "game/ecs/components.hpp"
|
||||
#include "raylib.h"
|
||||
|
||||
#include <raylib.h>
|
||||
#include <entt/entt.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <format>
|
||||
|
||||
const float TICK_INTERVAL = 0.2f;
|
||||
|
||||
namespace v = varicle;
|
||||
|
||||
const float SPEED = 300.0f;
|
||||
|
||||
void create_player(entt::registry ®istry);
|
||||
void update_player_system(entt::registry& registry,float dt);
|
||||
void update_movement_system(entt::registry& registry, float dt);
|
||||
|
||||
void MainScene::init() {
|
||||
v::ServiceLocator::provide(std::make_unique<ScoreSystem>());
|
||||
v::ServiceLocator::provide(std::make_unique<BodyManager>());
|
||||
|
||||
auto& asset_loader = v::ServiceLocator::get<v::RaylibAssetLoader>();
|
||||
asset_loader.load_asset("assets/snake_head.png");
|
||||
asset_loader.load_asset("assets/snake_body.png");
|
||||
asset_loader.load_asset("assets/fruit.png");
|
||||
|
||||
create_player(registry);
|
||||
create_fruit(registry);
|
||||
}
|
||||
|
||||
void MainScene::update(float dt) {
|
||||
update_player_system(registry,dt);
|
||||
update_movement_system(registry,dt);
|
||||
update_fruit_system(registry, dt);
|
||||
|
||||
tick_timer += dt;
|
||||
if (tick_timer >= TICK_INTERVAL) {
|
||||
tick_timer -= TICK_INTERVAL;
|
||||
update_body_system(registry);
|
||||
update_movement_system(registry,dt);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void MainScene::render() {
|
||||
v::update_render_system(registry);
|
||||
|
||||
auto& score_system = v::ServiceLocator::get<ScoreSystem>();
|
||||
DrawText(std::format("Score: {}",score_system.get_current_score()).c_str(),40,40,24,BLACK);
|
||||
}
|
||||
|
||||
void MainScene::ui() {
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////
|
||||
|
||||
void create_player(entt::registry ®istry){
|
||||
using namespace v;
|
||||
|
||||
auto& asset_loader = ServiceLocator::get<RaylibAssetLoader>();
|
||||
auto player_texture = asset_loader.get_texture("assets/snake_head.png");
|
||||
|
||||
const auto entity = registry.create();
|
||||
registry.emplace<Position>(entity,100.0f,100.0f);
|
||||
registry.emplace<Velocity>(entity,SPEED,0.0f);
|
||||
registry.emplace<Sprite>(entity,player_texture,0.0f,0.0f,70.0f,70.0f,false,false,0.0f);
|
||||
registry.emplace<Player>(entity);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void update_movement_system(entt::registry& registry, float dt) {
|
||||
using namespace varicle;
|
||||
|
||||
@@ -61,40 +66,8 @@ void update_movement_system(entt::registry& registry, float dt) {
|
||||
|
||||
view.each([dt](Position &position, Velocity &velocity) {
|
||||
// This will only run for pipes, enemies, or particles!
|
||||
position.x += velocity.dx * dt;
|
||||
position.y += velocity.dy * dt;
|
||||
position.x += velocity.dx;
|
||||
position.y += velocity.dy;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void update_player_system(entt::registry& registry,float dt){
|
||||
using namespace varicle;
|
||||
|
||||
auto view = registry.view<const Position,Velocity,Sprite>();
|
||||
|
||||
// for (entt::entity entity : view){
|
||||
view.each([](const auto entity, const Position& pos, Velocity& vel, Sprite& sprite){
|
||||
|
||||
|
||||
if (IsKeyPressed(KEY_W) && vel.dy <= 0.0f){
|
||||
vel.dx = 0;
|
||||
vel.dy = -SPEED;
|
||||
} else if (IsKeyPressed(KEY_S) && vel.dy >= 0.0f){
|
||||
vel.dx = 0;
|
||||
vel.dy = SPEED;
|
||||
} else if (IsKeyPressed(KEY_A) && vel.dx <= 0.0f){
|
||||
vel.dx = -SPEED;
|
||||
vel.dy = 0;
|
||||
} else if (IsKeyPressed(KEY_D) && vel.dx >= 0.0f){
|
||||
vel.dx = SPEED;
|
||||
vel.dy = 0;
|
||||
}
|
||||
|
||||
if (vel.dx != 0.0f || vel.dy != 0.0f) {
|
||||
// atan2 returns radians. Convert to degrees if your renderer expects it!
|
||||
float radians = std::atan2(vel.dy, vel.dx);
|
||||
sprite.rotation = radians * (180.0f / 3.14159265f);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "engine/scene/scene.hpp"
|
||||
|
||||
#include <entt/entt.hpp>
|
||||
@@ -5,6 +7,7 @@
|
||||
class MainScene : public varicle::Scene {
|
||||
private:
|
||||
entt::registry registry;
|
||||
float tick_timer = 0.0f;
|
||||
|
||||
public:
|
||||
void init() override;
|
||||
@@ -13,3 +16,5 @@ class MainScene : public varicle::Scene {
|
||||
void ui() override ;
|
||||
};
|
||||
|
||||
void update_movement_system(entt::registry& registry, float dt);
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
|
||||
#include "engine/ecs/components.hpp"
|
||||
#include "engine/core/service-locator.hpp"
|
||||
#include "engine/asset/raylib-asset.hpp"
|
||||
#include "game/ecs/components.hpp"
|
||||
|
||||
#include <entt/entt.hpp>
|
||||
|
||||
const float SPEED = 60.0f;
|
||||
|
||||
void create_player(entt::registry ®istry){
|
||||
using namespace varicle;
|
||||
|
||||
auto& asset_loader = ServiceLocator::get<RaylibAssetLoader>();
|
||||
auto player_texture = asset_loader.get_texture("assets/snake_head.png");
|
||||
|
||||
const auto entity = registry.create();
|
||||
registry.emplace<Position>(entity,100.0f,100.0f);
|
||||
registry.emplace<Velocity>(entity,SPEED,0.0f);
|
||||
registry.emplace<Sprite>(entity,player_texture,0.0f,0.0f,70.0f,70.0f,false,false,0.0f);
|
||||
registry.emplace<Player>(entity);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void update_player_system(entt::registry& registry,float dt){
|
||||
using namespace varicle;
|
||||
|
||||
auto view = registry.view<const Position,Velocity,Sprite>();
|
||||
|
||||
// for (entt::entity entity : view){
|
||||
view.each([](const auto entity, const Position& pos, Velocity& vel, Sprite& sprite){
|
||||
|
||||
|
||||
if (IsKeyPressed(KEY_W) && vel.dy <= 0.0f){
|
||||
vel.dx = 0;
|
||||
vel.dy = -SPEED;
|
||||
} else if (IsKeyPressed(KEY_S) && vel.dy >= 0.0f){
|
||||
vel.dx = 0;
|
||||
vel.dy = SPEED;
|
||||
} else if (IsKeyPressed(KEY_A) && vel.dx <= 0.0f){
|
||||
vel.dx = -SPEED;
|
||||
vel.dy = 0;
|
||||
} else if (IsKeyPressed(KEY_D) && vel.dx >= 0.0f){
|
||||
vel.dx = SPEED;
|
||||
vel.dy = 0;
|
||||
}
|
||||
|
||||
if (vel.dx != 0.0f || vel.dy != 0.0f) {
|
||||
// atan2 returns radians. Convert to degrees if your renderer expects it!
|
||||
float radians = std::atan2(vel.dy, vel.dx);
|
||||
sprite.rotation = radians * (180.0f / 3.14159265f);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <entt/entt.hpp>
|
||||
|
||||
void create_player(entt::registry ®istry);
|
||||
void update_player_system(entt::registry& registry,float dt);
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
class ScoreSystem{
|
||||
private:
|
||||
unsigned int current_score;
|
||||
unsigned int high_score;
|
||||
|
||||
public:
|
||||
ScoreSystem() :current_score(0), high_score(0){}
|
||||
int get_current_score(){return current_score;}
|
||||
int get_high_score(){return high_score;}
|
||||
void reset_score(){current_score = 0;}
|
||||
void reset_high_score(){high_score = 0;}
|
||||
void add_points(unsigned int points){ current_score +=points;}
|
||||
};
|
||||
@@ -0,0 +1,54 @@
|
||||
#include "menu.hpp"
|
||||
|
||||
#include "engine/core/service-locator.hpp"
|
||||
#include "raylib.h"
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
void MenuScene::init() {}
|
||||
|
||||
void MenuScene::update(float dt) {
|
||||
}
|
||||
|
||||
void MenuScene::render() {
|
||||
}
|
||||
|
||||
void MenuScene::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",button_size)){
|
||||
v::ServiceLocator::get<v::SceneManager>().switch_to_scene("main");
|
||||
}
|
||||
|
||||
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 MenuScene : public v::Scene{
|
||||
public:
|
||||
void init() override;
|
||||
void update(float dt) override;
|
||||
void render() override;
|
||||
void ui() override ;
|
||||
};
|
||||
Reference in New Issue
Block a user