@@ -11,6 +11,13 @@ void EntItemStack::draw(const Swan::Context &ctx, Swan::Win &win) { | |||
win.draw(sprite_); | |||
} | |||
void EntItemStack::tick(const Swan::Context &ctx, float dt) { | |||
despawn_timer_ -= dt; | |||
if (despawn_timer_ <= 0) { | |||
ctx.plane.despawnEntity(*this); | |||
} | |||
} | |||
void EntItemStack::readSRF(const Swan::Context &ctx, const Swan::SRF &srf) { | |||
auto &arr = dynamic_cast<const Swan::SRFArray &>(srf); | |||
auto *pos = dynamic_cast<Swan::SRFFloatArray *>(arr.val[0].get()); |
@@ -13,13 +13,16 @@ public: | |||
EntItemStack(const Swan::Context &ctx, const Swan::SRF ¶ms); | |||
void draw(const Swan::Context &ctx, Swan::Win &win) override; | |||
void tick(const Swan::Context &ctx, float dt) override; | |||
void readSRF(const Swan::Context &ctx, const Swan::SRF &srf) override; | |||
Swan::SRF *writeSRF(const Swan::Context &ctx) override; | |||
private: | |||
static constexpr float MASS = 80; | |||
static constexpr Swan::Vec2 SIZE = Swan::Vec2(0.5, 0.5); | |||
static constexpr float DESPAWN_TIME = 5 * 60; | |||
float despawn_timer_ = DESPAWN_TIME; | |||
Swan::Item *item_ = &Swan::Item::INVALID_ITEM; | |||
sf::Texture tex_; | |||
sf::Sprite sprite_; |
@@ -36,13 +36,13 @@ public: | |||
void decompress(); | |||
void render(const Context &ctx); | |||
void draw(const Context &ctx, Win &win); | |||
void tick(); | |||
void tick(float dt); | |||
bool keepActive(); // Returns true if chunk was inactive | |||
bool isActive() { return active_timer_ != 0; } | |||
bool isActive() { return deactivate_timer_ > 0; } | |||
private: | |||
static constexpr int ACTIVE_TIMEOUT = 200; | |||
static constexpr float DEACTIVATE_TIME = 20; | |||
static sf::Uint8 *renderbuf; | |||
bool isCompressed() { return compressed_size_ != -1; } | |||
@@ -51,7 +51,7 @@ private: | |||
ssize_t compressed_size_ = -1; // -1 if not compressed, a positive number if compressed | |||
bool need_render_ = false; | |||
int active_timer_ = ACTIVE_TIMEOUT; | |||
int deactivate_timer_ = DEACTIVATE_TIME; | |||
struct Visuals { | |||
sf::Texture tex_; |
@@ -29,9 +29,10 @@ public: | |||
virtual void draw(const Context &ctx, Win &win) {} | |||
virtual void update(const Context &ctx, float dt) {} | |||
virtual void tick() {} | |||
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 readSRF(const Swan::Context &ctx, const SRF &srf) {} | |||
virtual SRF *writeSRF(const Swan::Context &ctx) { return new SRFNone(); } | |||
}; |
@@ -34,7 +34,7 @@ public: | |||
void draw(); | |||
void update(float dt); | |||
void tick(); | |||
void tick(float dt); | |||
static void initGlobal(); | |||
@@ -39,7 +39,7 @@ public: | |||
void draw(Win &win); | |||
void update(float dt); | |||
void tick(); | |||
void tick(float dt); | |||
std::vector<std::shared_ptr<Tile>> tiles_; | |||
std::map<std::string, Tile::ID> tiles_map_; |
@@ -25,6 +25,7 @@ public: | |||
id_(id), world_(world), gen_(gen) {} | |||
Entity &spawnEntity(const std::string &name, const SRF ¶ms); | |||
void despawnEntity(Entity &ent); | |||
Context getContext(); | |||
@@ -40,7 +41,7 @@ public: | |||
void draw(Win &win); | |||
void update(float dt); | |||
void tick(); | |||
void tick(float dt); | |||
void debugBox(TilePos pos); | |||
@@ -53,7 +54,7 @@ private: | |||
std::set<Chunk *> active_chunks_; | |||
std::vector<std::unique_ptr<Entity>> entities_; | |||
std::vector<std::unique_ptr<Entity>> spawn_list_; | |||
std::vector<Entity *> kill_list_; | |||
std::vector<Entity *> despawn_list_; | |||
std::vector<TilePos> debug_boxes_; | |||
}; | |||
@@ -140,19 +140,19 @@ void Chunk::draw(const Context &ctx, Win &win) { | |||
win.draw(visuals_->sprite_); | |||
} | |||
void Chunk::tick() { | |||
if (active_timer_ == 0) | |||
void Chunk::tick(float dt) { | |||
if (deactivate_timer_ <= 0) | |||
return; | |||
active_timer_ -= 1; | |||
if (active_timer_ == 0) { | |||
deactivate_timer_ -= dt; | |||
if (deactivate_timer_ <= 0) { | |||
compress(); | |||
} | |||
} | |||
bool Chunk::keepActive() { | |||
bool wasActive = isActive(); | |||
active_timer_ = ACTIVE_TIMEOUT; | |||
deactivate_timer_ = DEACTIVATE_TIME; | |||
if (wasActive) | |||
return false; |
@@ -65,8 +65,8 @@ void Game::update(float dt) { | |||
world_->update(dt); | |||
} | |||
void Game::tick() { | |||
world_->tick(); | |||
void Game::tick(float dt) { | |||
world_->tick(dt); | |||
} | |||
void Game::initGlobal() { |
@@ -131,9 +131,9 @@ void World::update(float dt) { | |||
plane.update(dt); | |||
} | |||
void World::tick() { | |||
void World::tick(float dt) { | |||
for (auto &plane: planes_) | |||
plane.tick(); | |||
plane.tick(dt); | |||
auto bounds = *player_->getBounds(); | |||
chunk_renderer_.tick( |
@@ -47,6 +47,11 @@ Entity &WorldPlane::spawnEntity(const std::string &name, const SRF ¶ms) { | |||
return *ent; | |||
} | |||
void WorldPlane::despawnEntity(Entity &ent) { | |||
fprintf(stderr, "Despawned entity.\n"); | |||
despawn_list_.push_back(&ent); | |||
} | |||
bool WorldPlane::hasChunk(ChunkPos pos) { | |||
return chunks_.find(pos) != chunks_.end(); | |||
} | |||
@@ -148,14 +153,24 @@ void WorldPlane::update(float dt) { | |||
for (auto &ent: spawn_list_) | |||
entities_.push_back(std::move(ent)); | |||
spawn_list_.clear(); | |||
for (auto entptr: despawn_list_) { | |||
for (auto it = std::begin(entities_); it != std::end(entities_); ++it) { | |||
if (it->get() == entptr) { | |||
entities_.erase(it); | |||
break; | |||
} | |||
} | |||
} | |||
despawn_list_.clear(); | |||
} | |||
void WorldPlane::tick() { | |||
void WorldPlane::tick(float dt) { | |||
for (auto &ent: entities_) | |||
ent->tick(); | |||
ent->tick(getContext(), dt); | |||
for (auto &chunk: active_chunks_) { | |||
chunk->tick(); | |||
chunk->tick(dt); | |||
if (!chunk->isActive()) | |||
active_chunks_.erase(chunk); | |||
} |
@@ -115,7 +115,7 @@ int main() { | |||
tickAcc += dt; | |||
while (tickAcc >= 1.0 / TICK_RATE) { | |||
tickAcc -= 1.0 / TICK_RATE; | |||
game.tick(); | |||
game.tick(1.0 / TICK_RATE); | |||
} | |||
} | |||