From e1da92454d096c28292699f64d891a3af292a204 Mon Sep 17 00:00:00 2001 From: Paweł Redman Date: Thu, 12 Oct 2017 13:20:06 +0200 Subject: Initial work on animations. --- src/common.hpp | 36 +++++++++++++++++++++++++------ src/game.cpp | 16 ++++++++++++++ src/main.cpp | 21 +++++++++++++++--- src/render.cpp | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++------- src/world.cpp | 4 ++++ 5 files changed, 126 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/common.hpp b/src/common.hpp index 06e9d9f..d2b165b 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -33,6 +33,8 @@ namespace procgen { }; } +namespace render { class state_t; } + namespace world { #define SECTOR_SIZE 8 @@ -101,7 +103,7 @@ namespace world { void link(world_t *world); void unlink(); - virtual void render(sf::RenderWindow *window) = 0; + virtual void render(render::state_t *render) = 0; }; } @@ -112,12 +114,7 @@ namespace game { void start(void); void tick(void); - void render(sf::RenderWindow *window_); - }; - - class human_t : public world::entity_t { - public: - void render(sf::RenderWindow *window); + void render(render::state_t *render); }; } @@ -141,6 +138,31 @@ namespace interface { }; } +namespace render { + class animated_texture_t { + friend state_t; + protected: + sf::Texture *frames = NULL; + size_t frame_count; + + public: + ~animated_texture_t(void); + bool load(std::string prefix, size_t frame_count_); + }; + + class state_t { + sf::RenderWindow *window; + double now; + public: + + state_t(sf::RenderWindow *window_); + void begin_frame(double time_); + void end_frame(void); + void render(game::state_t *game); + void render(animated_texture_t *anim, sf::FloatRect bounds); + }; +} + // Divide and round to minus infinity. template T divide_rmi(T x, T y, T *rem) diff --git a/src/game.cpp b/src/game.cpp index 6416f93..396d26a 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -2,10 +2,26 @@ namespace game { + +class unit_t : public world::entity_t { + +}; + +static render::animated_texture_t test; + +class human_t : public unit_t { + void render(render::state_t *render) + { + render->render(&test, bounds); + } +}; + 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; diff --git a/src/main.cpp b/src/main.cpp index b63b610..e9a3301 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,8 +1,19 @@ #include "common.hpp" +#include + +uint64_t nano_clock(void) +{ + struct timespec ts; + + clock_gettime(CLOCK_MONOTONIC_RAW, &ts); + return ts.tv_sec * 1000000000LLU + ts.tv_nsec; +} int main() { + uint64_t t0 = nano_clock(); sf::RenderWindow window(sf::VideoMode(800, 600), "Minitrem"); + render::state_t render(&window); game::state_t game; interface::state_t interface(&window, &game); @@ -11,15 +22,19 @@ int main() game.start(); while (1) { + double now = (nano_clock() - t0) * 1.0e-9; + game.tick(); interface.tick(); if (!window.isOpen()) break; - + window.clear(); - game.render(&window); + render.begin_frame(now); + render.render(&game); + //game.render(&render); interface.render(); - window.display(); + render.end_frame(); } return 0; diff --git a/src/render.cpp b/src/render.cpp index 1baf0e0..08a4524 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -52,7 +52,29 @@ static void draw_sector(sf::RenderWindow *window, world::sector_t *sector) } } -void game::state_t::render(sf::RenderWindow *window) +void interface::state_t::render() +{ +} + +namespace render { + +state_t::state_t(sf::RenderWindow *window_) +{ + window = window_; +} + +void state_t::begin_frame(double time_) +{ + now = time_; + window->clear(); +} + +void state_t::end_frame(void) +{ + window->display(); +} + +void state_t::render(game::state_t *game) { sf::Vector2u size = window->getSize(); sf::Vector2f A, B, C, D; @@ -68,22 +90,51 @@ void game::state_t::render(sf::RenderWindow *window) 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; - for (world::sector_t *sector : world.get_sectors(bbox)) + for (world::sector_t *sector : game->world.get_sectors(bbox)) draw_sector(window, sector); - for (world::entity_t *ent : world.get_entities(bbox)) - ent->render(window); + for (world::entity_t *ent : game->world.get_entities(bbox)) + ent->render(this); } -void game::human_t::render(sf::RenderWindow *window) +void state_t::render(animated_texture_t *anim, sf::FloatRect bounds) { + size_t frame; + + 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)); - wot_rect.setFillColor(sf::Color::Red); - wot_rect.setOutlineColor(sf::Color::Transparent); window->draw(wot_rect); + wot_rect.setTexture(NULL); } -void interface::state_t::render() +animated_texture_t::~animated_texture_t(void) { + //delete[] frames; } + +bool animated_texture_t::load(std::string prefix, size_t frame_count_) +{ + frame_count = frame_count_; + frames = new sf::Texture[frame_count]; + + for (size_t i = 0; i < frame_count; i++) { + std::string path; + + path = prefix + std::to_string(i) + ".png"; + std::cout << "load " << path << "\n"; + + if (!frames[i].loadFromFile(path)) { + // FIXME + //delete[] frames; + return false; + } + } + + return true; +} + +} // namespace render diff --git a/src/world.cpp b/src/world.cpp index 9085b16..71098c6 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -131,6 +131,10 @@ std::list world_t::get_entities(sf::FloatRect rect) for (entity_t *ent : sector->ents) { if (ent->cookie == cookie) continue; + + if (!rect.intersects(ent->bounds)) + continue; + ent->cookie = cookie; list.push_back(ent); -- cgit