#include "common.hpp" #include static sf::RectangleShape wot_rect; static void draw_tile(sf::RenderWindow *window, float x, float y, world::tile_t *tile) { sf::Color color; wot_rect.setSize(sf::Vector2f(1.0f, 1.0f)); wot_rect.setPosition(sf::Vector2f(x, y)); 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); break; default: ; } wot_rect.setFillColor(color); wot_rect.setOutlineColor(sf::Color::Transparent); window->draw(wot_rect); } 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, 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() { } 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; sf::Rect bbox; A = window->mapPixelToCoords(sf::Vector2i(0, 0)); B = window->mapPixelToCoords(sf::Vector2i(size.x, 0)); 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; for (world::sector_t *sector : game->world.get_sectors(bbox)) draw_sector(window, sector); for (world::entity_t *ent : game->world.get_entities(bbox)) ent->render_to(this); } 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); 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; } 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)) { delete[] frames; frames = NULL; return false; } } 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