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
对象( shipX
和 shipY
)使用了相同 pygem.rect
通过 __init__()
传递给它的对象方法( rect
参数)。
当您调用update()
时方法,两艘船中的一艘改变了rect.centerx
和rect.centery
同一矩形的属性。这就是 PyGame 将两个 Sprite 绘制在相同(矩形)位置 ( allSpriteGroup.draw(screen)
) 的原因。
当您现在创建一艘新船时,请注意构造函数( __init__()
方法)不需要 rect
不再争论:
shipX = Ship(imgarray, movepersec, 100, 100, "E")
默认shipX
出现在左上角,因为 .get_rect()
方法返回 pygame.rect
哪个位置设置为 (0, 0)
。设置shipX
的位置根据通过的xpos
和ypos
构造函数中的参数,在 self.rect
的创建之后添加这两行对象:
self.rect.centerx = self.dx
self.rect.centery = self.dy
我希望这有帮助:)
关于使用相同类的 Python/Pygame Sprite 无法正确更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29354283/