Python / Pygame精灵使用相同的类没有正确更新

时间:2015-03-30 19:09:50

标签: 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()

快速断开,当按下箭头键并且shipY自行上下移动时,shipX应移动。我有一个问题,精灵只更新为shipY意味着他们只会上下移动。 ShipX精灵将正确旋转,x和y位置会在日志中发生变化,但精灵似乎会不断附加。我很难过,无法找到解决这个问题的方法。任何帮助都会很棒。谢谢

1 个答案:

答案 0 :(得分:1)

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

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 

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

在您的代码中每个Ship对象shipXshipY使用相同的 {{1}通过pygem.rect方法(__init__()参数)传递给它的对象 当您调用rect方法时,两艘船中的一艘 update()rect.centerx属性相同RECT 即可。这就是为什么PyGame在相同(rect)-position rect.centery)上绘制两个精灵的原因。

现在创建新船时,请注意构造函数(allSpriteGroup.draw(screen)方法)不再需要__init__()参数

rect

默认情况下,shipX = Ship(imgarray, movepersec, 100, 100, "E") 显示在左上角,因为shipX方法返回.get_rect(),该位置设置为pygame.rect。要根据构造函数中传递的(0, 0)shipX参数设置xpos的位置,ypos对象的基础之后添加这两行

self.rect

我希望这会有所帮助:)