我希望我的播放器以与水平或垂直移动时相同的速度对角线移动。当玩家沿着负梯度的直线移动时,这确实有效,但是当玩家沿着正梯度移动时,玩家并不能以完美的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.magnitude
和math.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