@@ -3,7 +3,8 @@ | |||
void WGDefault::genChunk(Swan::WorldPlane &plane, Swan::Chunk &chunk) { | |||
for (int cx = 0; cx < Swan::CHUNK_WIDTH; ++cx) { | |||
for (int cy = 0; cy < Swan::CHUNK_HEIGHT; ++cy) { | |||
Swan::TilePos tpos = Swan::TilePos(cx, cy) + chunk.pos_ * Swan::TILE_SIZE; | |||
Swan::TilePos tpos = Swan::TilePos(cx, cy) + Swan::TilePos( | |||
chunk.pos_.x_ * Swan::CHUNK_WIDTH, chunk.pos_.y_ * Swan::CHUNK_HEIGHT); | |||
if (tpos.y_ == 3) | |||
chunk.tiles_[cx][cy] = tGrass_; | |||
else if (tpos.y_ > 3 && tpos.y_ <= 5) |
@@ -4,6 +4,7 @@ add_library(libswan SHARED | |||
src/Game.cc | |||
src/Mod.cc | |||
src/Tile.cc | |||
src/Timer.cc | |||
src/World.cc | |||
src/WorldPlane.cc) | |||
target_include_directories(libswan PUBLIC "include/swan") |
@@ -0,0 +1,17 @@ | |||
#include <string> | |||
namespace Swan { | |||
class Timer { | |||
public: | |||
Timer &start(); | |||
Timer &print(const std::string &str); | |||
static double now(); | |||
private: | |||
std::string name_; | |||
double start_; | |||
}; | |||
} |
@@ -18,6 +18,14 @@ public: | |||
return std::pair<T, T>(x_, y_); | |||
} | |||
bool operator==(const Vector2<T> &vec) const { | |||
return x_ == vec.x_ && y_ == vec.y_; | |||
} | |||
bool operator!=(const Vector2<T> &vec) const { | |||
return !(*this == vec); | |||
} | |||
Vector2<T> operator-() const { | |||
return Vector2<T>(-x_, -y_); | |||
} | |||
@@ -83,5 +91,6 @@ public: | |||
}; | |||
using Vec2 = Vector2<float>; | |||
using Vec2i = Vector2<int>; | |||
} |
@@ -30,9 +30,18 @@ public: | |||
std::map<std::string, std::shared_ptr<WorldGen::Factory>> worldgens_; | |||
std::map<std::string, std::shared_ptr<Entity::Factory>> ents_; | |||
TileMap tile_map_; | |||
Entity *player_; | |||
private: | |||
Entity *player_; | |||
class ChunkRenderer { | |||
public: | |||
void tick(WorldPlane &plane, ChunkPos abspos); | |||
private: | |||
int level_ = 1; | |||
}; | |||
ChunkRenderer chunk_renderer_; | |||
WorldPlane::ID current_plane_; | |||
std::vector<WorldPlane> planes_; | |||
std::string default_world_gen_; |
@@ -24,6 +24,7 @@ public: | |||
Entity &spawnEntity(const std::string &name, const Vec2 &pos); | |||
bool hasChunk(ChunkPos pos); | |||
Chunk &getChunk(ChunkPos pos); | |||
void setTileID(TilePos pos, Tile::ID id); | |||
Tile &getTile(TilePos pos); |
@@ -9,11 +9,11 @@ namespace Swan { | |||
static constexpr int TILE_SIZE = 32; | |||
static constexpr int TICK_RATE = 20; | |||
static constexpr int CHUNK_HEIGHT = 32; | |||
static constexpr int CHUNK_WIDTH = 32; | |||
static constexpr int CHUNK_HEIGHT = 4; | |||
static constexpr int CHUNK_WIDTH = 8; | |||
using TilePos = Vector2<int>; | |||
using ChunkPos = Vector2<int>; | |||
using TilePos = Vec2i; | |||
using ChunkPos = Vec2i; | |||
struct Win { | |||
public: |
@@ -7,6 +7,7 @@ | |||
#include <swan/Mod.h> | |||
#include <swan/Tile.h> | |||
#include <swan/TileMap.h> | |||
#include <swan/Timer.h> | |||
#include <swan/Vector2.h> | |||
#include <swan/WorldGen.h> | |||
#include <swan/World.h> |
@@ -0,0 +1,30 @@ | |||
#include "Timer.h" | |||
#include <time.h> | |||
namespace Swan { | |||
Timer &Timer::start() { | |||
start_ = now(); | |||
return *this; | |||
} | |||
Timer &Timer::print(const std::string &str) { | |||
double t = now() - start_; | |||
if (t > 1) | |||
fprintf(stderr, "%s: %.2fs\n", str.c_str(), t); | |||
else if (t > 0.001) | |||
fprintf(stderr, "%s: %.2fms\n", str.c_str(), t * 1000); | |||
else | |||
fprintf(stderr, "%s: %.2fμ\n", str.c_str(), t * 1000000); | |||
return *this; | |||
} | |||
double Timer::now() { | |||
struct timespec ts; | |||
clock_gettime(CLOCK_MONOTONIC, &ts); | |||
return (double)ts.tv_sec + ((double)ts.tv_nsec / 1000000000.0); | |||
} | |||
} |
@@ -2,6 +2,32 @@ | |||
namespace Swan { | |||
void World::ChunkRenderer::tick(WorldPlane &plane, ChunkPos abspos) { | |||
Vec2i dir(1, 0); | |||
ChunkPos relpos(-level_, -level_); | |||
if (!plane.hasChunk(abspos)) { | |||
plane.getChunk(abspos); | |||
level_ = 1; | |||
relpos = ChunkPos(-level_, -level_); | |||
} | |||
do { | |||
if (relpos == ChunkPos(level_, -level_)) | |||
dir = Vec2i(0, 1); | |||
else if (relpos == ChunkPos(level_, level_)) | |||
dir = Vec2i(-1, 0); | |||
else if (relpos == ChunkPos(-level_, level_)) | |||
dir = Vec2i(0, -1); | |||
plane.getChunk(abspos + relpos); | |||
relpos += dir; | |||
} while (relpos != ChunkPos(-level_, -level_)); | |||
if (level_ < 5) | |||
level_ += 1; | |||
} | |||
void World::setCurrentPlane(WorldPlane &plane) { | |||
current_plane_ = plane.id_; | |||
} | |||
@@ -57,6 +83,11 @@ void World::update(float dt) { | |||
void World::tick() { | |||
for (auto &plane: planes_) | |||
plane.tick(); | |||
const Vec2 &abspos = player_->getPos(); | |||
chunk_renderer_.tick( | |||
planes_[current_plane_], | |||
ChunkPos((int)abspos.x_ / CHUNK_WIDTH, (int)abspos.y_ / CHUNK_HEIGHT)); | |||
} | |||
} |
@@ -1,6 +1,7 @@ | |||
#include "WorldPlane.h" | |||
#include "World.h" | |||
#include "Timer.h" | |||
namespace Swan { | |||
@@ -33,6 +34,10 @@ Entity &WorldPlane::spawnEntity(const std::string &name, const Vec2 &pos) { | |||
return *ent; | |||
} | |||
bool WorldPlane::hasChunk(ChunkPos pos) { | |||
return chunks_.find(pos) != chunks_.end(); | |||
} | |||
Chunk &WorldPlane::getChunk(ChunkPos pos) { | |||
auto iter = chunks_.find(pos); | |||
@@ -40,7 +45,6 @@ Chunk &WorldPlane::getChunk(ChunkPos pos) { | |||
iter = chunks_.emplace(pos, new Chunk(pos)).first; | |||
gen_->genChunk(*this, *iter->second); | |||
iter->second->redraw(world_->tile_map_); | |||
fprintf(stderr, "Generated chunk %i,%i\n", pos.x_, pos.y_); | |||
} | |||
return *iter->second; |
@@ -5,15 +5,10 @@ | |||
#include <swan/common.h> | |||
#include <swan/World.h> | |||
#include <swan/Game.h> | |||
#include <swan/Timer.h> | |||
using namespace Swan; | |||
static double getTime() { | |||
struct timespec ts; | |||
clock_gettime(CLOCK_MONOTONIC, &ts); | |||
return (double)ts.tv_sec + (double)ts.tv_nsec / 1000000000.0; | |||
} | |||
int main() { | |||
sf::RenderWindow window(sf::VideoMode(800, 600), "good gaem"); | |||
window.setVerticalSyncEnabled(true); | |||
@@ -26,7 +21,7 @@ int main() { | |||
game.createWorld("core::default"); | |||
double prevtime = getTime(); | |||
double prevtime = Timer::now(); | |||
double fpsAcc = 0; | |||
double tickAcc = 0; | |||
int fcount = 0; | |||
@@ -43,7 +38,7 @@ int main() { | |||
} | |||
// Display FPS | |||
double now = getTime(); | |||
double now = Timer::now(); | |||
double dt = now - prevtime; | |||
prevtime = now; | |||
fpsAcc += dt; |