【问题标题】:Variable doesnt change within an object list变量在对象列表中不变
【发布时间】:2012-11-28 21:15:31
【问题描述】:

我正在使用 openGL 和 c++ 制作一个小行星游戏。 我遇到了一个问题,我现在将尝试描述。

我有一个包含变量和方法的小行星类。它有一个 create 方法来设置小行星的当前位置,还有一个 draw 方法用来随机改变小行星的位置。

当我尝试在我的主课中使用这颗小行星时,它工作正常。它会移动并做我想做的一切。

然后我为创建小行星列表的 Asteroid Generator 创建了一个类,并且我还有一个方法可以初始化列表中每个元素的 draw 方法。但是当我运行它时,小行星并没有移动。我使用visual studio完成了我的代码,我发现在小行星的draw方法中值被正确更改,但是当再次绘制时,位置被重置回原来的值,所以它不会移动.这可能与每个方法之后的 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();  
    }
}

小行星.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();
}

谢谢。

【问题讨论】:

  • 那段代码不应该编译,为什么要在类中使用作用域运算符::
  • Draw()里面的代码是什么?当我们看不到您实际更新职位的方式时,我们很难提供帮助。
  • 对不起,我添加了draw方法。我不认为这是问题所在,但我想可能是。

标签: c++ list class draw


【解决方案1】:

问题是listAsteroids 持有小行星,而不是指向小行星的指针。通过将std::list&lt;Asteroid&gt; listAsteroids; 更改为std::list&lt;Asteroid*&gt; listAsteroids; 来修复它,而不是Asteroid temp;Asteroid* temp = new Asteroid

您的实际问题是在 for 循环中引起的。 for each (Asteroid c in listAsteroids) 在这里,您将每个 Asteroid 实例的值复制为 Asteroid c,然后它会被更改,并且不会更改实际实例。再次在这里使用Asteroid* c,这样你就得到了一个指向实际实例的指针。

这样,您的列表包含指向 Asteroids 实际实例的指针,而不是按值复制实例(这会导致这些临时更改为临时对象)

除了解决您的问题之外,还可以节省时间和资源;例如,如果您曾经将列表用作函数中的参数,则复制指针比复制值要快得多。请记住使用-&gt; 而不是.

【讨论】:

  • 效果很好!我知道这是指针的问题。我对使用它们感到非常困惑。非常感谢:)
  • 不客气,我知道指针和引用对于新手来说是多么令人沮丧——它们是迄今为止我学习 C++ 中最难的部分。但是继续编码,你最终会习惯的!
【解决方案2】:

这只是一个猜测,但您的 Astroid 类的复制构造函数可能无法在 OpenGL 中正常工作?我注意到在 generate 方法中,您在堆栈上创建了一个新的 astroid,调用 Create() 函数,然后将其推送到列表中。在那个时间点,该列表有一个创建的 astroid 的副本,而不是那个名为 temp 的确切副本。我会亲自在堆上创建一个 astroid,然后将列表设为指向 astroid 的指针列表。只要您记得进行所有适当的内存清理,这可能会有所帮助。让我知道这是否更接近!

【讨论】:

  • 是的,我这样做的方式有点奇怪,但我不知道该怎么做 :( 我对指针很不好。它确实在随机位置创建了随机生成的小行星. 他们只是不移动,因为每次 Draw() 调用都会重置位置。
【解决方案3】:

我认为问题在于“for each”循环;它似乎是按值迭代列表,因此获取列表中每个 Asteroid 的副本,然后在其 Draw 方法中对其进行修改,但这些修改会丢失,因为它只是一个副本。

我不完全确定,因为那是非标准语法;据我所知,这是一些奇怪的 Visual C++ 扩展。标准的写法是:

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

因为这是一个参考,所以更改应该保留。

【讨论】:

  • 此语法似乎无法识别。
  • 我猜你的 Visual C++ 版本不支持 C++0x?
猜你喜欢
  • 2013-04-13
  • 1970-01-01
  • 1970-01-01
  • 2011-03-10
  • 1970-01-01
  • 2019-11-20
  • 2011-09-08
  • 2020-02-02
  • 1970-01-01
相关资源
最近更新 更多