Browse Source

traits

opengl-renderer-broken
Martin Dørum 4 years ago
parent
commit
3b4ce891fe

+ 3
- 2
core.mod/src/WGDefault.cc View File

@@ -21,6 +21,7 @@ void WGDefault::genChunk(Swan::WorldPlane &plane, Swan::Chunk &chunk) {
}
}

Swan::Entity &WGDefault::spawnPlayer(Swan::WorldPlane &plane) {
return plane.spawnEntity("core::player", Swan::SRFFloatArray{0, 0});
Swan::BodyTrait::HasBody *WGDefault::spawnPlayer(Swan::WorldPlane &plane) {
return dynamic_cast<Swan::BodyTrait::HasBody *>(
plane.spawnEntity("core::player", Swan::SRFFloatArray{0, 0}));
}

+ 1
- 1
core.mod/src/WGDefault.h View File

@@ -16,7 +16,7 @@ public:
tStone_(world.getTileID("core::stone")), tAir_(world.getTileID("core::air")) {}

void genChunk(Swan::WorldPlane &plane, Swan::Chunk &chunk) override;
Swan::Entity &spawnPlayer(Swan::WorldPlane &plane) override;
Swan::BodyTrait::HasBody *spawnPlayer(Swan::WorldPlane &plane) override;

private:
Swan::Tile::ID tGrass_, tDirt_, tStone_, tAir_;

+ 1
- 1
libswan/CMakeLists.txt View File

@@ -1,6 +1,6 @@
add_library(libswan SHARED
src/traits/BodyTrait.cc
src/Animation.cc
src/Body.cc
src/Chunk.cc
src/Clock.cc
src/Game.cc

+ 0
- 38
libswan/include/swan/Body.h View File

@@ -1,38 +0,0 @@
#pragma once

#include "common.h"
#include "BoundingBox.h"

namespace Swan {

class WorldPlane;

class Body {
public:
Body(Vec2 size, float mass, Vec2 pos = Vec2::ZERO):
size_(size), mass_(mass), pos_(pos) {};

void friction(Vec2 coef = Vec2(400, 50));
void gravity(Vec2 g = Vec2(0, 20));

void outline(Win &win);
void update(WorldPlane &plane, float dt);
void updateWithoutCollision(float dt);

BoundingBox getBounds() { return { pos_, size_ }; }

Vec2 force_ = { 0, 0 };
Vec2 vel_ = { 0, 0 };
bool on_ground_ = false;
Vec2 size_;
float mass_;
Vec2 pos_;
float bounciness_ = 0;
float mushyness_ = 2;

private:
void collideX(WorldPlane &plane);
void collideY(WorldPlane &plane);
};

}

+ 0
- 17
libswan/include/swan/BoundingBox.h View File

@@ -1,17 +0,0 @@
#pragma once

#include "Vector2.h"

namespace Swan {

struct BoundingBox {
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; }
};

}

+ 5
- 12
libswan/include/swan/Entity.h View File

@@ -5,9 +5,8 @@

#include "common.h"
#include "log.h"
#include "traits/BodyTrait.h"
#include "SRF.h"
#include "BoundingBox.h"
#include "Body.h"

namespace Swan {

@@ -26,24 +25,21 @@ public:

virtual ~Entity() = default;

virtual std::optional<BoundingBox> getBounds() { return std::nullopt; }

virtual void draw(const Context &ctx, Win &win) {}
virtual void update(const Context &ctx, float dt) {}
virtual void tick(const Context &ctx, float dt) {}
virtual void move(const Vec2 &pos) {}
virtual void moveTo(const Vec2 &pos) {}
virtual void despawn() {}

virtual void readSRF(const Swan::Context &ctx, const SRF &srf) {}
virtual SRF *writeSRF(const Swan::Context &ctx) { return new SRFNone(); }
};

class PhysicsEntity: public Entity {
class PhysicsEntity: public Entity, public BodyTrait::HasBody {
public:
PhysicsEntity(Vec2 size, float mass):
body_(size, mass) {}

virtual std::optional<BoundingBox> getBounds() override { return body_.getBounds(); }
virtual BodyTrait::Body &getBody() override { return body_; }

virtual void update(const Context &ctx, float dt) override {
body_.friction();
@@ -51,11 +47,8 @@ public:
body_.update(ctx.plane, dt);
}

virtual void move(const Vec2 &rel) override { body_.pos_ += rel; }
virtual void moveTo(const Vec2 &pos) override { body_.pos_ = pos; }

protected:
Body body_;
BodyTrait::PhysicsBody body_;
};

}

+ 1
- 1
libswan/include/swan/World.h View File

@@ -51,7 +51,7 @@ public:
std::unordered_map<std::string, WorldGen::Factory *> worldgens_;
std::unordered_map<std::string, Entity::Factory *> ents_;

Entity *player_;
BodyTrait::HasBody *player_;
Game *game_;

std::mt19937 random_;

+ 2
- 1
libswan/include/swan/WorldGen.h View File

@@ -4,6 +4,7 @@

#include "Chunk.h"
#include "Entity.h"
#include "traits/BodyTrait.h"

namespace Swan {

@@ -22,7 +23,7 @@ public:
virtual ~WorldGen() = default;

virtual void genChunk(WorldPlane &plane, Chunk &chunk) = 0;
virtual Entity &spawnPlayer(WorldPlane &plane) = 0;
virtual BodyTrait::HasBody *spawnPlayer(WorldPlane &plane) = 0;
};

}

+ 3
- 2
libswan/include/swan/WorldPlane.h View File

@@ -7,6 +7,7 @@
#include <set>

#include "common.h"
#include "traits/BodyTrait.h"
#include "Chunk.h"
#include "Tile.h"
#include "WorldGen.h"
@@ -24,7 +25,7 @@ public:
WorldPlane(ID id, World *world, std::shared_ptr<WorldGen> gen):
id_(id), world_(world), gen_(std::move(gen)) {}

Entity &spawnEntity(const std::string &name, const SRF &params);
Entity *spawnEntity(const std::string &name, const SRF &params);
void despawnEntity(Entity &ent);

Context getContext();
@@ -36,7 +37,7 @@ public:
Tile::ID getTileID(TilePos pos);
Tile &getTile(TilePos pos);

Entity &spawnPlayer();
BodyTrait::HasBody *spawnPlayer();
void breakBlock(TilePos pos);

void draw(Win &win);

+ 1
- 2
libswan/include/swan/swan.h View File

@@ -1,8 +1,7 @@
#pragma once

#include <swan/traits/BodyTrait.h>
#include <swan/Animation.h>
#include <swan/Body.h>
#include <swan/BoundingBox.h>
#include <swan/Chunk.h>
#include <swan/Clock.h>
#include <swan/Entity.h>

+ 68
- 0
libswan/include/swan/traits/BodyTrait.h View File

@@ -0,0 +1,68 @@
#pragma once

#include "../Vector2.h"

namespace Swan {

class WorldPlane;
class Win;

namespace BodyTrait {

class Body;
class HasBody {
public:
virtual Body &getBody() = 0;
};

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; }
};

class Body {
public:
virtual Bounds getBounds() = 0;
virtual void move(Vec2 rel) = 0;
virtual void moveTo(Vec2 pos) = 0;
};

// PhysicsBody is an implementation of BodyTrait::Body which implements
// a bunch of physics stuff.
class PhysicsBody: public Body {
public:
PhysicsBody(Vec2 size, float mass, Vec2 pos = Vec2::ZERO):
size_(size), mass_(mass), pos_(pos) {};

BodyTrait::Bounds getBounds() override { return BodyTrait::Bounds{ pos_, size_ }; };
void move(Vec2 rel) { pos_ += rel; }
void moveTo(Vec2 pos) { pos_ = pos; }

void friction(Vec2 coef = Vec2(400, 50));
void gravity(Vec2 g = Vec2(0, 20));

void outline(Win &win);
void update(WorldPlane &plane, float dt);
void updateWithoutCollision(float dt);

Vec2 force_ = { 0, 0 };
Vec2 vel_ = { 0, 0 };
bool on_ground_ = false;
Vec2 size_;
float mass_;
Vec2 pos_;
float bounciness_ = 0;
float mushyness_ = 2;

private:
void collideX(WorldPlane &plane);
void collideY(WorldPlane &plane);
};

}
}

+ 3
- 3
libswan/src/World.cc View File

@@ -80,7 +80,7 @@ void World::setWorldGen(const std::string &gen) {
}

void World::spawnPlayer() {
player_ = &planes_[current_plane_].spawnPlayer();
player_ = planes_[current_plane_].spawnPlayer();
}

void World::setCurrentPlane(WorldPlane &plane) {
@@ -131,7 +131,7 @@ Tile &World::getTile(const std::string &name) {
}

void World::draw(Win &win) {
auto bounds = *player_->getBounds();
auto bounds = player_->getBody().getBounds();
win.cam_ = bounds.pos - (win.getSize() / 2) + (bounds.size / 2);
planes_[current_plane_].draw(win);
}
@@ -145,7 +145,7 @@ void World::tick(float dt) {
for (auto &plane: planes_)
plane.tick(dt);

auto bounds = *player_->getBounds();
auto bounds = player_->getBody().getBounds();
chunk_renderer_.tick(
planes_[current_plane_],
ChunkPos((int)bounds.pos.x / CHUNK_WIDTH, (int)bounds.pos.y / CHUNK_HEIGHT));

+ 9
- 6
libswan/src/WorldPlane.cc View File

@@ -31,20 +31,23 @@ Context WorldPlane::getContext() {
return { .game = *world_->game_, .world = *world_, .plane = *this, .resources = world_->resources_ };
}

Entity &WorldPlane::spawnEntity(const std::string &name, const SRF &params) {
Entity *WorldPlane::spawnEntity(const std::string &name, const SRF &params) {
if (world_->ents_.find(name) == world_->ents_.end()) {
panic << "Tried to spawn a non-existant entity " << name << "!";
abort();
}

Entity *ent = world_->ents_[name]->create(getContext(), params);
if (auto bounds = ent->getBounds(); bounds) {
ent->move({ 0.5f - bounds->size.x / 2, 0 });
if (auto has_body = dynamic_cast<BodyTrait::HasBody *>(ent); has_body) {
BodyTrait::Body &body = has_body->getBody();
BodyTrait::Bounds bounds = body.getBounds();

body.move({ 0.5f - bounds.size.x / 2, 0 });
}

spawn_list_.push_back(std::unique_ptr<Entity>(ent));
info << "Spawned " << name << ". SRF: " << params;
return *ent;
return ent;
}

void WorldPlane::despawnEntity(Entity &ent) {
@@ -101,7 +104,7 @@ Tile &WorldPlane::getTile(TilePos pos) {
return world_->getTileByID(getTileID(pos));
}

Entity &WorldPlane::spawnPlayer() {
BodyTrait::HasBody *WorldPlane::spawnPlayer() {
return gen_->spawnPlayer(*this);
}

@@ -127,7 +130,7 @@ void WorldPlane::breakBlock(TilePos pos) {
}

void WorldPlane::draw(Win &win) {
auto pbounds = *world_->player_->getBounds();
auto pbounds = world_->player_->getBody().getBounds();
ChunkPos pcpos = ChunkPos(
(int)floor(pbounds.pos.x / CHUNK_WIDTH),
(int)floor(pbounds.pos.y / CHUNK_HEIGHT));

libswan/src/Body.cc → libswan/src/traits/BodyTrait.cc View File

@@ -1,4 +1,4 @@
#include "Body.h"
#include "traits/BodyTrait.h"

#include <math.h>
#include <array>
@@ -8,18 +8,19 @@
#include "Win.h"

namespace Swan {
namespace BodyTrait {

static float epsilon = 0.0001;

void Body::friction(Vec2 coef) {
void PhysicsBody::friction(Vec2 coef) {
force_ += -vel_ * coef;
}

void Body::gravity(Vec2 g) {
void PhysicsBody::gravity(Vec2 g) {
force_ += g * mass_;
}

void Body::collideX(WorldPlane &plane) {
void PhysicsBody::collideX(WorldPlane &plane) {
auto bounds = getBounds();
bool collided = false;

@@ -50,7 +51,7 @@ void Body::collideX(WorldPlane &plane) {
}
}

void Body::collideY(WorldPlane &plane) {
void PhysicsBody::collideY(WorldPlane &plane) {
auto bounds = getBounds();
bool collided = false;
on_ground_ = false;
@@ -83,11 +84,11 @@ void Body::collideY(WorldPlane &plane) {
}
}

void Body::outline(Win &win) {
void PhysicsBody::outline(Win &win) {
win.drawRect(pos_, size_);
}

void Body::update(WorldPlane &plane, float dt) {
void PhysicsBody::update(WorldPlane &plane, float dt) {
vel_ += (force_ / mass_) * dt;
force_ = { 0, 0 };

@@ -97,10 +98,11 @@ void Body::update(WorldPlane &plane, float dt) {
collideY(plane);
}

void Body::updateWithoutCollision(float dt) {
void PhysicsBody::updateWithoutCollision(float dt) {
vel_ += (force_ / mass_) * dt;
pos_ += vel_ * dt;
force_ = { 0, 0 };
}

}
}

Loading…
Cancel
Save