我正在使用OpenGL / Glut,并尝试制作简单的“雨”效果。我有一堂雨滴课程:
class Drop {
private:
int speed;
int posY;
int posX;
public:
Drop() { // constructor
speed = 5;
posY = 15;
posX = (rand() % 500);
}
void move() {
speed += 1;
posY += speed;
}
int getPosY() {
return posY;
}
int getPosX() {
return posX;
}
};
Drop
列表以及将Drop
添加到列表的函数。
list<Drop> listDrops;
void placeDrop() {
Drop d = Drop();
listDrops.push_back(d);
}
重绘OpenGL窗口的功能:
void refreshDisplay() {
if (rand() % 5 == 1) {
placeDrop();
}
glClear(GL_COLOR_BUFFER_BIT);
glPointSize(5);
glBegin(GL_POINTS);
for (Drop a : listDrops) {
glColor3f(255,255,255); // white
glVertex2i(a.getPosX(),a.getPosY());
a.move();
}
glEnd();
glFlush();
glutSwapBuffers();
}
void repeater(int val) {
glutPostRedisplay();
glutTimerFunc(5, repeater, 0);
}
当然还有我的主要和Glut初始化:
int main(int argc, char** argv) {
srand(time(NULL));
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowSize(500, 500);
glutCreateWindow("Rain");
gluOrtho2D(0.0, 500.0, 500.0, 0.0);
glutDisplayFunc(refreshDisplay);
glutTimerFunc(0, repeater, 0);
glutMainLoop();
return 0;
}
所有Drop
均已正确初始化,我可以在创建后通过输出其坐标来进行确认。但是他们一点也不动。就像Drop::move()
被忽略了。
如果我改为初始化一个全局Drop aDrop
(仅一个),并在listDrops
的{{1}}上取消迭代器,而只绘制了refreshDisplay()
,它会按预期移动。
答案 0 :(得分:3)
您正在为每个move()
的副本调用Drop
,而该副本仅适用于一次循环迭代
您可以使用
//---------
// |
// v
for (Drop &a : listDrops) {
glColor3f(255,255,255); // white
glVertex2i(a.getPosX(),a.getPosY());
a.move();
}
通过引用获取Drop
s
您之前所做的等同于
for (int i=0; i<listDrops.size();++i) {
Drop a = listDrops[i]; //a is a copy of the entry
assert(&a != &listDrops[i])
//...
}