# Astrocrash07 # Add explosions import math, random from livewires import games games.init(screen_width = 640, screen_height = 480, fps = 50) class Wrapper(games.Sprite): """ A sprite that wraps around the screen. """ def update(self): """ Wrap sprite around screen. """ if self.top > games.screen.height: self.bottom = 0 if self.bottom < 0: self.top = games.screen.height if self.left > games.screen.width: self.right = 0 if self.right < 0: self.left = games.screen.width def die(self): """ Destroy self. """ self.destroy() class Collider(Wrapper): """ A Wrapper that can collide with another object. """ def update(self): """ Check for overlapping sprites. """ super(Collider, self).update() if self.overlapping_sprites: for sprite in self.overlapping_sprites: sprite.die() self.die() def die(self): """ Destroy self and leave explosion behind. """ new_explosion = Explosion(x = self.x, y = self.y) games.screen.add(new_explosion) self.destroy() class Asteroid(Wrapper): """ An asteroid which floats across the screen. """ SMALL = 1 MEDIUM = 2 LARGE = 3 images = {SMALL : games.load_image("asteroid_small.bmp"), MEDIUM : games.load_image("asteroid_med.bmp"), LARGE : games.load_image("asteroid_big.bmp") } SPEED = 2 SPAWN = 2 def __init__(self, x, y, size): """ Initialize asteroid sprite. """ super(Asteroid, self).__init__( image = Asteroid.images[size], x = x, y = y, dx = random.choice([1, -1]) * Asteroid.SPEED * random.random()/size, dy = random.choice([1, -1]) * Asteroid.SPEED * random.random()/size) self.size = size def die(self): """ Destroy asteroid. """ # if asteroid isn't small, replace with two smaller asteroids if self.size != Asteroid.SMALL: for i in range(Asteroid.SPAWN): new_asteroid = Asteroid(x = self.x, y = self.y, size = self.size - 1) games.screen.add(new_asteroid) super(Asteroid, self).die() class Ship(Collider): """ The player's ship. """ image = games.load_image("ship.bmp") sound = games.load_sound("thrust.wav") ROTATION_STEP = 3 VELOCITY_STEP = .03 MISSILE_DELAY = 25 def __init__(self, x, y): """ Initialize ship sprite. """ super(Ship, self).__init__(image = Ship.image, x = x, y = y) self.missile_wait = 0 def update(self): """ Rotate, thrust and fire missiles based on keys pressed. """ super(Ship, self).update() # rotate based on left and right arrow keys if games.keyboard.is_pressed(games.K_LEFT): self.angle -= Ship.ROTATION_STEP if games.keyboard.is_pressed(games.K_RIGHT): self.angle += Ship.ROTATION_STEP # apply thrust based on up arrow key if games.keyboard.is_pressed(games.K_UP): Ship.sound.play() # change velocity components based on ship's angle angle = self.angle * math.pi / 180 # convert to radians self.dx += Ship.VELOCITY_STEP * math.sin(angle) self.dy += Ship.VELOCITY_STEP * -math.cos(angle) # if waiting until the ship can fire next, decrease wait if self.missile_wait > 0: self.missile_wait -= 1 # fire missile if spacebar pressed and missile wait is over if games.keyboard.is_pressed(games.K_SPACE) and self.missile_wait == 0: new_missile = Missile(self.x, self.y, self.angle) games.screen.add(new_missile) self.missile_wait = Ship.MISSILE_DELAY class Missile(Collider): """ A missile launched by the player's ship. """ image = games.load_image("missile.bmp") sound = games.load_sound("missile.wav") BUFFER = 40 VELOCITY_FACTOR = 7 LIFETIME = 40 def __init__(self, ship_x, ship_y, ship_angle): """ Initialize missile sprite. """ Missile.sound.play() # convert to radians angle = ship_angle * math.pi / 180 # calculate missile's starting position buffer_x = Missile.BUFFER * math.sin(angle) buffer_y = Missile.BUFFER * -math.cos(angle) x = ship_x + buffer_x y = ship_y + buffer_y # calculate missile's velocity components dx = Missile.VELOCITY_FACTOR * math.sin(angle) dy = Missile.VELOCITY_FACTOR * -math.cos(angle) # create the missile super(Missile, self).__init__(image = Missile.image, x = x, y = y, dx = dx, dy = dy) self.lifetime = Missile.LIFETIME def update(self): """ Move the missile. """ super(Missile, self).update() # if lifetime is up, destroy the missile self.lifetime -= 1 if self.lifetime == 0: self.destroy() class Explosion(games.Animation): """ Explosion animation. """ sound = games.load_sound("explosion.wav") images = ["explosion1.bmp", "explosion2.bmp", "explosion3.bmp", "explosion4.bmp", "explosion5.bmp", "explosion6.bmp", "explosion7.bmp", "explosion8.bmp", "explosion9.bmp"] def __init__(self, x, y): super(Explosion, self).__init__(images = Explosion.images, x = x, y = y, repeat_interval = 4, n_repeats = 1, is_collideable = False) Explosion.sound.play() def main(): # establish background nebula_image = games.load_image("nebula.jpg") games.screen.background = nebula_image # create 8 asteroids for i in range(8): x = random.randrange(games.screen.width) y = random.randrange(games.screen.height) size = random.choice([Asteroid.SMALL, Asteroid.MEDIUM, Asteroid.LARGE]) new_asteroid = Asteroid(x = x, y = y, size = size) games.screen.add(new_asteroid) # create the ship the_ship = Ship(x = games.screen.width/2, y = games.screen.height/2) games.screen.add(the_ship) games.screen.mainloop() # kick it off! main()