1

我正在尝试 SFML 并正在创建经典游戏 Snake。

我已经成功地让蛇在一定时间后移动了一定数量的像素。问题是执行游戏循环需要不同的时间。所以当我写出每一步的不同时间时,它看起来像这样:

  • 时间:0.273553
  • 时间:0.259873
  • 时间:0.260135
  • 时间:0.396735
  • 时间:0.258397
  • 时间:0.262811
  • 时间:0.259681
  • 时间:0.257136
  • 时间:0.266248
  • 时间:0.412772
  • 时间:0.260008

0.39 和 0.41 的凸点都不好。它们使蛇有时移动得更慢,而且看起来一点也不好看。

时间应始终为 0.25,以便蛇在屏幕上平稳运行。这是我在游戏循环中实现的代码(snake.getSpeed() 函数返回 4):

    if(_clock.GetElapsedTime() > (1 / snake.getSpeed())){
        std::cout << "Time: " << _clock.GetElapsedTime() << std::endl;
        snake.changeDir(keyDown);       //Change direction
        snake.move();           //Move the snake
        _clock.Reset();
    }

处理器只是变慢还是有人对如何使代码更好有其他想法?

编辑:忽略上述。实时保险杠似乎是作为 GetEvent 函数。不知道为什么,但是执行需要 0 到 0.2 秒。这是我的测试代码:

    //This is just i bit of code, therefore there's no ending brackets ;)
    _clock.Reset();
    while(_mainWindow.GetEvent(currentEvent)) {
        std::cout << _clock.GetElapsedTime() << std::endl;    //cout the elapsed time for GetEvent

(_mainWindow 是一个 sf::RenderWindow)不知道这是否可以解决,但我没有回答这个问题,如果有人有想法,那就太好了。谢谢!

4

1 回答 1

4

首先我建议你使用 SFML 2,因为 SFML 1.6 已经有 2.5 年没有维护了,有很多已知和丑陋的错误,并且缺少 SFML 2 的许多不错的功能。

接下来最好不要尝试强制某个帧速率,因为有一些因素无法真正做到这一点(操作系统中断,移动鼠标时的大量事件等),而是让移动取决于帧率。最简单的方法是使用欧拉方法

pos.x = pos.x*velocity.x*dt

其中pos是物体位置的velocity向量, 是二维速度的向量,dt是增量时间,即两帧之间的时间。不幸的是,简单的欧拉方法不是很精确,也许Verlet 积分可以提供更平滑的运动。

但这还不是全部,因为即使运动现在更紧密地绑定到帧速率,仍然会出现尖峰并导致不需要的效果。因此,最好修复您的时间步长,因此使用其 FPS(每秒帧数)计数的渲染与物理计算无关。还有很多方法可以解决这个问题,我发现一篇有用的文章.

于 2012-12-27T18:00:14.047 回答