Explorar el Código

traits

opengl-renderer-broken
Martin Dørum hace 4 años
padre
commit
3b4ce891fe

+ 3
- 2
core.mod/src/WGDefault.cc Ver fichero

} }
} }


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 Ver fichero

tStone_(world.getTileID("core::stone")), tAir_(world.getTileID("core::air")) {} tStone_(world.getTileID("core::stone")), tAir_(world.getTileID("core::air")) {}


void genChunk(Swan::WorldPlane &plane, Swan::Chunk &chunk) override; 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: private:
Swan::Tile::ID tGrass_, tDirt_, tStone_, tAir_; Swan::Tile::ID tGrass_, tDirt_, tStone_, tAir_;

+ 1
- 1
libswan/CMakeLists.txt Ver fichero

add_library(libswan SHARED add_library(libswan SHARED
src/traits/BodyTrait.cc
src/Animation.cc src/Animation.cc
src/Body.cc
src/Chunk.cc src/Chunk.cc
src/Clock.cc src/Clock.cc
src/Game.cc src/Game.cc

+ 0
- 38
libswan/include/swan/Body.h Ver fichero

#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 Ver fichero

#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 Ver fichero



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


namespace Swan { namespace Swan {




virtual ~Entity() = default; virtual ~Entity() = default;


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

virtual void draw(const Context &ctx, Win &win) {} virtual void draw(const Context &ctx, Win &win) {}
virtual void update(const Context &ctx, float dt) {} virtual void update(const Context &ctx, float dt) {}
virtual void tick(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 despawn() {}

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


class PhysicsEntity: public Entity {
class PhysicsEntity: public Entity, public BodyTrait::HasBody {
public: public:
PhysicsEntity(Vec2 size, float mass): PhysicsEntity(Vec2 size, float mass):
body_(size, 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 { virtual void update(const Context &ctx, float dt) override {
body_.friction(); body_.friction();
body_.update(ctx.plane, dt); 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: protected:
Body body_;
BodyTrait::PhysicsBody body_;
}; };


} }

+ 1
- 1
libswan/include/swan/World.h Ver fichero

std::unordered_map<std::string, WorldGen::Factory *> worldgens_; std::unordered_map<std::string, WorldGen::Factory *> worldgens_;
std::unordered_map<std::string, Entity::Factory *> ents_; std::unordered_map<std::string, Entity::Factory *> ents_;


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


std::mt19937 random_; std::mt19937 random_;

+ 2
- 1
libswan/include/swan/WorldGen.h Ver fichero



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


namespace Swan { namespace Swan {


virtual ~WorldGen() = default; virtual ~WorldGen() = default;


virtual void genChunk(WorldPlane &plane, Chunk &chunk) = 0; 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 Ver fichero

#include <set> #include <set>


#include "common.h" #include "common.h"
#include "traits/BodyTrait.h"
#include "Chunk.h" #include "Chunk.h"
#include "Tile.h" #include "Tile.h"
#include "WorldGen.h" #include "WorldGen.h"
WorldPlane(ID id, World *world, std::shared_ptr<WorldGen> gen): WorldPlane(ID id, World *world, std::shared_ptr<WorldGen> gen):
id_(id), world_(world), gen_(std::move(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); void despawnEntity(Entity &ent);


Context getContext(); Context getContext();
Tile::ID getTileID(TilePos pos); Tile::ID getTileID(TilePos pos);
Tile &getTile(TilePos pos); Tile &getTile(TilePos pos);


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


void draw(Win &win); void draw(Win &win);

+ 1
- 2
libswan/include/swan/swan.h Ver fichero

#pragma once #pragma once


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

+ 68
- 0
libswan/include/swan/traits/BodyTrait.h Ver fichero

#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 Ver fichero

} }


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


void World::setCurrentPlane(WorldPlane &plane) { void World::setCurrentPlane(WorldPlane &plane) {
} }


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


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

+ 9
- 6
libswan/src/WorldPlane.cc Ver fichero

return { .game = *world_->game_, .world = *world_, .plane = *this, .resources = world_->resources_ }; 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()) { if (world_->ents_.find(name) == world_->ents_.end()) {
panic << "Tried to spawn a non-existant entity " << name << "!"; panic << "Tried to spawn a non-existant entity " << name << "!";
abort(); abort();
} }


Entity *ent = world_->ents_[name]->create(getContext(), params); 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)); spawn_list_.push_back(std::unique_ptr<Entity>(ent));
info << "Spawned " << name << ". SRF: " << params; info << "Spawned " << name << ". SRF: " << params;
return *ent;
return ent;
} }


void WorldPlane::despawnEntity(Entity &ent) { void WorldPlane::despawnEntity(Entity &ent) {
return world_->getTileByID(getTileID(pos)); return world_->getTileByID(getTileID(pos));
} }


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


} }


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

libswan/src/Body.cc → libswan/src/traits/BodyTrait.cc Ver fichero

#include "Body.h"
#include "traits/BodyTrait.h"


#include <math.h> #include <math.h>
#include <array> #include <array>
#include "Win.h" #include "Win.h"


namespace Swan { namespace Swan {
namespace BodyTrait {


static float epsilon = 0.0001; static float epsilon = 0.0001;


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


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


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


} }
} }


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


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


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


collideY(plane); collideY(plane);
} }


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


} }
}

Cargando…
Cancelar
Guardar