Pygame精灵旋转后然后移动

时间:2017-12-14 21:32:16

标签: python-3.x pygame

我正在创建一个基本的坦克游戏,我目前正在研究坦克的枪。我设法使枪围绕轴旋转,只要按下“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用于旋转。这只是检测按下哪个键的方法。)

2 个答案:

答案 0 :(得分:1)

问题出现是因为您在轮换后没有更新self.x位置。旋转图像时,其边界框大小会发生变化,因此新的矩形x self.rect.x位置将会更改。但是,self.x属性仍然保持不变,当您下次移动水箱时,您再次同步self.xself.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

我更倾向于使用xy属性作为中心坐标,然后设置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 - 即。 directionstep

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)