@@ -3,7 +3,8 @@ project(swan) | |||
find_package(SFML 2.5 COMPONENTS graphics system window REQUIRED) | |||
add_compile_options(-Wall -Wextra -Wpedantic -Wno-unused-parameter -g) | |||
add_compile_options(-Wall -Wextra -Wpedantic -Wno-unused-parameter -g -fsanitize=address) | |||
add_link_options(-fsanitize=address) | |||
include_directories("${PROJECT_SOURCE_DIR}/libswan/include") | |||
add_subdirectory(libswan) |
@@ -4,10 +4,11 @@ | |||
extern "C" void mod_init(Swan::Mod &mod) { | |||
mod.init("core"); | |||
mod.registerTile("air", "assets/tiles/air.png"); | |||
mod.registerTile("stone", "assets/tiles/stone.png"); | |||
mod.registerTile("dirt", "assets/tiles/dirt.png"); | |||
mod.registerTile("grass", "assets/tiles/grass.png"); | |||
mod.registerTile("air", "assets/tiles/air.png", Swan::Tile::Opts() | |||
.transparent()); | |||
mod.registerTile("stone", "assets/tiles/stone.png", Swan::Tile::Opts()); | |||
mod.registerTile("dirt", "assets/tiles/dirt.png", Swan::Tile::Opts()); | |||
mod.registerTile("grass", "assets/tiles/grass.png", Swan::Tile::Opts()); | |||
} | |||
int main() { |
@@ -3,6 +3,7 @@ | |||
#include <SFML/Graphics.hpp> | |||
#include "common.h" | |||
#include "WorldPlane.h" | |||
namespace Swan { | |||
@@ -19,6 +20,7 @@ public: | |||
void friction(float coef); | |||
void gravity(Vec2 g = Vec2(0, 9.81)); | |||
void collide(WorldPlane &plane); | |||
void outline(Win &win); | |||
void update(float dt); |
@@ -14,7 +14,7 @@ class Game { | |||
public: | |||
std::vector<Mod> registered_mods_; | |||
World *world_ = NULL; | |||
std::unique_ptr<World> world_ = NULL; | |||
void loadMod(const std::string &path); | |||
void createWorld(); |
@@ -18,7 +18,7 @@ public: | |||
bool inited_ = false; | |||
void init(const std::string &name); | |||
void registerTile(const std::string &name, const std::string &asset); | |||
void registerTile(const std::string &name, const std::string &asset, const Tile::Opts &opts); | |||
}; | |||
} |
@@ -2,6 +2,7 @@ | |||
#include "common.h" | |||
#include "Body.h" | |||
#include "WorldPlane.h" | |||
namespace Swan { | |||
@@ -11,7 +12,7 @@ public: | |||
body_(pos, SIZE, MASS) {} | |||
void draw(Win &win); | |||
void update(float dt); | |||
void update(WorldPlane &plane, float dt); | |||
private: | |||
static const float FORCE; |
@@ -10,8 +10,15 @@ class Tile { | |||
public: | |||
using ID = uint16_t; | |||
struct Opts { | |||
bool transparent_ = false; | |||
Opts &transparent() { transparent_ = true; return *this; } | |||
}; | |||
std::string name_; | |||
sf::Image image_; | |||
Opts opts_; | |||
}; | |||
} |
@@ -21,8 +21,9 @@ public: | |||
ID id_; | |||
World *world_; | |||
Chunk &getChunk(int x, int y); | |||
void setTileID(int x, int y, Tile::ID id); | |||
Tile *getTile(int x, int y); | |||
Tile &getTile(int x, int y); | |||
void draw(Win &win); | |||
void update(float dt); |
@@ -10,6 +10,20 @@ void Body::gravity(Vec2 g) { | |||
force_ += g * mass_; | |||
} | |||
void Body::collide(WorldPlane &plane) { | |||
int startx = (int)pos_.x; | |||
int endx = (int)(pos_.x + size_.x); | |||
int y = (int)(pos_.y + size_.y); | |||
for (int x = startx; x <= endx; ++x) { | |||
Tile &tile = plane.getTile(x, y); | |||
if (!tile.opts_.transparent_) { | |||
pos_.y = y - size_.y; | |||
vel_.y = 0; | |||
} | |||
} | |||
} | |||
void Body::outline(Win &win) { | |||
sf::RectangleShape rect(size_ * TILE_SIZE); | |||
rect.setPosition(pos_ * TILE_SIZE); |
@@ -24,10 +24,7 @@ void Game::loadMod(const std::string &path) { | |||
} | |||
void Game::createWorld() { | |||
if (world_ != NULL) | |||
delete world_; | |||
world_ = new World(); | |||
world_.reset(new World()); | |||
for (auto &mod: registered_mods_) { | |||
for (auto &tile: mod.tiles_) { | |||
world_->registerTile(&tile); |
@@ -11,10 +11,11 @@ void Mod::init(const std::string &name) { | |||
fprintf(stderr, "Mod initing: %s\n", name_.c_str()); | |||
} | |||
void Mod::registerTile(const std::string &name, const std::string &asset) { | |||
void Mod::registerTile(const std::string &name, const std::string &asset, const Tile::Opts &opts) { | |||
tiles_.push_back(Tile()); | |||
Tile &t = tiles_.back(); | |||
t.name_ = name_ + "::" + name; | |||
t.opts_ = opts; | |||
fprintf(stderr, "Adding tile: %s\n", t.name_.c_str()); | |||
std::string asset_path = path_ + "/" + asset; |
@@ -13,7 +13,7 @@ void Player::draw(Win &win) { | |||
body_.outline(win); | |||
} | |||
void Player::update(float dt) { | |||
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)) | |||
@@ -26,6 +26,7 @@ void Player::update(float dt) { | |||
body_.friction(FRICTION); | |||
body_.gravity(); | |||
body_.update(dt); | |||
body_.collide(plane); | |||
} | |||
} |
@@ -20,7 +20,7 @@ void World::update(float dt) { | |||
for (auto &plane: planes_) | |||
plane.update(dt); | |||
player_->update(dt); | |||
player_->update(planes_[current_plane_], dt); | |||
} | |||
void World::tick() { |
@@ -4,7 +4,7 @@ | |||
namespace Swan { | |||
void WorldPlane::setTileID(int x, int y, Tile::ID id) { | |||
Chunk &WorldPlane::getChunk(int x, int y) { | |||
auto coord = Coord(x / CHUNK_WIDTH, y / CHUNK_HEIGHT); | |||
auto it = chunks_.find(coord); | |||
@@ -13,19 +13,15 @@ void WorldPlane::setTileID(int x, int y, Tile::ID id) { | |||
it->second.fill(world_->tile_map_, 0); | |||
} | |||
it->second.setTileID(world_->tile_map_, x % CHUNK_WIDTH, y % CHUNK_HEIGHT, id); | |||
return it->second; | |||
} | |||
Tile *WorldPlane::getTile(int x, int y) { | |||
auto coord = Coord(x / CHUNK_WIDTH, y / CHUNK_HEIGHT); | |||
auto it = chunks_.find(coord); | |||
if (it == chunks_.end()) { | |||
it = chunks_.emplace(coord, Chunk(coord.first, coord.second)).first; | |||
it->second.fill(world_->tile_map_, 0); | |||
} | |||
void WorldPlane::setTileID(int x, int y, Tile::ID id) { | |||
getChunk(x, y).setTileID(world_->tile_map_, x % CHUNK_WIDTH, y % CHUNK_HEIGHT, id); | |||
} | |||
return it->second.getTile(world_->tile_map_, x % CHUNK_WIDTH, y % CHUNK_HEIGHT); | |||
Tile &WorldPlane::getTile(int x, int y) { | |||
return *getChunk(x, y).getTile(world_->tile_map_, x % CHUNK_WIDTH, y % CHUNK_HEIGHT); | |||
} | |||
void WorldPlane::draw(Win &win) { |