![](/img/trans.png)
[英]Unreal Engine 4 C++ - How to make an actor move up and down along the Z axis
[英]How to make a cube fall smoothly down the Y-Axis in Open Gl, C++
我正在嘗試為一個學校項目創建一個非常簡單的物理模擬器,我想要做的就是擁有一個在重力作用下落下的露水的立方體,當它撞到地板上時它會彈起,依此類推,直到立方體沒有能量並且只會停止移動,例如在地板上休息。 我還沒有添加碰撞檢測,但是大多數其他事情都可以正常工作,我唯一的問題是立方體不能平穩地下落,其跳躍性很強,例如,下落並加速然后減速然后再次加速,我有不知道為什么。
我已包含以下代碼:
timestep++;
velo += 0.005;
cout << velo << "\n";
glTranslatef(0.0, -velo, 0.0);//timestep * gravity, 0.0);
我還包括了整個程序代碼,以防萬一它是一個探查,而上面的摘錄只是在顯示功能的頂部
#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();
}
我的代碼有幾個問題:
假設時間步長固定,則不能保證以均勻間隔調用顯示函數。 本質上,您是以“每幀米( 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。 這些單位很有意義,它們測量每幀的距離。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.