Compare commits
2 Commits
d7a6689cf5
...
f62614191f
Author | SHA1 | Date |
---|---|---|
bog | f62614191f | |
bog | b605d7393d |
|
@ -31,9 +31,13 @@ executable(
|
|||
'src/ECS.cpp',
|
||||
'src/BaseComponent.cpp',
|
||||
'src/BaseSystem.cpp',
|
||||
'src/EntityFactory.cpp',
|
||||
|
||||
# systems
|
||||
'src/sys/BodySystem.cpp',
|
||||
'src/sys/ActorSystem.cpp',
|
||||
'src/sys/PlayerSystem.cpp',
|
||||
'src/sys/AnimationSystem.cpp',
|
||||
|
||||
# arena
|
||||
'src/arena/Arena.cpp',
|
||||
|
@ -43,6 +47,9 @@ executable(
|
|||
'src/gfx/Shaders.cpp',
|
||||
'src/gfx/Canvas.cpp',
|
||||
'src/gfx/Texture.cpp',
|
||||
|
||||
# input
|
||||
'src/input/Joystick.cpp',
|
||||
],
|
||||
dependencies: [
|
||||
dependency('glew'),
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
#include "EntityFactory.hpp"
|
||||
#include "comps/BodyC.hpp"
|
||||
#include "comps/SpriteC.hpp"
|
||||
#include "comps/PlayerC.hpp"
|
||||
#include "comps/AnimationC.hpp"
|
||||
|
||||
namespace rid
|
||||
{
|
||||
/*explicit*/ EntityFactory::EntityFactory(ECS& ecs)
|
||||
: m_ecs { ecs }
|
||||
{
|
||||
}
|
||||
|
||||
/*virtual*/ EntityFactory::~EntityFactory()
|
||||
{
|
||||
}
|
||||
|
||||
size_t EntityFactory::create_actor(float x, float y)
|
||||
{
|
||||
size_t e = m_ecs.create_entity();
|
||||
m_ecs.attach_component<BodyC>(e, glm::vec2 {x, y});
|
||||
m_ecs.attach_component<SpriteC>(e, Frame {0, 0, 32, 32}, glm::vec2 {96, 96});
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
size_t EntityFactory::create_player(int controller, float x, float y)
|
||||
{
|
||||
size_t e = create_actor(x, y);
|
||||
m_ecs.attach_component<PlayerC>(e, controller);
|
||||
m_ecs.attach_component<AnimationC>(e, 0.1f, 4);
|
||||
|
||||
return e;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef rid_ENTITYFACTORY_HPP
|
||||
#define rid_ENTITYFACTORY_HPP
|
||||
|
||||
#include "conf.hpp"
|
||||
#include "ECS.hpp"
|
||||
|
||||
namespace rid
|
||||
{
|
||||
class EntityFactory
|
||||
{
|
||||
public:
|
||||
explicit EntityFactory(ECS& ecs);
|
||||
virtual ~EntityFactory();
|
||||
|
||||
size_t create_actor(float x, float y);
|
||||
size_t create_player(int controller, float x, float y);
|
||||
|
||||
private:
|
||||
ECS& m_ecs;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,14 +1,20 @@
|
|||
#include "Arena.hpp"
|
||||
#include "conf.hpp"
|
||||
#include "../EntityFactory.hpp"
|
||||
|
||||
// Components
|
||||
// ----------
|
||||
#include "../comps/BodyC.hpp"
|
||||
#include "../comps/SpriteC.hpp"
|
||||
#include "../comps/PlayerC.hpp"
|
||||
#include "../comps/AnimationC.hpp"
|
||||
|
||||
// Systems
|
||||
// -------
|
||||
|
||||
#include "../sys/BodySystem.hpp"
|
||||
#include "../sys/ActorSystem.hpp"
|
||||
#include "../sys/PlayerSystem.hpp"
|
||||
#include "../sys/AnimationSystem.hpp"
|
||||
|
||||
namespace rid
|
||||
{
|
||||
|
@ -16,9 +22,12 @@ namespace rid
|
|||
: BaseScene(game)
|
||||
{
|
||||
m_ecs.add_system<BodyC>(std::make_unique<BodySystem>());
|
||||
m_ecs.add_system<BodyC, SpriteC>(std::make_unique<ActorSystem>());
|
||||
m_ecs.add_system<PlayerC, BodyC>(std::make_unique<PlayerSystem>());
|
||||
m_ecs.add_system<SpriteC, AnimationC, BodyC>(std::make_unique<AnimationSystem>());
|
||||
|
||||
m_ecs.attach_component<BodyC>(m_ecs.create_entity(), glm::vec2 {64.f, 64.f}, glm::vec2 {64.f, 64.f});
|
||||
m_ecs.attach_component<BodyC>(m_ecs.create_entity(), glm::vec2 {640.f, 640.f}, glm::vec2 {128.f, 300.f});
|
||||
EntityFactory factory {m_ecs};
|
||||
factory.create_player(0, 512.f, 512.f);
|
||||
}
|
||||
|
||||
/*virtual*/ Arena::~Arena()
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef rid_ANIMATIONC_HPP
|
||||
#define rid_ANIMATIONC_HPP
|
||||
|
||||
#include "conf.hpp"
|
||||
#include "../BaseComponent.hpp"
|
||||
|
||||
namespace rid
|
||||
{
|
||||
struct AnimationC: public BaseComponent
|
||||
{
|
||||
float time;
|
||||
float timer = 0.0f;
|
||||
|
||||
size_t duration;
|
||||
size_t current = 0;
|
||||
|
||||
explicit AnimationC(float _time, size_t _duration)
|
||||
: time { _time }
|
||||
, duration { _duration }
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -9,11 +9,13 @@ namespace rid
|
|||
struct BodyC: public BaseComponent
|
||||
{
|
||||
glm::vec2 pos;
|
||||
glm::vec2 size;
|
||||
glm::vec2 vel { 0.f, 0.f };
|
||||
glm::vec2 heading = { 0.f, -1.f};
|
||||
glm::vec2 side = {-heading.y, heading.x};
|
||||
float max_speed = 256.f;
|
||||
|
||||
explicit BodyC(glm::vec2 _pos, glm::vec2 _size)
|
||||
explicit BodyC(glm::vec2 _pos)
|
||||
: pos { _pos }
|
||||
, size { _size }
|
||||
{
|
||||
}
|
||||
};
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef rid_PLAYERC_HPP
|
||||
#define rid_PLAYERC_HPP
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include "conf.hpp"
|
||||
#include "../BaseComponent.hpp"
|
||||
#include "../input/Joystick.hpp"
|
||||
|
||||
namespace rid
|
||||
{
|
||||
RID_ERROR(player_error);
|
||||
|
||||
struct PlayerC: public BaseComponent
|
||||
{
|
||||
std::unique_ptr<Joystick> joystick;
|
||||
|
||||
explicit PlayerC(int _index)
|
||||
: joystick { std::make_unique<Joystick>(_index) }
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~PlayerC()
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef rid_SPRITEC_HPP
|
||||
#define rid_SPRITEC_HPP
|
||||
|
||||
#include "conf.hpp"
|
||||
#include "../BaseComponent.hpp"
|
||||
#include "../gfx/Texture.hpp"
|
||||
|
||||
namespace rid
|
||||
{
|
||||
struct Frame
|
||||
{
|
||||
Frame(int _x, int _y, int _w, int _h)
|
||||
: x { _x }
|
||||
, y { _y }
|
||||
, w { _w }
|
||||
, h { _h }
|
||||
{
|
||||
}
|
||||
|
||||
int x;
|
||||
int y;
|
||||
int w;
|
||||
int h;
|
||||
};
|
||||
|
||||
struct SpriteC: public BaseComponent
|
||||
{
|
||||
Frame frame;
|
||||
glm::vec2 size;
|
||||
|
||||
explicit SpriteC(Frame _frame, glm::vec2 _size)
|
||||
: frame { _frame }
|
||||
, size { _size }
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -5,6 +5,8 @@
|
|||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
#include <optional>
|
||||
#include <unordered_map>
|
||||
#include <filesystem>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
|
|
@ -108,8 +108,8 @@ namespace rid
|
|||
use();
|
||||
m_shaders->set_mat4("proj", transform);
|
||||
|
||||
auto rot = glm::rotate(glm::mat4 {1.0f}, m_angle, glm::vec3 {0.f, 0.f, 1.f});
|
||||
auto loc = glm::translate(glm::mat4 {1.0f}, glm::vec3 {m_pos.x, m_pos.y, 0.f});
|
||||
auto rot = glm::rotate(glm::mat4 {1.0f}, m_angle, glm::vec3 {0.f, 0.f, 1.f});
|
||||
|
||||
m_shaders->set_mat4("model", loc * rot);
|
||||
glDrawArrays(GL_TRIANGLES, 0, m_vertices.size());
|
||||
|
|
|
@ -22,6 +22,9 @@ namespace rid
|
|||
|
||||
void move(glm::vec2 pos);
|
||||
void rotate(float rad);
|
||||
void set_pos(glm::vec2 pos) { m_pos = pos; }
|
||||
void set_angle(float rad) { m_angle = rad; }
|
||||
|
||||
|
||||
void set_texture(std::unique_ptr<Texture> texture);
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "Window.hpp"
|
||||
#include "SDL.h"
|
||||
#include "SDL_image.h"
|
||||
|
||||
namespace rid
|
||||
|
@ -7,7 +8,8 @@ namespace rid
|
|||
: m_width { width }
|
||||
, m_height { height }
|
||||
{
|
||||
if (SDL_Init(SDL_INIT_VIDEO) != 0)
|
||||
if (SDL_Init(SDL_INIT_VIDEO
|
||||
| SDL_INIT_GAMECONTROLLER) != 0)
|
||||
{
|
||||
throw display_error {"Cannot initialize SDL 2."};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
#include "Joystick.hpp"
|
||||
|
||||
namespace rid
|
||||
{
|
||||
/*explicit*/ Joystick::Joystick(int index)
|
||||
: m_controller { SDL_GameControllerOpen(index) }
|
||||
{
|
||||
if (!m_controller)
|
||||
{
|
||||
throw joystick_error {"Cannot open game controller '" + std::to_string(index) + "'."};
|
||||
}
|
||||
}
|
||||
|
||||
/*virtual*/ Joystick::~Joystick()
|
||||
{
|
||||
SDL_GameControllerClose(m_controller);
|
||||
}
|
||||
|
||||
bool Joystick::is_pressed(SDL_GameControllerButton btn) const
|
||||
{
|
||||
return SDL_GameControllerGetButton(m_controller, btn);
|
||||
}
|
||||
|
||||
bool Joystick::is_just_pressed(SDL_GameControllerButton btn) const
|
||||
{
|
||||
bool ok = is_pressed(btn);
|
||||
|
||||
if (m_prev_btn != ok)
|
||||
{
|
||||
m_prev_btn = ok;
|
||||
return ok;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
float Joystick::axis(SDL_GameControllerAxis axis) const
|
||||
{
|
||||
return SDL_GameControllerGetAxis(m_controller, axis) / 32767.0f;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef rid_JOYSTICK_HPP
|
||||
#define rid_JOYSTICK_HPP
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include "conf.hpp"
|
||||
|
||||
namespace rid
|
||||
{
|
||||
RID_ERROR(joystick_error);
|
||||
|
||||
class Joystick
|
||||
{
|
||||
public:
|
||||
explicit Joystick(int index);
|
||||
virtual ~Joystick();
|
||||
|
||||
bool is_pressed(SDL_GameControllerButton btn) const;
|
||||
bool is_just_pressed(SDL_GameControllerButton btn) const;
|
||||
|
||||
float axis(SDL_GameControllerAxis axis) const;
|
||||
|
||||
private:
|
||||
SDL_GameController* m_controller;
|
||||
mutable bool m_prev_btn = false;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,45 @@
|
|||
#include "ActorSystem.hpp"
|
||||
#include "../ECS.hpp"
|
||||
#include "../comps/SpriteC.hpp"
|
||||
#include "../comps/BodyC.hpp"
|
||||
|
||||
namespace rid
|
||||
{
|
||||
/*explicit*/ ActorSystem::ActorSystem()
|
||||
{
|
||||
auto texture = std::make_unique<Texture>();
|
||||
texture->load(RID_DATADIR / "assets" / "images" / "walk_0.png");
|
||||
|
||||
m_canvas.set_texture(std::move(texture));
|
||||
}
|
||||
|
||||
/*virtual*/ ActorSystem::~ActorSystem()
|
||||
{
|
||||
}
|
||||
|
||||
void ActorSystem::update(ECS&, std::vector<size_t> const&) /*override*/
|
||||
{
|
||||
}
|
||||
|
||||
void ActorSystem::draw(ECS& ecs, std::vector<size_t> const& entities) /*override*/
|
||||
{
|
||||
for (auto entity: entities)
|
||||
{
|
||||
m_canvas.clear();
|
||||
|
||||
auto const& body = ecs.getc<BodyC>(entity);
|
||||
auto const& sprite = ecs.getc<SpriteC>(entity);
|
||||
|
||||
m_canvas.draw_tex(glm::vec2 {0.f},
|
||||
glm::vec2 {sprite.size.x, sprite.size.y},
|
||||
glm::vec4 {1, 1, 1, 1},
|
||||
glm::vec2 {sprite.frame.x, sprite.frame.y},
|
||||
glm::vec2 {sprite.frame.w, sprite.frame.h});
|
||||
|
||||
m_canvas.set_pos(body.pos);
|
||||
m_canvas.set_angle(std::atan2(body.heading.y, body.heading.x) - M_PI / 2.0f);
|
||||
|
||||
ecs.window().draw(m_canvas);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef rid_ACTORSYSTEM_HPP
|
||||
#define rid_ACTORSYSTEM_HPP
|
||||
|
||||
#include "conf.hpp"
|
||||
#include "../gfx/Canvas.hpp"
|
||||
#include "../BaseSystem.hpp"
|
||||
|
||||
namespace rid
|
||||
{
|
||||
class ActorSystem: public BaseSystem
|
||||
{
|
||||
public:
|
||||
explicit ActorSystem();
|
||||
virtual ~ActorSystem();
|
||||
|
||||
void update(ECS& ecs, std::vector<size_t> const& entities) override;
|
||||
void draw(ECS& ecs, std::vector<size_t> const& entities) override;
|
||||
|
||||
private:
|
||||
Canvas m_canvas;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,46 @@
|
|||
#include "AnimationSystem.hpp"
|
||||
#include "../ECS.hpp"
|
||||
#include "../comps/AnimationC.hpp"
|
||||
#include "../comps/SpriteC.hpp"
|
||||
#include "../comps/BodyC.hpp"
|
||||
|
||||
namespace rid
|
||||
{
|
||||
/*explicit*/ AnimationSystem::AnimationSystem()
|
||||
: BaseSystem()
|
||||
{
|
||||
auto texture = std::make_unique<Texture>();
|
||||
texture->load(RID_DATADIR / "assets" / "images" / "walk_0.png");
|
||||
|
||||
m_canvas.set_texture(std::move(texture));
|
||||
}
|
||||
|
||||
/*virtual*/ AnimationSystem::~AnimationSystem()
|
||||
{
|
||||
}
|
||||
|
||||
void AnimationSystem::update(ECS& ecs, std::vector<size_t> const& entities) /*override*/
|
||||
{
|
||||
for (auto entity: entities)
|
||||
{
|
||||
auto& anim = ecs.getc<AnimationC>(entity);
|
||||
auto& sprite = ecs.getc<SpriteC>(entity);
|
||||
auto& body = ecs.getc<BodyC>(entity);
|
||||
|
||||
if (glm::length(body.vel) > 0.0f && anim.timer >= anim.time)
|
||||
{
|
||||
anim.current++;
|
||||
anim.current %= anim.duration;
|
||||
anim.timer = 0.0f;
|
||||
sprite.frame.x = sprite.frame.w * anim.current;
|
||||
}
|
||||
|
||||
anim.timer += ecs.dt();
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationSystem::draw(ECS& ecs, std::vector<size_t> const& entities) /*override*/
|
||||
{
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef rid_ANIMATIONSYSTEM_HPP
|
||||
#define rid_ANIMATIONSYSTEM_HPP
|
||||
|
||||
#include "conf.hpp"
|
||||
#include "../BaseSystem.hpp"
|
||||
#include "../gfx/Canvas.hpp"
|
||||
|
||||
namespace rid
|
||||
{
|
||||
class AnimationSystem: public BaseSystem
|
||||
{
|
||||
public:
|
||||
explicit AnimationSystem();
|
||||
virtual ~AnimationSystem();
|
||||
|
||||
void update(ECS& ecs, std::vector<size_t> const& entities) override;
|
||||
void draw(ECS& ecs, std::vector<size_t> const& entities) override;
|
||||
|
||||
private:
|
||||
Canvas m_canvas;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -13,21 +13,30 @@ namespace rid
|
|||
{
|
||||
}
|
||||
|
||||
void BodySystem::update(ECS&, std::vector<size_t> const&) /*override*/
|
||||
void BodySystem::update(ECS& ecs, std::vector<size_t> const& entities) /*override*/
|
||||
{
|
||||
}
|
||||
|
||||
void BodySystem::draw(ECS& ecs, std::vector<size_t> const& entities) /*override*/
|
||||
{
|
||||
Canvas canvas;
|
||||
|
||||
for (auto entity: entities)
|
||||
{
|
||||
auto const& body = ecs.getc<BodyC>(entity);
|
||||
auto& body = ecs.getc<BodyC>(entity);
|
||||
|
||||
canvas.draw_rect(body.pos, body.size, glm::vec4 {1, 1, 1, 1});
|
||||
float vel_len = glm::length(body.vel);
|
||||
|
||||
if (vel_len > body.max_speed)
|
||||
{
|
||||
body.vel = glm::normalize(body.vel) * body.max_speed;
|
||||
}
|
||||
|
||||
body.pos += body.vel * ecs.dt();
|
||||
|
||||
if (vel_len > 0.f)
|
||||
{
|
||||
body.heading = body.vel / vel_len;
|
||||
body.side = glm::vec2 {-body.heading.y, body.heading.x};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ecs.window().draw(canvas);
|
||||
void BodySystem::draw(ECS&, std::vector<size_t> const&) /*override*/
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
#include <SDL2/SDL.h>
|
||||
#include "PlayerSystem.hpp"
|
||||
#include "../ECS.hpp"
|
||||
#include "../comps/PlayerC.hpp"
|
||||
#include "../comps/BodyC.hpp"
|
||||
|
||||
namespace rid
|
||||
{
|
||||
/*explicit*/ PlayerSystem::PlayerSystem()
|
||||
{
|
||||
}
|
||||
|
||||
/*virtual*/ PlayerSystem::~PlayerSystem()
|
||||
{
|
||||
}
|
||||
|
||||
void PlayerSystem::update(ECS& ecs, std::vector<size_t> const& entities) /*override*/
|
||||
{
|
||||
for (auto entity: entities)
|
||||
{
|
||||
auto& player = ecs.getc<PlayerC>(entity);
|
||||
auto& body = ecs.getc<BodyC>(entity);
|
||||
|
||||
glm::vec2 dir {
|
||||
player.joystick->axis(SDL_CONTROLLER_AXIS_LEFTX),
|
||||
player.joystick->axis(SDL_CONTROLLER_AXIS_LEFTY)
|
||||
};
|
||||
|
||||
float len = glm::length(dir);
|
||||
float const threshold = 0.25f;
|
||||
|
||||
if (len >= threshold)
|
||||
{
|
||||
dir /= len;
|
||||
body.vel = dir * body.max_speed;
|
||||
}
|
||||
else
|
||||
{
|
||||
body.vel = glm::vec2 {0.f};
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerSystem::draw(ECS&, std::vector<size_t> const&) /*override*/
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef rid_PLAYERSYSTEM_HPP
|
||||
#define rid_PLAYERSYSTEM_HPP
|
||||
|
||||
#include "conf.hpp"
|
||||
#include "../BaseSystem.hpp"
|
||||
|
||||
namespace rid
|
||||
{
|
||||
class PlayerSystem: public BaseSystem
|
||||
{
|
||||
public:
|
||||
explicit PlayerSystem();
|
||||
virtual ~PlayerSystem();
|
||||
|
||||
void update(ECS& ecs, std::vector<size_t> const& entities) override;
|
||||
void draw(ECS& ecs, std::vector<size_t> const& entities) override;
|
||||
|
||||
|
||||
private:
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue