Pozycja wynosi -nan(ind) kiedy dodaję obiekt do świata

0

Cześć! Robię sobie dla nauki taki mały silnik. Posiadam w nim klasy World i Body.

World - dodaje i updateuje body
Body - zbiór danych - pozycja, przyśpieszenie itp.

class World
{
public:
	World(float gravity);
	~World();

	void AddBody(Body* body) {
		this->body.push_back(body);
	}
	
	void AddBody(std::vector<Body*> body) {
		for(const auto& b: body) {
			this->body.push_back(b);
		}
	}

	void Update(float deltaTime) {
		for(const auto& b : body {
			b->update(deltaTime);
		}
	}
private:
	std::vector<Body*> body;
};

I w już projekcie gry mam klasę Entity, która jest matką.

class Entity {
public:
	Entity();
	virtual ~Entity();

	virtual void Update(float deltaTime);
	virtual void Draw();

	Body* getBody() {
		return body.get();
	}

	void MakeBody(Vector2 position) {
		body = std::make_unique<Body>(position);
	}
private:
std::unique_ptr<Body> body; // próbowałem zwykłego pointera i całą resztę smart pointerów
};
class Potwor: public Entity
{
	Potwor(Vector2 position) {
		 MakeBody(position);
	}

	void Update(float deltaTime) override {
		std::cout<<body->getPosition().x<<std::endl;
	};
};

I klasę, która obsługuje dodawanie przeciwników jako singleton, bo chce mieć tylko jedną taką klasę

class EntityManager {
public:
	static EntityManager getInstance();
	~EntityManager();

	void AddEntity(Vector2 position);
	void Update(float deltaTime);
	void Draw();

	std::vector<Body*> getBody() {
		std::vector<Body*> result;

		for(const auto& e : entity) {
			result.push_back(e->getBody());
		}
		
		return result;
	}
private:	
	EntityManager();
	std::vector<std::unique_ptr<Entity>> entity;
};

i główną klasę gry

class GameplayScreen {
public:
	GameplayScreen() {
		world = std::make_unique<World>(9.81f);
		
		EntityManager::getInstance().AddEntity(`some position`);
		world->AddBody(EntityManager::getInstance().getBody());
	}
	~GameplayScreen();

	void Update(float deltaTime);
	void Draw();
private:
	std::unique_ptr<World> world;
};

I pozycja, która X, która jest wypisywana przez klasę potwor jest równa -nan(ind).

Jeśli jednak wezmę w komentarz world->AddBody(EntityManager::getInstance().getBody()); pozycja wraca do normy i jest taka jaką sobie ustawiłem.

world na pewno działa dobrze, bo gdy dodaję Gracza, który nie ma klasy bazowej, wszystko działa bardzo dobrze

class Player {
public:
	Player();
	~Player();

	Body* getBody() {
		return &body;
	};
private:

	Body body;
};

world->AddBody(player.getBody());

I wszystko ładnie pięknie się updateuje u gracza.

Co jest przyczyną takiego zachowania?
Gdzie popełniam błąd?
W jaki sposób to naprawić?

0

Nie podajesz implementacji konstruktorów, więc można jedynie zgadywać, że EntityManager nie inicjalizuje obiektów Entity, które trzyma w wektorze wskaźników i/lub nie inicjalizujesz body w konstruktorze Entity.

Inna rzecz, dlaczego przekazujesz wektor przez wartość (to nie ma związku z błędem)?

void AddBody(std::vector<Body*> body) {

No i nazewnictwo masakryczne, mieszanie polskiego z angielskim, słowo body jest używane w wielu różnych miejscach gdy powinno być monsters, players itd.

0

No i nazewnictwo masakryczne, mieszanie polskiego z angielskim, słowo body jest używane w wielu różnych miejscach gdy powinno być monsters, players itd.

Nie rozumiem o co ci tutaj chodzi. Jak Body może nazywać się mosters albo players? Klasa Body nie jest do polimorfizmu. Tutaj nazewnictwo jest dobre, jedyne do czego można się przyczepić to do nazwy `Potwor' ale nazwalem to tak po prostu bez sensu, żeby sprawdzić czy po prostu działa.

Konstruktor od EntityManager ma być pusty, bo za to odpowiada AddEntity();

AddEntity(Vector2 pozycja) {
	entity.push_back(std::make_unique<Potwor>(position));
}

Inna rzecz, dlaczego przekazujesz wektor przez wartość (to nie ma związku z błędem)?

A void AddBody(std::vector<Body*> body) przyjmuje vektor, ponieważ może być więcej Entity niż jeden.

Może być 1000 Potworów i każdy potwór ma własne ciało (Body) czyli 1000 innych updateów.

void AddBody(std::vector<Body*> body) {
	for(const auto& b: body) { // <- dla 1000 ciał, czyli 1000 potworów 
		this->body.push_back(b); // <- Dodaj do tablicy ciał
	}
}

Pewnie jakoś to nieudolnie wytłumaczyłem.

0

Konstruktor od EntityManager ma być pusty, bo za to odpowiada AddEntity();

No to jeszcze pytanie jak getInstance() jest zaimplementowane.

Nie rozumiem o co ci tutaj chodzi. Jak Body może nazywać się mosters albo players?

Nie Body klasa, tylko np. std::vector<Body*> body; w klasie World.

A void AddBody(std::vector<Body*> body) przyjmuje vektor, ponieważ może być więcej Entity niż jeden.

Tak, tylko że powinno być

void AddBody(const std::vector<Body*>& body)  // kolejne miejsce gdzie nazwa body nic nie wnosi
0

No to jeszcze pytanie jak getInstance() jest zaimplementowane.

EntityManager::getInstance() {
	static EntityManager instance;
	return instance;
}

Nie Body klasa, tylko np. std::vector<Body*> body; w klasie World.

To co jest w tej nazwie nie tak?

Tak, tylko że powinno być

void AddBody(const std::vector<Body*>& body)

Tak czy siak nie działa i pozycja wynosi -nan(ind)

1 użytkowników online, w tym zalogowanych: 0, gości: 1