简单的拖动物理,向左或向右移动时表现不同
Simple drag physics, acting differently when moving left or right
我的代码对负速度的作用与对正速度的作用不同
我正在尝试实现平台物理,玩家在 X 方向上有速度,当用户分别按下“A”或“D”时速度增加或减少,或者当玩家碰撞时设置为 0有墙。
为了模拟与地面的摩擦,玩家的 X 速度乘以“self.drag”(小于 1 的浮点数)
我预计这段代码会降低玩家的 X 速度,随着时间的推移,它会微不足道地降低到接近 0,而不会实际反转速度(就像减去一个值一样),这会阻止玩家在用户不在时不受控制地滑动'输入移动命令。
这在向右移动时按预期工作,但是在向左移动时它的行为不同,
向左移动时,播放器似乎继续漂浮了一段时间才停止。
这是在玩家内部 class、运行 每帧接受玩家输入的代码:
dx = 0
if pygame.key.get_pressed()[pygame.K_a]:
dx -= self.speed
if pygame.key.get_pressed()[pygame.K_d]:
dx += self.speed
# to slow down horizontal movement
self.vx *= self.drag
# Add change in velocity to total velocity
self.vx += dx
self.vy += dy
也许这个概念可行,但我实施不正确?
有可能以我没有注意到的方式影响速度的碰撞代码?
该系统对于正速度和负速度的工作方式是否不同?
谢谢!
非常感谢任何帮助
问题是因为pygame.Rect
存储了积分坐标:
The coordinates for Rect objects are all integers. [...]
当您这样做时,dx
和 dy
的小数部分会丢失:
self.Rect.x += dx
self.Rect.y += dy
您必须以浮点精度进行计算。给class添加一个x
和y
属性。增加 move
中的属性并同步 Rect
属性:
class Player:
def __init__(self, color):
self.Rect = pygame.Rect([50, 50], [30, 50])
self.x = self.Rect.x
self.y = slef.Rect.y
# [...]
def move(self, dx, dy, platforms):
# Test for collisions with platforms
# handle movement on the X axis
self.x += dx
self.Rect.x = round(self.x)
for platform in platforms:
if self.Rect.colliderect(platform.Rect):
if dx > 0:
self.Rect.right = platform.Rect.left
if dx < 0:
self.Rect.left = platform.Rect.right
self.x = self.Rect.x
# Reset velocity when collision with wall
self.vx = 0
# handle movement on the Y axis
self.Rect.y += dy
self.Rect.y = round(self.y)
for platform in platforms:
if self.Rect.colliderect(platform.Rect):
if dy > 0:
self.Rect.bottom = platform.Rect.top
if dy < 0:
self.Rect.top = platform.Rect.bottom
self.y = self.Rect.y
# Reset velocity when collision with floor or roof
self.vy = 0
# return correctly collided rect to draw()
return self.Rect
我的代码对负速度的作用与对正速度的作用不同
我正在尝试实现平台物理,玩家在 X 方向上有速度,当用户分别按下“A”或“D”时速度增加或减少,或者当玩家碰撞时设置为 0有墙。
为了模拟与地面的摩擦,玩家的 X 速度乘以“self.drag”(小于 1 的浮点数)
我预计这段代码会降低玩家的 X 速度,随着时间的推移,它会微不足道地降低到接近 0,而不会实际反转速度(就像减去一个值一样),这会阻止玩家在用户不在时不受控制地滑动'输入移动命令。
这在向右移动时按预期工作,但是在向左移动时它的行为不同, 向左移动时,播放器似乎继续漂浮了一段时间才停止。
这是在玩家内部 class、运行 每帧接受玩家输入的代码:
dx = 0
if pygame.key.get_pressed()[pygame.K_a]:
dx -= self.speed
if pygame.key.get_pressed()[pygame.K_d]:
dx += self.speed
# to slow down horizontal movement
self.vx *= self.drag
# Add change in velocity to total velocity
self.vx += dx
self.vy += dy
也许这个概念可行,但我实施不正确? 有可能以我没有注意到的方式影响速度的碰撞代码? 该系统对于正速度和负速度的工作方式是否不同?
谢谢! 非常感谢任何帮助
问题是因为pygame.Rect
存储了积分坐标:
The coordinates for Rect objects are all integers. [...]
当您这样做时,dx
和 dy
的小数部分会丢失:
self.Rect.x += dx
self.Rect.y += dy
您必须以浮点精度进行计算。给class添加一个x
和y
属性。增加 move
中的属性并同步 Rect
属性:
class Player:
def __init__(self, color):
self.Rect = pygame.Rect([50, 50], [30, 50])
self.x = self.Rect.x
self.y = slef.Rect.y
# [...]
def move(self, dx, dy, platforms):
# Test for collisions with platforms
# handle movement on the X axis
self.x += dx
self.Rect.x = round(self.x)
for platform in platforms:
if self.Rect.colliderect(platform.Rect):
if dx > 0:
self.Rect.right = platform.Rect.left
if dx < 0:
self.Rect.left = platform.Rect.right
self.x = self.Rect.x
# Reset velocity when collision with wall
self.vx = 0
# handle movement on the Y axis
self.Rect.y += dy
self.Rect.y = round(self.y)
for platform in platforms:
if self.Rect.colliderect(platform.Rect):
if dy > 0:
self.Rect.bottom = platform.Rect.top
if dy < 0:
self.Rect.top = platform.Rect.bottom
self.y = self.Rect.y
# Reset velocity when collision with floor or roof
self.vy = 0
# return correctly collided rect to draw()
return self.Rect