计算帧独立运动的问题

我正在使用SDL在C ++中开发一个Breakout风格的游戏。 到目前为止的问题是,球没有特别的原因减速和加速。

放缓通常会持续几秒钟。

编辑:当全屏运行时,我注意到球运动似乎也有点生涩。 这使我相信时机应该更加细化。 但是与此同时,不应该有必要有μs精度…

这里是我的代码来计算球的运动:

double deltaMovement = tick * speed; rect.x += static_cast<int> ( deltaMovement * dirX ); rect.y += stnecessearyatic_cast<int> ( deltaMovement * dirY ); 

我试图改变它来帮助防止浮动截断,但是这会影响速度,使得球只能水平或垂直移动(这在上面的代码中是不会发生的)。

 double movementX = ( deltaMovement * dirX ); double movementY = ( deltaMovement * dirY ); movementX += ( movementX > 0.0f )? 0.5f: -0.5f; movementY += ( movementY > 0.0f )? 0.5f: -0.5f; rect.x += static_cast<int> ( movementX ); rect.y += static_cast<int> ( movementX ); 

rect是一个SDL_Rect并且保持球的位置。 dirXdirYdouble并且保持球的方向,值范围从-1.01.0

我不知道如果问题是floatint转换。 我想这也可能是SDL内部的东西,但我相当肯定SDL应该能够stream畅的animation。


这里是我的主要游戏循环(我已经删除了一些不相关的部分)while(!quit){while(SDL_PollEvent(&event)){//处理input,移动paddle,检查用户是否按下esc //是我有办法逃避外部while循环。 } double delta = timer.GetDelta();

  // Update the ball, check for collisions with wall/paddle/tiles UpdateBalls( delta ); // Redraws everything UpdateGUI(); } 

我很确定这个问题不是我的德尔塔时间,因为它在1-4毫秒内是相当一致的。 即使它确实改变了很多,也没关系。 但为了以防万一,这里是我用来计算增量时间的代码:

 double Timer::GetDelta( ) { timespec tmCurrent; clock_gettime( CLOCK_MONOTONIC_RAW, &tmCurrent); // Get current time in nanoseconds unsigned long long deltaCurrent = static_cast< unsigned long long > ( tm.tv_sec * 1000000000 + tm.tv_nsec ); // Get diff. Delta is an unsigned long long that holds previous tick ( see below) unsigned long long diff = deltaCurrent - delta; // Convert into ms and assign to a double double deltaMSec = static_cast< float > ( diff / 1000000.0f ); // Reset delta so that it can be used the next time delta is calculated delta = deltaCurrent; return deltaMSec; } 

我究竟做错了什么?

我不认为你的问题是与时间相关的。 如果你改变你的物体速度,使每次更新的移动量非常低(即每次更新less于0.5个单位),我的猜测是你的物体永远不会移动!

目前,您正在以一个整数(SDL_Rect基于整数)跟踪移动的位置。 与每个更新相关的任何分数运动都会由于转换为整数而丢失。 随着时间的推移,这些缺less的分数运动累加起来,导致整个对象的不平滑运动。 这对于移动速度较慢的物体尤其明显,舍入不会平均出来,舍弃的小数部分代表整体移动的较大部分。

解决scheme是跟踪你的位置在浮点坐标,然后转换为整数坐标只有当渲染。