I’m making a little asteroids game using openGL and c++.
I ran into a problem which I will try to describe now.
I have a class for an asteroid that has variables and methods. It has a create method that sets current position of the asteroid and a draw method that it uses to change the position of the asteroid randomly.
When I try to use this asteroid in my main class, it works fine. It moves and does everything I wanted it to.
I then created a class for an Asteroid Generator that creates a list of asteroids and I also have a method that initialises the draw method on every element of the list. But when I run it, the asteroid doesn’t move. I did a step through my code using visual studio and I found out that inside the draw method of the asteroid the value is changed correctly, but when the draw happens again the position is reset back to its original value, so it doesn’t move. It could be something to do with c++ dumping memory after every method, so I believe Im messing up with pointers. I would appreciate any help you could give in spotting my error!
I added the header files and methods to show how Im using my asteroid generator.
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
Initialised once
asteroidgen.generateAsteroid(1, false);
draw method every frame
asteroidgen.DrawAsteroids();
EDIT:
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();
}
Thank you.
The problem is
listAsteroidsholding Asteroids, instead of pointers to Asteroids. Fix it by changingstd::list<Asteroid> listAsteroids;tostd::list<Asteroid*> listAsteroids;and instead ofAsteroid temp;doAsteroid* temp = new Asteroid.Your actual problem is caused in the for loop.
for each (Asteroid c in listAsteroids)here you get a copy-by-value of every one of your Asteroid instances asAsteroid c, which then gets changed, and doesn’t change the actual instance. Again useAsteroid* chere, so you get a pointer to the actual instance.This way your list contains pointers to the actual instances of Asteroids, rather than ever copying the instances by value (which causes those temporary changes to a temporary object)
On top of fixing your problem, this saves both time and resources; if you ever use the list for example as a parameter in a function, it’s much faster to copy the pointers rather than values. Just remember to use
->instead of.