123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- #pragma once
- #include <SFML/Graphics.hpp>
- #include <nlohmann/json.hpp>
- #include <vector>
- #include <fstream>
- #include <array>
- #include <iostream>
- #include <sstream>
- #include <cmath>
- #include "Log.hpp"
- #include "Asset.hpp"
- #include "Collider.hpp"
- #include "Sand.hpp"
- #include "Spike.hpp"
- #define CW 20
- #define CH 12
- using json = nlohmann::json;
- using Block = std::array<sf::Vertex, 4u>;
- class BlockLayer final: public sf::Drawable {
- public:
- BlockLayer() = delete;
- BlockLayer(const std::string& filename, const std::string& tileset):
- m_tex(&Asset::texture(tileset)),
- m_tileSize(32.f) {
- std::ifstream ifs(filename);
- json j;
- ifs >> j;
-
- auto layer = j["layers"][2];
- m_size.x = layer["width"];
- m_size.y = layer["height"];
-
- m_blocks.reserve(m_size.x * m_size.y);
-
- for(std::size_t i = 0; i < layer["data"].size(); ++i) {
- int tile = layer["data"][i];
- size_t x = i % m_size.x;
- size_t y = i / m_size.x;
-
- int collide_type = Collider::AIR;
- switch(tile) {
- case 1:
- collide_type = Collider::SOLID;
- break;
- case 2:
- collide_type = Collider::SAND;
- break;
- case 3:
- collide_type = Collider::LEVER;
- break;
- case 4:
- collide_type = Collider::SPIKE;
- break;
- default:
- break;
- }
- m_map.push_back(collide_type);
-
- if(0 && tile == 2) {
- sf::Vector2f tileOffset(x * m_tileSize, y * m_tileSize);
- std::size_t tileIndex = tile - 1;
- m_blocks.emplace_back(
- tileOffset,
- sf::Color::White,
- sf::Vector2f(tileIndex * m_tileSize, 0.f)
- );
- m_blocks.emplace_back(
- tileOffset + sf::Vector2f(m_tileSize, 0.f),
- sf::Color::White,
- sf::Vector2f((tileIndex + 1) * m_tileSize, 0.f)
- );
- m_blocks.emplace_back(
- tileOffset + sf::Vector2f(m_tileSize, m_tileSize),
- sf::Color::White,
- sf::Vector2f((tileIndex + 1) * m_tileSize,
- m_tileSize)
- );
- m_blocks.emplace_back(
- tileOffset + sf::Vector2f(0.f, m_tileSize),
- sf::Color::White,
- sf::Vector2f(tileIndex * m_tileSize,
- m_tileSize)
- );
- } else {
- for(std::size_t i = 0; i < 4; ++i) {
- m_blocks.emplace_back(sf::Vector2f(0.f, 0.f), sf::Color::White, sf::Vector2f(0.f, 0.f));
- }
- }
- }
- }
- ~BlockLayer() {
- /*for(std::size_t i = 0; i < m_blocks.size(); ++i) {
- if(m_blocks[i]) {
- delete m_blocks[i];
- }
- }*/
- }
-
- std::vector<int> rebuildCollider(int focus) {
- std::vector<int> res;
- res.reserve(CW * CH);
- for(int j = 0; j < CH; ++j) {
- for(int i = focus * CW; i < focus * CW + CW; ++i) {
- int curr = m_map[i + j * m_size.x];
- if(curr != Collider::SPIKE && curr != Collider::SAND) {
- res.push_back(m_map[i + j * m_size.x]);
- } else {
- res.push_back(Collider::AIR);
- }
- }
- }
- return res;
- }
-
- std::vector<Spike> reloadSpikes(int focus, Collider* collider) {
- std::vector<Spike> res;
- for(int j = 1; j < CH; ++j) {
- for(int i = focus * CW; i < focus * CW + CW; ++i) {
- if(m_map[i + j * m_size.x] == Collider::SPIKE) {
- res.emplace_back(collider, m_map[i + (j - 1) * m_size.x] == Collider::LEVER);
- res.back().setPosition(i * 32.f, j * 32.f);
- res.back().setTexture(Asset::texture("data/tileset.png"));
- res.back().setTextureRect(sf::IntRect(
- 96,
- 0,
- 32,
- 32
- ));
- }
- }
- }
- return res;
- }
-
- std::vector<Sand> reloadSand(int focus, Collider* collider) {
- std::vector<Sand> res;
- for(int j = 0; j < CH; ++j) {
- for(int i = focus * CW; i < focus * CW + CW; ++i) {
- if(m_map[i + j * m_size.x] == Collider::SAND) {
- res.emplace_back(collider);
- res.back().setPosition(i * 32.f, j * 32.f);
- res.back().setTexture(Asset::texture("data/tileset.png"));
- res.back().setTextureRect(sf::IntRect(
- 32,
- 0,
- 32,
- 32
- ));
- }
- }
- }
- return res;
- }
-
- std::vector<sf::Vertex> m_blocks;
- std::vector<int> m_map;
-
- BlockLayer(const BlockLayer&) = delete;
- BlockLayer& operator=(const BlockLayer&) = delete;
- //const sf::FloatRect& getGlobalBounds() const {
- // return m_globalBounds;
- //}
- private:
- const sf::Texture* m_tex;
- sf::Vector2u m_size;
- float m_tileSize;
- void draw(sf::RenderTarget& rt, sf::RenderStates states) const override {
- states.texture = m_tex;
- rt.draw(m_blocks.data(), m_blocks.size(), sf::Quads, states);
- }
- };
|