【问题标题】:Smooth movement in GLUTGLUT 中的平滑运动
【发布时间】:2015-11-03 23:11:54
【问题描述】:

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

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

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

它可以工作并移动角色,但我不太喜欢它,因为它非常跳跃且不流畅。

我希望有更流畅的动作,就像马里奥或类似的东西。

你能告诉我如何实现吗?

【问题讨论】:

  • 您是否在考虑加速/减速,而不是您目前拥有的离散“停止/移动”?
  • 会很好,但这不是我目前关注的。基本上现在,0.05 值会在两个位置之间产生明显的“跳跃”,这很容易被注意到。当我减小这个值时,移动更平滑(因为跳跃更短),但它也使角色移动更慢(因为移动一段设定的距离需要更多的“跳跃”。)我不知道如何平衡它,使角色在屏幕上移动得相当快,但它也使它在非常小的跳跃中,所以看起来很流畅。
  • 这是一个帧率问题。帧速率越快,移动步长越小,以便在同一时间段内从 A 到 B。那么如何检测角色应该移动并重绘场景呢?
  • 我只有一个检测输入的函数:` void Keyboard(int key, int x, int y) { switch (key) { case GLUT_KEY_UP: s.movePlayer(1);休息; case GLUT_KEY_LEFT: s.movePlayer(2);休息; case GLUT_KEY_DOWN: s.movePlayer(3);休息; case GLUT_KEY_RIGHT: s.movePlayer(4);休息;默认值:中断; glutPostRedisplay(); }` 就是这样。当没有输入时,游戏不会做任何事情,因为我不知道如何制作,所以当没有输入时,游戏仍然会继续做一些事情(比如说动画背景或其他东西)
  • 您需要在按键按下时将速度设置为某个值,在松开按键时将速度设置为零,即处理向下和向上消息,然后将此量应用于主循环中的位置.

标签: c++ opengl glut glew


【解决方案1】:

你所追求的是加速(也许还有减速——让我在回答时考虑一下)。

要遵循的步骤如下:

  1. 您的马里奥在x 位置静止不动。将speed 设置为0.0,将acceleration 设置为较小的值,例如0.01
  2. 用户按下 LeftRight 键。将acceleration 添加到speed 并更新他的位置。确保加速度的符号正确——左移为负,右移为正。
  3. 只要用户不释放密钥,就继续将acceleration 添加到speed - 但一旦speed 达到合适的值(例如您的0.05)就停止。
  4. 如果您希望马里奥在松开按键时滑到停止,请将acceleration 设置为负值,例如-0.015(通常大于加速时),并使用它来降低速度直到小于或等于0.0。当它较少时,请确保将其重置为完全 0.0!浮点运算是不准确的,一个非常小的剩余值可能会让你的马里奥保持如此轻微的移动。

此过程与整个游戏循环的实际时间密切相关。您只需在每个游戏帧中添加或减去 acceleration 一次。
可以使其以可变的更新间隔工作(即,根据两次连续 speed 更新之间的时间调整速度),但从固定帧速率开始更容易,例如 25 或每秒 50 帧。这样acceleration 可以保持不变;正确的值可以通过试运行来估计。我想你最终通过同样的过程得到了你的xx = xx + 0.05;

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

如果您的马里奥沿着无限直线移动,这将正常工作。然后你只需要留意他的yy 位置——它可能不会延伸到“地板”以下。如果要添加不同的垂直水平以继续前进,您可以为左右移动(使其成为死停而不是滑到停止)和上下移动(同样,死停)添加碰撞检查如果他跳起来用头撞到什么东西,然后是“跌倒”,如果他从某物上走下来,速度会越来越快,直到他撞到底部的一个街区)。

【讨论】:

  • 非常感谢您的帮助。你能告诉我如何在我的程序中限制帧率吗?到目前为止,它在我全新的游戏电脑和非常旧的弱笔记本电脑上运行相同,所以我想现在这不是一个真正的大问题,但我想知道以供将来参考。
  • 我能想到的最简单的方法是使用glutTimerFunc——将你的速度和位置更新放在它的回调函数中。 msecs 的值为 40(请参阅 its description)应该给你大约 25 fps。
猜你喜欢
  • 2016-09-25
  • 2018-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-06
  • 2012-01-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多