我正在尝试给出飞船速度(我正在做标准的小行星游戏)并且它有效,但我的问题是,如果 x 或 y 减小,飞船将朝那个方向行驶一段时间匀速运行很长时间
我认为这是因为 self.rect.x 和 self.rect.y 是整数,而 velx 和 vely 是 float ,但我不知道如何修复它。
这是重要的一点:
class Ship(pygame.sprite.Sprite):
# ...
def update(self):
self.image = pygame.transform.rotate(self.template, self.rotation)
self.rect = self.image.get_rect(center=self.rect.center)
real_rot = math.radians(self.rotation+90)
key = pygame.key.get_pressed()
if key[pygame.K_a]:
self.rotation += 3
if self.rotation >= 360:
self.rotation += -360
if key[pygame.K_d]:
self.rotation += -3
if self.rotation < 0:
self.rotation += 360
if key[pygame.K_w]:
self.velx += math.cos(real_rot)*speed
self.vely += -math.sin(real_rot)*speed
if key[pygame.K_s]:
self.velx += -math.cos(real_rot)*speed
self.vely += math.sin(real_rot)*speed
self.rect.y += self.vely
self.rect.x += self.velx
print(self.rect.x, self.rect.y)
self.velx *= 0.9
self.vely *= 0.9
## if abs(self.velx) < 1:
## self.velx = 0
## if abs(self.vely) < 1:
## self.vely = 0
这是完整的代码:
import pygame
import math
pygame.init()
screen_size = (800, 600)
ship_size = (50, 50)
line_thickness = 4
speed = 2
screen = pygame.display.set_mode(screen_size)
white, black = (255, 255, 255), (0, 0, 0)
sprites = pygame.sprite.Group()
class Ship(pygame.sprite.Sprite):
def __init__(self):
super(Ship, self).__init__()
self.rotation = 0
self.velx = 0
self.vely = 0
self.template = pygame.Surface((ship_size[0]+line_thickness*2, ship_size[1]+line_thickness*2))
self.template.fill((0, 0, 127))
pygame.draw.polygon(self.template, white, ((ship_size[0]/2+line_thickness, line_thickness), (ship_size[0]+line_thickness, ship_size[1]+line_thickness), (ship_size[0]/2+line_thickness, 0.8*ship_size[1]+line_thickness), (line_thickness, ship_size[1]+line_thickness)), line_thickness)
self.image = self.template
self.rect = self.image.get_rect()
self.rect.x, self.rect.y = screen_size[0]/2 - ship_size[0]/2, screen_size[1]/2 - ship_size[1]/2
self.add(sprites)
def update(self):
self.image = pygame.transform.rotate(self.template, self.rotation)
self.rect = self.image.get_rect(center=self.rect.center)
real_rot = math.radians(self.rotation+90)
key = pygame.key.get_pressed()
if key[pygame.K_a]:
self.rotation += 3
if self.rotation >= 360:
self.rotation += -360
if key[pygame.K_d]:
self.rotation += -3
if self.rotation < 0:
self.rotation += 360
if key[pygame.K_w]:
self.velx += math.cos(real_rot)*speed
self.vely += -math.sin(real_rot)*speed
if key[pygame.K_s]:
self.velx += -math.cos(real_rot)*speed
self.vely += math.sin(real_rot)*speed
self.rect.y += self.vely
self.rect.x += self.velx
print(self.rect.x, self.rect.y)
self.velx *= 0.9
self.vely *= 0.9
## if abs(self.velx) < 1:
## self.velx = 0
## if abs(self.vely) < 1:
## self.vely = 0
player = Ship()
running = True
while running:
pygame.time.Clock().tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
running = False
screen.fill(black)
player.update()
sprites.draw(screen)
pygame.display.flip()
pygame.quit()
您会注意到,在第 63-66 行我尝试了一些方法,但这并不是一个很好的解决方案。
问题是因为您使用的是矩形的 x
和 y
值。由于船舶旋转时矩形的大小会发生变化,因此 x
和 y
值会稍微漂移/与旋转发生奇怪的交互。
要修复此问题,请将您的 update
方法修改为如下所示:
def update(self):
self.image = pygame.transform.rotate(self.template, self.rotation)
self.rect = self.image.get_rect(center=self.rect.center)
real_rot = math.radians(self.rotation+90)
key = pygame.key.get_pressed()
if key[pygame.K_a]:
self.rotation += 3
if self.rotation >= 360:
self.rotation += -360
if key[pygame.K_d]:
self.rotation += -3
if self.rotation < 0:
self.rotation += 360
if key[pygame.K_w]:
self.velx += math.cos(real_rot)*speed
self.vely += -math.sin(real_rot)*speed
if key[pygame.K_s]:
self.velx += -math.cos(real_rot)*speed
self.vely += math.sin(real_rot)*speed
self.x += self.velx
self.y += self.vely
self.rect.x = self.x
self.rect.y = self.y
self.velx *= 0.9
self.vely *= 0.9
现在,你的飞船的坐标与其旋转/变换的方式无关,并且两者不会互相干扰。 (目前,船在旋转时看起来有点滑稽,但计算出数学来解决这个问题应该不会太困难)。
顺便说一句,您可能需要考虑存储船舶的旋转和大小,而不是 x 和 y 速度。如果您使用极坐标,并且仅当您需要在板上显示内容时才转换为 x 和 y 值,那么您的很多数学运算都会得到简化。
我是一名优秀的程序员,十分优秀!