@@ -1,4 +1,7 @@ | |||
add_library(core.mod SHARED src/mod.cc) | |||
add_library(core.mod SHARED | |||
src/main.cc | |||
src/WGDefault.cc | |||
src/entities/EntPlayer.cc) | |||
set_target_properties(core.mod PROPERTIES OUTPUT_NAME mod PREFIX "") | |||
target_link_libraries(core.mod libswan) | |||
file(COPY assets DESTINATION .) |
@@ -0,0 +1,16 @@ | |||
#include "WGDefault.h" | |||
void WGDefault::genChunk(Swan::WorldPlane &plane, Swan::Chunk &chunk, int x, int y) { | |||
for (int cx = 0; cx < Swan::CHUNK_WIDTH; ++cx) { | |||
for (int cy = 0; cy < Swan::CHUNK_HEIGHT; ++cy) { | |||
if (y == 0 && cy == 3) | |||
chunk.tiles_[cx][cy] = tGrass_; | |||
else | |||
chunk.tiles_[cx][cy] = tAir_; | |||
} | |||
} | |||
if (plane.id_ == 0 && x == 0 && y == 0) { | |||
plane.spawnEntity("core::player", Swan::Vec2(0, 0)); | |||
} | |||
} |
@@ -0,0 +1,18 @@ | |||
#pragma once | |||
#include <swan/swan.h> | |||
class WGDefault: public Swan::WorldGen { | |||
public: | |||
class Factory: public Swan::WorldGen::Factory { | |||
public: | |||
WorldGen *create(Swan::TileMap &tmap) { return new WGDefault(tmap); } | |||
}; | |||
Swan::Tile::ID tGrass_, tAir_; | |||
WGDefault(Swan::TileMap &tmap): | |||
tGrass_(tmap.getID("core::grass")), tAir_(tmap.getID("core::air")) {} | |||
void genChunk(Swan::WorldPlane &plane, Swan::Chunk &chunk, int x, int y); | |||
}; |
@@ -0,0 +1,26 @@ | |||
#include "EntPlayer.h" | |||
const float EntPlayer::FORCE = 600; | |||
const float EntPlayer::FRICTION = 100; | |||
const float EntPlayer::MASS = 80; | |||
const Swan::Vec2 EntPlayer::SIZE = Swan::Vec2(1, 2); | |||
void EntPlayer::draw(Swan::Win &win) { | |||
body_.outline(win); | |||
} | |||
void EntPlayer::update(Swan::WorldPlane &plane, float dt) { | |||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W) || sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) | |||
body_.force_ += Swan::Vec2(0, -FORCE); | |||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::S) || sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) | |||
body_.force_ += Swan::Vec2(0, FORCE); | |||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A) || sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) | |||
body_.force_ += Swan::Vec2(-FORCE, 0); | |||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::D) || sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) | |||
body_.force_ += Swan::Vec2(FORCE, 0); | |||
body_.friction(FRICTION); | |||
body_.gravity(); | |||
body_.update(dt); | |||
body_.collide(plane); | |||
} |
@@ -0,0 +1,25 @@ | |||
#pragma once | |||
#include <swan/swan.h> | |||
class EntPlayer: public Swan::Entity { | |||
public: | |||
class Factory: public Swan::Entity::Factory { | |||
public: | |||
Swan::Entity *create(const Swan::Vec2 &pos) override { return new EntPlayer(pos); } | |||
}; | |||
Swan::Body body_; | |||
EntPlayer(Swan::Vec2 pos): | |||
body_(pos, SIZE, MASS) {} | |||
void draw(Swan::Win &win) override; | |||
void update(Swan::WorldPlane &plane, float dt) override; | |||
private: | |||
static const float FORCE; | |||
static const float FRICTION; | |||
static const float MASS; | |||
static const Swan::Vec2 SIZE; | |||
}; |
@@ -0,0 +1,22 @@ | |||
#include <swan/swan.h> | |||
#include "WGDefault.h" | |||
#include "entities/EntPlayer.h" | |||
extern "C" void mod_init(Swan::Mod &mod) { | |||
mod.init("core"); | |||
mod.registerTile("air", (new Swan::Tile("assets/tiles/air.png"))->solid(false)); | |||
mod.registerTile("stone", (new Swan::Tile("assets/tiles/stone.png"))); | |||
mod.registerTile("dirt", (new Swan::Tile("assets/tiles/dirt.png"))); | |||
mod.registerTile("grass", (new Swan::Tile("assets/tiles/grass.png"))); | |||
mod.registerWorldGen("default", new WGDefault::Factory()); | |||
mod.registerEntity("player", new EntPlayer::Factory()); | |||
} | |||
int main() { | |||
Swan::Mod mod; | |||
mod.init("core"); | |||
} |
@@ -1,39 +0,0 @@ | |||
#include <swan/Mod.h> | |||
class DefaultWorldGen: public Swan::WorldGen { | |||
public: | |||
class Factory: public Swan::WorldGen::Factory { | |||
public: | |||
WorldGen *create(Swan::TileMap &tmap) { return new DefaultWorldGen(tmap); } | |||
}; | |||
Swan::Tile::ID tGrass_, tAir_; | |||
DefaultWorldGen(Swan::TileMap &tmap): | |||
tGrass_(tmap.getID("core::grass")), tAir_(tmap.getID("core::air")) {} | |||
void genChunk(Swan::Chunk &chunk, int x, int y) { | |||
fprintf(stderr, "genChunk at %i, %i\n", x, y); | |||
for (int x = 0; x < Swan::CHUNK_WIDTH; ++x) { | |||
for (int y = 0; y < Swan::CHUNK_HEIGHT; ++y) { | |||
chunk.tiles_[x][y] = y == 3 ? tGrass_ : tAir_; | |||
} | |||
} | |||
} | |||
}; | |||
extern "C" void mod_init(Swan::Mod &mod) { | |||
mod.init("core"); | |||
mod.registerTile("air", (new Swan::Tile("assets/tiles/air.png"))->solid(false)); | |||
mod.registerTile("stone", (new Swan::Tile("assets/tiles/stone.png"))); | |||
mod.registerTile("dirt", (new Swan::Tile("assets/tiles/dirt.png"))); | |||
mod.registerTile("grass", (new Swan::Tile("assets/tiles/grass.png"))); | |||
mod.registerWorldGen("default", new DefaultWorldGen::Factory()); | |||
} | |||
int main() { | |||
Swan::Mod mod; | |||
mod.init("core"); | |||
} |
@@ -3,7 +3,6 @@ add_library(libswan SHARED | |||
src/Chunk.cc | |||
src/Game.cc | |||
src/Mod.cc | |||
src/Player.cc | |||
src/Tile.cc | |||
src/World.cc | |||
src/WorldPlane.cc) |
@@ -25,32 +25,11 @@ public: | |||
sprite_ = sf::Sprite(texture_); | |||
} | |||
void setTileID(TileMap &tmap, RelPos pos, Tile::ID id) { | |||
tiles_[pos.x_][pos.y_] = id; | |||
drawBlock(tmap, pos, id); | |||
} | |||
Tile &getTile(TileMap &tmap, RelPos pos) { | |||
return tmap.get(tiles_[pos.x_][pos.y_]); | |||
} | |||
void drawBlock(RelPos pos, const Tile &t) { | |||
texture_.update(t.image_, pos.x_ * TILE_SIZE, pos.y_ * TILE_SIZE); | |||
dirty_ = true; | |||
} | |||
void drawBlock(TileMap &tmap, RelPos pos, Tile::ID id) { | |||
drawBlock(pos, tmap.get(id)); | |||
} | |||
void redraw(TileMap &tmap) { | |||
for (int x = 0; x < CHUNK_WIDTH; ++x) { | |||
for (int y = 0; y < CHUNK_HEIGHT; ++y) { | |||
drawBlock(tmap, ChunkPos(x, y), tiles_[x][y]); | |||
} | |||
} | |||
} | |||
void setTileID(TileMap &tmap, RelPos pos, Tile::ID id); | |||
Tile &getTile(TileMap &tmap, RelPos pos); | |||
void drawBlock(RelPos pos, const Tile &t); | |||
void drawBlock(TileMap &tmap, RelPos pos, Tile::ID id); | |||
void redraw(TileMap &tmap); | |||
void draw(Win &win); | |||
}; | |||
@@ -3,19 +3,23 @@ | |||
#include <memory> | |||
#include "common.h" | |||
#include "WorldPlane.h" | |||
namespace Swan { | |||
class Entity { | |||
public: | |||
class Factory { | |||
public: | |||
std::string name_; | |||
virtual Entity *create(const Vec2 &pos) = 0; | |||
public: | |||
std::string name_; | |||
virtual Entity *create(const Vec2 &pos) = 0; | |||
virtual ~Factory() = default; | |||
}; | |||
virtual ~Entity() = default; | |||
virtual void draw(Win &win) {} | |||
virtual void update(float dt) {} | |||
virtual void update(WorldPlane &plane, float dt) {} | |||
virtual void tick() {} | |||
}; | |||
@@ -1,26 +0,0 @@ | |||
#pragma once | |||
#include "common.h" | |||
#include "Body.h" | |||
#include "WorldPlane.h" | |||
namespace Swan { | |||
class Player { | |||
public: | |||
Player(Vec2 pos): | |||
body_(pos, SIZE, MASS) {} | |||
void draw(Win &win); | |||
void update(WorldPlane &plane, float dt); | |||
private: | |||
static const float FORCE; | |||
static const float FRICTION; | |||
static const float MASS; | |||
static const Vec2 SIZE; | |||
Body body_; | |||
}; | |||
} |
@@ -5,7 +5,6 @@ | |||
#include <string> | |||
#include "common.h" | |||
#include "Player.h" | |||
#include "Tile.h" | |||
#include "WorldPlane.h" | |||
#include "WorldGen.h" | |||
@@ -15,8 +14,6 @@ namespace Swan { | |||
class World { | |||
public: | |||
Player *player_; | |||
WorldPlane::ID current_plane_; | |||
std::vector<WorldPlane> planes_; | |||
std::string default_worldgen_; |
@@ -4,6 +4,7 @@ | |||
#include "Chunk.h" | |||
#include "TileMap.h" | |||
#include "WorldPlane.h" | |||
namespace Swan { | |||
@@ -13,11 +14,12 @@ public: | |||
public: | |||
std::string name_; | |||
virtual WorldGen *create(TileMap &tmap) = 0; | |||
virtual ~Factory() = default; | |||
}; | |||
virtual ~WorldGen() = default; | |||
virtual void genChunk(Chunk &chunk, int x, int y) = 0; | |||
virtual void genChunk(WorldPlane &plane, Chunk &chunk, int x, int y) = 0; | |||
}; | |||
} |
@@ -8,12 +8,12 @@ | |||
#include "Chunk.h" | |||
#include "Tile.h" | |||
#include "TileMap.h" | |||
#include "WorldGen.h" | |||
#include "Entity.h" | |||
namespace Swan { | |||
class World; | |||
class WorldGen; | |||
class Entity; | |||
class WorldPlane { | |||
public: | |||
@@ -26,7 +26,11 @@ public: | |||
std::vector<std::shared_ptr<Entity>> entities_; | |||
WorldPlane(ID id, World *world, std::shared_ptr<WorldGen> gen): | |||
id_(id), world_(world), gen_(gen) {} | |||
id_(id), world_(world), gen_(gen) { | |||
getChunk(0, 0); // Create the initial chunk | |||
} | |||
Entity &spawnEntity(const std::string &name, const Vec2 &pos); | |||
Chunk &getChunk(int x, int y); | |||
void setTileID(int x, int y, Tile::ID id); |
@@ -0,0 +1,14 @@ | |||
#pragma once | |||
#include <swan/Body.h> | |||
#include <swan/Chunk.h> | |||
#include <swan/Entity.h> | |||
#include <swan/Game.h> | |||
#include <swan/Mod.h> | |||
#include <swan/Tile.h> | |||
#include <swan/TileMap.h> | |||
#include <swan/Vector2.h> | |||
#include <swan/WorldGen.h> | |||
#include <swan/World.h> | |||
#include <swan/WorldPlane.h> | |||
#include <swan/common.h> |
@@ -2,6 +2,32 @@ | |||
namespace Swan { | |||
void Chunk::setTileID(TileMap &tmap, RelPos pos, Tile::ID id) { | |||
tiles_[pos.x_][pos.y_] = id; | |||
drawBlock(tmap, pos, id); | |||
} | |||
Tile &Chunk::getTile(TileMap &tmap, RelPos pos) { | |||
return tmap.get(tiles_[pos.x_][pos.y_]); | |||
} | |||
void Chunk::drawBlock(RelPos pos, const Tile &t) { | |||
texture_.update(t.image_, pos.x_ * TILE_SIZE, pos.y_ * TILE_SIZE); | |||
dirty_ = true; | |||
} | |||
void Chunk::drawBlock(TileMap &tmap, RelPos pos, Tile::ID id) { | |||
drawBlock(pos, tmap.get(id)); | |||
} | |||
void Chunk::redraw(TileMap &tmap) { | |||
for (int x = 0; x < CHUNK_WIDTH; ++x) { | |||
for (int y = 0; y < CHUNK_HEIGHT; ++y) { | |||
drawBlock(tmap, ChunkPos(x, y), tiles_[x][y]); | |||
} | |||
} | |||
} | |||
void Chunk::draw(Win &win) { | |||
if (dirty_) { | |||
sprite_.setTexture(texture_); |
@@ -40,18 +40,15 @@ void Game::createWorld(std::string worldgen) { | |||
} | |||
void Game::draw(Win &win) { | |||
if (world_) | |||
world_->draw(win); | |||
world_->draw(win); | |||
} | |||
void Game::update(float dt) { | |||
if (world_) | |||
world_->update(dt); | |||
world_->update(dt); | |||
} | |||
void Game::tick() { | |||
if (world_) | |||
world_->tick(); | |||
world_->tick(); | |||
} | |||
void Game::initGlobal() { |
@@ -1,32 +0,0 @@ | |||
#include "Player.h" | |||
namespace Swan { | |||
const float Player::FORCE = 600; | |||
const float Player::FRICTION = 100; | |||
const float Player::MASS = 80; | |||
const Vec2 Player::SIZE = Vec2(1, 2); | |||
using Keyboard = sf::Keyboard; | |||
void Player::draw(Win &win) { | |||
body_.outline(win); | |||
} | |||
void Player::update(WorldPlane &plane, float dt) { | |||
if (Keyboard::isKeyPressed(Keyboard::W) || Keyboard::isKeyPressed(Keyboard::Up)) | |||
body_.force_ += Vec2(0, -FORCE); | |||
if (Keyboard::isKeyPressed(Keyboard::S) || Keyboard::isKeyPressed(Keyboard::Down)) | |||
body_.force_ += Vec2(0, FORCE); | |||
if (Keyboard::isKeyPressed(Keyboard::A) || Keyboard::isKeyPressed(Keyboard::Left)) | |||
body_.force_ += Vec2(-FORCE, 0); | |||
if (Keyboard::isKeyPressed(Keyboard::D) || Keyboard::isKeyPressed(Keyboard::Right)) | |||
body_.force_ += Vec2(FORCE, 0); | |||
body_.friction(FRICTION); | |||
body_.gravity(); | |||
body_.update(dt); | |||
body_.collide(plane); | |||
} | |||
} |
@@ -17,14 +17,11 @@ WorldPlane::ID World::addPlane(std::string gen) { | |||
void World::draw(Win &win) { | |||
planes_[current_plane_].draw(win); | |||
player_->draw(win); | |||
} | |||
void World::update(float dt) { | |||
for (auto &plane: planes_) | |||
plane.update(dt); | |||
player_->update(planes_[current_plane_], dt); | |||
} | |||
void World::tick() { |
@@ -20,14 +20,28 @@ static Chunk::RelPos relPos(int x, int y) { | |||
return Chunk::RelPos(rx, ry); | |||
} | |||
Entity &WorldPlane::spawnEntity(const std::string &name, const Vec2 &pos) { | |||
if (world_->ents_.find(name) == world_->ents_.end()) { | |||
fprintf(stderr, "Tried to spawn non-existant entity %s!", | |||
name.c_str()); | |||
abort(); | |||
} | |||
Entity *ent = world_->ents_[name]->create(pos); | |||
entities_.push_back(std::shared_ptr<Entity>(ent)); | |||
fprintf(stderr, "Spawned %s at %f,%f.\n", name.c_str(), pos.x_, pos.y_); | |||
return *ent; | |||
} | |||
Chunk &WorldPlane::getChunk(int x, int y) { | |||
Chunk::ChunkPos pos = chunkPos(x, y); | |||
auto it = chunks_.find(pos); | |||
if (it == chunks_.end()) { | |||
it = chunks_.emplace(pos, Chunk(pos)).first; | |||
gen_->genChunk(it->second, pos.x_, pos.y_); | |||
gen_->genChunk(*this, it->second, pos.x_, pos.y_); | |||
it->second.redraw(world_->tile_map_); | |||
fprintf(stderr, "Generated chunk %i,%i\n", pos.x_, pos.y_); | |||
} | |||
return it->second; | |||
@@ -51,7 +65,7 @@ void WorldPlane::draw(Win &win) { | |||
void WorldPlane::update(float dt) { | |||
for (auto &ent: entities_) | |||
ent->update(dt); | |||
ent->update(*this, dt); | |||
} | |||
void WorldPlane::tick() { |
@@ -3,7 +3,6 @@ | |||
#include <unistd.h> | |||
#include <swan/common.h> | |||
#include <swan/Player.h> | |||
#include <swan/World.h> | |||
#include <swan/Game.h> | |||
@@ -27,7 +26,6 @@ int main() { | |||
game.createWorld("core::default"); | |||
game.world_->setCurrentPlane(game.world_->addPlane()); | |||
game.world_->player_ = new Player(Vec2(1, 1)); | |||
double prevtime = getTime(); | |||
double fpsAcc = 0; |