2D C 游戏中的移动错误

问题描述 投票:0回答:1
由于某种原因,mySprite 结构向左方向(

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

    

c game-development
1个回答
0
投票
核心问题看起来像是您对成员

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。

通常,物理系统使用浮点或足够精细的定点建模比使用整数运算更好。除非您有理由相信所有计算的数量都将具有整数值,否则您通常应该使用浮点算术进行计算和存储值。

这可能会产生非整数的点坐标值。要将它们渲染在由整数坐标寻址的显示器上,您必须将点坐标转换为整数。最好将其作为渲染的一部分来完成,其中坐标值会临时转换为要绘制的整数。坐标值不更新为该整数;它被保存为浮点值。这允许您拥有非整数的速度和位置,从而允许精细地改变速度和位置,而不是离散的跳跃。

如果您确实希望将坐标保留为整数类型,则需要设计计算以便它们产生整数结果。

© www.soinside.com 2019 - 2024. All rights reserved.