Переменная не изменяется в списке объектов

Я делаю маленькую игру с астероидами, используя openGL и c ++.
Я столкнулся с проблемой, которую попытаюсь описать сейчас.

У меня есть класс для астероида, который имеет переменные и методы. У него есть метод create, который устанавливает текущую позицию астероида, и метод рисования, который он использует для случайного изменения положения астероида.

Когда я пытаюсь использовать этот астероид в своем основном классе, он работает нормально. Он двигается и делает все, что хотел.

Затем я создал класс для Генератора астероидов, который создает список астероидов, и у меня также есть метод, который инициализирует метод рисования для каждого элемента списка. Но когда я запускаю его, астероид не двигается. Я сделал шаг по моему коду с использованием Visual Studio и обнаружил, что внутри метода рисования астероида значение изменяется правильно, но когда рисование происходит снова, позиция возвращается к исходному значению, поэтому она не двигается , Это может быть связано с дампированием памяти c ++ после каждого метода, так что я считаю, что я испорчен указателями. Буду признателен за любую помощь в выявлении моей ошибки!

Я добавил заголовочные файлы и методы, чтобы показать, как я использую свой генератор астероидов.

AsteroidGen.h

#ifndef ASTEROIDGEN_H
#define ASTEROIDGEN_H

#undef UNICODE
#define WIN32_LEAN_AND_MEAN

#include <windows.h>    // for timeGetTime()
#include <mmsystem.h>   // ditto
#include <iostream>     // I/O
#include "model3DS.h"#include "Camera.h"#include <glut.h>       // for gluPerspective & gluLookAt
#include <List>
#include "asteroid.h"#include "position.h"
class AsteroidGen{
public:
std::list<Asteroid> listAsteroids;
void AsteroidGen::generateAsteroid(int amount, int delet);
void AsteroidGen::DrawAsteroids();
};

#endif // ASTEROIDGEN_H

AsteroidGen.cpp

#include "asteroidgen.h"
void AsteroidGen::generateAsteroid(int amount, int delet){
if (delet == true)
listAsteroids.clear();

for (int i = 0; i < amount; i++)
{
Asteroid temp;
temp.Create();
listAsteroids.push_front(temp);
}
}

void AsteroidGen::DrawAsteroids(){
for each (Asteroid c in listAsteroids){
c.Draw();
}
}

Asteroid.h

#ifndef ASTEROID_H
#define ASTEROID_H

#undef UNICODE
#define WIN32_LEAN_AND_MEAN

#include <windows.h>    // for timeGetTime()
#include <mmsystem.h>   // ditto
#include <iostream>     // I/O
#include "model3DS.h"#include "Camera.h"#include "position.h"#include <glut.h>       // for gluPerspective & gluLookAt
#include <cmath>
#include "textureTGA.h"
class Asteroid{
public:
GLuint textureId;
GLuint list;
Position pos;
float incX;
float incY;
float asteroidSpeed;
float radio;
float rotation;
bool status;

void Asteroid::GenSphere();
void Asteroid::Reset();
void Asteroid::Draw();
void Asteroid::Create();
};

#endif // ASTEROID_H

main.cpp

Инициализирован один раз

asteroidgen.generateAsteroid(1, false);

метод рисования каждый кадр

asteroidgen.DrawAsteroids();

РЕДАКТИРОВАТЬ:

void Asteroid::Draw(){
pos.z += asteroidSpeed;
pos.y += incY;
pos.x += incX;
rotation += 1;

glPushMatrix();
glTranslatef(pos.x, pos.y, pos.z);
glRotatef(rotation, 1, 1, 1);
glBindTexture(GL_TEXTURE_2D,textureId);
glCallList(list);
glPopMatrix();
}

Спасибо.

0

Решение

Проблема в listAsteroids держа астероиды вместо указателей на астероиды. Исправьте это, изменив std::list<Asteroid> listAsteroids; в std::list<Asteroid*> listAsteroids; и вместо Asteroid temp; делать Asteroid* temp = new Asteroid,

Ваша настоящая проблема вызвана в цикле for. for each (Asteroid c in listAsteroids) здесь вы получите копию по значению каждого из ваших экземпляров Asteroid как Asteroid c, который затем изменяется, и не меняет фактический экземпляр. Снова использовать Asteroid* c здесь, так что вы получите указатель на фактический пример.

Таким образом, ваш список содержит указатели на фактические экземпляры астероидов, а не копируют экземпляры по значению (что приводит к временным изменениям временного объекта).

Помимо решения вашей проблемы, это экономит время и ресурсы; если вы когда-либо используете список, например, в качестве параметра функции, гораздо быстрее копировать указатели, а не значения. Просто не забудьте использовать -> вместо .

1

Другие решения

Это всего лишь предположение, но возможно, что ваш конструктор копирования вашего класса Astroid не работает правильно с OpenGL? Я заметил, что в методе generate вы создаете нового астроида в стеке, вызываете функцию Create () и затем помещаете его в список. В этот момент в списке есть копия созданного астроида, а не точная, которая называется временная. Я лично создал бы кучу астроидов, а затем составил бы список указателей на астроидов. Пока вы помните, чтобы все правильно очистить память, это может помочь. Дайте мне знать, если это было даже близко!

0

Я думаю, что проблема с этим «для каждого» цикла; похоже, он выполняет итерацию списка по значению, поэтому берется копия каждого астероида в списке, который затем модифицируется в его методе Draw, но эти изменения теряются, потому что это только копия.

Я не совсем уверен, хотя, потому что это нестандартный синтаксис; насколько я вижу, это странное расширение Visual C ++. Стандартный способ записи:

for (Asteroid& asteroid : listAsteroids) {
asteroid.Draw();
}

И потому что это ссылка, изменения должны придерживаться.

0
По вопросам рекламы [email protected]