Piszę ostatnio grę w SFML i natknąłem się na pewien problem. Napisałem klasę odpowiedzialną za mapę gry i z niewiadomego powodu zamiast całej mapy na ekranie wyświetlana jest tylko część mapy np.: tylko niebo, lub tylko podłoga. Po sprawdzeniu okazuje się, że w funkcji MapTile::load() wszystkie zmienne są prawidłowe, a w zaraz w funckji MapTile::render() te zmienne są najprawdopodobniej wyzerowane. Błagam o pomoc to jest mój kod:
Map.h
#pragma once
#include "State.h"
class MapTile
{
struct MapObject
{
float x, y;
bool is_ground = false;
MapObject(float x, float y, bool is_ground = false) : x{x}, y{y}, is_ground{is_ground}
{
}
};
std::vector<MapObject> objects;
sf::Texture* texture;
sf::Sprite* sprite;
public:
explicit MapTile(std::string texture_path);
// The rule of five
~MapTile();
MapTile(const MapTile& mo); // Copy constructor
MapTile(MapTile&& mo) noexcept; // R-value constructor
MapTile& operator=(const MapTile& mo);
MapTile& operator=(MapTile&& mo) noexcept;
void render(sf::RenderWindow* w);
void load(std::string file_path, sf::Vector2i& map_size, char type);
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class Map // contains tilemap
{
sf::Thread thread; // on this thread, load the map
std::ifstream map_file;
sf::Vector2i size;
std::vector<MapTile> tiles;
std::string path; // Path to map file
void load();
public:
explicit Map(std::string path);
void render(sf::RenderWindow* w);
};
Map.cpp
#include "Map.h"
MapTile::MapTile(std::string texture_path)
{
// Load texture's texture and set up the sprite
texture = new sf::Texture;
texture->loadFromFile(texture_path);
sprite = new sf::Sprite(*texture);
}
MapTile::~MapTile()
{
delete texture;
delete sprite;
}
MapTile::MapTile(const MapTile& mo)
{
texture = new sf::Texture;
*texture = *(mo.texture);
sprite = new sf::Sprite(*texture);
}
MapTile::MapTile(MapTile&& mo) noexcept
{
texture = mo.texture;
sprite = mo.sprite;
mo.sprite = nullptr;
mo.texture = nullptr;
}
MapTile& MapTile::operator=(const MapTile& mo)
{
if (&mo != this)
{
delete texture;
delete sprite;
texture = new sf::Texture;
*texture = *(mo.texture);
sprite = new sf::Sprite(*texture);
}
return *this;
}
MapTile& MapTile::operator=(MapTile&& mo) noexcept
{
if (&mo != this)
{
delete texture;
delete sprite;
texture = mo.texture;
sprite = mo.sprite;
mo.sprite = nullptr;
mo.texture = nullptr;
}
return *this;
}
void MapTile::load(std::string file_path, sf::Vector2i& map_size, char type)
{
std::ifstream file;
file.open(file_path + ".kimap");
// Assign the tiles based off map
std::string row;
for (int i = 0; i < map_size.y; i++)
{
std::getline(file, row);
for (int j = 0; j < row.size(); j++)
{
if (row[j] == type)
{
objects.push_back(MapObject{ j * 40.f, i * 40.f });
}
}
}
std::cout << objects.size() << std::endl;
file.close();
}
void MapTile::render(sf::RenderWindow* w)
{
for (int i = 0; i < objects.size(); i++)
{
sprite->setPosition(objects[i].x, objects[i].y);
w->draw(*sprite);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Map::load()
{
std::ifstream file(path + ".size");
file >> size.x >> size.y >> std::ws;
file.close();
tiles.push_back(MapTile{ "Textures/sky.png" }); // Sky
tiles[0].load(path, size, ' ');
tiles.push_back(MapTile{ "Textures/floor.png" }); // Floor
tiles[1].load(path, size, 'g');
tiles.push_back(MapTile{ "Textures/ground.png" }); // Ground
tiles[2].load(path, size, 'G');
}
Map::Map(std::string path) : thread{&Map::load, this}, path{path}
{
thread.launch();
}
void Map::render(sf::RenderWindow* w)
{
for (int i = 0; i < tiles.size(); i++)
{
tiles[i].render(w);
}
}
Mam nadzieje, że ktoś mi pomoże