Pygame对角线移动角度不正确



我希望我的播放器以与水平或垂直移动时相同的速度对角线移动。当玩家沿着负梯度的直线移动时,这确实有效,但是当玩家沿着正梯度移动时,玩家并不能以完美的45度角移动。

这是我移动播放器的代码:
def move(self, speed):
if self.direction.magnitude() != 0:
self.direction = self.direction.normalize()

self.rect.x += self.direction.x * speed
self.rect.y += self.direction.y * speed

正如我之前所说的,我所希望的只是让玩家以与x或y方向相同的速度对角线移动。

这里是完整的播放器类,以防需要:

class Player:
def __init__(self, x, y):
self.image = pygame.Surface((30, 30))
self.image.fill((255, 255, 255))
self.rect = self.image.get_rect(center = (x, y))
self.direction = pygame.math.Vector2()
self.speed = 5 
def input(self):
keys = pygame.key.get_pressed()
if keys[K_w]:
self.direction.y = -1
elif keys[K_s]:
self.direction.y = 1
else:
self.direction.y = 0

if keys[K_a]:
self.direction.x = -1
elif keys[K_d]:
self.direction.x = 1
else:
self.direction.x = 0
def move(self, speed):
if self.direction.magnitude() != 0:
self.direction = self.direction.normalize()

self.rect.x += self.direction.x * speed
self.rect.y += self.direction.y * speed
def update(self):
self.input()
self.move(self.speed)

def draw(self, screen):
screen.blit(self.image, self.rect.center)

由于pygame.Rect应该表示屏幕上的一个区域,因此pygame.Rect对象只能存储整型数据。

矩形对象的坐标都是整数。[…]

当对象的新位置被分配给Rect对象时,坐标的分数部分将丢失。如果你想以浮点精度移动对象,你必须将对象的位置分别存储在单独的变量属性中,并同步pygame.Rect对象。round将坐标赋值给矩形的位置:
class Player:
def __init__(self, x, y):
self.image = pygame.Surface((30, 30))
self.image.fill((255, 255, 255))
self.rect = self.image.get_rect(center = (x, y))
self.direction = pygame.math.Vector2()
self.speed = 5 
self.position = pygame.math.Vector2(x, y)
def input(self):
keys = pygame.key.get_pressed()
dx = keys[K_d] - keys[K_a]
dy = keys[K_s] - keys[K_w]
self.direction = pygame.math.Vector2(dx, dy)
if dx != 0 and dy != 0:
self.direction /= 1.41421
def move(self, speed):    
self.position += self.direction * speed
self.rect.x = round(self.position.x)
self.rect.y = round(self.position.y)

def update(self):
self.input()
self.move(self.speed)

def draw(self, screen):
screen.blit(self.image, self.rect.center)

请参阅Pygame不允许我使用float来执行rect.move,但我需要它,并且在Pygame中使用标准化向量移动不一致?


注意,pygame.math.Vector2.magnitudemath.Vector2.normalize在性能上是昂贵的。尽量避免这种操作。矢量的归一化仅在沿两个轴移动时才需要。由于在这种情况下向量的绝对值为√2,因此可以用除以√2来代替归一化。

dx = keys[K_d] - keys[K_a]                   # dx is -1, 0 or 1
dy = keys[K_s] - keys[K_w]                   # dy is -1, 0 or 1
self.direction = pygame.math.Vector2(dx, dy)
if dx != 0 and dy != 0:  
self.direction /= 1.41421                # sqrt(2) is ~1.41421

最新更新