void WGDefault::genChunk(Swan::WorldPlane &plane, Swan::Chunk &chunk) { | void WGDefault::genChunk(Swan::WorldPlane &plane, Swan::Chunk &chunk) { | ||||
for (int cx = 0; cx < Swan::CHUNK_WIDTH; ++cx) { | for (int cx = 0; cx < Swan::CHUNK_WIDTH; ++cx) { | ||||
for (int cy = 0; cy < Swan::CHUNK_HEIGHT; ++cy) { | 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) | if (tpos.y_ == 3) | ||||
chunk.tiles_[cx][cy] = tGrass_; | chunk.tiles_[cx][cy] = tGrass_; | ||||
else if (tpos.y_ > 3 && tpos.y_ <= 5) | else if (tpos.y_ > 3 && tpos.y_ <= 5) |
src/Game.cc | src/Game.cc | ||||
src/Mod.cc | src/Mod.cc | ||||
src/Tile.cc | src/Tile.cc | ||||
src/Timer.cc | |||||
src/World.cc | src/World.cc | ||||
src/WorldPlane.cc) | src/WorldPlane.cc) | ||||
target_include_directories(libswan PUBLIC "include/swan") | target_include_directories(libswan PUBLIC "include/swan") |
#include <string> | |||||
namespace Swan { | |||||
class Timer { | |||||
public: | |||||
Timer &start(); | |||||
Timer &print(const std::string &str); | |||||
static double now(); | |||||
private: | |||||
std::string name_; | |||||
double start_; | |||||
}; | |||||
} |
return std::pair<T, T>(x_, y_); | 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 { | Vector2<T> operator-() const { | ||||
return Vector2<T>(-x_, -y_); | return Vector2<T>(-x_, -y_); | ||||
} | } | ||||
}; | }; | ||||
using Vec2 = Vector2<float>; | using Vec2 = Vector2<float>; | ||||
using Vec2i = Vector2<int>; | |||||
} | } |
std::map<std::string, std::shared_ptr<WorldGen::Factory>> worldgens_; | std::map<std::string, std::shared_ptr<WorldGen::Factory>> worldgens_; | ||||
std::map<std::string, std::shared_ptr<Entity::Factory>> ents_; | std::map<std::string, std::shared_ptr<Entity::Factory>> ents_; | ||||
TileMap tile_map_; | TileMap tile_map_; | ||||
Entity *player_; | |||||
private: | private: | ||||
Entity *player_; | |||||
class ChunkRenderer { | |||||
public: | |||||
void tick(WorldPlane &plane, ChunkPos abspos); | |||||
private: | |||||
int level_ = 1; | |||||
}; | |||||
ChunkRenderer chunk_renderer_; | |||||
WorldPlane::ID current_plane_; | WorldPlane::ID current_plane_; | ||||
std::vector<WorldPlane> planes_; | std::vector<WorldPlane> planes_; | ||||
std::string default_world_gen_; | std::string default_world_gen_; |
Entity &spawnEntity(const std::string &name, const Vec2 &pos); | Entity &spawnEntity(const std::string &name, const Vec2 &pos); | ||||
bool hasChunk(ChunkPos pos); | |||||
Chunk &getChunk(ChunkPos pos); | Chunk &getChunk(ChunkPos pos); | ||||
void setTileID(TilePos pos, Tile::ID id); | void setTileID(TilePos pos, Tile::ID id); | ||||
Tile &getTile(TilePos pos); | Tile &getTile(TilePos pos); |
static constexpr int TILE_SIZE = 32; | static constexpr int TILE_SIZE = 32; | ||||
static constexpr int TICK_RATE = 20; | 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 { | struct Win { | ||||
public: | public: |
#include <swan/Mod.h> | #include <swan/Mod.h> | ||||
#include <swan/Tile.h> | #include <swan/Tile.h> | ||||
#include <swan/TileMap.h> | #include <swan/TileMap.h> | ||||
#include <swan/Timer.h> | |||||
#include <swan/Vector2.h> | #include <swan/Vector2.h> | ||||
#include <swan/WorldGen.h> | #include <swan/WorldGen.h> | ||||
#include <swan/World.h> | #include <swan/World.h> |
#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); | |||||
} | |||||
} |
namespace Swan { | 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) { | void World::setCurrentPlane(WorldPlane &plane) { | ||||
current_plane_ = plane.id_; | current_plane_ = plane.id_; | ||||
} | } | ||||
void World::tick() { | void World::tick() { | ||||
for (auto &plane: planes_) | for (auto &plane: planes_) | ||||
plane.tick(); | plane.tick(); | ||||
const Vec2 &abspos = player_->getPos(); | |||||
chunk_renderer_.tick( | |||||
planes_[current_plane_], | |||||
ChunkPos((int)abspos.x_ / CHUNK_WIDTH, (int)abspos.y_ / CHUNK_HEIGHT)); | |||||
} | } | ||||
} | } |
#include "WorldPlane.h" | #include "WorldPlane.h" | ||||
#include "World.h" | #include "World.h" | ||||
#include "Timer.h" | |||||
namespace Swan { | namespace Swan { | ||||
return *ent; | return *ent; | ||||
} | } | ||||
bool WorldPlane::hasChunk(ChunkPos pos) { | |||||
return chunks_.find(pos) != chunks_.end(); | |||||
} | |||||
Chunk &WorldPlane::getChunk(ChunkPos pos) { | Chunk &WorldPlane::getChunk(ChunkPos pos) { | ||||
auto iter = chunks_.find(pos); | auto iter = chunks_.find(pos); | ||||
iter = chunks_.emplace(pos, new Chunk(pos)).first; | iter = chunks_.emplace(pos, new Chunk(pos)).first; | ||||
gen_->genChunk(*this, *iter->second); | gen_->genChunk(*this, *iter->second); | ||||
iter->second->redraw(world_->tile_map_); | iter->second->redraw(world_->tile_map_); | ||||
fprintf(stderr, "Generated chunk %i,%i\n", pos.x_, pos.y_); | |||||
} | } | ||||
return *iter->second; | return *iter->second; |
#include <swan/common.h> | #include <swan/common.h> | ||||
#include <swan/World.h> | #include <swan/World.h> | ||||
#include <swan/Game.h> | #include <swan/Game.h> | ||||
#include <swan/Timer.h> | |||||
using namespace Swan; | 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() { | int main() { | ||||
sf::RenderWindow window(sf::VideoMode(800, 600), "good gaem"); | sf::RenderWindow window(sf::VideoMode(800, 600), "good gaem"); | ||||
window.setVerticalSyncEnabled(true); | window.setVerticalSyncEnabled(true); | ||||
game.createWorld("core::default"); | game.createWorld("core::default"); | ||||
double prevtime = getTime(); | |||||
double prevtime = Timer::now(); | |||||
double fpsAcc = 0; | double fpsAcc = 0; | ||||
double tickAcc = 0; | double tickAcc = 0; | ||||
int fcount = 0; | int fcount = 0; | ||||
} | } | ||||
// Display FPS | // Display FPS | ||||
double now = getTime(); | |||||
double now = Timer::now(); | |||||
double dt = now - prevtime; | double dt = now - prevtime; | ||||
prevtime = now; | prevtime = now; | ||||
fpsAcc += dt; | fpsAcc += dt; |