@@ -1,7 +1,11 @@ | |||
#include "EntPlayer.h" | |||
#include <cmath> | |||
#include "EntItemStack.h" | |||
EntPlayer::EntPlayer(const Swan::Context &ctx, const Swan::SRF ¶ms): | |||
PhysicsEntity(SIZE, MASS), | |||
PhysicsEntity(SIZE, MASS), inventory_(INVENTORY_SIZE), | |||
anims_{ | |||
Swan::Animation(ctx.resources.getImage("core::player-still"), 0.8), | |||
Swan::Animation(ctx.resources.getImage("core::player-running"), 1, SDL_FLIP_HORIZONTAL), | |||
@@ -57,7 +61,19 @@ void EntPlayer::update(const Swan::Context &ctx, float dt) { | |||
anims_[(int)state_].reset(); | |||
anims_[(int)state_].tick(dt); | |||
Swan::PhysicsEntity::update(ctx, dt); | |||
PhysicsEntity::update(ctx, dt); | |||
} | |||
void EntPlayer::tick(const Swan::Context &ctx, float dt) { | |||
for (EntItemStack *ent: ctx.plane.getEntsOfType<EntItemStack>()) { | |||
float squared_dist = | |||
(getBody().getBounds().bottomMid() - ent->getBody().getBounds().center()) | |||
.squareLength(); | |||
if (squared_dist < 0.5 * 0.5) { | |||
Swan::info << "Will pick up item at " << ent->getBody().getBounds().center() << "..."; | |||
} | |||
} | |||
} | |||
void EntPlayer::readSRF(const Swan::Context &ctx, const Swan::SRF &srf) { |
@@ -3,7 +3,7 @@ | |||
#include <swan/swan.h> | |||
#include <array> | |||
class EntPlayer: public Swan::PhysicsEntity { | |||
class EntPlayer: public Swan::PhysicsEntity, public Swan::InventoryTrait::HasInventory { | |||
public: | |||
class Factory: public Swan::Entity::Factory { | |||
public: | |||
@@ -14,18 +14,24 @@ public: | |||
EntPlayer(const Swan::Context &ctx, const Swan::SRF ¶ms); | |||
Swan::InventoryTrait::Inventory &getInventory() { return inventory_; } | |||
void draw(const Swan::Context &ctx, Swan::Win &win) override; | |||
void update(const Swan::Context &ctx, float dt) override; | |||
void tick(const Swan::Context &ctx, float dt) override; | |||
void readSRF(const Swan::Context &ctx, const Swan::SRF &srf) override; | |||
Swan::SRF *writeSRF(const Swan::Context &ctx) override; | |||
private: | |||
static constexpr int INVENTORY_SIZE = 18; | |||
static constexpr float MASS = 80; | |||
static constexpr float MOVE_FORCE = 34 * MASS; | |||
static constexpr float JUMP_VEL = 11; | |||
static constexpr float DOWN_FORCE = 20 * MASS; | |||
static constexpr Swan::Vec2 SIZE = Swan::Vec2(0.6, 1.9); | |||
Swan::InventoryTrait::BasicInventory inventory_; | |||
enum class State { | |||
IDLE, | |||
RUNNING_L, |
@@ -42,9 +42,8 @@ public: | |||
virtual BodyTrait::Body &getBody() override { return body_; } | |||
virtual void update(const Context &ctx, float dt) override { | |||
body_.friction(); | |||
body_.gravity(); | |||
body_.update(ctx.plane, dt); | |||
body_.standardForces(); | |||
body_.update(ctx, dt); | |||
} | |||
protected: |
@@ -20,7 +20,11 @@ struct Vector2 { | |||
} | |||
constexpr T length() { | |||
return (T)std::sqrt((double)(this->x * this->x + this->y * this->y)); | |||
return (T)std::sqrt((double)squareLength()); | |||
} | |||
constexpr T squareLength() { | |||
return this->x * this->x + this->y * this->y; | |||
} | |||
constexpr Vector2<T> sign() { |
@@ -41,9 +41,9 @@ public: | |||
Iter<Entity *> getEntsInArea(Vec2 center, float radius); | |||
template<typename T> | |||
Iter<Entity *>getEntsOfType() { | |||
return mapFilter(entities_.begin(), entities_.end(), [](Entity *ent) -> std::optional<T *> { | |||
if (T *e = dynamic_cast<T *>(ent); e != nullptr) | |||
Iter<T *>getEntsOfType() { | |||
return mapFilter(entities_.begin(), entities_.end(), [](std::unique_ptr<Entity> &ent) -> std::optional<T *> { | |||
if (T *e = dynamic_cast<T *>(ent.get()); e != nullptr) | |||
return e; | |||
return std::nullopt; | |||
}); |
@@ -1,6 +1,7 @@ | |||
#pragma once | |||
#include <swan/traits/BodyTrait.h> | |||
#include <swan/traits/InventoryTrait.h> | |||
#include <swan/Animation.h> | |||
#include <swan/Chunk.h> | |||
#include <swan/Clock.h> |
@@ -1,5 +1,6 @@ | |||
#pragma once | |||
#include "../common.h" | |||
#include "../Vector2.h" | |||
namespace Swan { | |||
@@ -20,10 +21,22 @@ struct Bounds { | |||
Vec2 pos; | |||
Vec2 size; | |||
double left() { return pos.x; } | |||
double right() { return pos.x + size.x; } | |||
double top() { return pos.y; } | |||
double bottom() { return pos.y + size.y; } | |||
float left() { return pos.x; } | |||
float right() { return pos.x + size.x; } | |||
float midX() { return pos.x + size.x / 2; } | |||
float top() { return pos.y; } | |||
float bottom() { return pos.y + size.y; } | |||
float midY() { return pos.y + size.y / 2; } | |||
Vec2 topLeft() { return { left(), top() }; } | |||
Vec2 midLeft() { return { left(), midY() }; } | |||
Vec2 bottomLeft() { return { left(), bottom() }; } | |||
Vec2 topMid() { return { midX(), top() }; } | |||
Vec2 center() { return { midX(), midY() }; } | |||
Vec2 bottomMid() { return { midX(), bottom() }; } | |||
Vec2 topRight() { return { right(), top() }; } | |||
Vec2 midRight() { return { right(), midY() }; } | |||
Vec2 bottomRight() { return { right(), bottom() }; } | |||
}; | |||
class Body { | |||
@@ -48,9 +61,10 @@ public: | |||
void friction(Vec2 coef = Vec2(400, 50)); | |||
void gravity(Vec2 g = Vec2(0, 20)); | |||
void standardForces() { friction(); gravity(); } | |||
void outline(Win &win); | |||
void update(WorldPlane &plane, float dt); | |||
void update(const Swan::Context &ctx, float dt); | |||
void updateWithoutCollision(float dt); | |||
Vec2 force_ = { 0, 0 }; |
@@ -1,6 +1,7 @@ | |||
#pragma once | |||
#include <vector> | |||
#include <stdlib.h> | |||
#include "../Vector2.h" | |||
#include "../ItemStack.h" | |||
@@ -21,23 +22,32 @@ public: | |||
virtual ~Inventory() = default; | |||
virtual int size() = 0; | |||
virtual ItemStack &get(int slot) = 0; | |||
virtual ItemStack insert(ItemStack stack, int slot = 0) = 0; | |||
virtual ItemStack get(int slot) = 0; | |||
virtual ItemStack set(int slot, ItemStack stack) = 0; | |||
virtual ItemStack insert(int slot, ItemStack stack) = 0; | |||
ItemStack insert(ItemStack stack) { return insert(0, stack); } | |||
}; | |||
class BasicInventory: public Inventory { | |||
public: | |||
BasicInventory(int size): size_(size) {} | |||
BasicInventory(int size): size_(size), content_(size) {} | |||
int size() override { return size_; } | |||
ItemStack &get(int slot) { | |||
ItemStack get(int slot) override { | |||
if (slot < size_) | |||
return content_[slot]; | |||
return ItemStack(); | |||
} | |||
ItemStack insert(ItemStack stack) { | |||
ItemStack set(int slot, ItemStack stack) override { | |||
ItemStack st = content_[slot]; | |||
content_[slot] = stack; | |||
return st; | |||
} | |||
ItemStack insert(int slot, ItemStack stack) override { | |||
for (int i = 0; !stack.empty() && i < size_; ++i) | |||
stack = content_[i].insert(stack); | |||
return stack; | |||
@@ -45,7 +55,7 @@ public: | |||
private: | |||
int size_; | |||
std::vector<ItemStack> content_(size_); | |||
std::vector<ItemStack> content_; | |||
}; | |||
} |
@@ -88,7 +88,7 @@ void PhysicsBody::outline(Win &win) { | |||
win.drawRect(pos_, size_); | |||
} | |||
void PhysicsBody::update(WorldPlane &plane, float dt) { | |||
void PhysicsBody::update(const Swan::Context &ctx, float dt) { | |||
vel_ += (force_ / mass_) * dt; | |||
force_ = { 0, 0 }; | |||
@@ -99,20 +99,20 @@ void PhysicsBody::update(WorldPlane &plane, float dt) { | |||
// Move in increments of at most 'step', on the X axis | |||
while (abs(dist.x) > abs(step.x)) { | |||
pos_.x += step.x; | |||
collideX(plane); | |||
collideX(ctx.plane); | |||
dist.x -= step.x; | |||
} | |||
pos_.x += dist.x; | |||
collideX(plane); | |||
collideX(ctx.plane); | |||
// Move in increments of at most 'step', on the Y axis | |||
while (abs(dist.y) > abs(step.y)) { | |||
pos_.y += step.y; | |||
collideY(plane); | |||
collideY(ctx.plane); | |||
dist.y -= step.y; | |||
} | |||
pos_.y += dist.y; | |||
collideY(plane); | |||
collideY(ctx.plane); | |||
} | |||
void PhysicsBody::updateWithoutCollision(float dt) { |