| @@ -2,7 +2,7 @@ | |||
| #include <swan/swan.h> | |||
| class ItemStackEntity: public Swan::PhysicsEntity { | |||
| class ItemStackEntity final: public Swan::PhysicsEntity { | |||
| public: | |||
| ItemStackEntity(const Swan::Context &ctx, Swan::Vec2 pos, const std::string &item); | |||
| ItemStackEntity(const Swan::Context &ctx, const PackObject &obj); | |||
| @@ -3,7 +3,7 @@ | |||
| #include <swan/swan.h> | |||
| #include <array> | |||
| class PlayerEntity: public Swan::PhysicsEntity, public Swan::InventoryTrait { | |||
| class PlayerEntity final: public Swan::PhysicsEntity, public Swan::InventoryTrait { | |||
| public: | |||
| PlayerEntity(const Swan::Context &ctx, Swan::Vec2 pos); | |||
| PlayerEntity(const Swan::Context &ctx, const PackObject &obj); | |||
| @@ -51,5 +51,5 @@ private: | |||
| Swan::TilePos lightTile_; | |||
| bool placedLight_ = false; | |||
| BasicInventory inventory_{INVENTORY_SIZE}; | |||
| Swan::BasicInventory inventory_{INVENTORY_SIZE}; | |||
| }; | |||
| @@ -27,12 +27,12 @@ public: | |||
| Entity() = default; | |||
| Entity(Entity &&) = default; | |||
| virtual ~Entity() = default; | |||
| Entity &operator=(Entity &&) = default; | |||
| void despawn(const Swan::Context &ctx); | |||
| virtual ~Entity() = default; | |||
| virtual void draw(const Context &ctx, Cygnet::Renderer &rnd) {} | |||
| virtual void update(const Context &ctx, float dt) {} | |||
| virtual void tick(const Context &ctx, float dt) {} | |||
| @@ -54,7 +54,7 @@ public: | |||
| void physics( | |||
| const Context &ctx, float dt, | |||
| const PhysicsTrait::PhysicsProps &props) { | |||
| const BasicPhysics::Props &props) { | |||
| physics_.standardForces(props.mass); | |||
| physics_.update(ctx, dt, body_, props); | |||
| @@ -62,7 +62,7 @@ public: | |||
| protected: | |||
| BodyTrait::Body body_; | |||
| PhysicsTrait::Physics physics_; | |||
| BasicPhysics physics_; | |||
| }; | |||
| } | |||
| @@ -11,6 +11,9 @@ namespace Swan { | |||
| class EventEmitterInterface { | |||
| public: | |||
| virtual void unsubscribe(size_t id) = 0; | |||
| protected: | |||
| ~EventEmitterInterface() = default; | |||
| }; | |||
| class EventListener: NonCopyable { | |||
| @@ -50,7 +53,7 @@ private: | |||
| }; | |||
| template<typename... Evt> | |||
| class EventEmitter: public EventEmitterInterface { | |||
| class EventEmitter final: public EventEmitterInterface { | |||
| public: | |||
| using Callback = std::function<void(Evt...)>; | |||
| @@ -36,6 +36,8 @@ struct LightChunk { | |||
| class LightCallback { | |||
| public: | |||
| virtual ~LightCallback() = default; | |||
| virtual void onLightChunkUpdated(const LightChunk &chunk, ChunkPos pos) = 0; | |||
| }; | |||
| @@ -5,11 +5,9 @@ | |||
| namespace Swan { | |||
| struct BodyTrait { | |||
| struct Body; | |||
| struct Tag {}; | |||
| virtual Body &get(Tag) = 0; | |||
| struct Body { | |||
| struct Body final { | |||
| Vec2 pos{}; | |||
| Vec2 size{}; | |||
| @@ -29,9 +27,11 @@ struct BodyTrait { | |||
| Vec2 topRight() { return { right(), top() }; } | |||
| Vec2 midRight() { return { right(), midY() }; } | |||
| Vec2 bottomRight() { return { right(), bottom() }; } | |||
| //void outline(Win &win); TODO | |||
| }; | |||
| virtual ~BodyTrait() = default; | |||
| virtual Body &get(Tag) = 0; | |||
| }; | |||
| } | |||
| @@ -9,9 +9,7 @@ | |||
| namespace Swan { | |||
| struct InventoryTrait { | |||
| struct Inventory; | |||
| struct Tag {}; | |||
| virtual Inventory &get(Tag) = 0; | |||
| struct Inventory { | |||
| virtual ~Inventory() = default; | |||
| @@ -24,16 +22,20 @@ struct InventoryTrait { | |||
| ItemStack insert(ItemStack stack) { return insert(0, stack); } | |||
| }; | |||
| struct BasicInventory: Inventory { | |||
| BasicInventory(int size): content(size) {} | |||
| virtual ~InventoryTrait() = default; | |||
| virtual Inventory &get(Tag) = 0; | |||
| }; | |||
| struct BasicInventory final: InventoryTrait::Inventory { | |||
| BasicInventory(int size): content(size) {} | |||
| std::vector<ItemStack> content; | |||
| std::vector<ItemStack> content; | |||
| int size() override { return content.size(); } | |||
| ItemStack get(int slot) override; | |||
| ItemStack set(int slot, ItemStack stack) override; | |||
| ItemStack insert(int slot, ItemStack stack) override; | |||
| }; | |||
| int size() override { return content.size(); } | |||
| ItemStack get(int slot) override; | |||
| ItemStack set(int slot, ItemStack stack) override; | |||
| ItemStack insert(int slot, ItemStack stack) override; | |||
| }; | |||
| } | |||
| @@ -6,41 +6,63 @@ | |||
| namespace Swan { | |||
| struct PhysicsTrait { | |||
| struct Physics; | |||
| struct Tag {}; | |||
| struct Physics { | |||
| virtual ~Physics() = default; | |||
| virtual void applyForce(Vec2 force) = 0; | |||
| virtual void addVelocity(Vec2 vel) = 0; | |||
| virtual Vec2 getVelocity() = 0; | |||
| }; | |||
| virtual ~PhysicsTrait() = default; | |||
| virtual Physics &get(Tag) = 0; | |||
| }; | |||
| struct PhysicsProps { | |||
| struct BasicPhysics final: public PhysicsTrait::Physics { | |||
| struct Props { | |||
| float mass; | |||
| float bounciness = 0; | |||
| float mushyness = 2; | |||
| }; | |||
| struct Physics { | |||
| Vec2 vel{}; | |||
| Vec2 force{}; | |||
| bool onGround = false; | |||
| Vec2 vel{}; | |||
| Vec2 force{}; | |||
| bool onGround = false; | |||
| void friction(Vec2 coef = Vec2(400, 50)); | |||
| void gravity(float mass, Vec2 g = Vec2(0, 20)); | |||
| void standardForces(float mass) { friction(); gravity(mass); } | |||
| void friction(Vec2 coef = Vec2(400, 50)); | |||
| void gravity(float mass, Vec2 g = Vec2(0, 20)); | |||
| void standardForces(float mass) { friction(); gravity(mass); } | |||
| void update( | |||
| const Swan::Context &ctx, float dt, | |||
| BodyTrait::Body &body, const PhysicsProps &props); | |||
| }; | |||
| void applyForce(Vec2 f) override; | |||
| void addVelocity(Vec2 v) override; | |||
| Vec2 getVelocity() override { return vel; } | |||
| void update( | |||
| const Swan::Context &ctx, float dt, | |||
| BodyTrait::Body &body, const Props &props); | |||
| }; | |||
| /* | |||
| * Physics | |||
| * BasicPhysics | |||
| */ | |||
| inline void PhysicsTrait::Physics::friction(Vec2 coef) { | |||
| inline void BasicPhysics::friction(Vec2 coef) { | |||
| force += -vel * coef; | |||
| } | |||
| inline void PhysicsTrait::Physics::gravity(float mass, Vec2 g) { | |||
| inline void BasicPhysics::gravity(float mass, Vec2 g) { | |||
| force += g * mass; | |||
| } | |||
| inline void BasicPhysics::applyForce(Vec2 f) { | |||
| force += f; | |||
| } | |||
| inline void BasicPhysics::addVelocity(Vec2 v) { | |||
| vel += v; | |||
| } | |||
| } | |||
| @@ -6,7 +6,6 @@ libswan = declare_dependency( | |||
| include_directories: 'include', | |||
| dependencies: libswan_deps, | |||
| link_with: library('swan', | |||
| 'src/traits/BodyTrait.cc', | |||
| 'src/traits/InventoryTrait.cc', | |||
| 'src/traits/PhysicsTrait.cc', | |||
| 'src/Animation.cc', | |||
| @@ -1,10 +0,0 @@ | |||
| #include "traits/BodyTrait.h" | |||
| namespace Swan { | |||
| /* | |||
| void BodyTrait::Body::outline(Win &win) { | |||
| win.drawRect(pos, size); | |||
| } TODO */ | |||
| } | |||
| @@ -2,14 +2,14 @@ | |||
| namespace Swan { | |||
| ItemStack InventoryTrait::BasicInventory::get(int slot) { | |||
| ItemStack BasicInventory::get(int slot) { | |||
| if (slot >= (ssize_t)content.size()) | |||
| return ItemStack{}; | |||
| return content[slot]; | |||
| } | |||
| ItemStack InventoryTrait::BasicInventory::set(int slot, ItemStack stack) { | |||
| ItemStack BasicInventory::set(int slot, ItemStack stack) { | |||
| if (slot >= (ssize_t)content.size()) | |||
| return stack; | |||
| @@ -18,7 +18,7 @@ ItemStack InventoryTrait::BasicInventory::set(int slot, ItemStack stack) { | |||
| return st; | |||
| } | |||
| ItemStack InventoryTrait::BasicInventory::insert(int slot, ItemStack stack) { | |||
| ItemStack BasicInventory::insert(int slot, ItemStack stack) { | |||
| for (int i = 0; !stack.empty() && i < (ssize_t)content.size(); ++i) | |||
| stack = content[i].insert(stack); | |||
| return stack; | |||
| @@ -7,8 +7,8 @@ namespace Swan { | |||
| static float epsilon = 0.05; | |||
| static void collideX( | |||
| PhysicsTrait::Physics &phys, BodyTrait::Body &body, | |||
| WorldPlane &plane, const PhysicsTrait::PhysicsProps &props) { | |||
| BasicPhysics &phys, BodyTrait::Body &body, | |||
| WorldPlane &plane, const BasicPhysics::Props &props) { | |||
| bool collided = false; | |||
| for (int y = (int)floor(body.top() + epsilon); y <= (int)floor(body.bottom() - epsilon); ++y) { | |||
| @@ -37,8 +37,8 @@ static void collideX( | |||
| } | |||
| static void collideY( | |||
| PhysicsTrait::Physics &phys, BodyTrait::Body &body, | |||
| WorldPlane &plane, const PhysicsTrait::PhysicsProps &props) { | |||
| BasicPhysics &phys, BodyTrait::Body &body, | |||
| WorldPlane &plane, const BasicPhysics::Props &props) { | |||
| bool collided = false; | |||
| phys.onGround = false; | |||
| @@ -68,9 +68,9 @@ static void collideY( | |||
| } | |||
| } | |||
| void PhysicsTrait::Physics::update( | |||
| void BasicPhysics::update( | |||
| const Swan::Context &ctx, float dt, | |||
| BodyTrait::Body &body, const PhysicsProps &props) { | |||
| BodyTrait::Body &body, const BasicPhysics::Props &props) { | |||
| vel += (force / props.mass) * dt; | |||
| force = { 0, 0 }; | |||