From 6723790daa66c333103f940540ea7ef83a4057d9 Mon Sep 17 00:00:00 2001 From: PaweÅ‚ Redman Date: Tue, 24 Oct 2017 18:39:03 +0200 Subject: Begin working on proper tile graphics. --- assets/src/ground-wall.xcf | Bin 0 -> 52103 bytes assets/tiles/dirt.png | Bin 0 -> 259 bytes src/assets.cpp | 5 +++ src/common.hpp | 52 +++++++++++++++++++----- src/game.cpp | 24 +++++++++++- src/main.cpp | 2 +- src/path_finder.cpp | 2 - src/render.cpp | 96 +++++++++++++++++++++++++++++++++------------ src/world.cpp | 63 ++++++++++++++++------------- 9 files changed, 179 insertions(+), 65 deletions(-) create mode 100644 assets/src/ground-wall.xcf create mode 100644 assets/tiles/dirt.png diff --git a/assets/src/ground-wall.xcf b/assets/src/ground-wall.xcf new file mode 100644 index 0000000..d6864a9 Binary files /dev/null and b/assets/src/ground-wall.xcf differ diff --git a/assets/tiles/dirt.png b/assets/tiles/dirt.png new file mode 100644 index 0000000..afb2970 Binary files /dev/null and b/assets/tiles/dirt.png differ diff --git a/src/assets.cpp b/src/assets.cpp index 530723d..7d77a38 100644 --- a/src/assets.cpp +++ b/src/assets.cpp @@ -3,6 +3,8 @@ namespace assets { human_assets_t human; +render::tile_monotonic_t tile_dirt; +render::tile_connecting12_t tile_wall; void load(void) { @@ -10,6 +12,9 @@ void load(void) human.body_idle.load("assets/units/human/body_idle", 2, 2, 2); human.legs_idle.load("assets/units/human/legs_idle", 2, 2); human.legs_walking.load("assets/units/human/legs_walking", 2, 2); + + tile_dirt.load("assets/tiles/dirt"); + tile_wall.load("assets/tiles/wall"); } } // namespace assets diff --git a/src/common.hpp b/src/common.hpp index bf2a300..5da7f33 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -40,15 +40,27 @@ namespace render { class state_t; } namespace world { #define SECTOR_SIZE 8 - class tile_t { - public: - char type; - }; - typedef int64_t coord_t; typedef vec_t sector_index_t; typedef vec_t tile_index_t; + static tile_index_t neighbor_offsets[4] = { + {1, 0}, {0, 1}, {-1, 0}, {0, -1} + }; + + enum { + TILE_NONE, + TILE_DIRT, + TILE_WALL + }; + + class tile_t { + public: + unsigned type : 8; + unsigned neighbors : 4; + unsigned variant : 8; + }; + sector_index_t sector_index_at(v2f_t x); tile_index_t tile_index_at(v2f_t x); @@ -71,7 +83,7 @@ namespace world { std::map sectors; void generate_tile(tile_t *tile, tile_index_t index); - void generate(sector_t *sector, sector_index_t index); + void generate(sector_t *sector, sector_index_t index, bool partial); protected: friend render::state_t; @@ -83,8 +95,8 @@ namespace world { public: world_t(void); - sector_t *get_sector(sector_index_t index); - tile_t *get_tile(tile_index_t index); + sector_t *get_sector(sector_index_t index, bool partial = false); + tile_t *get_tile(tile_index_t index, bool partial = false); bool find_path(v2f_t src, v2f_t dst, rectf_t size, entity_t *ignore, std::list *path); @@ -147,7 +159,7 @@ namespace game { world::world_t world; void start(void); - void tick(void); + void tick(double now); void debug_click(v2f_t x); }; @@ -209,6 +221,26 @@ namespace render { void load(std::string prefix, size_t xc, size_t yc); }; + class tile_t { + public: + virtual void load(std::string prefix) = 0; + virtual sf::Texture *get_texture(int neighbors, bool *mirror) = 0; + }; + + class tile_monotonic_t : public tile_t { + sf::Texture texture; + public: + void load(std::string prefix); + sf::Texture *get_texture(int neighbors, bool *mirror); + }; + + class tile_connecting12_t : public tile_t { + sf::Texture textures[12]; + public: + void load(std::string prefix); + sf::Texture *get_texture(int neighbors, bool *mirror); + }; + class state_t { sf::RenderWindow *window; double now; @@ -232,6 +264,8 @@ namespace assets { } human_assets_t; extern human_assets_t human; + extern render::tile_monotonic_t tile_dirt; + extern render::tile_connecting12_t tile_wall; void load(void); }; diff --git a/src/game.cpp b/src/game.cpp index f4b5057..2694350 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -4,7 +4,6 @@ namespace game { class unit_t : public world::entity_t { world::world_t *world; - v2f_t x; void compute_bounds() { @@ -15,6 +14,7 @@ class unit_t : public world::entity_t { } public: + v2f_t x; rectf_t size, render_size; struct { @@ -93,6 +93,8 @@ public: class human_t : public unit_t { public: + double last_follow = -INFINITY; + void render_to(render::state_t *render) { render->render((move.moving ? &assets::human.legs_walking : @@ -128,9 +130,27 @@ void state_t::debug_click(v2f_t x) human.start_moving(x); } -void state_t::tick(void) +void state_t::tick(double now) { + if ((human2.x - human.x).len() > 3) { + if (now > human2.last_follow + 0.5) { + for (size_t i = 0; i < 8; i++) { + float angle; + v2f_t offset; + + angle = (float)i / 8 * 2 * M_PI; + offset[0] = cos(angle); + offset[1] = sin(angle); + + if (human2.start_moving(human.x + offset)) + break; + } + human2.last_follow = now; + } + } + human.keep_moving(); + human2.keep_moving(); } } //namespace game diff --git a/src/main.cpp b/src/main.cpp index 82b5e2e..352981c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -26,7 +26,7 @@ int main() while (1) { double now = (nano_clock() - t0) * 1.0e-9; - game.tick(); + game.tick(now); interface.tick(); if (!window.isOpen()) break; diff --git a/src/path_finder.cpp b/src/path_finder.cpp index ab8126a..4ace89d 100644 --- a/src/path_finder.cpp +++ b/src/path_finder.cpp @@ -46,8 +46,6 @@ void path_finder_t::eliminate_nodes(rectf_t bounds) rect_t index_bounds; tile_index_t index; - std::cout << "eliminate " << bounds << "\n"; - index_bounds[0] = tile_index_t(bounds[0].floor()) - base; index_bounds[1] = tile_index_t(bounds[1].ceil()) - base; diff --git a/src/render.cpp b/src/render.cpp index 907dcf0..819641f 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -1,43 +1,50 @@ #include "common.hpp" #include +#include static sf::RectangleShape wot_rect; static sf::Font font; 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(x); + render::tile_t *tile_assets; + sf::Texture *texture; + bool mirror; switch (tile->type) { - case -1: - color = sf::Color(30, 30, 150); - break; - case 0: - color = sf::Color(50, 70, 200); - break; - case 1: - color = sf::Color(255, 255, 90); - break; - case 2: - color = sf::Color(30, 210, 40); - break; - case 3: - color = sf::Color(29, 190, 45); + default: + return; + + case world::TILE_DIRT: + tile_assets = &assets::tile_dirt; break; - case 4: - color = sf::Color(120, 120, 120); + + case world::TILE_WALL: + tile_assets = &assets::tile_wall; break; - default: - ; } - wot_rect.setFillColor(color); + texture = tile_assets->get_texture(tile->neighbors, &mirror); + + wot_rect.setTexture(texture); + wot_rect.setSize(sf::Vector2f(1.0f, 1.0f)); + if (!mirror) { + wot_rect.setPosition(x); + wot_rect.setScale(v2f_t(1, 1)); + } else { + wot_rect.setPosition(x + v2f_t(1.0f, 0)); + wot_rect.setScale(v2f_t(-1, 1)); + } + wot_rect.setFillColor(sf::Color::White); wot_rect.setOutlineColor(sf::Color::Transparent); window->draw(wot_rect); + + std::stringstream ss; + ss << tile->type << ":" << tile->neighbors; + sf::Text text(ss.str(), font, 20); + text.setPosition(x); + text.setScale(0.005, 0.005); + window->draw(text); } static void draw_sector(sf::RenderWindow *window, world::sector_t *sector) @@ -267,4 +274,45 @@ void oriented_sprite_4M2_t::load(std::string prefix, size_t xc, size_t yc) textures[1].load(prefix + "_y_", yc); } +void tile_monotonic_t::load(std::string prefix) +{ + texture.loadFromFile(prefix + ".png"); +} + +void tile_connecting12_t::load(std::string prefix) +{ + for (size_t i = 0; i < 12; i++) + textures[i].loadFromFile(prefix + "_" + std::to_string(i) + ".png"); +} + +sf::Texture *tile_monotonic_t::get_texture(int neighbors, bool *mirror) +{ + *mirror = false; + return &texture; +} + +sf::Texture *tile_connecting12_t::get_texture(int neighbors, bool *mirror) +{ + const static struct{ size_t index; bool mirror; } map[16] = { + {0, false}, + {1, false}, + {2, false}, + {3, false}, + {1, true}, + {4, false}, + {3, true}, + {5, false}, + {6, false}, + {7, false}, + {8, false}, + {9, false}, + {7, true}, + {10, false}, + {9, true} + }; + + *mirror = map[neighbors].mirror; + return textures + map[neighbors].index; +} + } // namespace render diff --git a/src/world.cpp b/src/world.cpp index 07d5638..e176913 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -32,40 +32,50 @@ void world_t::generate_tile(tile_t *tile, tile_index_t x) perlin.get(x, 4.0f) * 0.1f + perlin.get(x, 1.0f) * 0.05f; - if (height < waterlevel - 0.2f) - tile->type = -1; - else if (height < waterlevel) - tile->type = 0; - else if (height < waterlevel + 0.05f) - tile->type = 1; - else { - if (perlin.get(x, 5.0f) > 0.0f) - tile->type = 3; - else - tile->type = 2; - - if (height > waterlevel + 0.1f && - perlin.get(x, 2.0f) > 0.3f) - tile->type = 4; - } + if (height < waterlevel) + tile->type = TILE_NONE; + else if (height < waterlevel + 0.3) + tile->type = TILE_DIRT; + else + tile->type = TILE_WALL; } -void world_t::generate(sector_t *sector, sector_index_t index) +void world_t::generate(sector_t *sector, sector_index_t index, bool partial) { sector->index = index; sector->bounds.v[0] = (v2f_t)index * SECTOR_SIZE; sector->bounds.v[1] = sector->bounds.v[0] + v2f_t(SECTOR_SIZE, SECTOR_SIZE); - std::cout << "generating " << index << "\n"; - - for (ssize_t ly = 0; ly < SECTOR_SIZE; ly++) - for (ssize_t lx = 0; lx < SECTOR_SIZE; lx++) + for (coord_t ly = 0; ly < SECTOR_SIZE; ly++) + for (coord_t lx = 0; lx < SECTOR_SIZE; lx++) generate_tile(sector->tiles + ly * SECTOR_SIZE + lx, tile_index_t(index[0] * SECTOR_SIZE + lx, index[1] * SECTOR_SIZE + ly)); sector->empty = false; + + if (partial) + return; + + for (coord_t ly = 0; ly < SECTOR_SIZE; ly++) + for (coord_t lx = 0; lx < SECTOR_SIZE; lx++) { + tile_t *tile; + + tile = sector->tiles + ly * SECTOR_SIZE + lx; + tile->neighbors = 0; + + for (size_t i = 0; i < 4; i++) { + tile_index_t neighbor_index; + tile_t *neighbor; + + neighbor_index = index * SECTOR_SIZE + tile_index_t(lx, ly) + neighbor_offsets[i]; + neighbor = get_tile(neighbor_index, true); + + if (neighbor->type == tile->type) + tile->neighbors |= (1 << i); + } + } } bool world_t::find_path(v2f_t src, v2f_t dst, rectf_t size, entity_t *ignore, @@ -82,8 +92,7 @@ bool world_t::find_path(v2f_t src, v2f_t dst, rectf_t size, entity_t *ignore, tile_index_t index; index = finder.base + tile_index_t(x, y); - node->accessible = (get_tile(index)->type >= 1 && - get_tile(index)->type <= 3); + node->accessible = get_tile(index)->type == TILE_DIRT; } bounds = rectf_t(src, dst).norm(); @@ -116,19 +125,19 @@ bool world_t::find_path(v2f_t src, v2f_t dst, rectf_t size, entity_t *ignore, return true; } -sector_t *world_t::get_sector(sector_index_t index) +sector_t *world_t::get_sector(sector_index_t index, bool partial) { sector_t *sector; sector = §ors[index]; if (sector->empty) - generate(sector, index); + generate(sector, index, partial); return sector; } -tile_t *world_t::get_tile(tile_index_t index) +tile_t *world_t::get_tile(tile_index_t index, bool partial) { sector_index_t sector_index; sector_t *sector; @@ -136,7 +145,7 @@ tile_t *world_t::get_tile(tile_index_t 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); + sector = get_sector(sector_index, partial); return sector->tiles + ty * SECTOR_SIZE + tx; } -- cgit