diff options
-rw-r--r-- | src/common.hpp | 18 | ||||
-rw-r--r-- | src/game.cpp | 14 | ||||
-rw-r--r-- | src/math.hpp | 45 | ||||
-rw-r--r-- | src/render.cpp | 47 | ||||
-rw-r--r-- | src/world.cpp | 41 |
5 files changed, 93 insertions, 72 deletions
diff --git a/src/common.hpp b/src/common.hpp index 6798ec8..e135d56 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -48,11 +48,12 @@ namespace world { typedef vec_t<int64_t, 2> tile_index_t; class entity_t; + class sector_iterator_t; class sector_t { public: sector_index_t index; - sf::FloatRect bounds; + rectf_t bounds; std::unordered_set<entity_t*> ents; bool empty = true; @@ -62,6 +63,7 @@ namespace world { class world_t { procgen::prng_t prng; procgen::perlin_noise_t perlin; + std::map<sector_index_t, sector_t> sectors; void generate_tile(tile_t *tile, tile_index_t index); @@ -70,12 +72,12 @@ namespace world { public: world_t(void); sector_t *get_sector(sector_index_t index); - tile_t *get_tile(ssize_t x, ssize_t y); + tile_t *get_tile(tile_index_t index); // FIXME: iterators instead of returning std::lists - std::list<sector_t*> get_sectors(sf::FloatRect rect); - std::list<entity_t*> get_entities(sf::FloatRect rect); - std::list<entity_t*> get_render_entities(sf::FloatRect rect); + std::list<sector_t*> get_sectors(rectf_t rect); + std::list<entity_t*> get_entities(rectf_t rect); + std::list<entity_t*> get_render_entities(rectf_t rect); void render(sf::RenderWindow *window); @@ -93,7 +95,7 @@ namespace world { size_t cookie = 0; public: - sf::FloatRect bounds, render_bounds; + rectf_t bounds, render_bounds; void link(world_t *world); void unlink(); @@ -179,8 +181,8 @@ namespace render { void begin_frame(double time_); void end_frame(void); void render(game::state_t *game); - void render(animated_texture_t *anim, sf::FloatRect bounds, bool mirror = false); - void render(oriented_sprite_t *sprite, sf::FloatRect bounds, float angle); + void render(animated_texture_t *anim, rectf_t bounds, bool mirror = false); + void render(oriented_sprite_t *sprite, rectf_t bounds, float angle); }; } diff --git a/src/game.cpp b/src/game.cpp index 59b8ad9..725d6f0 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -30,10 +30,8 @@ void state_t::start(void) human_t &human = *(--humans.end()); - human.bounds.left = 0.33f; - human.bounds.top = 0; - human.bounds.width = 0.66f; - human.bounds.height = 1.0f; + human.bounds.v[0] = v2f_t(0.33f, 0); + human.bounds.v[1] = human.bounds.v[0] + v2f_t(0.66f, 1.0f); human.render_bounds = human.bounds; human.link(&world); } @@ -47,11 +45,15 @@ void state_t::tick(void) human.walking = false; if (human.stalin < 0) { + v2f_t delta; + human.walking = true; human.angle += (rand() & 2 ? 0.2f : -0.2f); human.unlink(); - human.bounds.left += cos(human.angle) * 0.04; - human.bounds.top += sin(human.angle) * 0.04; + delta = v2f_t(cos(human.angle), sin(human.angle)) * 0.04; + human.bounds[0] += delta; + human.bounds[1] += delta; + human.render_bounds = human.bounds; human.link(&world); } diff --git a/src/math.hpp b/src/math.hpp index b958092..f20cc99 100644 --- a/src/math.hpp +++ b/src/math.hpp @@ -44,6 +44,12 @@ public: return v[i]; } + void broadcast(T x) + { + for (size_t i = 0; i < N; i++) + v[i] = x; + } + // Comparison friend bool operator==(const vec_t<T, N> &a, const vec_t<T, N> &b) @@ -205,27 +211,48 @@ public: } }; -// Shorthands -typedef vec_t<float, 2> v2f_t; -typedef vec_t<double, 2> v2d_t; - template <typename T, size_t N> class rect_t { public: - vec_t<T, N> a, b; + vec_t<T, N> v[2]; rect_t() = default; - rect_t(vec_t<T, N> a_, vec_t<T, N> b_) + rect_t(vec_t<T, N> a, vec_t<T, N> b) { - a = a_; - b = b_; + v[0] = a; + v[1] = b; + } + + vec_t<T, N>& operator[](size_t i) + { + return v[i]; + } + + const vec_t<T, N>& operator[](size_t i) const + { + return v[i]; + } + + bool intersects(const rect_t<T, N> &b) const + { + for (size_t i = 0; i < N; i++) + if (v[1][i] < b[0][i] || v[0][i] > b[1][i]) + return false; + + return true; } friend std::ostream& operator<<(std::ostream& stream, rect_t<T, N> r) { - stream << "(" << r.a << ", " << r.b << ")"; + stream << "(" << r[0] << ", " << r[1] << ")"; return stream; } }; +// Shorthands +typedef vec_t<float, 2> v2f_t; +typedef vec_t<double, 2> v2d_t; +typedef rect_t<float, 2> rectf_t; +typedef rect_t<double, 2> rectd_t; + diff --git a/src/render.cpp b/src/render.cpp index 0353f97..5e7d1a4 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -3,14 +3,13 @@ static sf::RectangleShape wot_rect; -static void draw_tile(sf::RenderWindow *window, float x, float y, - world::tile_t *tile) +static void draw_tile(sf::RenderWindow *window, v2f_t x, world::tile_t *tile) { sf::Color color; wot_rect.setTexture(NULL); wot_rect.setSize(sf::Vector2f(1.0f, 1.0f)); - wot_rect.setPosition(sf::Vector2f(x, y)); + wot_rect.setPosition(x); switch (tile->type) { case -1: @@ -41,16 +40,8 @@ static void draw_sector(sf::RenderWindow *window, world::sector_t *sector) { for (ssize_t y = 0; y < SECTOR_SIZE; y++) for (ssize_t x = 0; x < SECTOR_SIZE; x++) - draw_tile(window, - sector->bounds.left + x, sector->bounds.top + y, + draw_tile(window, sector->bounds.v[0] + v2f_t(x, y), sector->tiles + y * SECTOR_SIZE + x); - - /*if ((sector->index.x & 2) ^ (sector->index.y & 2)) { - wot_rect.setSize(sf::Vector2f(SECTOR_SIZE, SECTOR_SIZE)); - wot_rect.setPosition(sf::Vector2f(sector->bounds.left, sector->bounds.top)); - wot_rect.setFillColor(sf::Color(0, 0, 0, 50)); - window->draw(wot_rect); - }*/ } void interface::state_t::render() @@ -78,8 +69,8 @@ void state_t::end_frame(void) void state_t::render(game::state_t *game) { sf::Vector2u size = window->getSize(); - sf::Vector2f A, B, C, D; - sf::Rect<float> bbox; + v2f_t A, B, C, D; + rectf_t bbox; std::list<world::entity_t*> ents; A = window->mapPixelToCoords(sf::Vector2i(0, 0)); @@ -87,10 +78,10 @@ void state_t::render(game::state_t *game) C = window->mapPixelToCoords(sf::Vector2i(0, size.y)); D = window->mapPixelToCoords(sf::Vector2i(size.x, size.y)); - bbox.left = std::min({A.x, B.x, C.x, D.x}); - bbox.top = std::min({A.y, B.y, C.y, D.y}); - bbox.width = std::max({A.x, B.x, C.x, D.x}) - bbox.left; - bbox.height = std::max({A.y, B.y, C.y, D.y}) - bbox.top; + bbox[0][0] = std::min({A[0], B[0], C[0], D[0]}); + bbox[0][1] = std::min({A[1], B[1], C[1], D[1]}); + bbox[1][0] = std::max({A[0], B[0], C[0], D[0]}); + bbox[1][1] = std::max({A[1], B[1], C[1], D[1]}); for (world::sector_t *sector : game->world.get_sectors(bbox)) draw_sector(window, sector); @@ -99,15 +90,14 @@ void state_t::render(game::state_t *game) ents.sort( [](const world::entity_t *x, const world::entity_t *y) -> bool { - return x->bounds.top + x->bounds.height - < y->bounds.top + y->bounds.height; + return x->bounds[1][0] < y->bounds[1][0]; }); for (world::entity_t *ent : ents) ent->render_to(this); } -void state_t::render(animated_texture_t *anim, sf::FloatRect bounds, bool mirror){ +void state_t::render(animated_texture_t *anim, rectf_t bounds, bool mirror){ size_t frame; if (!anim) @@ -122,20 +112,21 @@ void state_t::render(animated_texture_t *anim, sf::FloatRect bounds, bool mirror wot_rect.setFillColor(sf::Color::White); if (!mirror) { - wot_rect.setPosition(bounds.left, bounds.top); - wot_rect.setSize(sf::Vector2f(bounds.width, bounds.height)); + wot_rect.setPosition(bounds[0]); + wot_rect.setSize(bounds[1] - bounds[0]); } else { - wot_rect.setPosition(bounds.left + bounds.width, bounds.top); - wot_rect.setSize(sf::Vector2f(bounds.width, bounds.height)); - wot_rect.setScale(sf::Vector2f(-1, 1)); + float dx = bounds[1][0] - bounds[0][0]; + wot_rect.setPosition(bounds[0] + v2f_t(dx, 0)); + wot_rect.setSize(bounds[1] - bounds[0]); + wot_rect.setScale(v2f_t(-1, 1)); } window->draw(wot_rect); wot_rect.setTexture(NULL); - wot_rect.setScale(sf::Vector2f(1, 1)); + wot_rect.setScale(v2f_t(1, 1)); } -void state_t::render(oriented_sprite_t *sprite, sf::FloatRect bounds, float angle) +void state_t::render(oriented_sprite_t *sprite, rectf_t bounds, float angle) { size_t index; bool mirror; diff --git a/src/world.cpp b/src/world.cpp index c18a7ab..511de12 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -43,10 +43,9 @@ void world_t::generate_tile(tile_t *tile, tile_index_t x) void world_t::generate(sector_t *sector, sector_index_t index) { sector->index = index; - sector->bounds.left = index[0] * SECTOR_SIZE; - sector->bounds.top = index[1] * SECTOR_SIZE; - sector->bounds.width = SECTOR_SIZE; - sector->bounds.height = SECTOR_SIZE; + + sector->bounds.v[0] = (v2f_t)index * SECTOR_SIZE; + sector->bounds.v[1].broadcast(SECTOR_SIZE); std::cout << "generating " << index << "\n"; @@ -71,26 +70,26 @@ sector_t *world_t::get_sector(sector_index_t index) return sector; } -tile_t *world_t::get_tile(ssize_t x, ssize_t y) +tile_t *world_t::get_tile(tile_index_t index) { - sector_index_t index; + sector_index_t sector_index; sector_t *sector; - ssize_t tx, ty; + int64_t tx, ty; - index[0] = divide_rmi(x, (ssize_t)SECTOR_SIZE, &tx); - index[1] = divide_rmi(y, (ssize_t)SECTOR_SIZE, &ty); - sector = get_sector(index); + sector_index[0] = divide_rmi(index[0], (int64_t)SECTOR_SIZE, &tx); + sector_index[1] = divide_rmi(index[1], (int64_t)SECTOR_SIZE, &ty); + sector = get_sector(sector_index); return sector->tiles + ty * SECTOR_SIZE + tx; } -std::list<sector_t*> world_t::get_sectors(sf::FloatRect rect) +std::list<sector_t*> world_t::get_sectors(rectf_t rect) { sector_index_t base, upper; std::list<sector_t*> list; - base = sector_index_at(v2f_t(rect.left, rect.top)); - upper = sector_index_at(v2f_t(rect.left + rect.width, rect.top + rect.height)); + base = sector_index_at(rect.v[0]); + upper = sector_index_at(rect.v[1]); for (int64_t y = base[1]; y <= upper[1]; y++) for (int64_t x = base[0]; x <= upper[0]; x++) { @@ -101,7 +100,7 @@ std::list<sector_t*> world_t::get_sectors(sf::FloatRect rect) return list; } -std::list<entity_t*> world_t::get_render_entities(sf::FloatRect rect) +std::list<entity_t*> world_t::get_entities(rectf_t rect) { static size_t cookie = 0; std::list<entity_t*> list; @@ -113,7 +112,7 @@ std::list<entity_t*> world_t::get_render_entities(sf::FloatRect rect) if (ent->cookie == cookie) continue; - if (!rect.intersects(ent->render_bounds)) + if (!rect.intersects(ent->bounds)) continue; ent->cookie = cookie; @@ -124,7 +123,7 @@ std::list<entity_t*> world_t::get_render_entities(sf::FloatRect rect) return list; } -std::list<entity_t*> world_t::get_entities(sf::FloatRect rect) +std::list<entity_t*> world_t::get_render_entities(rectf_t rect) { static size_t cookie = 0; std::list<entity_t*> list; @@ -136,7 +135,7 @@ std::list<entity_t*> world_t::get_entities(sf::FloatRect rect) if (ent->cookie == cookie) continue; - if (!rect.intersects(ent->bounds)) + if (!rect.intersects(ent->render_bounds)) continue; ent->cookie = cookie; @@ -173,12 +172,12 @@ void entity_t::link(world_t *world) //total.bounds.width = std::max(bounds.width, render_bounds.width); //total.bounds.height = std::max(bounds.height, render_bounds.height); - fx = floor(bounds.left); - fy = floor(bounds.top); + fx = floor(bounds[0][0]); + fy = floor(bounds[0][1]); base = sector_index_at(v2f_t(fx, fy)); - xlip = bounds.left + bounds.width - (base[0] + 1) * SECTOR_SIZE; - ylip = bounds.top + bounds.height - (base[1] + 1) * SECTOR_SIZE; + xlip = bounds[1][0] - (base[0] + 1) * SECTOR_SIZE; + ylip = bounds[1][1] - (base[1] + 1) * SECTOR_SIZE; if (xlip > 0.0f) xsecs = ceil(xlip / SECTOR_SIZE) + 1; |