C++ 供过于求的平稳运动

C++ 供过于求的平稳运动,c++,opengl,glut,glew,C++,Opengl,Glut,Glew,我制作了一个非常简单的引擎,基本上可以画一个角色,然后你可以在屏幕上移动它 但是我用一种非常可怕的方式做了这个运动,我的意思是它是基于这样的离散值: void Scene::movePlayer(int dir) { switch (dir){ case 1: yy = yy + 0.05; break; case 2: xx = xx - 0.05; break; case 3:

我制作了一个非常简单的引擎,基本上可以画一个角色,然后你可以在屏幕上移动它

但是我用一种非常可怕的方式做了这个运动,我的意思是它是基于这样的离散值:

void Scene::movePlayer(int dir) {

    switch (dir){
    case 1:     yy = yy + 0.05;
            break;

    case 2:     xx = xx - 0.05;
            break;

    case 3:
            yy = yy - 0.05;
            break;

    case 4:
            xx = xx + 0.05;
            break;

    default:
            break;
}
它工作并移动角色,但我不太喜欢它,因为它非常跳跃,而且不平滑

我希望有更流畅的动作,就像《马里奥》或类似的作品

你能告诉我如何做到这一点吗?

你追求的是加速(也可能是减速——让我在回答时思考一下)

以下步骤是:

  • 您的马里奥站在位置
    x
    处静止不动。将
    速度
    设置为
    0.0
    并将
    加速度
    设置为较小的值,例如
    0.01
  • 用户按下左键或右键。将
    加速度
    添加到
    速度
    并更新其位置。确保加速度具有正确的符号–向左移动为负值,向右移动为正值
  • 只要用户不松开钥匙,就继续向
    速度添加
    加速度
    ——但在
    速度
    达到合适的值时停止(例如,您的
    0.05
  • 如果您想让马里奥在松开钥匙时停止滑动,请将
    加速度设置为负值,例如
    -0.015
    (通常大于加速时),并使用它降低速度,直到小于或等于
    0.0
    。当其值较低时,请确保将其精确重置为
    0.0
    !浮点运算是不准确的,一个非常小的剩余值可能会使您的Mario保持轻微的移动
  • 此过程与整个游戏循环的实际计时紧密相关。每个游戏帧只需添加或减去
    加速度

    您可以使用可变的更新间隔(即,根据两次连续的
    速度
    更新之间的时间调整速度),但使用固定帧速率(例如每秒25或50帧)更容易启动。这样,
    加速度
    就可以是恒定的;可以通过试运行来估计正确的值。我想你的
    xx=xx+0.05通过相同的过程完成

    同样的程序可用于“跳跃”和“坠落”。若要跳跃,请将初始速度设置为高值,并在每个游戏循环中降低它。如果低于
    0
    ,不要担心,这是让上升的东西再次下降的必要条件。要下降,请将速度设置为
    0.0
    ,然后再次使用
    加速度提高速度


    如果你的马里奥沿着一条无限长的直线移动,这将很好地工作。然后你只需注意他的
    yy
    位置,它可能不会延伸到“地板”下方。如果要添加不同的垂直标高以继续移动,则可以为左右移动(使其成为死止点而不是停止滑动)和上下移动添加碰撞检查(同样,如果他跳起来,头撞到什么东西上,就会停下来,但随后会“摔倒”,如果他离开什么东西,就会加速,直到他撞到底部的一个街区)。

    你是在考虑加速/减速,而不是离散的“停/动”吗你现在有吗?这很好,但这不是我现在关注的。基本上现在,0.05值在两个位置之间输出一个明显的“跳跃”,很容易被注意到。当我减小这个值时,移动更平滑(因为跳跃更短),但它也使角色移动更慢(因为要移动设定的距离,需要更多的“跳跃”。)我不知道如何平衡它,使角色在屏幕上移动得相当快,但也使它在非常小的跳跃中移动,使其看起来平滑。这是一个帧速率问题。帧速率越快,移动步长越小,以便在同一时间段内从a移动到B。那么,您如何检测到角色C我只是有一个检测输入的功能:`void Keyboard(int key,int x,int y){开关(key){case GLUT_key\u UP:s.movePlayer(1);break;case GLUT_key\u LEFT:s.movePlayer(2);break;case GLUT_key\u DOWN:s.movePlayer(3);break;case GLUT_KEY_RIGHT:s.movePlayer(4);break;default:break;}glutPostRedisplay();}就是这样。当没有输入时,游戏不会做任何事情,因为我不知道如何做,所以游戏仍然会继续做一些事情(比如动画背景或其他事情)当没有输入时,您需要在按键向下时将速度设置为某个值,在按键释放时将速度设置为零,即,处理向下和向上消息,然后将此数量应用到主循环中的位置。非常感谢您,这非常有帮助。您能告诉我如何在我的程序中限制帧速率吗?到目前为止,它运行的是相同的在我全新的游戏pc和非常旧的虚弱笔记本电脑上,我想现在这不是一个大问题,但我想知道,以供将来参考。我能想到的最简单的方法是使用
    glutTimerFunc
    –将你的速度和位置更新放在它的回调函数中。值为40的
    msecs
    值(请参阅)应该给你一个25帧左右的循环。