""" TO DO: - Splash screen - Play again? """ import random import time import pgzrun from pgzhelper import * WIDTH = 800 HEIGHT = 600 # globals score = 0 health = 19 health_holdoff = 0 powerup_time = 0 game_over_played = False lasers = [] laser_holdoff = 0 laser_hit_idx = 0 music.play('music1') # local helper functions def rotate(actor): if actor.angle == 360: actor.angle = 0 else: actor.angle += 1 def relocate(actor, scale=1): # Avoid ship x = ship.x y = ship.y while (x == ship.x) and (y == ship.y): x = random.randint(20, 780) y = random.randint(20, 580) actor.x = x actor.y = y actor.scale = scale actor.direction = random.randint(0, 359) background = Actor('spacebg') health_bar = Actor(f'health{health}') health_bar.scale = 0.8 health_bar.x = 140 health_bar.y = 30 ship = Actor('playership') ship.images = [ship.image, 'playership_damage'] ship.fps = 10 ship.y = 550 ship.x = 400 meteors = [Actor('meteorbrown1'), Actor('meteorbrown2'), Actor('meteorbrown3'), Actor('meteorbrown4'), Actor('meteorgrey1'), Actor('meteorgrey2'), Actor('meteorgrey3'), Actor('meteorgrey4')] for meteor in meteors: relocate(meteor, round(random.uniform(0.5, 1.5), 1)) explosions = [] powerups = [] def on_mouse_move(pos, rel, buttons): ship.x = pos[0] ship.y = pos[1] def on_mouse_down(pos, button): global lasers, laser_holdoff if button == 1: if laser_holdoff == 0: sounds.laser.play() laser = Actor('laser') laser.angle = 90 laser.x = ship.x laser.y = ship.y - 30 lasers.append(laser) laser_holdoff = 1 else: laser_holdoff -= 1 def update(): global score, health, health_holdoff, laser_hit_idx, powerup_time health_bar.image = f'health{health}' health_bar.scale = 0.8 health_bar.x = 140 health_bar.y = 30 # meteors for meteor in meteors: rotate(meteor) meteor.move_in_direction(round(random.uniform(0.5, 1.5), 1)) # meteor speed # meteor collisions if meteor.collidelist(lasers) != -1: try: del lasers[laser_hit_idx] except IndexError: pass finally: explotion = Actor('explosion_1') explotion.images = [explotion.image, 'explosion_2', 'explosion_3', 'explosion_4', 'explosion_5', 'explosion_6', 'explosion_7', 'explosion_8', 'explosion_9', 'explosion_10'] explotion.x = meteor.x explotion.y = meteor.y explotion.scale = 0.5 explotion.fps = 10 explosions.append(explotion) sounds.explosion.play() score += 1 relocate(meteor, round(random.uniform(0.5, 1.5), 1)) if (meteor.x > 800) or (meteor.y > 600) or (meteor.x < 0) or (meteor.y < 0): relocate(meteor, round(random.uniform(0.5, 1.5), 1)) for explotion in explosions: if explotion.animate() >= 9: explosions.remove(explotion) # ship collides with meteors if ship.collidelist(meteors) != -1: ship.animate() if health_holdoff == 0: if health > 0: health -= 1 sounds.loose.play() health_holdoff = 50 else: health_holdoff -= 1 else: ship.image = 'playership' # laser collisions for idx, laser in enumerate(lasers): if laser.y > 595: lasers.remove(laser) elif laser.collidelist(meteors) != -1: laser_hit_idx = idx else: laser.y -= 5 # Power Up if health < 19 and powerup_time == 0: # TO DO: fix random time - use a counter with random values: powerup_time powerup = Actor('powerup') relocate(powerup) powerups.append(powerup) powerup_time = random.randint(100, 300) if powerup_time > 0: powerup_time -= 1 for powerup in powerups: powerup.move_in_direction(round(random.uniform(0.5, 1.5), 1)) # powerup speed # detect collision with ship if powerup.colliderect(ship): powerups.remove(powerup) sounds.powerup.set_volume(4) sounds.powerup.play() health += 1 if health > 19: health = 19 # remove if outside the screen elif (powerup.x > 800) or (powerup.y > 600) or (powerup.x < 0) or (powerup.y < 0): powerups.remove(powerup) def draw(): global game_over_played screen.fill((0, 0, 0)) background.draw() health_bar.draw() if health > 0: screen.draw.text(f'Score: {score}', (330, 18), color=(255, 255, 255), fontsize=40) for meteor in meteors: meteor.draw() for explotion in explosions: explotion.draw() for powerup in powerups: powerup.draw() ship.draw() for laser in lasers: laser.draw() else: powerups.clear() meteors.clear() explosions.clear() lasers.clear() screen.draw.text(f'Score: {score}', (250, 300), color=(245, 243, 127), fontsize=100) screen.draw.text('Game Over', (220, 450), color=(255, 255, 255), fontsize=100) music.stop() if not game_over_played: sounds.game_over.play() game_over_played = True # Main loop pgzrun.go()