0

openGL と c++ を使用して、小さな小惑星ゲームを作成しています。私は今説明しようとしている問題に遭遇しました。

変数とメソッドを持つ小惑星のクラスがあります。小惑星の現在の位置を設定する create メソッドと、小惑星の位置をランダムに変更するために使用する draw メソッドがあります。

この小惑星をメイン クラスで使用しようとすると、問題なく動作します。それは動き、私が望んでいたすべてを行います。

次に、小惑星のリストを作成する Asteroid Generator のクラスを作成し、リストのすべての要素で draw メソッドを初期化するメソッドも用意しました。しかし、実行すると、小惑星は動きません。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();  
    }
}

小惑星.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

メイン.cpp

一度初期化

asteroidgen.generateAsteroid(1, false);

フレームごとの draw メソッド

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();
}

ありがとうございました。

4

3 に答える 3

1

問題はlistAsteroids、小惑星へのポインターではなく、小惑星を保持することです。doの代わりにに変更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へのポインタを取得します。

このように、リストには、インスタンスを値でコピーするのではなく、小惑星の実際のインスタンスへのポインターが含まれます(これにより、一時オブジェクトに一時的な変更が加えられます)

問題を修正することに加えて、これは時間とリソースの両方を節約します。たとえば、関数のパラメータとしてリストを使用する場合は、値よりもポインタをコピーする方がはるかに高速です。->代わりに使用することを忘れないでください.

于 2012-11-28T22:13:13.993 に答える
0

これは単なる推測ですが、Astroid クラスのコピー コンストラクターが OpenGL で正しく動作しない可能性はありますか? generate メソッドで、スタック上に新しいアステロイドを作成し、Create() 関数を呼び出してからリストにプッシュしていることに気付きました。その時点で、リストには作成されたアステロイドのコピーがあり、temp と呼ばれる正確なものではありません。私は個人的にヒープ上にアステロイドを作成し、リストをアステロイドへのポインターのリストにします。適切なメモリのクリーンアップをすべて行うことを覚えている限り、それは役立つかもしれません. これが近いかどうか教えてください!

于 2012-11-28T21:25:17.627 に答える
0

問題はその「for each」ループにあると思います。リストを値で反復しているように見えるため、リスト内の各小惑星のコピーを取得し、それを Draw メソッドで変更しますが、コピーに過ぎないため、これらの変更は失われます。

これは非標準の構文であるため、完全にはわかりません。私が見る限り、これは奇妙な Visual C++ 拡張機能です。標準的な書き方は次のとおりです。

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

これは参照であるため、変更は適用されます。

于 2012-11-28T21:57:26.540 に答える