summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--assets/src/ground-wall.xcfbin0 -> 52103 bytes
-rw-r--r--assets/tiles/dirt.pngbin0 -> 259 bytes
-rw-r--r--src/assets.cpp5
-rw-r--r--src/common.hpp52
-rw-r--r--src/game.cpp24
-rw-r--r--src/main.cpp2
-rw-r--r--src/path_finder.cpp2
-rw-r--r--src/render.cpp96
-rw-r--r--src/world.cpp63
9 files changed, 179 insertions, 65 deletions
diff --git a/assets/src/ground-wall.xcf b/assets/src/ground-wall.xcf
new file mode 100644
index 0000000..d6864a9
--- /dev/null
+++ b/assets/src/ground-wall.xcf
Binary files differ
diff --git a/assets/tiles/dirt.png b/assets/tiles/dirt.png
new file mode 100644
index 0000000..afb2970
--- /dev/null
+++ b/assets/tiles/dirt.png
Binary files 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<coord_t, 2> sector_index_t;
typedef vec_t<coord_t, 2> 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<sector_index_t, sector_t> 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<v2f_t> *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<coord_t, 2> 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 <list>
+#include <sstream>
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 = &sectors[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;
}