类变量的更改未被保留

时间:2013-12-01 21:48:52

标签: c++ class visual-c++ opengl

这必定是一些愚蠢的错误,但我已经在这个bug工作了好几天,并最终将其缩小到一个奇怪的问题。也许我只是没有看到它,因为我的大多数经验都是用Java编程,而不是C ++编程。我正在设置一个雪人在openGL中的某些地形上移动,每当我将雪人的速度设置为随机游走时,下次调用更新函数时都不会保留它。我通过计算概率来做到这一点,并且如果该概率检查成功,则给予雪人随机速度并且每次更新时将其添加到位置。不知何故,每次更新功能退出时,速度都会不断重置为0,导致它们在一帧中跳跃一点,然后传送回原来的位置以备将来的帧,最终不会让它们移动。 x和y位置也会在调用时恢复到之前的值。命令提示输出的示例如下:

DEBUG: new frame
2) dx dy 0.000000 0.000000
256.000000 15.000000 0.000000 0.000000
2) dx dy 0.000000 0.000000
104.000000 17.000000 0.000000 0.000000
2) dx dy 0.000000 0.000000
256.000000 256.000000 0.000000 0.000000
1) dx dy -0.100000 -0.400000
2) dx dy -0.100000 -0.400000
306.000000 498.000000 -0.100000 -0.400000
2)dx dy 0.000000 0.000000
6.000000 256.000000 0.000000 0.000000
DEBUG: new frame
2) dx dy 0.000000 0.000000
256.000000 15.000000 0.000000 0.000000
2) dx dy 0.000000 0.000000
104.000000 17.000000 0.000000 0.000000
2) dx dy 0.000000 0.000000
256.000000 256.000000 0.000000 0.000000
2) dx dy 0.000000 0.000000
256.000000 256.000000 0.000000 0.000000
2)dx dy 0.000000 0.000000
6.000000 256.000000 0.000000 0.000000

这些打印出一堆值,但要注意的是第四个元素在调用之间应该具有相同的值,并且它们不会。他们被重置。

Snowman.h

#pragma once
#include "ppm_canvas.h"
class Snowman
{
public:
Snowman(canvas_t);
~Snowman(void);

void setWireframe(bool);
void toggleWireframe(void);
void setAnimate(bool);
void toggleAnimate(void);
void setArmSegments(int);
void addArmSegment(void);
void subtractArmSegment(void);

void update(canvas_t);
void draw(void);

private:
bool wireFrame;
bool animate;
bool walking;
int armSegments;
int animationFrameNumber;
float manualUserOffset;

float x, y, z;
float dx, dy;

inline float f(void);
inline void drawMouth(int headRadius);
inline void drawFace(int headRadius);
void drawArm(int remainingSegments);
inline void drawBody();
inline float getHeight(canvas_t);
};

来自Snowman.cpp

void Snowman::update(canvas_t texture){
    //randomly toggle the walking variable
    int probability = rand() % 100;
    if(probability <= 2){
        walking = !walking;
        this->dx = static_cast<float>(( (rand() % 100) - 50))/10.0;
        this->dy = static_cast<float>(( (rand() % 100) - 50))/10.0;
        printf("1) dx dy %f %f\n", dx, dy);
    }
    printf("2) dx dy %f %f\n", dx, dy);
    //code to control movement
    if(walking){
        this->animate = true;
        this->x += this->dx;
        this->y += this->dy;
        constrain(this->x, 0, texture.width * 2);
        constrain(this->y, 0, texture.height * 2);
    }else{
        animate = false;
    }

    //set the height after x and y are resolved
    this->z = getHeight(texture);
}    

void Snowman::draw(void){
glPushMatrix();{
    //turns out x is correct, y is vertical, and z is the other horozintal.  oops...
    float alittlebit = 10.0;//offset because the center of the bottom sphere is below 0
    glRotatef(atan2(dy, dx), 0, 1, 0);
    glTranslatef(x, z + alittlebit, y);
    drawBody();
}glPopMatrix();
printf(" %f %f %f %f\n", this->x, this->y, this->dx, this->dy );
}

来自Main.cpp

inline void drawSnowmen(){
printf("DEBUG: new frame\n");
glPushMatrix();{
    glScalef(0.4, 0.4, 0.4);
    glBindTexture(GL_TEXTURE_2D, 0);
    for(Snowman i:snowmen){
        i.update(terrain);
        i.draw();
    }
    glBindTexture(GL_TEXTURE_2D, 1);
}glPopMatrix();
}

我还在其中包含了下面的错误视频。我非常渴望解决这个问题已经花费了8个多小时,我们将非常感谢您的帮助。

http://www.youtube.com/watch?v=76uuu1sage0&feature=youtu.be

此外,没有办法将问题压缩到只有这个,但这里是整个源代码: http://people.ucsc.edu/~cchilder/openGLBug.zip

1 个答案:

答案 0 :(得分:1)

尝试在drawSnowmen()中使用ref元素。请参阅上面有关复制构造函数的注释。

    for(Snowman &i:snowmen){
        i.update(terrain);
        i.draw();
    }

没有引用,update()正在修改Snowman的临时实例,而不是存储在向量中的实例:

    for(Snowman i:snowmen){
        i.update(terrain);
        i.draw();
    }