• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

SFML - zmienne składowe klasy są zerowane po opuszczeniu funkcji

VPS Starter Arubacloud
0 głosów
224 wizyt
pytanie zadane 27 lutego 2023 w C i C++ przez Filip Sośnicki Nowicjusz (230 p.)

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

komentarz 28 lutego 2023 przez Great Stary wyjadacz (12,300 p.)
Relacja pomiędzy sf::Sprite, a sf::Texture to Flyweight. sf::Sprite posiada wskaźnik na sf::Texture. Obiekty klasy sf::Texture są ciężkie i nie chcemy ich przenosić/kopiować, a zwłaszcza trzymać w jednym obiekcie ze spritem. Od tego powinien być resource manager.
komentarz 28 lutego 2023 przez j23 Mędrzec (194,920 p.)

... albo std::shared_ptr.

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;
    std::shared_ptr<sf::Texture> texture;
    std::shared_ptr<sf::Sprite> sprite;

public:
    explicit MapTile(std::string texture_path);

    void render(sf::RenderWindow* w);
    void load(std::string file_path, sf::Vector2i& map_size, char type);
};

MapTile::MapTile(std::string texture_path)
{
    texture = std::make_shared<sf::Texture>();
    texture->loadFromFile(texture_path);
    sprite = std::make_shared<sf::Sprite>(*texture);
}

 

Zaloguj lub zarejestruj się, aby odpowiedzieć na to pytanie.

Podobne pytania

0 głosów
2 odpowiedzi 567 wizyt
pytanie zadane 7 czerwca 2016 w C i C++ przez Avernis Nałogowiec (27,400 p.)
0 głosów
1 odpowiedź 267 wizyt
+1 głos
1 odpowiedź 409 wizyt

92,454 zapytań

141,262 odpowiedzi

319,089 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...