Reputation: 11
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()
Quick rundown, shipX should move when the arrow keys are pressed and shipY moves up and down by itself. Im having an issue where the sprites update only to shipY meaning they will only move up and down. the ShipX sprite will rotate properly and the x and y locations change in the log, but the sprites seem to constantly be attached. I'm stumped and cannot figure out a way to fix this issue. Any help would be great. thank you
Upvotes: 1
Views: 308
Reputation: 4007
To solve the problem change the __init__()
method of your Ship
sprite class to:
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
The important thing is that every time you create a new instance (i.e. a new sprite) you must also create a new pygem.rect
object (see above code).
In your code every Ship
object (shipX
and shipY
) used the same pygem.rect
object which was passed to it via the __init__()
method (rect
argument).
When you called the update()
method, one of the two ships changed the rect.centerx
and rect.centery
attributes of the same rect. That´s the reason why PyGame drew both sprites on the same (rect)-position (allSpriteGroup.draw(screen)
).
When you create now a new ship, be aware that the constructor (__init__()
method) does not need the rect
argument anymore:
shipX = Ship(imgarray, movepersec, 100, 100, "E")
By default shipX
appears in the top left corner, because the .get_rect()
method returns a pygame.rect
which location is set to (0, 0)
. To set the position of shipX
according to the passed xpos
and ypos
arguments in the constructor, add these two lines after the craetion of the self.rect
object:
self.rect.centerx = self.dx
self.rect.centery = self.dy
I hope this helps :)
Upvotes: 1