From bb0a7bfe31714ff56ce1c1ce428cdf240804db14 Mon Sep 17 00:00:00 2001 From: Paweł Redman Date: Sat, 14 Oct 2017 15:34:53 +0200 Subject: Oriented sprites and the human sprite. --- assets/units/human/body_idle_ny_0.png | Bin 0 -> 2049 bytes assets/units/human/body_idle_ny_1.png | Bin 0 -> 1962 bytes assets/units/human/body_idle_y_0.png | Bin 0 -> 2414 bytes assets/units/human/body_idle_y_1.png | Bin 0 -> 2544 bytes assets/units/human/head_idle_ny_0.png | Bin 0 -> 1591 bytes assets/units/human/legs_idle_x_0.png | Bin 0 -> 793 bytes assets/units/human/legs_idle_x_1.png | Bin 0 -> 848 bytes assets/units/human/legs_idle_y_0.png | Bin 0 -> 751 bytes assets/units/human/legs_idle_y_1.png | Bin 0 -> 655 bytes assets/units/human/legs_walking_y_0.png | Bin 0 -> 502 bytes assets/units/human/legs_walking_y_1.png | Bin 0 -> 587 bytes src/common.hpp | 31 ++++++++- src/game.cpp | 61 +++++++++++++----- src/main.cpp | 1 + src/render.cpp | 110 +++++++++++++++++++++++++++++--- src/world.cpp | 12 ++-- 16 files changed, 184 insertions(+), 31 deletions(-) create mode 100644 assets/units/human/body_idle_ny_0.png create mode 100644 assets/units/human/body_idle_ny_1.png create mode 100644 assets/units/human/body_idle_y_0.png create mode 100644 assets/units/human/body_idle_y_1.png create mode 100644 assets/units/human/head_idle_ny_0.png create mode 100644 assets/units/human/legs_idle_x_0.png create mode 100644 assets/units/human/legs_idle_x_1.png create mode 100644 assets/units/human/legs_idle_y_0.png create mode 100644 assets/units/human/legs_idle_y_1.png create mode 100644 assets/units/human/legs_walking_y_0.png create mode 100644 assets/units/human/legs_walking_y_1.png diff --git a/assets/units/human/body_idle_ny_0.png b/assets/units/human/body_idle_ny_0.png new file mode 100644 index 0000000..a4305fe Binary files /dev/null and b/assets/units/human/body_idle_ny_0.png differ diff --git a/assets/units/human/body_idle_ny_1.png b/assets/units/human/body_idle_ny_1.png new file mode 100644 index 0000000..ea99192 Binary files /dev/null and b/assets/units/human/body_idle_ny_1.png differ diff --git a/assets/units/human/body_idle_y_0.png b/assets/units/human/body_idle_y_0.png new file mode 100644 index 0000000..524ed6a Binary files /dev/null and b/assets/units/human/body_idle_y_0.png differ diff --git a/assets/units/human/body_idle_y_1.png b/assets/units/human/body_idle_y_1.png new file mode 100644 index 0000000..6714693 Binary files /dev/null and b/assets/units/human/body_idle_y_1.png differ diff --git a/assets/units/human/head_idle_ny_0.png b/assets/units/human/head_idle_ny_0.png new file mode 100644 index 0000000..d46674a Binary files /dev/null and b/assets/units/human/head_idle_ny_0.png differ diff --git a/assets/units/human/legs_idle_x_0.png b/assets/units/human/legs_idle_x_0.png new file mode 100644 index 0000000..eca9f71 Binary files /dev/null and b/assets/units/human/legs_idle_x_0.png differ diff --git a/assets/units/human/legs_idle_x_1.png b/assets/units/human/legs_idle_x_1.png new file mode 100644 index 0000000..4867503 Binary files /dev/null and b/assets/units/human/legs_idle_x_1.png differ diff --git a/assets/units/human/legs_idle_y_0.png b/assets/units/human/legs_idle_y_0.png new file mode 100644 index 0000000..89624f7 Binary files /dev/null and b/assets/units/human/legs_idle_y_0.png differ diff --git a/assets/units/human/legs_idle_y_1.png b/assets/units/human/legs_idle_y_1.png new file mode 100644 index 0000000..47ec27e Binary files /dev/null and b/assets/units/human/legs_idle_y_1.png differ diff --git a/assets/units/human/legs_walking_y_0.png b/assets/units/human/legs_walking_y_0.png new file mode 100644 index 0000000..9197a87 Binary files /dev/null and b/assets/units/human/legs_walking_y_0.png differ diff --git a/assets/units/human/legs_walking_y_1.png b/assets/units/human/legs_walking_y_1.png new file mode 100644 index 0000000..c4ac188 Binary files /dev/null and b/assets/units/human/legs_walking_y_1.png differ diff --git a/src/common.hpp b/src/common.hpp index d2b165b..4645bea 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -103,11 +103,13 @@ namespace world { void link(world_t *world); void unlink(); - virtual void render(render::state_t *render) = 0; + virtual void render_to(render::state_t *render) = 0; }; } namespace game { + bool load_assets(void); + class state_t { public: world::world_t world; @@ -150,6 +152,30 @@ namespace render { bool load(std::string prefix, size_t frame_count_); }; + class oriented_sprite_t { + protected: + friend state_t; + animated_texture_t *textures; + virtual size_t select_index(float angle, bool *mirror) = 0; + + public: + ~oriented_sprite_t(void); + }; + + class oriented_sprite_4M_t : public oriented_sprite_t { + size_t select_index(float angle, bool *mirror); + + public: + void load(std::string prefix, size_t xc, size_t yc, size_t nyc); + }; + + class oriented_sprite_4M2_t : public oriented_sprite_t { + size_t select_index(float angle, bool *mirror); + + public: + void load(std::string prefix, size_t xc, size_t yc); + }; + class state_t { sf::RenderWindow *window; double now; @@ -159,7 +185,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); + void render(animated_texture_t *anim, sf::FloatRect bounds, bool mirror = false); + void render(oriented_sprite_t *sprite, sf::FloatRect bounds, float angle); }; } diff --git a/src/game.cpp b/src/game.cpp index 396d26a..bb04ee7 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -2,17 +2,37 @@ namespace game { - class unit_t : public world::entity_t { - }; -static render::animated_texture_t test; +struct { + struct { + render::oriented_sprite_4M_t head_idle, body_idle; + render::oriented_sprite_4M2_t legs_idle, legs_walking; + } human; +} assets; + +bool load_assets(void) +{ + assets.human.head_idle.load("assets/units/human/head_idle", 1, 1, 1); + assets.human.body_idle.load("assets/units/human/body_idle", 2, 2, 2); + assets.human.legs_idle.load("assets/units/human/legs_idle", 2, 2); + assets.human.legs_walking.load("assets/units/human/legs_walking", 2, 2); + return true; +} class human_t : public unit_t { - void render(render::state_t *render) + +public: + float angle = 0.0f; + bool walking = false; + + void render_to(render::state_t *render) { - render->render(&test, bounds); + render->render((walking ? &assets.human.legs_walking : + &assets.human.legs_idle), bounds, angle); + render->render(&assets.human.body_idle, bounds, angle); + render->render(&assets.human.head_idle, bounds, angle); } }; @@ -20,22 +40,33 @@ static human_t *human; void state_t::start(void) { - test.load("assets/test_", 4); - human = new human_t; - human->bounds.left = -0.2f; - human->bounds.top = -0.2f; - human->bounds.width = 3.0f; - human->bounds.height = 3.0f; + human->bounds.left = 0.33f; + human->bounds.top = 0.0f; + human->bounds.width = 0.66f; + human->bounds.height = 1.0f; human->link(&world); } void state_t::tick(void) { - human->unlink(); - human->bounds.left += 0.05f; - human->bounds.top += 0.05f; - human->link(&world); + static float stalin = 2.0f; + + stalin -= ((float)rand() / RAND_MAX) * 0.1f; + + human->walking = false; + + if (stalin < 0) { + 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; + human->link(&world); + } + + if (stalin < -4.0f) + stalin = 2.0f; } } //namespace game diff --git a/src/main.cpp b/src/main.cpp index e9a3301..4aa234c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -19,6 +19,7 @@ int main() window.setVerticalSyncEnabled(true); + game::load_assets(); game.start(); while (1) { diff --git a/src/render.cpp b/src/render.cpp index 08a4524..f56cb37 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -94,26 +94,46 @@ void state_t::render(game::state_t *game) draw_sector(window, sector); for (world::entity_t *ent : game->world.get_entities(bbox)) - ent->render(this); + ent->render_to(this); } -void state_t::render(animated_texture_t *anim, sf::FloatRect bounds) -{ +void state_t::render(animated_texture_t *anim, sf::FloatRect bounds, bool mirror){ size_t frame; + if (!anim->frame_count) + return; + frame = floor(fmod(now * 20.0, anim->frame_count)); wot_rect.setTexture(anim->frames + frame, true); wot_rect.setFillColor(sf::Color::White); - wot_rect.setPosition(bounds.left, bounds.top); - wot_rect.setSize(sf::Vector2f(bounds.width, bounds.height)); + + if (!mirror) { + wot_rect.setPosition(bounds.left, bounds.top); + wot_rect.setSize(sf::Vector2f(bounds.width, bounds.height)); + } 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)); + } + window->draw(wot_rect); wot_rect.setTexture(NULL); + wot_rect.setScale(sf::Vector2f(1, 1)); +} + +void state_t::render(oriented_sprite_t *sprite, sf::FloatRect bounds, float angle) +{ + size_t index; + bool mirror; + + index = sprite->select_index(angle, &mirror); + render(sprite->textures + index, bounds, mirror); } animated_texture_t::~animated_texture_t(void) { - //delete[] frames; + delete[] frames; } bool animated_texture_t::load(std::string prefix, size_t frame_count_) @@ -128,8 +148,8 @@ bool animated_texture_t::load(std::string prefix, size_t frame_count_) std::cout << "load " << path << "\n"; if (!frames[i].loadFromFile(path)) { - // FIXME - //delete[] frames; + delete[] frames; + frames = NULL; return false; } } @@ -137,4 +157,78 @@ bool animated_texture_t::load(std::string prefix, size_t frame_count_) return true; } +oriented_sprite_t::~oriented_sprite_t(void) +{ + delete[] textures; +} + +float normalize_angle(float angle) +{ + float t; + + t = angle / (2 * M_PI); + t -= floor(t); + + return t * 2 * M_PI; +} + +size_t oriented_sprite_4M_t::select_index(float angle, bool *mirror) +{ + angle = normalize_angle(angle); + + if (angle < 0.25f * M_PI) { + select_x: + *mirror = false; + return 0; + } else if (angle < 0.75f * M_PI) { + *mirror = false; + return 1; + } else if (angle < 1.25f * M_PI) { + *mirror = true; + return 0; + } else if (angle < 1.75f * M_PI) { + *mirror = false; + return 2; + } else + goto select_x; +} + +void oriented_sprite_4M_t::load(std::string prefix, size_t xc, size_t yc, size_t nyc) +{ + textures = new animated_texture_t[3]; + + textures[0].load(prefix + "_x_", xc); + textures[1].load(prefix + "_y_", yc); + textures[2].load(prefix + "_ny_", nyc); +} + +size_t oriented_sprite_4M2_t::select_index(float angle, bool *mirror) +{ + angle = normalize_angle(angle); + + if (angle < 0.25f * M_PI) { + select_x: + *mirror = false; + return 0; + } else if (angle < 0.75f * M_PI) { + *mirror = false; + return 1; + } else if (angle < 1.25f * M_PI) { + *mirror = true; + return 0; + } else if (angle < 1.75f * M_PI) { + *mirror = false; + return 1; + } else + goto select_x; +} + +void oriented_sprite_4M2_t::load(std::string prefix, size_t xc, size_t yc) +{ + textures = new animated_texture_t[2]; + + textures[0].load(prefix + "_x_", xc); + textures[1].load(prefix + "_y_", yc); +} + } // namespace render diff --git a/src/world.cpp b/src/world.cpp index 71098c6..d340cc1 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -39,13 +39,13 @@ void world_t::generate_tile(ssize_t x, ssize_t y, tile_t *tile) { float waterlevel, height; - waterlevel = perlin.get(x, y, 100.0f) * 0.3f + - perlin.get(x, y, 50.0f) * 0.1f; + waterlevel = perlin.get(x, y, 1000.0f) * 0.3f + + perlin.get(x, y, 500.0f) * 0.1f; - height = perlin.get(x, y, 30.0f) * 0.6f + - perlin.get(x, y, 15.0f) * 0.25f + - perlin.get(x, y, 7.0f) * 0.1f + - perlin.get(x, y, 3.0f) * 0.05f; + height = perlin.get(x, y, 60.0f) * 0.6f + + perlin.get(x, y, 30.0f) * 0.25f + + perlin.get(x, y, 14.0f) * 0.1f + + perlin.get(x, y, 6.0f) * 0.05f; if (height < waterlevel - 0.2f) tile->type = -1; -- cgit