Pygame Enemy Spawn Troubles
Hi,
I'm having some troubles with a game that I am attempting to modify at this moment. I just got working a health meter or sorts, not really a meter but a just numbers that go down to zero when the ship is hit. But now when my character dies, the game spawns way too many enemies at one time, making my game crash. Any help is appreciated.
The Spawn method given by the program.
def SpawnAliens(level, aliens):
# this creates our starting aliens
# aliencount * x -- must be less than SCREEN_WIDTH game contant
aliencount = 10 + (level*2)
while aliencount > 0:
Alien()
aliencount = aliencount - 1
x = 0
y = 30
for alien in aliens.sprites():
alien.SetPosition(x, y)
x = x + 50
if (x > SCREEN_WIDTH):
# if there too many aliens to fit on one line
# start a new line of them
y = y + 50
x = 0
code for where i implemented player health, life and reposition of ship
for alien in pygame.sprite.spritecollide(player, aliens, 1):
# when the player is hit by an alien ship the level
# restarts
playerHealth = playerHealth - 20
if playerHealth == 0:
player.Explode()
SpaceShipExplosion(player)
playerLife = playerLife - 1
playerHealth = 100
player.rect.bottom = SCREEN_HEIGHT
# clear the aliens group, and respawn them
for alien in aliens.sprites():
alien.kill()
SpawnAliens(gamelevel, aliens)
You should edit your post and put your code inside
tags. This will maintain the indentation, which is necessary for us to understand your python code.
You should edit your post and put your code inside
tags. This will maintain the indentation, which is necessary for us to understand your python code.
Hi I would just like to say that I solved the problem, however a new problem has become apparent. I would like to create a missile that goes from my ship to the top of the screen destroying all enemies who touch it. Unfortunately the missile kills itself when it hits any of the enemies. I tried to get rid of the kill line code, and am quite confused on how the group collide function works. Any help would be great.
## Modification of RAFT Invaders## Copyright 2004## by: RAFT CodeWalkers## Modification done by Justin Mah and Shannon Tinkleyimport os, sys, pygamefrom pygame.locals import *# Game constantsMAX_SHOTS = 10 # Max number of player bullets onscreenSCREEN_WIDTH = 640SCREEN_HEIGHT = 480MISSILE = 1# Global VariableplayerScore = 0global playerLifeplayerLife = 3global playerHealthplayerHealth = 100global gameLevelgameLevel = 1#################################### Functions to load sound and images#def load_sound(name): class NoneSound: def play(self): pass if not pygame.mixer or not pygame.mixer.get_init(): return NoneSound() fullname = os.path.join('data', name) if os.path.exists(fullname) == True: sound = pygame.mixer.Sound(fullname) else: print 'Cannot load sound:', fullname return sound#################################### We need a spaceship class to handle the player's spaceship#class SpaceShip(pygame.sprite.Sprite): name = "" lives = 3 image = "" rect = "" ## set up the class when it starts def __init__(self): pygame.sprite.Sprite.__init__(self, self.containers) self.image = pygame.image.load('jet1.gif') self.rect = self.image.get_rect() ## give the ship a new name def SetName(self, newName): self.shipName = newName ## set the position of the ship def SetPosition(self, x, y): self.rect.left = x self.rect.top = y ## move the ship to the left by a distance def MoveLeft(self, distance): self.rect.left = self.rect.left - distance ## move the ship to the right by a distance def MoveRight(self, distance): self.rect.left = self.rect.left + distance ## move the ship up by a distance def MoveUp(self, distance): self.rect.top = self.rect.top - distance ## move the ship down by a distance def MoveDown(self, distance): self.rect.top = self.rect.top + distance ## what happens when the ship is hit def Explode(self): self.lives = self.lives - 1#################################### When an alien hits the player they explode#class SpaceShipExplosion(pygame.sprite.Sprite): animcycle = 3 images = [] def __init__(self, actor): pygame.sprite.Sprite.__init__(self, self.containers) self.explosion_sound = load_sound('explos.wav') self.explosion_sound.play() # define our explosion animation frames self.images.append(pygame.image.load('jet2.bmp')) self.images.append(pygame.image.load('jet2.bmp')) self.images.append(pygame.image.load('jet4.bmp')) self.image = self.images[0] self.rect = self.image.get_rect() self.life = playerLife self.rect.center = actor.rect.center def update(self): self.life = self.life - 1 self.image = self.images[self.life/self.animcycle%3] if self.life <= 0: self.kill()#################################### A separate class for a spaceship bullet#class SpaceShipBullet(pygame.sprite.Sprite): speed = [0, -8] image = "" rect = "" ## set up the class when it starts def __init__(self, x, y): pygame.sprite.Sprite.__init__(self, self.containers) self.image = pygame.image.load('bullet.bmp') self.bullet_sound = load_sound('fire.wav') self.bullet_sound.play() self.rect = self.image.get_rect() self.SetPosition(x, y) ## set the bullet speed def SetSpeed(self, x, y): self.speed = [x,y] ## set the position of the ship def SetPosition(self, x, y): self.rect.left = x self.rect.top = y ## move the bullet def update(self): self.rect.move_ip(self.speed[0], self.speed[1]) if self.rect.top <= 0: self.kill()#################################### A separate class for a spaceship bomb#class SpaceShipMissile(pygame.sprite.Sprite): speed = [0, -4] image = "" rect = "" images = [] ## set up the class when it starts def __init__(self, x, y): pygame.sprite.Sprite.__init__(self, self.containers) self.image = pygame.image.load('missile.gif') self.missileX_sound = load_sound('bomb.wav') self.missileX_sound.play() self.rect = self.image.get_rect() self.SetPosition(x, y) ## set the bullet speed def SetSpeed(self, x, y): self.speed = [x,y] ## set the position of the ship def SetPosition(self, x, y): self.rect.left = x self.rect.top = y ## move the bullet def update(self): self.rect.move_ip(self.speed[0], self.speed[1]) if self.rect.top <= 0: self.kill() #################################### The bad guys in our game deserve a class too!#class Alien(pygame.sprite.Sprite): horzspeed = 5 vertspeed = 0 alive = 1 image = "" rect = "" ## set up the class when it starts def __init__(self): pygame.sprite.Sprite.__init__(self, self.containers) self.image = pygame.image.load('enemy1.gif') self.rect = self.image.get_rect() self.vertspeed = self.rect.height + 5 ## set the position of the alien def SetPosition(self, x, y): self.rect.left = x self.rect.top = y ## the aliens move mindlessly def update(self): self.rect.move_ip(self.horzspeed, 0) # turn around at the edges of the screen # and move vertically too if self.rect.right > SCREEN_WIDTH or self.rect.left < 0: self.horzspeed = -self.horzspeed self.rect.move_ip(self.horzspeed, self.vertspeed)#################################### When an alien is hit it needs a custom explosion# otherwise it just disappears from the screen#class AlienExplosion(pygame.sprite.Sprite): defaultlife = 9 animcycle = 3 images = [] def __init__(self, actor): pygame.sprite.Sprite.__init__(self, self.containers) # define our explosion animation frames self.explosion_sound = load_sound('explos.wav') self.explosion_sound.play() self.images.append(pygame.image.load('enemy2.gif')) self.images.append(pygame.image.load('enemy3.gif')) self.images.append(pygame.image.load('enemy4.gif')) self.image = self.images[0] self.rect = self.image.get_rect() self.life = self.defaultlife self.rect.center = actor.rect.center def update(self): self.life = self.life - 1 self.image = self.images[self.life/self.animcycle%3] if self.life <= 0: self.kill()#################################### The score text will be a sprite#class Score(pygame.sprite.Sprite): global playerScore image = "" rect = "" def __init__(self): pygame.sprite.Sprite.__init__(self) self.font = pygame.font.Font(None, 20) self.color = Color('white') self.update() self.rect = self.image.get_rect().move(75, 1) def update(self): msg = "Score: %d" % playerScore self.image = self.font.render(msg, 0, self.color)#################################### The ship health text will be a sprite#class Health(pygame.sprite.Sprite): image = "" rect = "" def __init__(self): pygame.sprite.Sprite.__init__(self) self.font = pygame.font.Font(None, 20) self.color = Color('white') self.update() self.rect = self.image.get_rect().move(250, 1) def update(self): msg = "Health: %d" % playerHealth self.image = self.font.render(msg, 0, self.color)#################################### The player's Lives text will be a sprite#class Lives(pygame.sprite.Sprite): image = "" rect = "" def __init__(self): pygame.sprite.Sprite.__init__(self) self.font = pygame.font.Font(None, 20) self.color = Color('white') self.update() self.rect = self.image.get_rect().move(150, 1) def update(self): msg = "Lives: %d" % playerLife self.image = self.font.render(msg, 0, self.color)#################################### The game level will also be sprite#class Level(pygame.sprite.Sprite): image = "" rect = "" level = 0 def __init__(self, gamelevel): pygame.sprite.Sprite.__init__(self) self.level = gamelevel self.font = pygame.font.Font(None, 20) self.color = Color('white') self.update() self.rect = self.image.get_rect().move(1, 1) def update(self): msg = "Level: %d" % self.level self.image = self.font.render(msg, 0, self.color)#################################### Spawn aliens based on the game level#def SpawnAliens(level, aliens): # this creates our starting aliens # aliencount * x -- must be less than SCREEN_WIDTH game contant aliencount = 10 + level while aliencount > 0: Alien() aliencount = aliencount - 1 x = 0 y = 30 for alien in aliens.sprites(): alien.SetPosition(x, y) x = x + 50 if (x > SCREEN_WIDTH): # if there too many aliens to fit on one line # start a new line of them y = y + 50 x = 0 #################################### Main Game Code#def PlayGame(gamelevel): global playerScore global playerLife global playerHealth # This function is called when the program starts. # it initializes everything it needs, then runs in # a loop until the function returns. # Initialize everything pygame.init() screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) pygame.display.set_caption('RAFT Invaders') pygame.mouse.set_visible(0) # Create the backgound surface background = pygame.Surface(screen.get_size()) background = background.convert() background.fill((0, 0, 0)) # Display the default background screen.blit(background, (0, 0)) pygame.display.flip() # Prepare game objects clock = pygame.time.Clock() # Initialize game groups allsprites = pygame.sprite.RenderUpdates() shots = pygame.sprite.Group() aliens = pygame.sprite.Group() # Assign default groups to each sprite class SpaceShip.containers = allsprites SpaceShipExplosion.containers = allsprites SpaceShipBullet.containers = shots, allsprites SpaceShipMissile.containers = shots, allsprites Alien.containers = aliens, allsprites AlienExplosion.containers = allsprites Score.containers = allsprites Level.containers = allsprites Lives.containers = allsprites Health.containers = allsprites # Prepare game objects player = SpaceShip() player.SetPosition( (SCREEN_WIDTH/2)-(player.rect.width/2), (SCREEN_HEIGHT - player.rect.height) ) # spawn the aliens based on the game level SpawnAliens(gamelevel, aliens) # Set up the score and level sprites player.score = 0 if pygame.font: allsprites.add(Score()) allsprites.add(Level(gamelevel)) allsprites.add(Lives()) allsprites.add(Health()) # Main Loop while 1: # Keep the game at a set speed clock.tick(60) # Handle input events for event in pygame.event.get(): if event.type == QUIT: return 0 elif event.type == KEYDOWN and event.key == K_ESCAPE: return 0 # Get the key pressed keystate = pygame.key.get_pressed() # Move player based on arrow input if keystate[K_RIGHT] == 1: player.MoveRight(8) # Keep the ship on the screen if player.rect.right >= SCREEN_WIDTH: player.rect.right = SCREEN_WIDTH elif keystate[K_LEFT] == 1: player.MoveLeft(8) # Keep the ship on the screen if player.rect.left <= 0: player.rect.left = 0 elif keystate[K_UP] == 1: player.MoveUp(8) # Keep the ship on the screen if player.rect.top <= 0: player.rect.top = 0 elif keystate[K_DOWN] == 1: player.MoveDown(8) # Keep the ship on the screen if player.rect.bottom >= SCREEN_HEIGHT: player.rect.bottom = SCREEN_HEIGHT # Shoot a bullet when the space bar is pressed if keystate[K_SPACE] == 1: if len(shots) < MAX_SHOTS: SpaceShipBullet(player.rect.centerx, player.rect.centery) if keystate[K_x] == 1: if len(shots) < MISSILE: SpaceShipMissile(player.rect.centerx, player.rect.centery) # Check for collisions for alien in pygame.sprite.groupcollide(shots, aliens, 1, 1).keys(): AlienExplosion(alien) # add to the score playerScore = playerScore + 10 #player will lose life, but continue on in the game #the level will not reset itself for alien in pygame.sprite.spritecollide(player, aliens, 1): playerHealth = playerHealth - 20 if playerHealth == 0: player.Explode() SpaceShipExplosion(player) playerHealth = 100 player.rect.bottom = SCREEN_HEIGHT playerLife = playerLife - 1 if playerLife <= 0: playerLife = 3 gameLevel = 1 IntroScreen() #for now until a gameover screen is made ### Draw everything # Clear/erase the last drawn sprites allsprites.clear(screen, background) # Update sprites via their update functions allsprites.update() # Locate all the sprite rectangles and update # their location on the screen dirty = allsprites.draw(screen) pygame.display.update(dirty) pygame.display.flip() if len(aliens) == 0: # No more aliens? # Level completed! return 2 if player.lives <= 0: # No more lives? # Game Over return 1#################################### Show the intro screen#def IntroScreen(): # Initialize everything pygame.init() screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) pygame.display.set_caption('RAFT Invaders') pygame.mouse.set_visible(0) # Create the backgound surface background = pygame.Surface(screen.get_size()) background = background.convert() background.fill((0, 0, 0)) # Display some text font = pygame.font.Font(None, 26) text = font.render("Press SPACE to play", 1, (250, 250, 250)) textpos = text.get_rect() textpos.centerx = background.get_rect().centerx textpos.centery = 20 background.blit(text, textpos) # Display some text font = pygame.font.Font(None, 26) text = font.render("Press Q to quit", 1, (250, 250, 250)) textpos = text.get_rect() textpos.centerx = background.get_rect().centerx textpos.centery = 60 background.blit(text, textpos) # Blit everything to the screen screen.blit(background, (0, 0)) pygame.display.flip() # wait for a decision while 1: # Handle input events for event in pygame.event.get(): if event.type == QUIT: return 0 elif event.type == KEYDOWN and event.key == K_q: return 0 elif event.type == KEYDOWN and event.key == K_SPACE: return 2 ###################### Python runs the code below first#while 1: exitcode = IntroScreen() if exitcode == 0: # player asked to quit sys.exit(0) elif exitcode == 2: # player has chosen to play! exitcode = 2 gamelevel = 1 playerScore = 0 while exitcode == 2: print "Going to level", gamelevel exitcode = PlayGame(gamelevel) if exitcode == 0: # player asked to quit, return to the intro screen exitcode == 2 elif exitcode == 1: # end of game, player has died break elif exitcode == 2: # level cleared, go to the next gamelevel = gamelevel + 1 elif player.live <= 0: gamelevel = 1
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement