2013-03-07 39 views
0

中我正在尝试为一个学校项目创建一个非常简单的物理模拟器,我希望它所做的就是让一个立方体落到重力下当它碰到地板时它会反弹,直到立方体没有能量,它会停止移动,例如休息在地板上。我还没有添加碰撞检测,但其他大部分工作都很好,我唯一的问题是立方体不能平稳地落下,如此剧烈跳跃,例如,它下降并加速然后放慢速度,然后再次加速,我不知道为什么。如何使立方体沿着Y轴平滑地落在开放式G1,C++

我已经incluided代码如下:

timestep++; 
velo += 0.005; 
cout << velo << "\n"; 
glTranslatef(0.0, -velo, 0.0);//timestep * gravity, 0.0); 

我也包括整个程序代码只是柜面它是一个probem别的地方上面的提取物只是在显示函数的顶部

#include <GLTools.h> 
#include <GLShaderManager.h> 
#include <GLFrustum.h> 
#include <GLBatch.h> 
#include <GLFrame.h> 
#include <GLMatrixStack.h> 
#include <GLGeometryTransform.h> 
#include <StopWatch.h> 

#include <math.h> 
#include <stdio.h> 

#ifdef __APPLE__ 
#include <glut/glut.h> 
#else 
#define FREEGLUT_STATIC 
#include <GL/glut.h> 
#endif 

#include <iostream>; 
using namespace std; 

void display(); 
void specialKeys(int, int, int); 
void animate(); 

double rotate_y = 0; 
double rotate_x = 0; 

// Gravity Varibles 
int timestep = 0; 
float gravity = 0.0098; 
float velo = 0.0f; 


int main(int argc, char* argv[]) 
{ 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL); 
    glutCreateWindow("DANIELS CUBE"); 
    glEnable(GL_DEPTH_TEST); 
    glShadeModel(GL_SMOOTH); 

    glutDisplayFunc(display); 
    glutSpecialFunc(specialKeys); 
    glutIdleFunc(animate); 

    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    glOrtho(-2.0, 2.0, -2.0, 2.0, -2.0, 2.0); 

    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
    gluLookAt(5.0, 5.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); 
    glutMainLoop(); 

    return 0; 
} 

void animate() 
{ 
    glutPostRedisplay(); 
} 

void display() 
{ 
    //Clears the window 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    // Changes the way the polygons are drawn so it looks like a wire frame 
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 

    /////////// 
    // CUBE /// 
    /////////// 

    // Resets the transformation matrix 
    glLoadIdentity(); 
    glScalef(0.2, 0.2, 0.2); 
    // Rotates the cuube around the x by 'rotate_x' 
    glRotatef(rotate_x, 1.0, 0.0, 0.0); 
    // Rotates the cuube around the y by 'rotate_y' 
    glRotatef(rotate_y, 0.0, 1.0, 0.0); 

    // move dew to gravity 
    timestep++; 
    velo += 0.005; 
    cout << velo << "\n"; 
    glTranslatef(0.0, -velo, 0.0);//timestep * gravity, 0.0); 

    // Defines the folowing verticys as this polygon 
    glBegin(GL_POLYGON); 

    //Changes color 
    glColor3f(1.0, 0.0, 0.5); 
    // Adds verted to polygon 
    glVertex3f(-0.5, -0.5, -0.5); // F1 
    glColor3f(0.0, 1.0, 0.0); 
    glVertex3f(-0.5, 0.5, -0.5 ); // F2 
    glColor3f(0.0, 0.0, 1.0); 
    glVertex3f(0.5, 0.5, -0.5); // F3 
    glColor3f(1.0, 0.0, 1.0); 
    glVertex3f(0.5, -0.5, -0.5); // F4 

    // Closes the polygon 
    glEnd(); 

    glBegin(GL_POLYGON); 

    glColor3f(1.0, 1.0, 1.0); 
    glVertex3f(0.5, -0.5, -0.5); // Back1 
    glVertex3f(0.5, 0.5, -0.5 ); // Back2 
    glVertex3f(0.5, 0.5, 0.5); // Back3 
    glVertex3f(0.5, -0.5, 0.5); // Back4 

    glEnd(); 

    glBegin(GL_POLYGON); 

    glColor3f(1.0, 0.0, 1.0); 
    glVertex3f(0.5, -0.5, -0.5); // F1 
    glVertex3f(0.5, 0.5, -0.5 ); // F2 
    glVertex3f(0.5, 0.5, 0.5); // F3 
    glVertex3f(0.5, -0.5, 0.5); // F4 

    glEnd(); 

    glBegin(GL_POLYGON); 

    glColor3f(0.0, 1.0, 0.0); 
    glVertex3f(-0.5, -0.5, 0.5); // F1 
    glVertex3f(-0.5, 0.5, 0.5 ); // F2 
    glVertex3f(-0.5, 0.5, -0.5); // F3 
    glVertex3f(-0.5, -0.5, -0.5); // F4 

    glEnd(); 

    glBegin(GL_POLYGON); 

    glColor3f(0.0, 0.0, 1.0); 
    glVertex3f(0.5, 0.5, 0.5); // F1 
    glVertex3f(0.5, 0.5, -0.5 ); // F2 
    glVertex3f(-0.5, 0.5, -0.5); // F3 
    glVertex3f(-0.5, 0.5, 0.5); // F4 

    glEnd(); 

    glBegin(GL_POLYGON); 

    glColor3f(1.0, 0.0, 0.0); 
    glVertex3f(0.5, -0.5, -0.5); // F1 
    glVertex3f(0.5, -0.5, 0.5 ); // F2 
    glVertex3f(-0.5, -0.5, 0.5); // F3 
    glVertex3f(-0.5, 0.5, -0.5); // F4 

    glEnd(); 

    //////////// 
    // Floor // 
    ////////// 

    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 
    glLoadIdentity(); 

    // Rotates the cuube around the x by 'rotate_x' 
    glRotatef(rotate_x, 1.0, 0.0, 0.0); 
    // Rotates the cuube around the y by 'rotate_y' 
    glRotatef(rotate_y, 0.0, 1.0, 0.0); 

    glColor3f(1.0, 1.0, 1.0); 
    glBegin(GL_LINES); 
    for(GLfloat i = -2.5; i < 2.5; i += 0.25) 
    { 
     glVertex3f(i, -1.0, 2.5); 
     glVertex3f(i, -1.0, -2.5); 
     glVertex3f(2.5, -1.0, i); 
     glVertex3f(-2.5, -1.0, i); 
    } 
    glEnd(); 

    // Flushes the buffers 
    glFlush(); 
    // Draws what has just been done on the screen 
    glutSwapBuffers(); 
    } 

void specialKeys(int key, int x, int y) 
{ 
    if(key == GLUT_KEY_RIGHT) 
    { 
     rotate_y += 5; 
    } 
    else if(key == GLUT_KEY_LEFT) 
    { 
     rotate_y -= 5; 
    } 
    else if(key == GLUT_KEY_UP) 
    { 
     rotate_x += 5; 
    } 
    else if(key == GLUT_KEY_DOWN) 
    { 
     rotate_x -= 5; 
    } 

    glutPostRedisplay(); 
} 
+0

如果你只是绘制四边形,我会避免使用'GL_POLYGON'。改用'GL_QUADS'。 – genpfault 2013-03-07 23:36:59

+0

我不确定你计划用这些旋转变量做什么,但如果你在glTranslate之前glRotate由于重力,你也要旋转重力方向!如果您只是希望立方体在落下时旋转,请在glTranslate之后执行glRotate *。 – wxs 2013-03-08 17:16:13

回答

4

有几个问题,我与你的代码中看到:

假设固定时间步长 您的显示功能不能保证以均匀间隔时间进行调用。基本上,你要以“每米的米数(m/f)”而不是“每秒的米数(m/s)”为单位给出立方体的速度。 (我在这里使用米作为一般距离单位)

所以,一些基本的数学告诉我,m/f = m/s * s/f。换句话说,您想要缩放从最后一帧开始的实际时间步数的每帧移动多维数据集的量。

速度问题 你编写代码的方式,你velo变量实际上代表的位置,而你与数0.005我认为这是你的意思是你的加速更新每一帧。如果你想因重力加速,你需要存储两个值,它的位置和速度。然后在每一帧中,您需要通过添加加速度来更新速度,并通过添加速度来更新位置。

下面是一些代码,做这些事情都

int lastTime=0; 

void display() { 
    int time = glutGet(GLUT_ELAPSED_TIME); // Time since the start of the program 
    if (lastTime>0) { // Don't move anything the first frame 
     int deltaTime = time-lastTime; // millis elapsed since the last frame 
     velo += -0.005*deltaTime; // Gravity accelerates downwards 
     pos += velo*deltaTime; // Position updated by velocity 
     glTranslateF(0.0, pos, 0.0); // Actually position the square in the correct location 
    } 
    lastTime = deltaTime; 
} 

注意如何当我加速更新自己的速度我缩放通过的DeltaTime,当我更新我跟我做同样的速度位置。同样,从以前的单位分析是一个简单的方法来记住这一点:deltaTime告诉你从最后一帧开始经过的毫秒数,所以它的单位是“s/f”。 velo应该有单位“m/s”以使运动随着时间的推移平滑。更新该帧的位置的量是m/s * s/f = m/f。这些单位是有道理的,他们测量每帧的距离。

+1

另请参见:[修复您的Timestep](http://gafferongames.com/game-physics/fix-your-timestep/) – genpfault 2013-03-07 23:35:17

+0

我做了你所说的,但程序仍然跳动,它跳起来,因为它下降 – Dan 2013-03-08 00:55:52

+0

我注意到您的代码存在其他一些问题;我已经相应地更新了答案。 – wxs 2013-03-08 17:14:49

相关问题