我正在创建一个基本的坦克游戏,我目前正在研究坦克的枪。我设法使枪围绕轴旋转,只要按下“a”和“d”键就会移动,但有时当枪旋转然后移动时,它会因某种原因向右移动。这是代码:
class tankGun(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = tankGunImage
self.rect = self.image.get_rect()
self.x = 400
self.xx = 410
self.y = 400
self.rect.x = self.x
self.rect.y = self.y
self.angle = 0
self.original = self.image
tankGunList.add(self)
tankGunList.draw(gameDisplay)
def rotate(self, chk):
test = False
if chk == 1:
self.angle += 1
elif chk == 2:
self.angle -= 1
if self.angle > 0 and self.angle < 180:
test = True
else:
if chk == 1:
self.angle = 180
elif chk == 2:
self.angle = 0
if test == True:
self.image = pygame.transform.rotate(self.original, self.angle)
tankGunList.clear(gameDisplay, background)
tankGunList.draw(gameDisplay)
self.rect = self.image.get_rect(center = self.rect.center)
def move(self, chk):
self.x += chk
self.xx = self.x + 10
self.rect.x = self.x
tankGunList.clear(gameDisplay, background)
tankGunList.draw(gameDisplay)
(旁注:chk以+1或-1的形式发送到机芯,1或2用于旋转。这只是检测按下哪个键的方法。)
答案 0 :(得分:1)
问题出现是因为您在轮换后没有更新self.x
位置。旋转图像时,其边界框大小会发生变化,因此新的矩形x self.rect.x
位置将会更改。但是,self.x
属性仍然保持不变,当您下次移动水箱时,您再次同步self.x
和self.rect.x
并跳转。
要解决此问题,请在轮换后更新self.x
:
if turn == True:
self.image = pg.transform.rotate(self.original, self.angle)
self.rect = self.image.get_rect(center=self.rect.center)
self.x = self.rect.x
我更倾向于使用x
和y
属性作为中心坐标,然后设置self.rect.center = (self.x, self.y)
,这样您就不必更新self.x
旋转后1}}。
import pygame as pg
pg.init()
screen = pg.display.set_mode((640, 480))
tankGunImage = pg.Surface((30, 50), pg.SRCALPHA)
tankGunImage.fill((70, 200, 30))
class tankGun(pg.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = tankGunImage
self.rect = self.image.get_rect()
self.x = 300 # Center x.
self.xx = 310
self.y = 200 # Center y.
# Set the center attributes.
self.rect.centerx = self.x
self.rect.centery = self.y
self.angle = 0
self.original = self.image
def rotate(self, chk):
turn = False
if chk == 1:
self.angle += 4
elif chk == 2:
self.angle -= 4
if self.angle > 0 and self.angle < 180:
turn = True
else:
if chk == 1:
self.angle = 180
elif chk == 2:
self.angle = 0
if turn == True:
self.image = pg.transform.rotate(self.original, self.angle)
self.rect = self.image.get_rect(center=self.rect.center)
# No need to update the `self.x` now, since the center stays the same.
def move(self, chk):
self.x += chk
self.xx = self.x + 10
self.rect.center = (self.x, self.y)
def main():
clock = pg.time.Clock()
color = pg.Color(30, 30, 30)
all_sprites = pg.sprite.Group()
tank = tankGun()
all_sprites.add(tank)
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
keys = pg.key.get_pressed()
if keys[pg.K_a]:
tank.rotate(1)
if keys[pg.K_d]:
tank.rotate(2)
if keys[pg.K_j]:
tank.move(-4)
if keys[pg.K_l]:
tank.move(4)
all_sprites.update()
screen.fill(color)
all_sprites.draw(screen)
pg.display.flip()
clock.tick(30)
if __name__ == '__main__':
main()
pg.quit()
答案 1 :(得分:0)
我不知道你为什么遇到问题 - 我无法运行它来查看问题。
但是我展示了我会改变的东西。也许它会有所帮助。
首先,我会使用更易读的名称而不是chk
- 即。 direction
,step
class tankGun(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.original = tankGunImage
self.image = self.original
self.rect = self.image.get_rect()
self.rect.x = 400
self.rect.y = 400
self.xx = self.rect.x + 10
self.angle = 0
tankGunList.add(self)
def rotate(self, direction):
rotate_image = False
if direction == 1:
if self.angle < 180
self.angle += 1
rotate_image = True
elif direction == 2:
if self.angle > 0
self.angle -= 1
rotate_image = True
if rotate_image == True:
self.image = pygame.transform.rotate(self.original, self.angle)
self.rect = self.image.get_rect(center=self.rect.center)
def move(self, step):
self.rect.x += step
self.xx = self.rect.x + 10
# --- in mainloop ---
tankGunList.clear(gameDisplay, background)
tankGunList.draw(gameDisplay)