我正在尝试使飞船控制功能如下:
按 W 会增加飞船面向方向的动量。 当飞船有动量时旋转飞船不应影响动量的方向。 旋转后向宇宙飞船添加推力,同时在不同方向上具有动量,应该在新方向上添加动量,而不消除之前的动量(除非您朝相反方向推力,否则它应该慢慢抵消并最终增加动量反方向)。
我设法让它发挥作用,但目前动力在船所面向的方向上不断增加。基本上,在有动量的情况下转弯会使船像汽车一样转弯。
def blit_rotate_center(win, image, top_left, angle):
rotated_image = pygame.transform.rotate(image, angle)
new_rect = rotated_image.get_rect(center = image.get_rect(topleft = top_left).center)
win.blit(rotated_image, new_rect.topleft)
class PlayerShip:
def __init__(self):
self.img = assets.SPACE_SHIP_1
self.max_vel = 12
self.vel = 0
self.acceleration = 0.02
self.rotation_vel = 0.8
self.angle = 0
self.x = 400
self.y = 400
self.drag = 0.015
self.acc_angle = 0
self.vertical = 0
self.horizontal = 0
def rotate(self, left = False, right = False):
if left:
self.angle += self.rotation_vel
elif right:
self.angle -= self.rotation_vel
def draw(self, win):
blit_rotate_center(win, self.img, (self.x, self.y), self.angle)
# Moving the player according to angle
radians = math.radians(self.angle)
self.vertical = math.cos(radians) * self.vel
self.horizontal = math.sin(radians) * self.vel
self.y -= self.vertical
self.x -= self.horizontal
self.reduce_speed()
def key_input(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_a]:
self.rotate(left = True)
if keys[pygame.K_d]:
self.rotate(right = True)
if keys[pygame.K_w]:
self.move_forward()
if keys[pygame.K_s]:
self.move_backward()
def move_forward(self):
self.vel = min(self.vel + self.acceleration, self.max_vel)
def move_backward(self):
self.vel = min(self.vel - self.acceleration, self.max_vel)
if self.vel < self.max_vel - self.max_vel * 2:
self.vel = self.max_vel - self.max_vel * 2
def reduce_speed(self):
if self.vel < 0:
self.vel += self.drag
elif self.vel > 0:
self.vel -= self.drag
我认为这与 self.angle 不断更新有关,但我已经没有关于如何让它发挥作用的想法了。
我尝试将速度存储在多个变量中,将它们应用到不同的函数中,等等。
您可以通过以下方法来实现此目的:
您可以存储代表船舶当前动量的方向和大小的动量向量。当您施加推力时,您会将船舶当前旋转方向的矢量添加到该动量矢量中。
以下是如何执行此操作的简化实现:
class PlayerShip:
def __init__(self):
...
self.momentum = pygame.Vector2(0, 0)
...
def draw(self, win):
...
# Use momentum for movement, instead of the ship's rotation
self.x += self.momentum.x
self.y += self.momentum.y
...
def move_forward(self):
# Calculate a vector in the direction the ship is currently facing
radians = math.radians(self.angle)
forward = pygame.Vector2(math.cos(radians), math.sin(radians))
# Scale this vector by the acceleration amount, and add it to the ship's momentum
self.momentum += forward * self.acceleration
# Limit the magnitude of the momentum vector to max_vel
if self.momentum.length() > self.max_vel:
self.momentum.scale_to_length(self.max_vel)
def move_backward(self):
radians = math.radians(self.angle)
backward = pygame.Vector2(math.cos(radians), math.sin(radians))
# Subtract the backward vector from momentum to simulate moving backward
self.momentum -= backward * self.acceleration
# If the length of the momentum vector is greater than max_vel, scale it back down
if self.momentum.length() > self.max_vel:
self.momentum.scale_to_length(self.max_vel)
这里的主要区别在于,我们不是在每次绘制船舶时根据船舶的旋转来改变船舶的速度,而是在施加推力时添加动量向量,并且该向量在帧之间持续存在。当船舶旋转时,动量矢量的方向不会改变,因此即使船舶旋转,船舶也会继续沿上次推进的方向移动。
记得导入pygame向量:import pygame.math.Vector2。
这可能不太适合您的游戏(因为它是一个简化的示例),但希望它能让您了解如何修改现有代码以实现您想要的行为!