使用相同类的 Python/Pygame Sprite 无法正确更新

标签 python class pygame sprite

import pygame, sys, random
pygame.init()

class Ship(pygame.sprite.Sprite):
    movepersec = 0
    dx = 0
    dy = 0
    direction = ""
    imgarray = {}

    def __init__(self, imgarr, rect, speed, xpos, ypos, direct):
        pygame.sprite.Sprite.__init__(self)

        self.imgarray = imgarr
        self.rect = rect
        self.movepersec = speed
        self.dx = xpos
        self.dy = ypos
        self.direction = direct
        self.image = self.imgarray[self.direction]

    def setDirection(self, direct):
            self.direction = direct

    def setSpeed(self, speed):
            self.movepersec = speed

    def update(self, secs):

        movePix = self.movepersec*secs

        if self.direction == "N": self.dy -= movePix
        if self.direction == "S": self.dy += movePix
        if self.direction == "E": self.dx += movePix
        if self.direction == "W": self.dx -= movePix

        self.rect.centerx = self.dx
        self.rect.centery = self.dy

        self.image = self.imgarray[self.direction]

background = pygame.image.load("sea.jpg")
backgroundWidth = background.get_width()
backgroundHeight = background.get_height()
size = background.get_size()
screen = pygame.display.set_mode(size)
clock = pygame.time.Clock()
imgarray = {}
imgarray["N"] = pygame.image.load("shipNorth.png")
imgarray["S"] = pygame.image.load("shipSouth.png")
imgarray["E"] = pygame.image.load("shipEast.png")
imgarray["W"] = pygame.image.load("shipWest.png")
imgrect = imgarray["N"].get_rect()
movepersec = 150
keydownflag = False
allSpriteGroup = pygame.sprite.Group()

shipX = Ship(imgarray, imgrect, movepersec, 100, 100, "E")
allSpriteGroup.add(shipX)

shipY = Ship(imgarray, imgrect, movepersec, 100, 100, "S")
allSpriteGroup.add(shipY)

screen.blit(background,(0,0))

while True:
    secs = clock.tick(30)/1000.0

    for event in pygame.event.get():
        if event.type == pygame.QUIT : sys.exit(0)

        if event.type == pygame.KEYDOWN:
            keydownflag = True

            if event.key == pygame.K_LEFT:
                shipX.setDirection("W")
            if event.key == pygame.K_RIGHT:
                shipX.setDirection("E")
            if event.key == pygame.K_UP:
                shipX.setDirection("N")
            if event.key == pygame.K_DOWN:
                shipX.setDirection("S")

        if event.type == pygame.KEYUP:
            keydownflag = False

    if keydownflag:
        shipX.update(secs)

    shipY.update(secs)

    #shipX collision
    if shipX.rect.right + 65 >= backgroundWidth:
        shipX.setDirection("W")
    if shipX.rect.bottom >= backgroundHeight:
        shipX.setDirection("N")
    if shipX.rect.left <= 0:
        shipX.setDirection("E")
    if shipX.rect.top <= 0:
        shipX.setDirection("S")

    #Ship Y collision
    if shipY.rect.top <= 0:
        shipY.setDirection("S")
    if shipY.rect.bottom >= backgroundHeight:
        shipY.setDirection("N")

    print(shipX.dx)

    allSpriteGroup.clear(screen,background)

    allSpriteGroup.draw(screen)

    pygame.display.flip()

快速总结一下,按下箭头键时,shipX 应该移动,shipY 会自行上下移动。我遇到一个问题, Sprite 仅更新到shipY,这意味着它们只会上下移动。 ShipX Sprite 将正确旋转,并且日志中的 x 和 y 位置会发生变化,但 Sprite 似乎会不断附着。我很困惑,无法找到解决此问题的方法。任何帮助都会很棒。谢谢

最佳答案

要解决问题更改 __init__()您的 Ship 的方法 Sprite 类:

def __init__(self, imgarr, speed, xpos, ypos, direct):
    pygame.sprite.Sprite.__init__(self)
    self.imgarray = imgarr
    self.movepersec = speed
    self.dx = xpos
    self.dy = ypos
    self.direction = direct
    self.image = self.imgarray[self.direction]
    self.rect = self.image.get_rect() #create a *new* rect-object 

重要的是,每次创建实例(即 Sprite )您还必须创建一个 pygem.rect对象(参见上面的代码)。

在您的代码中每个 Ship对象( shipXshipY )使用了相同 pygem.rect通过 __init__() 传递给它的对象方法( rect 参数)。
当您调用update()时方法两艘船中的一艘改变了rect.centerxrect.centery 同一矩形的属性。这就是 PyGame 将两个 Sprite 绘制在相同(矩形)位置 ( allSpriteGroup.draw(screen) ) 的原因。

当您现在创建一艘新船时,请注意构造函数( __init__() 方法)不需要 rect不再争论:

shipX = Ship(imgarray, movepersec, 100, 100, "E")

默认shipX出现在左上角,因为 .get_rect()方法返回 pygame.rect哪个位置设置为 (0, 0) 。设置shipX的位置根据通过的xposypos构造函数中的参数,self.rect 的创建之后添加这两行对象:

self.rect.centerx = self.dx
self.rect.centery = self.dy

我希望这有帮助:)

关于使用相同类的 Python/Pygame Sprite 无法正确更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29354283/

相关文章:

python - 如何(重新)缩放 x Axis 以适合图中的某些点?

java - 子类从父类实例化

c++ - C++20 是否取消了类成员按升序排列的要求?

python - 发射多颗子弹并通过按键改变它们的位置

python - 如何从屏幕上删除单个 pygame 绘图?

python - 如何在 pygame 中可视化 2 个蒙版的重叠区域?

python - 通过python 3中的网络套接字接收二进制数据

python - 无法从源 pylance 解析导入 flask

python - 如何使用 Django Rest Framework 将数据添加到 ManyToMany 字段?

javascript - 你能改变 ES6 类定义来附加新的实例方法吗?