a 键)的移动速度比向右方向(d 键)快 2 倍,尽管 delta_time
和
speed_x
的大小在任一情况下完全相同按键被按下。运行此代码时,日志会告诉我
for a key: -2
和
for d key: 1
。这怎么可能?
typedef struct
{
int width;
int height;
int x, y;
pixel *pixels;
bool *mask;
} sprite_t;
sprite_t mySprite;
void update()
{
// Clear the surface
SDL_FillRect(surface, NULL, SDL_MapRGBA(surface->format, 0, 0, 0, 255));
Uint32 *framebuffer = (Uint32 *)surface->pixels;
// Draws pixels to the frame buffer
for (int i = 0; i < mySprite.height; ++i)
{
for (int j = 0; j < mySprite.width; ++j)
{
int pixel_index = (i * mySprite.width + j);
setPixel(framebuffer, mySprite.x + j, mySprite.y + i, rgbaToUint32(&mySprite.pixels[pixel_index]));
}
}
// Reset speed before processing input
speed_x = 0;
speed_y = 0;
if (key_state.w)
{
speed_y = -(SPEED);
}
if (key_state.s)
{
speed_y = SPEED;
}
if (key_state.a)
{
speed_x = -(SPEED);
}
if (key_state.d)
{
speed_x = SPEED;
}
// Halts execution of update until the frame rate reaches target time
int time_to_wait = FRAME_TARGET_TIME - (SDL_GetTicks() - last_frame_time);
if (time_to_wait > 0 && time_to_wait <= FRAME_TARGET_TIME)
{
SDL_Delay(time_to_wait);
}
// Finds difference between last and current frame and divides by 1000 to convert to sec
float delta_time = 0.016f;
last_frame_time = SDL_GetTicks();
int old_pos = mySprite.x;
// Update sprite position
mySprite.x += speed_x * delta_time;
mySprite.y += speed_y * delta_time;
if (key_state.a)
{
printf("for a key: %i \n", mySprite.x - old_pos);
}
if (key_state.d)
{
printf("for d key: %i \n", mySprite.x - old_pos);
}
}
尝试添加日志来隔离问题。他们应该打印:
for a key: -1
for d key: 1
x
和
y
使用整数类型,但使用浮点算术计算它们的值。这说明了根本问题:
#include <stdio.h>
int main(void)
{
int Start = 10;
float Delta = .016f;
int Speed = 100;
float FloatEndA = Start + Delta*Speed;
float FloatEndB = Start - Delta*Speed;
printf("Floating-point endpoints are %g and %g.\n", FloatEndA, FloatEndB);
int IntEndA = FloatEndA;
int IntEndB = FloatEndB;
printf("Integer endpoints are %d and %d.\n", IntEndA, IntEndB);
}
它表明浮点计算产生(大约)11.6 和 8.4 的端点,分别距起点 +1.6 和 -1.6。但是这段代码,正如您的代码所示,然后将这些点分配给整数类型。该赋值会自动转换,并且转换会截断值,生成 11 和 8,即距起点 +1 和 -2。通常,物理系统使用浮点或足够精细的定点建模比使用整数运算更好。除非您有理由相信所有计算的数量都将具有整数值,否则您通常应该使用浮点算术进行计算和存储值。
这可能会产生非整数的点坐标值。要将它们渲染在由整数坐标寻址的显示器上,您必须将点坐标转换为整数。最好将其作为渲染的一部分来完成,其中坐标值会临时转换为要绘制的整数。坐标值不更新为该整数;它被保存为浮点值。这允许您拥有非整数的速度和位置,从而允许精细地改变速度和位置,而不是离散的跳跃。
如果您确实希望将坐标保留为整数类型,则需要设计计算以便它们产生整数结果。