예제 #1
0
def main():
    
    def create_particles(number, x, y, image):
	for count in range(number):
	    for particle_count in range(MAX_PARTICLES):
		if particles[particle_count].active == False:
		    particles[particle_count].active = True
		    particles[particle_count].rect.left = x
		    particles[particle_count].rect.top = y
		    particles[particle_count].image = image
		    if number > 15:
			particles[particle_count].move_count = random.randint(20, 30)
		    else:
			particles[particle_count].move_count = random.randint(10, 17)
		    if random.randint(0, 10) > 5:
			particles[particle_count].vector_x = 0 - random.randint(0, 4)
			particles[particle_count].vector_y = 0 - random.randint(0, 4)
		    else:
			particles[particle_count].vector_x = random.randint(0, 4)
			particles[particle_count].vector_y = random.randint(0, 4)
		    break

    # Game Constants..
    SCREEN_HEIGHT = 468
    SCREEN_WIDTH = 640

    high_score = 750000

    TITLE_SCREEN_MODE = 1
    GAME_MODE = 2
    FPS = 60

    NUMBER_OF_LIVES = 6
    MAX_ENEMIES = 15
    PLAYER_BULLETS = 40
    MAX_ENEMY_BULLETS = 30
    MAX_UFOS = 1
    MAX_PARTICLES = 200

    # Counters..
    attack_timer = 0
    attack_max = 70
    ufo_attack_timer = 0
    ufo_attack_max = 500
    max_enemy_speed = 2
    max_ufo_speed = 2

    game_wave = 1
    enemy_killed = 0
    wave_break = 100
    wave_target_kills = 50
    game_over = False
    game_over_timer = 500
    game_victory = False
    game_victory_particle_timer = 0

    player_score = 0
    player_lives = 7
    player_flash_timer = 0
    player_flash_on = False

    # Game control stuff..
    game_mode = TITLE_SCREEN_MODE
    title_menu_choice = 0
    title_lit_message = True

    beaten_high_score = False

    enemy_fire_timer = 0
    enemy_fire_max = 50

    title_freeplay_timer = 0
    title_freeplay_on = False

    # Init the game and creating the display surface..
    pygame.init()
    screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT])
    #SCREEN_WIDTH, SCREEN_HEIGHT = screen.get_size()
    pygame.display.set_caption("Squadron: Yet Another Arcade Game!")
    clock = pygame.time.Clock()

    # Creating game fonts..
    pygame.font.init()
    game_font = pygame.font.Font(os.path.join("gfx", "04b_25__.ttf"), 18)
    game_font_large = pygame.font.Font(os.path.join("gfx", "04b_25__.ttf"), 36)
    game_font_xl = pygame.font.Font(os.path.join("gfx", "04b_25__.ttf"), 46)

    # Show loading message...
    screen.fill((0,0,0))
    screen.blit(game_font.render("Loading....", 0, ((176, 0, 0))), (270, SCREEN_HEIGHT / 2 - 36))
    pygame.display.flip()

    # Loading game gfx..
    player_bullet_image = pygame.image.load(os.path.join("gfx", "bullet1.png")).convert()
    enemy_bullet_image = pygame.image.load(os.path.join("gfx", "bullet2.png")).convert()
    invader_image = pygame.image.load(os.path.join("gfx", "invader.png")).convert()
    shooter_image = pygame.image.load(os.path.join("gfx", "shooter_invaders.png")).convert()
    transient_image = pygame.image.load(os.path.join("gfx", "Transient.png")).convert()
    ufo_image = pygame.image.load(os.path.join("gfx", "ufo.png")).convert()
    player_health_image = pygame.Surface((8, 16))
    player_health_image.fill((176, 0, 0))

    # Sort the sound driver
    pygame.mixer.quit()
    sound = pygame.mixer.init()

    # Loading all game sounds..
    damage_sound = pygame.mixer.Sound(os.path.join("sound", "damage.wav"))
    exit_sound = pygame.mixer.Sound(os.path.join("sound", "exit.wav"))
    expolde_sound = pygame.mixer.Sound(os.path.join("sound", "explode1.wav"))
    lazer_sound = pygame.mixer.Sound(os.path.join("sound", "lazer.wav"))
    menu_mov_sound = pygame.mixer.Sound(os.path.join("sound", "menu_move.wav"))
    menu_select_sound = pygame.mixer.Sound(os.path.join("sound", "menu_select.wav"))
    wave_sound = pygame.mixer.Sound(os.path.join("sound", "newwave.wav"))
    player_dead_sound = pygame.mixer.Sound(os.path.join("sound", "player_dead.wav"))
    shoot2_sound = pygame.mixer.Sound(os.path.join("sound", "shoot2.wav"))
    start_sound = pygame.mixer.Sound(os.path.join("sound", "start.wav"))
    ufo_sound = pygame.mixer.Sound(os.path.join("sound", "ufo.wav"))
    ufo_sound.set_volume(0.35)
    win_sound = pygame.mixer.Sound(os.path.join("sound", "win.wav"))

    # Create some particle images..
    red_particle_image = pygame.Surface((8, 8))
    red_particle_image.fill((176, 0, 0))

    green_particle_image = pygame.Surface((8, 8))
    green_particle_image.fill((31, 92, 14))

    blue_particle_image = pygame.Surface((8, 8))
    blue_particle_image.fill((46, 102, 187))

    yellow_particle_image = pygame.Surface((8, 8))
    yellow_particle_image.fill((255, 206, 0))

    gray_particle_image = pygame.Surface((8, 8))
    gray_particle_image.fill((88, 88, 88))
   
    # Create the players... TODO: Clean this!
    #player_side = Player(SCREEN_WIDTH, SCREEN_HEIGHT, side= True)
    #player_bottom = Player(SCREEN_WIDTH, SCREEN_HEIGHT, bottom= True)
    player_bottom = PlayerBottom(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_WIDTH / 2, SCREEN_HEIGHT - 35)
    player_side = PlayerSide(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_WIDTH -35, SCREEN_HEIGHT / 2)

    player_score = 0
    player_fire_rate = 5
    player_fire_delay_right = 0
    player_fire_delay_left = 0
    player_shield = 9
    player_lives = 10
    player_flash_on = False
    player_flash_timer = 0

    # Prepare the player pointed projectiles!
    player_bullets = []
    for count in range(PLAYER_BULLETS):
        player_bullets.append(Projectile(SCREEN_WIDTH, SCREEN_HEIGHT, player_bullet_image))
        player_bullets[count].active = False

    # Enemy bullets..
    enemy_bullets = []
    for count in range(MAX_ENEMY_BULLETS):
	enemy_bullets.append(Projectile(SCREEN_WIDTH, SCREEN_HEIGHT, enemy_bullet_image))
	enemy_bullets[count].active = False

    # Prepare enemies..
    invaders = []
    shooter_invaders = []
    transient_invaders = []

    for count in range (MAX_ENEMIES):
   	# invaders 
   	invaders.append(Enemy(SCREEN_WIDTH, SCREEN_HEIGHT, invader_image))
   	invaders[count].rect.top = 0
      	invaders[count].rect.left = 0
   	invaders[count].vector_x = 0
   	invaders[count].vector_y = 0
   	invaders[count].active = False
   	invaders[count].anim_max_frame = 3
   	invaders[count].movement_type = 0

   	# shooter invaders 
   	shooter_invaders.append(Enemy(SCREEN_WIDTH, SCREEN_HEIGHT, shooter_image))
   	shooter_invaders[count].rect.top = 0
   	shooter_invaders[count].rect.left = 0
   	shooter_invaders[count].vector_x = 0
   	shooter_invaders[count].vector_y = 0
   	shooter_invaders[count].active = False
   	shooter_invaders[count].anim_max_frame = 3
   	shooter_invaders[count].movement_type = 0

   	# transient invaders 
   	transient_invaders.append(Enemy(SCREEN_WIDTH, SCREEN_HEIGHT, transient_image))
   	transient_invaders[count].rect.top = 0
   	transient_invaders[count].rect.left = 0
   	transient_invaders[count].vector_x = 0
   	transient_invaders[count].vector_y = 0
   	transient_invaders[count].active = False
   	transient_invaders[count].anim_max_frame = 3
   	transient_invaders[count].movement_type = 1
    
    ufos = []
    for count in range(MAX_UFOS):
	ufos.append(Enemy(SCREEN_WIDTH, SCREEN_HEIGHT, ufo_image))
	ufos[count].anim_max_frame = 9

    particles = []
    for count in range(MAX_PARTICLES):
        particles.append(Particle(SCREEN_WIDTH, SCREEN_HEIGHT, red_particle_image))
        particles[count].active = False   

#<<<><><><><><>||MAIN LOOP||<><><><><><><><>>>#
#<<<><><><><><><><><><><><><><><><><><><><>>>>#

    main_loop = True
    enemies_onscreen = False

    while main_loop:

        # Clear the screen (NOTE: This is not particularly efficient, but deadline is looming!)
        screen.fill((0,0,0)) 

	# Check the game mode if TITLE_SCREEN_MODE
	if game_mode == TITLE_SCREEN_MODE:

	    #-----------------------#
	    #----||TITLE SCREEN||---#
	    #-----------------------#
	    
	    # Render the game title..
	    screen.blit(game_font_xl.render("Squadron",  0, ((255, 206, 0))), (230, 100))

	    title_freeplay_timer += 1
	    if title_freeplay_timer > 30:
	    	title_freeplay_timer = 0
		if title_freeplay_on == True:
		    title_freeplay_on = False
		else:
		    title_freeplay_on = True

	    if title_freeplay_on == True:
                screen.blit(game_font.render("Insert Coin", 0, ((175, 175, 175))), (280, 380))

	    if title_menu_choice == 1:
                screen.blit(game_font.render("Start", 0, ((255, 206, 0))), (300, 225))
	    else:
                screen.blit(game_font.render("Start", 0, ((176, 0, 0))), (300, 225))           

	    if title_menu_choice == 0:
                screen.blit(game_font.render("Exit", 0, ((255, 206, 0))), (308, 250))
	    else:
                screen.blit(game_font.render("Exit", 0, ((176, 0, 0))), (308, 250))

            screen.blit(game_font.render("Z and X to fire, cursor keys control both ships", 0, ((176, 0, 0))), (120, 450))

	   # Screen Events...
	    for event in pygame.event.get():
		if event.type == pygame.QUIT:
		    main_loop = False

		elif event.type == pygame.KEYDOWN:
		    if event.key == pygame.K_UP:
			menu_mov_sound.play()
			title_menu_choice -= 1
			if title_menu_choice < 0:
                            title_menu_choice = 0

		    if event.key == pygame.K_DOWN:
			title_menu_choice += 1
			menu_mov_sound.play()
			if title_menu_choice > 1:
                            title_menu_choice = 1

		    if event.key == pygame.K_ESCAPE:
			main_loop = False 

		    if event.key == pygame.K_z or event.key == pygame.K_x or event.key == pygame.K_SPACE or event.key == pygame.K_RETURN:
			if title_menu_choice == 0:
			    # Start the games
			    start_sound.play()
			    game_mode = GAME_MODE # Switch to the game play mode
			    attack_timer = 0
			    attack_max = 70
			    ufo_attack_timer = 0
			    ufo_attack_max = 500
			    max_enemy_speed = 2
			    max_ufo_speed = 2
			    beaten_high_score = False
			    game_wave = 1
			    enemy_killed = 0
			    wave_break = 100
			    wave_target_kills = 50
			    game_over = False
			    game_over_timer = 500
			    game_victory = False
			    game_victory_particle_timer = 0
			    enemy_fire_timer = 0
			    enemy_fire_max = 50 
			    player_fire_delay_left = 0
                            player_fire_delay_right = 0
			    player_score = 0
			    player_shield = 9
			    player_lives = 7
			    player_flash_timer = 0
			    player_flash_on = False

			    # Deactivate all enemies, particles, bullets
			    for count in range(MAX_ENEMIES):
				invaders[count].active = False
				shooter_invaders[count].active = False
				transient_invaders[count].active = False

			    for count in range(MAX_PARTICLES):
				particles[count].active = False

			    for count in range(PLAYER_BULLETS):
				player_bullets[count].active = False

			    for count in range(MAX_ENEMY_BULLETS):
				enemy_bullets[count].active = False

			    for count in range(MAX_UFOS):
				ufos[count].active = False

			if title_menu_choice == 1:
			    exit_sound.play()
			    main_loop = False
        else:

	    #-----------------------#
	    #-----||GAME MODE||-----#
	    #-----------------------#

	    # Game Events...
            for event in pygame.event.get():
		if event.type == pygame.QUIT:
		    main_loop = False

		elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        game_mode = TITLE_SCREEN_MODE # Switch back to the title screen
                    if event.key == pygame.K_z and player_fire_delay_left > player_fire_rate and game_over == False:
                        # Pop off a few projectiles...                    
                        for count in range(PLAYER_BULLETS):
                            if (player_bullets[count].active == False): # Find a 'free' bullet for the bottom ship
                                player_bullets[count].active = True
                                player_bullets[count].rect.top = player_bottom.rect.top
                                player_bullets[count].rect.left = player_bottom.rect.left + 12
                                player_bullets[count].vector_x = 0
                                player_bullets[count].vector_y = -9
                                player_fire_delay_left = 0
                                lazer_sound.play()                                
                                break
                    # Has side player fired
                    if event.key == pygame.K_x and player_fire_delay_left > player_fire_rate and game_over == False:
                        for count in range(PLAYER_BULLETS):
                            if (player_bullets[count].active == False):
                                player_bullets[count].active = True
                                player_bullets[count].rect.top = player_side.rect.top + 12
                                player_bullets[count].rect.left = player_side.rect.left
                                player_bullets[count].vector_x = -9
                                player_bullets[count].vector_y = 0
                                player_fire_delay_right = 0
                                lazer_sound.play()                            
                                break


		attack_timer += 1
		ufo_attack_timer += 1

		if attack_timer > attack_max and wave_break < 1 and enemy_killed < wave_target_kills and game_over == False:	
		    attack_timer = 0
		    
		    if game_wave > 2:
			enemy_type = random.randint(0, 2)
		    else:
			enemy_type = random.randint(0, 1)

		    direction = random.randint(0, 1)
		    if enemy_type == 0:
			for count in range(MAX_ENEMIES):
			    if invaders[count].active == False:
				if direction == 0: # if enemies come from left
				    invaders[count].rect.left = -32
				    invaders[count].rect.top = random.randint(0, (SCREEN_HEIGHT - 64) / 32) * 32
				    invaders[count].vector_x = max_enemy_speed
				    invaders[count].vector_y = 0
				    invaders[count].active = True
				    break
				else: # if enemies come from top
				    invaders[count].rect.left = random.randint(0, (SCREEN_WIDTH - 64) / 32) * 32
				    invaders[count].rect.top = -32
				    invaders[count].vector_x = 0
				    invaders[count].vector_y = max_enemy_speed
				    invaders[count].active = True
				    break
		    elif enemy_type == 1:
			for count in range(MAX_ENEMIES):
			    if shooter_invaders[count].active == False:
				if direction == 0: # if enemies come from left
				    shooter_invaders[count].rect.left = -32 # 32 is the icon size
				    shooter_invaders[count].rect.top = random.randint(0, (SCREEN_HEIGHT - 64) / 32) * 32
				    shooter_invaders[count].vector_x = max_enemy_speed
				    shooter_invaders[count].vector_y = 0
				    shooter_invaders[count].active = True
				    shooter_invaders[count].movement_type = 2
				    break
				else: # if enemies come from top
				    shooter_invaders[count].rect.left = random.randint(0, (SCREEN_WIDTH - 64) / 32) * 32
				    shooter_invaders[count].rect.top = -32
				    shooter_invaders[count].vector_x = 0
				    shooter_invaders[count].vector_y = max_enemy_speed
				    shooter_invaders[count].active = True
				    shooter_invaders[count].movement_type = 1
				    break
		    elif enemy_type == 2:
			for count in range(MAX_ENEMIES):
			    if shooter_invaders[count].active == False:
				if direction == 0: # if enemies come from left
				    transient_invaders[count].rect.left = -32
				    transient_invaders[count].rect.top = random.randint(0, (SCREEN_HEIGHT - 64) / 32) * 32
				    transient_invaders[count].vector_x = max_enemy_speed
				    transient_invaders[count].vector_y = random.randint(0, 1) - random.randint(0, 1)
				    transient_invaders[count].active = True
				    break
				else: # if enemies come from top
				    transient_invaders[count].rect.left = random.randint(0, (SCREEN_WIDTH - 64) / 32) * 32
				    transient_invaders[count].rect.top = -32
				    transient_invaders[count].vector_x = random.randint(0, 1) - random.randint(0, 1)
				    transient_invaders[count].vector_y = max_enemy_speed
				    transient_invaders[count].active = True
				    break

		# ufo attacks..
		for count in range(MAX_UFOS):
		    if ufos[count].active == False and ufo_attack_timer > ufo_attack_max and wave_break < 1 and game_over == False:
			ufo_attack_timer = 0
			ufo_sound.play()
			if random.randint(0, 10) > 4: # Attacking the side player
			    if random.randint(0, 10) > 4:
				ufos[count].rect.left = SCREEN_WIDTH - 32
				ufos[count].rect.top = -32
				ufos[count].vector_x = 0
				ufos[count].vector_y = max_ufo_speed
				ufos[count].active = True
			    else:
				ufos[count].rect.left = SCREEN_WIDTH -32
				ufos[count].rect.top = SCREEN_HEIGHT + 32
				ufos[count].vector_x = - max_ufo_speed
				ufos[count].vector_y = 0
				ufos[count].active = True
			else: # Attacking the bottom player
			    if random.randint(0, 10) > 4:
				ufos[count].rect.top = SCREEN_HEIGHT - 32
				ufos[count].rect.left = - 32
				ufos[count].vector_x = max_ufo_speed
				ufos[count].vector_y = 0
				ufos[count].rect.active = True
			    else:
				ufos[count].rect.top = SCREEN_HEIGHT -32
                                ufos[count].rect.left = SCREEN_WIDTH + 32                        
                                ufos[count].vector_x = 0 - max_ufo_speed
                                ufos[count].vector_y = 0
                                ufos[count].active = True  

		# Render the particles..
		for count in range(MAX_PARTICLES):
		    if particles[count].active == True:
			particles[count].update()
			screen.blit(particles[count].image, particles[count].rect)
		
		# Update the players due to their key events..
		player_bottom.update()
		player_side.update() 
		
		# If player recovers from damage..
		if player_flash_timer > 0:
		    player_flash_on -= 1
		    if player_flash_on == True:
			player_flash_on = False
		    else:
			player_flash_on = True
		else:
		    player_flash_on = False
		
		# Render all the player projectiles..
		for count in range(PLAYER_BULLETS):
		    if (player_bullets[count].active):
			player_bullets[count].update()
			screen.blit(player_bullets[count].image, player_bullets[count].rect)

		# Render all the enemies projectiles..
		for count in range(MAX_ENEMY_BULLETS):
		    if (enemy_bullets[count].active):
			enemy_bullets[count].update
			screen.blit(enemy_bullets[count].image, enemy_bullets[count].rect)

		# Increase the delay for the players fire..
		player_fire_delay_left += 1
		player_fire_delay_right += 1

		# Update the invaders (move and draw)..
		for count in range(MAX_ENEMIES):
		    if invaders[count].active:
			invaders[count].update()
			screen.blit(invaders[count].image, invaders[count].rect, (32 * invaders[count].anim_frame, 0, 32, 32))
			# Check the invader collision with any player_bullets
			for collision_count in range(PLAYER_BULLETS):
			    if player_bullets[collision_count].active:
				if player_bullets[collision_count].rect.colliderect((invaders[count].rect.left, invaders[count].rect.top, 32, 32)):        
				    invaders[count].active = False
				    player_bullets[collision_count].active = False
				    enemy_killed += 1
				    expolde_sound.play()
				    player_score += 2000
				    create_particles(15, invaders[count].rect.left + 8, invaders[count].rect.top + 8, green_particle_image)

		# Update the shooter_invaders (move and draw)..
		for count in range(MAX_ENEMIES):
		    if shooter_invaders[count].active:
			shooter_invaders[count].update()
			screen.blit(shooter_invaders[count].image, shooter_invaders[count].rect, (32* shooter_invaders[count].anim_frame, 0, 32, 32))
			for collision_count in range(PLAYER_BULLETS):
			    if player_bullets[collision_count].active == True:
				if player_bullets[collision_count].rect.colliderect((shooter_invaders[count].rect.left, shooter_invaders[count].rect.top, 32, 32)):        
				    shooter_invaders[count].active = False
				    player_bullets[collision_count].active = False
				    expolde_sound.play()
				    player_score += 4750
				    enemy_killed += 1
				    create_particles(15, shooter_invaders[count].rect.left + 8, shooter_invaders[count].rect.top + 8, red_particle_image)

		# How nmuch the shooter_invaders take to shoot?
		enemy_fire_timer += 1
		if enemy_fire_timer > enemy_fire_max and game_over == False:
		    enemy_fire_timer = 0
		    for count in range(MAX_ENEMIES):
			if shooter_invaders[count].active == True and shooter_invaders[count].rect.top < SCREEN_HEIGHT - 50 and shooter_invaders[count].rect.top > 50:
			    shoot2_sound.play()
			    bullets = 0
			    for bullet_count in range(MAX_ENEMY_BULLETS):
				if enemy_bullets[bullet_count].active == False:
				    if random.randint(0, 10) > 4:
					enemy_bullets[bullet_count].active = True
					enemy_bullets[bullet_count].vector_x = 7
					enemy_bullets[bullet_count].vector_y = 0
					enemy_bullets[bullet_count].rect.top = shooter_invaders[count].rect.top + 8
					enemy_bullets[bullet_count].rect.left = shooter_invaders[count].rect.left + 12
					break
				    else:
					enemy_bullets[bullet_count].active = True
					enemy_bullets[bullet_count].vector_x = 0
					enemy_bullets[bullet_count].vector_y = 7
					enemy_bullets[bullet_count].rect.top = shooter_invaders[count].rect.top + 16
					enemy_bullets[bullet_count].rect.left = shooter_invaders[count].rect.left + 8
					break

		# Update the ufos (move and draw)..
		for count in range(MAX_UFOS):
		    if ufos[count].active:
			ufos[count].update()
			screen.blit(ufos[count].image, ufos[count].rect, (32 * ufos[count].anim_frame, 0, 32, 32))
			for collision_count in range(PLAYER_BULLETS):
                            if player_bullets[collision_count].rect.colliderect((ufos[count].rect.left, ufos[count].rect.top, 32, 32)):        
				ufos[count].active = False
				create_particles
				player_bullets[collision_count].active = False
				expolde_sound.play()
				player_score += 3250
                                create_particles(15, ufos[count].rect.left + 8, ufos[count].rect.top + 8, gray_particle_image)

		# Update the transient invaders (move and draw)..
		for count in range(MAX_ENEMIES):
		    if transient_invaders[count].active:
			transient_invaders[count].update()
			screen.blit(transient_invaders[count].image, transient_invaders[count].rect, (32* transient_invaders[count].anim_frame, 0, 32, 32))
			for collision_count in range(PLAYER_BULLETS):
			    if player_bullets[collision_count].active == True:
				if player_bullets[collision_count].rect.colliderect(transient_invaders[count], player_bullets[count]):
				    transient_invaders[count].active = False
				    player_bullets[collision_count].active = False
				    expolde_sound.play()
				    player_score += 2500
				    enemy_killed += 1
				    create_particles(15, transient_invaders[count].rect.left + 8, transient_invaders[count].top + 8, blue_particle_image)

	    # Check for player and invaders collisions..
            if player_flash_timer < 1 and game_over == False:
                player_hit = False
                for collision_count in range(MAX_ENEMIES):
                    # Have any invaders collided with player?
                    if invaders[collision_count].active == True:
                        if player_side.rect.colliderect((invaders[collision_count].rect.left + 5, invaders[collision_count].rect.top + 5, 24, 24)):        
                            invaders[collision_count].active = False
                            create_particles(15, invaders[collision_count].rect.left + 8, invaders[collision_count].rect.top + 8, green_particle_image)
                            player_hit = True
                        if player_bottom.rect.colliderect((invaders[collision_count].rect.left + 5, invaders[collision_count].rect.top + 5, 24, 24)):        
                            invaders[collision_count].active = False
                            create_particles(15, invaders[collision_count].rect.left + 8, invaders[collision_count].rect.top + 8, green_particle_image)
                            player_hit = True
                            
                    # Have any transient_invaders collided with player?
                    if shooter_invaders[collision_count].active == True:
                        if player_side.rect.colliderect((shooter_invaders[collision_count].rect.left + 5, shooter_invaders[collision_count].rect.top + 5, 24, 24)):        
                            shooter_invaders[collision_count].active = False
                            create_particles(15, shooter_invaders[collision_count].rect.left + 8, shooter_invaders[collision_count].rect.top + 8, red_particle_image)
                            player_hit = True
                        if player_bottom.rect.colliderect((shooter_invaders[collision_count].rect.left + 5, shooter_invaders[collision_count].rect.top + 5, 24, 24)):        
                            shooter_invaders[collision_count].active = False
                            create_particles(15, shooter_invaders[collision_count].rect.left + 8, shooter_invaders[collision_count].rect.top + 8, red_particle_image)
                            player_hit = True
                            
                    # Have any transient_invaders collided with player?
                    if transient_invaders[collision_count].active == True:
                        if player_side.rect.colliderect((transient_invaders[collision_count].rect.left + 5, transient_invaders[collision_count].rect.top + 5, 24, 24)):        
                            transient_invaders[collision_count].active = False                    
                            create_particles(15, transient_invaders[collision_count].rect.left + 8, transient_invaders[collision_count].rect.top + 8, blue_particle_image)
                            player_hit = True
                        if player_bottom.rect.colliderect((transient_invaders[collision_count].rect.left + 5, transient_invaders[collision_count].rect.top + 5, 24, 24)):        
                            transient_invaders[collision_count].active = False
                            create_particles(15, transient_invaders[collision_count].rect.left + 8, transient_invaders[collision_count].rect.top + 8, blue_particle_image)
                            player_hit = True

                # Have any ufos collided with player?
                for collision_count in range (MAX_UFOS):
                    if ufos[collision_count].active == True:
                        if player_side.rect.colliderect((ufos[collision_count].rect.left + 5, ufos[collision_count].rect.top + 5, 24, 24)):        
                            ufos[collision_count].active = 0
                            create_particles(15, ufos[collision_count].rect.left + 8, ufos[collision_count].rect.top + 8, gray_particle_image)
                            player_hit = True
                        if player_bottom.rect.colliderect((ufos[collision_count].rect.left + 5, ufos[collision_count].rect.top + 5, 24, 24)):        
                            ufos[collision_count].active = 0
                            create_particles(15, ufos[collision_count].rect.left + 8, ufos[collision_count].rect.top + 8, gray_particle_image)
                            player_hit = True

                # Have any enemy bullets collided with player?
                for collision_count in range (MAX_ENEMY_BULLETS):
                    if player_bullets[collision_count].active == True:
                        if player_side.rect.colliderect((player_bullets[collision_count].rect.left, player_bullets[collision_count].rect.top, 8, 8)):        
                            player_bullets[collision_count].active = 0
                            player_hit = True
                        if player_bottom.rect.colliderect((player_bullets[collision_count].rect.left, player_bullets[collision_count].rect.top, 8, 8)):        
                            player_bullets[collision_count].active = 0
                            player_hit = True

                # Has player been hit by anything nasty?
                if player_hit == True and game_over == False:          
                    player_shield -= 1
                    create_particles(5, 85 + ((player_shield) * 11), 32, red_particle_image)                    
                    player_flash_timer = 50
                    damage_sound.play()                
                        
                    if player_shield == 0:
                        player_dead_sound.play()
                        create_particles(20, player_bottom.rect.left + 8, player_bottom.rect.top + 8, red_particle_image)
                        create_particles(20, player_bottom.rect.left + 8, player_bottom.rect.top + 8, yellow_particle_image)
                        create_particles(20, player_side.rect.left + 8, player_side.rect.top + 8, red_particle_image)
                        create_particles(20, player_side.rect.left + 8, player_side.rect.top + 8, yellow_particle_image)
                        game_over = True

            # Display hud stuff
            screen.blit(game_font.render("Score: " + str(player_score), 0, ((255, 206, 0))), (10, 10))
            screen.blit(game_font.render("High Score: " + str(high_score), 0, ((255, 206, 0))), (460, 10))

	    #NOTE: BOOKMARK HERE!
            # Beaten high score?
            if player_score > high_score:
                high_score = player_score
                # Make a little fuss of the player :)
                if BEATEN_HIGH_SCORE == False:
                    BEATEN_HIGH_SCORE = True
                    for count in range(5):
                        create_particles(5, 460 + (count * 15), 15, yellow_particle_image)                        
                
            if wave_break > 0:
                wave_break -= 1
                if game_over == False:
                    screen.blit(game_font_large.render("Wave " + str(game_wave) + " of 9", 0, ((255, 206, 0))), (240, SCREEN_HEIGHT / 2 - 36))        

	    for count in range(player_shield):
		screen.blit(game_font.render("Shields:", 0, ((255, 206, 0))), (10, 30))
		screen.blit(player_health_image, (85 + (count * 11), 32))

            if game_over == True:
                # Loss or victory?
                if game_victory == False:
                    screen.blit(game_font_large.render("GAME OVER", 0, ((176, 0, 0))), (260, SCREEN_HEIGHT / 2 - 36))
                else:
                    screen.blit(game_font_large.render("YOU ARE AWESOME!!!", 0, ((255, 206, 0))), (160, SCREEN_HEIGHT / 2 - 36))
                    game_victory_particle_timer += 1
                    if game_victory_particle_timer > 10:
                        create_particles(30, random.randint(160, 450), random.randint(160, 300), red_particle_image)                       
                        
                game_over_timer -= 1
                if game_over_timer == 0:
                    game_mode = TITLE_SCREEN_MODE
                    
            # Time for a new wave? Only start new wave display when all enemies are dead
            enemies_onscreen = False
            for count in range(MAX_ENEMIES):
                if invaders[count].active == True:
                    enemies_onscreen = True
                    break
                if shooter_invaders[count].active == True:
                    enemies_onscreen = True
                    break
                if transient_invaders[count].active == True:
                    enemies_onscreen = True
                    break
                
            for count in range(MAX_UFOS):
                if ufos[count].active == True:
                    enemies_onscreen = True

            if enemy_killed > wave_target_kills and enemies_onscreen == False and game_over == False:
                wave_break = 300
                wave_target_kills += 10
                game_wave += 1
                if game_wave == 10:
                    game_over = True
                    game_victory = True
                    game_over_timer = 700
                    win_sound.play()
                    
                enemy_killed = 0
               
                # Make the next round a bit harder :)
                if attack_max > 30:
                    attack_max -= 10
                if ufo_attack_max > 0:
                    ufo_attack_max -= 50
                if game_wave > 6:
                    player_fire_rate = 10
                wave_sound.play()

        pygame.display.flip()

        clock.tick(FPS)

		#    # Game Hack..
                #    if event.key == pygame.K_t:
		#	player_flash_on = True
		#	player_flash_timer = 50000

    pygame.quit()
예제 #2
0
def main():

    def create_particles(number, x, y, image):
        for count in range(number):
            for particle_count in range(MAX_PARTICLES):
                if particles[particle_count].active == False:
                    particles[particle_count].active = True
                    particles[particle_count].image = image
                    particles[particle_count].rect.left = x
                    particles[particle_count].rect.top = y
                    # Bigger number == bigger range explosion
                    if number > 15:
                        particles[particle_count].move_count = random.randint(20, 30)
                    else:
                        particles[particle_count].move_count = random.randint(10, 17)
                        
                    if random.randint(0, 10) > 5:
                        particles[particle_count].vector_x = 0 - random.randint(0, 4) 
                        particles[particle_count].vector_y = 0 - random.randint(0, 4)
                    else:
                        particles[particle_count].vector_x = random.randint(0, 4) 
                        particles[particle_count].vector_y = random.randint(0, 4)
                    break
    
    # Some constants
    SCREEN_WIDTH = 640
    SCREEN_HEIGHT = 480
    FPS = 60
    STARS = 18
    PLAYER_BULLETS = 40

    MAX_BADDIES = 15    
    MAX_UFOS = 1
    MAX_BADDIE_BULLETS = 30

    MAX_PARTICLES = 200

    TITLE_SCREEN_MODE = 2
    GAME_MODE = 1

    high_score = 750000
    beaten_high_score = False
    
    # Some game control stuff
    attack_timer = 0
    attack_max = 70
    ufo_attack_timer = 0
    ufo_attack_max = 500
    max_baddie_speed = 2
    max_ufo_speed = 2
    show_smiley = False 
    
    game_wave = 1
    baddies_killed = 0
    wave_break = 100
    wave_target_kills = 50
    game_over = False
    game_over_timer = 500
    game_victory = False
    game_victory_particle_timer = 0
    game_mode = TITLE_SCREEN_MODE
    
    baddie_fire_timer = 0
    baddie_fire_max = 50

    title_freeplay_timer = 0
    title_freeplay_on = False

    title_menu_choice = 0
        
    # Init the pygame library and sort the display
    pygame.init() 
    screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT])
    pygame.display.set_caption("CrossFire")
    clock = pygame.time.Clock()

    # Show loading message...
    game_font = pygame.font.Font(os.path.join("data", "04b_25__.ttf"), 18)
    screen.fill((0,0,0))
    screen.blit(game_font.render("Loading....", 0, ((176, 0, 0))), (270, SCREEN_HEIGHT / 2 - 36))
    pygame.display.flip()
    
    # Sort the sound driver
    pygame.mixer.quit()
    sound = pygame.mixer.init()
    
    player_shoot_sound = pygame.mixer.Sound(os.path.join("data", "lazer1.wav"))
    ufo_sound = pygame.mixer.Sound(os.path.join("data", "ufo.wav"))
    ufo_sound.set_volume(0.35)
    baddie_shoot_sound = pygame.mixer.Sound(os.path.join("data", "shoot2.wav"))
    wave_sound = pygame.mixer.Sound(os.path.join("data", "newwave.wav"))
    baddie_splosion = pygame.mixer.Sound(os.path.join("data", "explode1.wav"))
    player_boom_1 = pygame.mixer.Sound(os.path.join("data", "damage.wav"))
    player_boom_2 = pygame.mixer.Sound(os.path.join("data", "player_dead.wav"))
    menu_move_sound = pygame.mixer.Sound(os.path.join("data", "menu_move.wav"))
    exit_sound = pygame.mixer.Sound(os.path.join("data", "exit.wav"))
    start_sound = pygame.mixer.Sound(os.path.join("data", "start.wav"))
    win_sound = pygame.mixer.Sound(os.path.join("data", "win.wav"))
    
    # Load the gfx in
    invader_image = pygame.image.load(os.path.join("data", "invader.png")).convert()
    redinvader_image = pygame.image.load(os.path.join("data", "redthing.png")).convert()
    drone_image = pygame.image.load(os.path.join("data", "thingy.png")).convert()
    ufo_image = pygame.image.load(os.path.join("data", "ufo.png")).convert()
    player_bullet_image = pygame.image.load(os.path.join("data", "bullet1.png")).convert()
    game_font = pygame.font.Font(os.path.join("data", "04b_25__.ttf"), 18)
    game_font_large = pygame.font.Font(os.path.join("data", "04b_25__.ttf"), 36)
    game_font_xl = pygame.font.Font(os.path.join("data", "04b_25__.ttf"), 46)
    baddie_bullet_image = pygame.image.load(os.path.join("data", "bullet2.png")).convert()
    player_health_image = pygame.Surface((8, 16))
    player_health_image.fill((176, 0, 0))

    # Create some particle images
    red_particle_image = pygame.Surface((8, 8))
    red_particle_image.fill((176, 0, 0))
    green_particle_image = pygame.Surface((8, 8))
    green_particle_image.fill((31, 92, 14))
    blue_particle_image = pygame.Surface((8, 8))
    blue_particle_image.fill((46, 102, 187))
    gray_particle_image = pygame.Surface((8, 8))
    gray_particle_image.fill((88, 88, 88))
    yellow_particle_image = pygame.Surface((8, 8))
    yellow_particle_image.fill((255, 206, 0))

    # Setup the player objects
    player_bottom = PlayerBottom(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_WIDTH / 2, SCREEN_HEIGHT - 35)
    player_side = PlayerSide(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_WIDTH -35, SCREEN_HEIGHT / 2)
    player_fire_rate = 5
    player_fire_delay_left = 0
    player_fire_delay_right = 0
    player_score = 0
    player_shield = 9
    player_flash_timer = 0
    player_flash_on = False
    
    # Prepare the player pointed projectiles!
    player_bullets = []
    for count in range(PLAYER_BULLETS):
        player_bullets.append(Projectile(SCREEN_WIDTH, SCREEN_HEIGHT, player_bullet_image))
        player_bullets[count].active = False

    # Baddie bullets
    baddie_bullets = []
    for count in range(MAX_BADDIE_BULLETS):
        baddie_bullets.append(Projectile(SCREEN_WIDTH, SCREEN_HEIGHT, baddie_bullet_image))
        baddie_bullets[count].active = False

    # Setup the starfield
    stars = []    
    for count in range(STARS / 3):
        stars.append(Star(SCREEN_WIDTH, SCREEN_HEIGHT, random.randint(0, SCREEN_WIDTH),  random.randint(0, SCREEN_HEIGHT) , 4, (175, 175, 175)))        
    for count in range(STARS / 3):
        stars.append(Star(SCREEN_WIDTH, SCREEN_HEIGHT, random.randint(0, SCREEN_WIDTH),  random.randint(0, SCREEN_HEIGHT) , 3, (88, 88, 88)))        
    for count in range(STARS / 3):
        stars.append(Star(SCREEN_WIDTH, SCREEN_HEIGHT, random.randint(0, SCREEN_WIDTH),  random.randint(0, SCREEN_HEIGHT) , 1, (88, 88, 88)))        

    # Prepare the various baddies (max of 9 each)
    invaders = []
    red_invaders = []
    drones = []
    
    for count in range(MAX_BADDIES):
        # Green invaders
        invaders.append(Baddie(SCREEN_WIDTH, SCREEN_HEIGHT, invader_image))
        invaders[count].rect.top = 0
        invaders[count].rect.left = 0
        invaders[count].vector_x = 0
        invaders[count].vector_y = 0
        invaders[count].active = False
        invaders[count].anim_max_frame = 3
        invaders[count].movement_type = 0 

        # Red invaders 
        red_invaders.append(Baddie(SCREEN_WIDTH, SCREEN_HEIGHT, redinvader_image))
        red_invaders[count].rect.top = 0
        red_invaders[count].rect.left = 0
        red_invaders[count].vector_x = 0
        red_invaders[count].vector_y = 0
        red_invaders[count].active = False
        red_invaders[count].anim_max_frame = 3
        red_invaders[count].movement_type =0 

        # Drone things
        drones.append(Baddie(SCREEN_WIDTH, SCREEN_HEIGHT, drone_image))
        drones[count].rect.top = 0
        drones[count].rect.left = 0
        drones[count].vector_x = 0
        drones[count].vector_y = 0
        drones[count].active = False
        drones[count].anim_max_frame = 3
        drones[count].movement_type = 1 

    ufos = []
    for count in range(MAX_UFOS):
        ufos.append(Baddie(SCREEN_WIDTH, SCREEN_HEIGHT, ufo_image))
        ufos[count].anim_max_frame = 9

    # Setup particles
    particles = []
    for count in range(MAX_PARTICLES):
        particles.append(Particle(SCREEN_WIDTH, SCREEN_HEIGHT, red_particle_image))
        particles[count].active = False
    
    # Here we go..... main loop time
    # ------------------------------
    main_loop = True    
    baddies_onscreen = False
    
    while main_loop:
        
        # Clear the screen (NOTE: This is not particularly efficient, but deadline is looming!)
        screen.fill((0,0,0)) 

        # Process the stars
        for count in range(STARS):
            stars[count].update()
            screen.blit(stars[count].image, stars[count].rect)

        # Are we in game or at the title screen?    
        if game_mode == TITLE_SCREEN_MODE:

            #####################
            # TITLE SCREEN MODE #
            #####################
            screen.blit(game_font_xl.render("CrossFire", 0, ((255, 206, 0))), (230, 100))

            # Toggle little 'insert coin' message. It was originally 'Freeplay Mode' but I liked 'insert coin' more :)
            title_freeplay_timer += 1
            if title_freeplay_timer > 30:
                title_freeplay_timer = 0
                if title_freeplay_on == True:
                    title_freeplay_on = False
                else:
                    title_freeplay_on = True
    
            if title_freeplay_on == True:
                screen.blit(game_font.render("Insert Coin", 0, ((175, 175, 175))), (280, 380))

            if title_menu_choice == 0:
                screen.blit(game_font.render("Start", 0, ((255, 206, 0))), (300, 225))
            else:
                screen.blit(game_font.render("Start", 0, ((176, 0, 0))), (300, 225))           
                
            if title_menu_choice == 1:
                screen.blit(game_font.render("Exit", 0, ((255, 206, 0))), (308, 250))
            else:
                screen.blit(game_font.render("Exit", 0, ((176, 0, 0))), (308, 250))

            screen.blit(game_font.render("Z and X to fire, cursor keys control both ships", 0, ((176, 0, 0))), (120, 450))
                
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    main_loop = False
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_UP:
                        menu_move_sound.play()
                        title_menu_choice -= 1
                        if title_menu_choice < 0:
                            title_menu_choice = 0

                    if event.key == pygame.K_DOWN:
                        title_menu_choice += 1
                        menu_move_sound.play()
                        if title_menu_choice > 1:
                            title_menu_choice = 1
                                                        
                    if event.key == pygame.K_ESCAPE:
                        main_loop = False
                   
                    if event.key == pygame.K_z or event.key == pygame.K_x or event.key == pygame.K_SPACE or event.key == pygame.K_RETURN:
                        if title_menu_choice == 0:
                            # Start new game... reset values to defaults
                            start_sound.play()
                            attack_timer = 0
                            attack_max = 90
                            ufo_attack_timer = 0
                            ufo_attack_max = 500
                            max_baddie_speed = 2
                            max_ufo_speed = 2
                            show_smiley = False                             
                            game_wave = 1
                            beaten_high_score = False
                            baddies_killed = 0
                            wave_break = 100
                            wave_target_kills = 30
                            game_over = False
                            game_over_timer = 500
                            game_mode = GAME_MODE
                            game_victory = False
                            game_victory_particle_timer = 0
                            baddie_fire_timer = 0
                            baddie_fire_max = 50
                            player_fire_rate = 5
                            player_fire_delay_left = 0
                            player_fire_delay_right = 0
                            player_score = 0
                            player_shield = 9
                            player_flash_timer = 0
                            player_flash_on = False

                            # Make sure all the baddies, bullets and particles are deactivated
                            for count in range(MAX_BADDIES):
                                invaders[count].active = False
                                red_invaders[count].active = False
                                drones[count].active = False

                            for count in range(PLAYER_BULLETS):
                                player_bullets[count].active = False

                            for count in range(MAX_UFOS):
                                ufos[count].active = False

                            for count in range(MAX_BADDIE_BULLETS):
                                baddie_bullets[count].active = False

                            for count in range(MAX_PARTICLES):
                                particles[count].active = False
                                                            
                        if title_menu_choice == 1:
                            exit_sound.play()
                            main_loop = False
        else:
            
            #############
            # GAME MODE #
            #############
            # Grab all of the events and search for ones we are interested in, such as keyboard presses
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    main_loop = False
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        game_mode = TITLE_SCREEN_MODE
                    # Has bottom player fired?
                    if event.key == pygame.K_z and player_fire_delay_left > player_fire_rate and game_over == False:
                        # Pop off a few projectiles...                    
                        for count in range(PLAYER_BULLETS):
                            if (player_bullets[count].active == False): # Find a 'free' bullet for the bottom ship
                                player_bullets[count].active = True
                                player_bullets[count].rect.top = player_bottom.rect.top
                                player_bullets[count].rect.left = player_bottom.rect.left + 12
                                player_bullets[count].vector_x = 0
                                player_bullets[count].vector_y = -9
                                player_fire_delay_left = 0
                                player_shoot_sound.play()                                
                                break
                    # Has side player fired
                    if event.key == pygame.K_x and player_fire_delay_right > player_fire_rate and game_over == False:
                        for count in range(PLAYER_BULLETS):
                            if (player_bullets[count].active == False):
                                player_bullets[count].active = True
                                player_bullets[count].rect.top = player_side.rect.top + 12
                                player_bullets[count].rect.left = player_side.rect.left
                                player_bullets[count].vector_x = -9
                                player_bullets[count].vector_y = 0
                                player_fire_delay_right = 0
                                player_shoot_sound.play()                            
                                break
                            
                    if event.key == pygame.K_F9:
                        show_smiley = True                       
        
            if show_smiley:
                screen.blit(game_font_large.render("c:)", 0, ((255, 0, 0))), (SCREEN_WIDTH /2 , 10))
            
            # Manage baddie creation...
            attack_timer += 1
            ufo_attack_timer += 1
                    
            # Time for an attack?
            if attack_timer > attack_max and wave_break < 1 and baddies_killed < wave_target_kills and game_over == False:
                # Time for a new attack formation from the side... how many free baddies are there?
                attack_timer = 0            
                # Which baddie? Pick randomly... 0 = Green Invader, 1 = Drone, 2 = Red Invader                                        
                if game_wave > 2:                    
                    baddie_type = random.randint(0,2)
                else:
                    baddie_type = random.randint(0,1)
                    
                direction = random.randint(0, 1)
                if baddie_type == 0:
                    for count in range(MAX_BADDIES):  
                        if invaders[count].active == False:                                                    
                            if direction == 0: # from left
                                invaders[count].rect.left = -32
                                invaders[count].rect.top = random.randint(0, (SCREEN_HEIGHT - 64) / 32) * 32
                                invaders[count].vector_x = max_baddie_speed
                                invaders[count].vector_y = 0
                                invaders[count].active = True
                                break
                            else:
                                # from top
                                invaders[count].rect.left = random.randint(0, (SCREEN_WIDTH - 64) / 32) * 32
                                invaders[count].rect.top = -32
                                invaders[count].vector_x = 0
                                invaders[count].vector_y = max_baddie_speed
                                invaders[count].active = True
                                break
                elif baddie_type == 1:
                    for count in range(MAX_BADDIES):  
                        if drones[count].active == False:                                                                            
                            if direction == 0: # from left
                                drones[count].rect.left = -32
                                drones[count].rect.top = random.randint(0, (SCREEN_HEIGHT - 64) / 32) * 32
                                drones[count].vector_x = max_baddie_speed
                                drones[count].vector_y = 0
                                drones[count].active = True
                                drones[count].movement_type = 2
                                break
                            else:
                                # from top
                                drones[count].rect.left = random.randint(0, (SCREEN_WIDTH - 64) / 32) * 32
                                drones[count].rect.top = -32
                                drones[count].vector_x = 0
                                drones[count].vector_y = max_baddie_speed
                                drones[count].active = True
                                drones[count].movement_type = 1
                                break        
                elif baddie_type == 2:
                    for count in range(MAX_BADDIES):  
                        if red_invaders[count].active == False:                                                                            
                            if direction == 0: # from left
                                red_invaders[count].rect.left = -32
                                red_invaders[count].rect.top = random.randint(0, (SCREEN_HEIGHT - 64) / 32) * 32
                                red_invaders[count].vector_x = max_baddie_speed
                                red_invaders[count].vector_y = random.randint(0, 1) - random.randint(0, 1)
                                red_invaders[count].active = True
                                break
                            else:
                                # from top
                                red_invaders[count].rect.left = random.randint(0, (SCREEN_WIDTH - 64) / 32) * 32
                                red_invaders[count].rect.top = -32
                                red_invaders[count].vector_x = random.randint(0, 1) - random.randint(0, 1)
                                red_invaders[count].vector_y = max_baddie_speed
                                red_invaders[count].active = True
                                break
                            
            # Handle ufo attacks
            for count in range(MAX_UFOS):
                if ufos[count].active == False and ufo_attack_timer > ufo_attack_max and wave_break < 1 and game_over == False:
                    ufo_attack_timer = 0
                    ufo_sound.play()
                    # Pick a random direction
                    if random.randint(0, 10) > 4:
                        # Attack the side player
                        if random.randint(0, 10) > 4:
                            ufos[count].rect.top = -32
                            ufos[count].rect.left = SCREEN_WIDTH - 32
                            ufos[count].vector_y = max_ufo_speed
                            ufos[count].vector_x = 0
                            ufos[count].active = True
                        else:
                            ufos[count].rect.top = SCREEN_HEIGHT + 32
                            ufos[count].rect.left = SCREEN_WIDTH -32
                            ufos[count].vector_y = - max_ufo_speed
                            ufos[count].vector_x = 0
                            ufos[count].active = True
                    else:
                        # Attack the bottom player
                        if random.randint(0, 10) > 4:
                            ufos[count].rect.top = SCREEN_HEIGHT - 32
                            ufos[count].rect.left = -32
                            ufos[count].vector_x = max_ufo_speed
                            ufos[count].vector_y = 0
                            ufos[count].active = True            
                        else:
                            ufos[count].rect.top = SCREEN_HEIGHT -32
                            ufos[count].rect.left = SCREEN_WIDTH + 32                        
                            ufos[count].vector_x = 0 - max_ufo_speed
                            ufos[count].vector_y = 0
                            ufos[count].active = True                                        
                        
            # Process particles
            for count in range(MAX_PARTICLES):
                if particles[count].active == True:
                    particles[count].update()
                    screen.blit(particles[count].image, particles[count].rect)
                    
            # Process the player objects
            player_bottom.update()
            player_side.update()
        
            # Is player recovering from damage?
            if player_flash_timer > 0:
                player_flash_timer -= 1
                if player_flash_on == True:
                    player_flash_on = False
                else:
                    player_flash_on = True
            else:
                player_flash_on = False
                
            if player_flash_on == False and game_over == False:
                screen.blit(player_bottom.image, player_bottom.rect)
                screen.blit(player_side.image, player_side.rect)
            
            # Handle all of the player projectiles
            for count in range(PLAYER_BULLETS):
                if (player_bullets[count].active):
                    player_bullets[count].update()
                    screen.blit(player_bullets[count].image, player_bullets[count].rect)            

            # Handle all of the baddie projectiles
            for count in range(MAX_BADDIE_BULLETS):
                if (baddie_bullets[count].active == True):
                    baddie_bullets[count].update()            
                    screen.blit(baddie_bullets[count].image, baddie_bullets[count].rect)            
            
            # Slight delay for players fire rate
            player_fire_delay_left += 1
            player_fire_delay_right += 1                                

            # Move and draw the invaders
            for count in range(MAX_BADDIES):            
                if invaders[count].active:
                    invaders[count].update()
                    screen.blit(invaders[count].image, invaders[count].rect, (32 * invaders[count].anim_frame, 0, 32, 32))
                    # Has invader collided with a player bullet?
                    for collision_count in range(PLAYER_BULLETS):
                        if player_bullets[collision_count].active == True:
                            # Have to use a bit of jiggery pokery on the collision because the sprite.rect won't work as it is (too wide due to animation frames)
                            if player_bullets[collision_count].rect.colliderect((invaders[count].rect.left, invaders[count].rect.top, 32, 32)):        
                                invaders[count].active = False
                                player_score += 2000;
                                player_bullets[collision_count].active = False
                                baddies_killed += 1
                                baddie_splosion.play()
                                create_particles(15, invaders[count].rect.left + 8, invaders[count].rect.top + 8, green_particle_image)
                                
            # Move and draw the red invaders
            for count in range(MAX_BADDIES):            
                if red_invaders[count].active:
                    red_invaders[count].update()
                    screen.blit(red_invaders[count].image, red_invaders[count].rect, (32 * red_invaders[count].anim_frame, 0, 32, 32))
                    # Has invader collided with a player bullet?
                    for collision_count in range(PLAYER_BULLETS):
                        if player_bullets[collision_count].active == True:
                            # Have to use a bit of jiggery pokery on the collision because the sprite.rect won't work as it is (too wide due to animation frames)
                            if player_bullets[collision_count].rect.colliderect((red_invaders[count].rect.left, red_invaders[count].rect.top, 32, 32)):        
                                red_invaders[count].active = False
                                player_score += 4750;
                                player_bullets[collision_count].active = False
                                baddies_killed += 1   
                                baddie_splosion.play()
                                create_particles(15, red_invaders[count].rect.left + 8, red_invaders[count].rect.top + 8, red_particle_image)
                                
            # Time for red invaders to shoot?
            baddie_fire_timer += 1
            if baddie_fire_timer > baddie_fire_max and game_over == False:
                baddie_fire_timer = 0
                for count in range(MAX_BADDIES):
                    if red_invaders[count].active == True and red_invaders[count].rect.top < SCREEN_HEIGHT - 50 and red_invaders[count].rect.top > 50:
                        baddie_shoot_sound.play()
                        bullets = 0
                        for bullet_count in range(MAX_BADDIE_BULLETS):
                            if baddie_bullets[bullet_count].active == False:
                                if random.randint(0,10) > 4:
                                    baddie_bullets[bullet_count].active = True
                                    baddie_bullets[bullet_count].rect.top = red_invaders[count].rect.top + 8
                                    baddie_bullets[bullet_count].rect.left = red_invaders[count].rect.left + 12
                                    baddie_bullets[bullet_count].vector_x = 7
                                    baddie_bullets[bullet_count].vector_y = 0 
                                    break
                                else:
                                    baddie_bullets[bullet_count].active = True
                                    baddie_bullets[bullet_count].rect.top = red_invaders[count].rect.top +16
                                    baddie_bullets[bullet_count].rect.left = red_invaders[count].rect.left + 8
                                    baddie_bullets[bullet_count].vector_x = 0
                                    baddie_bullets[bullet_count].vector_y = 7
                                    break
                            
            # Move and draw the ufo
            for count in range(MAX_UFOS):
                if ufos[count].active == True:
                    ufos[count].update()
                    screen.blit(ufos[count].image, ufos[count].rect, (32 * ufos[count].anim_frame, 0, 32, 32))
                    # Has invader collided with a ufo?
                    for collision_count in range(PLAYER_BULLETS):
                        if player_bullets[collision_count].active == True:                        
                            if player_bullets[collision_count].rect.colliderect((ufos[count].rect.left, ufos[count].rect.top, 32, 32)):        
                                ufos[count].active = False
                                player_score += 3250
                                player_bullets[collision_count].active = False
                                baddies_killed += 1
                                baddie_splosion.play()
                                create_particles(15, ufos[count].rect.left + 8, ufos[count].rect.top + 8, gray_particle_image)

            # Move and draw the drones
            for count in range(MAX_BADDIES):            
                if drones[count].active:
                    drones[count].update()
                    screen.blit(drones[count].image, drones[count].rect, (32 * drones[count].anim_frame, 0, 32, 32))
                    # Has invader collided with a player bullet?
                    for collision_count in range(PLAYER_BULLETS):
                        if player_bullets[collision_count].active == True:
                            # Have to use a bit of jiggery pokery on the collision because the sprite.rect won't work as it is (too wide due to animation frames)
                            if player_bullets[collision_count].rect.colliderect((drones[count].rect.left, drones[count].rect.top, 32, 32)):        
                                drones[count].active = False
                                player_score += 2500;
                                player_bullets[collision_count].active = False
                                baddies_killed += 1
                                baddie_splosion.play()
                                create_particles(15, drones[count].rect.left + 8, drones[count].rect.top + 8, blue_particle_image)

            # Check for baddie to player collisions
            if player_flash_timer < 1 and game_over == False:
                player_hit = False
                for collision_count in range(MAX_BADDIES):
                    # Have any invaders collided with player?
                    if invaders[collision_count].active == True:
                        if player_side.rect.colliderect((invaders[collision_count].rect.left + 5, invaders[collision_count].rect.top + 5, 24, 24)):        
                            invaders[collision_count].active = False
                            create_particles(15, invaders[collision_count].rect.left + 8, invaders[collision_count].rect.top + 8, green_particle_image)
                            player_hit = True
                        if player_bottom.rect.colliderect((invaders[collision_count].rect.left + 5, invaders[collision_count].rect.top + 5, 24, 24)):        
                            invaders[collision_count].active = False
                            create_particles(15, invaders[collision_count].rect.left + 8, invaders[collision_count].rect.top + 8, green_particle_image)
                            player_hit = True
                            
                    # Have any drones collided with player?
                    if red_invaders[collision_count].active == True:
                        if player_side.rect.colliderect((red_invaders[collision_count].rect.left + 5, red_invaders[collision_count].rect.top + 5, 24, 24)):        
                            red_invaders[collision_count].active = False
                            create_particles(15, red_invaders[collision_count].rect.left + 8, red_invaders[collision_count].rect.top + 8, red_particle_image)
                            player_hit = True
                        if player_bottom.rect.colliderect((red_invaders[collision_count].rect.left + 5, red_invaders[collision_count].rect.top + 5, 24, 24)):        
                            red_invaders[collision_count].active = False
                            create_particles(15, red_invaders[collision_count].rect.left + 8, red_invaders[collision_count].rect.top + 8, red_particle_image)
                            player_hit = True
                            
                    # Have any drones collided with player?
                    if drones[collision_count].active == True:
                        if player_side.rect.colliderect((drones[collision_count].rect.left + 5, drones[collision_count].rect.top + 5, 24, 24)):        
                            drones[collision_count].active = False                    
                            create_particles(15, drones[collision_count].rect.left + 8, drones[collision_count].rect.top + 8, blue_particle_image)
                            player_hit = True
                        if player_bottom.rect.colliderect((drones[collision_count].rect.left + 5, drones[collision_count].rect.top + 5, 24, 24)):        
                            drones[collision_count].active = False
                            create_particles(15, drones[collision_count].rect.left + 8, drones[collision_count].rect.top + 8, blue_particle_image)
                            player_hit = True

                # Have any ufos collided with player?
                for collision_count in range (MAX_UFOS):
                    if ufos[collision_count].active == True:
                        if player_side.rect.colliderect((ufos[collision_count].rect.left + 5, ufos[collision_count].rect.top + 5, 24, 24)):        
                            ufos[collision_count].active = 0
                            create_particles(15, ufos[collision_count].rect.left + 8, ufos[collision_count].rect.top + 8, gray_particle_image)
                            player_hit = True
                        if player_bottom.rect.colliderect((ufos[collision_count].rect.left + 5, ufos[collision_count].rect.top + 5, 24, 24)):        
                            ufos[collision_count].active = 0
                            create_particles(15, ufos[collision_count].rect.left + 8, ufos[collision_count].rect.top + 8, gray_particle_image)
                            player_hit = True

                # Have any enemy bullets collided with player?
                for collision_count in range (MAX_BADDIE_BULLETS):
                    if baddie_bullets[collision_count].active == True:
                        if player_side.rect.colliderect((baddie_bullets[collision_count].rect.left, baddie_bullets[collision_count].rect.top, 8, 8)):        
                            baddie_bullets[collision_count].active = 0
                            player_hit = True
                        if player_bottom.rect.colliderect((baddie_bullets[collision_count].rect.left, baddie_bullets[collision_count].rect.top, 8, 8)):        
                            baddie_bullets[collision_count].active = 0
                            player_hit = True

                # Has player been hit by anything nasty?
                if player_hit == True and game_over == False:          
                    player_shield -= 1
                    create_particles(5, 85 + ((player_shield) * 11), 32, red_particle_image)                    
                    player_flash_timer = 50
                    player_boom_1.play()                
                        
                    if player_shield == 0:
                        player_boom_2.play()
                        create_particles(20, player_bottom.rect.left + 8, player_bottom.rect.top + 8, red_particle_image)
                        create_particles(20, player_bottom.rect.left + 8, player_bottom.rect.top + 8, yellow_particle_image)
                        create_particles(20, player_side.rect.left + 8, player_side.rect.top + 8, red_particle_image)
                        create_particles(20, player_side.rect.left + 8, player_side.rect.top + 8, yellow_particle_image)
                        game_over = True

            # Display hud stuff
            screen.blit(game_font.render("Score: " + str(player_score), 0, ((255, 206, 0))), (10, 10))
            screen.blit(game_font.render("High Score: " + str(high_score), 0, ((255, 206, 0))), (460, 10))

            # Beaten high score?
            if player_score > high_score:
                high_score = player_score
                # Make a little fuss of the player :)
                if beaten_high_score == False:
                    beaten_high_score = True
                    for count in range(5):
                        create_particles(5, 460 + (count * 15), 15, yellow_particle_image)                        
                
            if wave_break > 0:
                wave_break -= 1
                if game_over == False:
                    screen.blit(game_font_large.render("Wave " + str(game_wave) + " of 9", 0, ((255, 206, 0))), (240, SCREEN_HEIGHT / 2 - 36))        

            for count in range(player_shield):
                screen.blit(game_font.render("Shields:", 0, ((255, 206, 0))), (10, 30))
                screen.blit(player_health_image, (85 + (count * 11), 32))
            
            if game_over == True:
                # Loss or victory?
                if game_victory == False:
                    screen.blit(game_font_large.render("GAME OVER", 0, ((176, 0, 0))), (260, SCREEN_HEIGHT / 2 - 36))
                else:
                    screen.blit(game_font_large.render("YOU ARE AWESOME!!!", 0, ((255, 206, 0))), (160, SCREEN_HEIGHT / 2 - 36))
                    game_victory_particle_timer += 1
                    if game_victory_particle_timer > 10:
                        create_particles(30, random.randint(160, 450), random.randint(160, 300), red_particle_image)                       
                        
                game_over_timer -= 1
                if game_over_timer == 0:
                    game_mode = TITLE_SCREEN_MODE
                    
            # Time for a new wave? Only start new wave display when all baddies are dead
            baddies_onscreen = False
            for count in range(MAX_BADDIES):
                if invaders[count].active == True:
                    baddies_onscreen = True
                    break
                if red_invaders[count].active == True:
                    baddies_onscreen = True
                    break
                if drones[count].active == True:
                    baddies_onscreen = True
                    break
                
            for count in range(MAX_UFOS):
                if ufos[count].active == True:
                    baddies_onscreen = True

            if baddies_killed > wave_target_kills and baddies_onscreen == False and game_over == False:
                wave_break = 300
                wave_target_kills += 10
                game_wave += 1
                if game_wave == 10:
                    game_over = True
                    game_victory = True
                    game_over_timer = 700
                    win_sound.play()
                    
                baddies_killed = 0
                
                # Make the next round a bit harder :)
                if attack_max > 30:
                    attack_max -= 10
                if ufo_attack_max > 0:
                    ufo_attack_max -= 50
                if game_wave > 6:
                    baddie_fire_rate = 10
                wave_sound.play()

        # Show the newly rendered screen                
        pygame.display.flip()
        # Limit game speed
        clock.tick(FPS)
        
    # This is not strictly needed, but is included so that IDLE will play nice :)
    pygame.quit()
예제 #3
0
def main():
    def create_particles(number, x, y, image):
        for count in range(number):
            for particle_count in range(MAX_PARTICLES):
                if particles[particle_count].active == False:
                    particles[particle_count].active = True
                    particles[particle_count].image = image
                    particles[particle_count].rect.left = x
                    particles[particle_count].rect.top = y
                    # Bigger number == bigger range explosion
                    if number > 15:
                        particles[particle_count].move_count = random.randint(
                            20, 30)
                    else:
                        particles[particle_count].move_count = random.randint(
                            10, 17)

                    if random.randint(0, 10) > 5:
                        particles[
                            particle_count].vector_x = 0 - random.randint(
                                0, 4)
                        particles[
                            particle_count].vector_y = 0 - random.randint(
                                0, 4)
                    else:
                        particles[particle_count].vector_x = random.randint(
                            0, 4)
                        particles[particle_count].vector_y = random.randint(
                            0, 4)
                    break

    # Some constants
    SCREEN_WIDTH = 640
    SCREEN_HEIGHT = 480
    FPS = 60
    STARS = 18
    PLAYER_BULLETS = 40

    MAX_BADDIES = 15
    MAX_UFOS = 1
    MAX_BADDIE_BULLETS = 30

    MAX_PARTICLES = 200

    TITLE_SCREEN_MODE = 2
    GAME_MODE = 1

    high_score = 750000
    beaten_high_score = False

    # Some game control stuff
    attack_timer = 0
    attack_max = 70
    ufo_attack_timer = 0
    ufo_attack_max = 500
    max_baddie_speed = 2
    max_ufo_speed = 2
    show_smiley = False

    game_wave = 1
    baddies_killed = 0
    wave_break = 100
    wave_target_kills = 50
    game_over = False
    game_over_timer = 500
    game_victory = False
    game_victory_particle_timer = 0
    game_mode = TITLE_SCREEN_MODE

    baddie_fire_timer = 0
    baddie_fire_max = 50

    title_freeplay_timer = 0
    title_freeplay_on = False

    title_menu_choice = 0

    # Init the pygame library and sort the display
    pygame.init()
    screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT])
    pygame.display.set_caption("CrossFire")
    clock = pygame.time.Clock()

    # Show loading message...
    game_font = pygame.font.Font(os.path.join("data", "04b_25__.ttf"), 18)
    screen.fill((0, 0, 0))
    screen.blit(game_font.render("Loading....", 0, ((176, 0, 0))),
                (270, SCREEN_HEIGHT / 2 - 36))
    pygame.display.flip()

    # Sort the sound driver
    pygame.mixer.quit()
    sound = pygame.mixer.init()

    player_shoot_sound = pygame.mixer.Sound(os.path.join("data", "lazer1.wav"))
    ufo_sound = pygame.mixer.Sound(os.path.join("data", "ufo.wav"))
    ufo_sound.set_volume(0.35)
    baddie_shoot_sound = pygame.mixer.Sound(os.path.join("data", "shoot2.wav"))
    wave_sound = pygame.mixer.Sound(os.path.join("data", "newwave.wav"))
    baddie_splosion = pygame.mixer.Sound(os.path.join("data", "explode1.wav"))
    player_boom_1 = pygame.mixer.Sound(os.path.join("data", "damage.wav"))
    player_boom_2 = pygame.mixer.Sound(os.path.join("data", "player_dead.wav"))
    menu_move_sound = pygame.mixer.Sound(os.path.join("data", "menu_move.wav"))
    exit_sound = pygame.mixer.Sound(os.path.join("data", "exit.wav"))
    start_sound = pygame.mixer.Sound(os.path.join("data", "start.wav"))
    win_sound = pygame.mixer.Sound(os.path.join("data", "win.wav"))

    # Load the gfx in
    invader_image = pygame.image.load(os.path.join("data",
                                                   "invader.png")).convert()
    redinvader_image = pygame.image.load(os.path.join(
        "data", "redthing.png")).convert()
    drone_image = pygame.image.load(os.path.join("data",
                                                 "thingy.png")).convert()
    ufo_image = pygame.image.load(os.path.join("data", "ufo.png")).convert()
    player_bullet_image = pygame.image.load(os.path.join(
        "data", "bullet1.png")).convert()
    game_font = pygame.font.Font(os.path.join("data", "04b_25__.ttf"), 18)
    game_font_large = pygame.font.Font(os.path.join("data", "04b_25__.ttf"),
                                       36)
    game_font_xl = pygame.font.Font(os.path.join("data", "04b_25__.ttf"), 46)
    baddie_bullet_image = pygame.image.load(os.path.join(
        "data", "bullet2.png")).convert()
    player_health_image = pygame.Surface((8, 16))
    player_health_image.fill((176, 0, 0))

    # Create some particle images
    red_particle_image = pygame.Surface((8, 8))
    red_particle_image.fill((176, 0, 0))
    green_particle_image = pygame.Surface((8, 8))
    green_particle_image.fill((31, 92, 14))
    blue_particle_image = pygame.Surface((8, 8))
    blue_particle_image.fill((46, 102, 187))
    gray_particle_image = pygame.Surface((8, 8))
    gray_particle_image.fill((88, 88, 88))
    yellow_particle_image = pygame.Surface((8, 8))
    yellow_particle_image.fill((255, 206, 0))

    # Setup the player objects
    player_bottom = PlayerBottom(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_WIDTH / 2,
                                 SCREEN_HEIGHT - 35)
    player_side = PlayerSide(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_WIDTH - 35,
                             SCREEN_HEIGHT / 2)
    player_fire_rate = 5
    player_fire_delay_left = 0
    player_fire_delay_right = 0
    player_score = 0
    player_shield = 9
    player_flash_timer = 0
    player_flash_on = False

    # Prepare the player pointed projectiles!
    player_bullets = []
    for count in range(PLAYER_BULLETS):
        player_bullets.append(
            Projectile(SCREEN_WIDTH, SCREEN_HEIGHT, player_bullet_image))
        player_bullets[count].active = False

    # Baddie bullets
    baddie_bullets = []
    for count in range(MAX_BADDIE_BULLETS):
        baddie_bullets.append(
            Projectile(SCREEN_WIDTH, SCREEN_HEIGHT, baddie_bullet_image))
        baddie_bullets[count].active = False

    # Setup the starfield
    stars = []
    for count in range(STARS / 3):
        stars.append(
            Star(SCREEN_WIDTH, SCREEN_HEIGHT, random.randint(0, SCREEN_WIDTH),
                 random.randint(0, SCREEN_HEIGHT), 4, (175, 175, 175)))
    for count in range(STARS / 3):
        stars.append(
            Star(SCREEN_WIDTH, SCREEN_HEIGHT, random.randint(0, SCREEN_WIDTH),
                 random.randint(0, SCREEN_HEIGHT), 3, (88, 88, 88)))
    for count in range(STARS / 3):
        stars.append(
            Star(SCREEN_WIDTH, SCREEN_HEIGHT, random.randint(0, SCREEN_WIDTH),
                 random.randint(0, SCREEN_HEIGHT), 1, (88, 88, 88)))

    # Prepare the various baddies (max of 9 each)
    invaders = []
    red_invaders = []
    drones = []

    for count in range(MAX_BADDIES):
        # Green invaders
        invaders.append(Baddie(SCREEN_WIDTH, SCREEN_HEIGHT, invader_image))
        invaders[count].rect.top = 0
        invaders[count].rect.left = 0
        invaders[count].vector_x = 0
        invaders[count].vector_y = 0
        invaders[count].active = False
        invaders[count].anim_max_frame = 3
        invaders[count].movement_type = 0

        # Red invaders
        red_invaders.append(
            Baddie(SCREEN_WIDTH, SCREEN_HEIGHT, redinvader_image))
        red_invaders[count].rect.top = 0
        red_invaders[count].rect.left = 0
        red_invaders[count].vector_x = 0
        red_invaders[count].vector_y = 0
        red_invaders[count].active = False
        red_invaders[count].anim_max_frame = 3
        red_invaders[count].movement_type = 0

        # Drone things
        drones.append(Baddie(SCREEN_WIDTH, SCREEN_HEIGHT, drone_image))
        drones[count].rect.top = 0
        drones[count].rect.left = 0
        drones[count].vector_x = 0
        drones[count].vector_y = 0
        drones[count].active = False
        drones[count].anim_max_frame = 3
        drones[count].movement_type = 1

    ufos = []
    for count in range(MAX_UFOS):
        ufos.append(Baddie(SCREEN_WIDTH, SCREEN_HEIGHT, ufo_image))
        ufos[count].anim_max_frame = 9

    # Setup particles
    particles = []
    for count in range(MAX_PARTICLES):
        particles.append(
            Particle(SCREEN_WIDTH, SCREEN_HEIGHT, red_particle_image))
        particles[count].active = False

    # Here we go..... main loop time
    # ------------------------------
    main_loop = True
    baddies_onscreen = False

    while main_loop:

        # Clear the screen (NOTE: This is not particularly efficient, but deadline is looming!)
        screen.fill((0, 0, 0))

        # Process the stars
        for count in range(STARS):
            stars[count].update()
            screen.blit(stars[count].image, stars[count].rect)

        # Are we in game or at the title screen?
        if game_mode == TITLE_SCREEN_MODE:

            #####################
            # TITLE SCREEN MODE #
            #####################
            screen.blit(game_font_xl.render("CrossFire", 0, ((255, 206, 0))),
                        (230, 100))

            # Toggle little 'insert coin' message. It was originally 'Freeplay Mode' but I liked 'insert coin' more :)
            title_freeplay_timer += 1
            if title_freeplay_timer > 30:
                title_freeplay_timer = 0
                if title_freeplay_on == True:
                    title_freeplay_on = False
                else:
                    title_freeplay_on = True

            if title_freeplay_on == True:
                screen.blit(
                    game_font.render("Insert Coin", 0, ((175, 175, 175))),
                    (280, 380))

            if title_menu_choice == 0:
                screen.blit(game_font.render("Start", 0, ((255, 206, 0))),
                            (300, 225))
            else:
                screen.blit(game_font.render("Start", 0, ((176, 0, 0))),
                            (300, 225))

            if title_menu_choice == 1:
                screen.blit(game_font.render("Exit", 0, ((255, 206, 0))),
                            (308, 250))
            else:
                screen.blit(game_font.render("Exit", 0, ((176, 0, 0))),
                            (308, 250))

            screen.blit(
                game_font.render(
                    "Z and X to fire, cursor keys control both ships", 0,
                    ((176, 0, 0))), (120, 450))

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    main_loop = False
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_UP:
                        menu_move_sound.play()
                        title_menu_choice -= 1
                        if title_menu_choice < 0:
                            title_menu_choice = 0

                    if event.key == pygame.K_DOWN:
                        title_menu_choice += 1
                        menu_move_sound.play()
                        if title_menu_choice > 1:
                            title_menu_choice = 1

                    if event.key == pygame.K_ESCAPE:
                        main_loop = False

                    if event.key == pygame.K_z or event.key == pygame.K_x or event.key == pygame.K_SPACE or event.key == pygame.K_RETURN:
                        if title_menu_choice == 0:
                            # Start new game... reset values to defaults
                            start_sound.play()
                            attack_timer = 0
                            attack_max = 90
                            ufo_attack_timer = 0
                            ufo_attack_max = 500
                            max_baddie_speed = 2
                            max_ufo_speed = 2
                            show_smiley = False
                            game_wave = 1
                            beaten_high_score = False
                            baddies_killed = 0
                            wave_break = 100
                            wave_target_kills = 30
                            game_over = False
                            game_over_timer = 500
                            game_mode = GAME_MODE
                            game_victory = False
                            game_victory_particle_timer = 0
                            baddie_fire_timer = 0
                            baddie_fire_max = 50
                            player_fire_rate = 5
                            player_fire_delay_left = 0
                            player_fire_delay_right = 0
                            player_score = 0
                            player_shield = 9
                            player_flash_timer = 0
                            player_flash_on = False

                            # Make sure all the baddies, bullets and particles are deactivated
                            for count in range(MAX_BADDIES):
                                invaders[count].active = False
                                red_invaders[count].active = False
                                drones[count].active = False

                            for count in range(PLAYER_BULLETS):
                                player_bullets[count].active = False

                            for count in range(MAX_UFOS):
                                ufos[count].active = False

                            for count in range(MAX_BADDIE_BULLETS):
                                baddie_bullets[count].active = False

                            for count in range(MAX_PARTICLES):
                                particles[count].active = False

                        if title_menu_choice == 1:
                            exit_sound.play()
                            main_loop = False
        else:

            #############
            # GAME MODE #
            #############
            # Grab all of the events and search for ones we are interested in, such as keyboard presses
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    main_loop = False
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        game_mode = TITLE_SCREEN_MODE
                    # Has bottom player fired?
                    if event.key == pygame.K_z and player_fire_delay_left > player_fire_rate and game_over == False:
                        # Pop off a few projectiles...
                        for count in range(PLAYER_BULLETS):
                            if (player_bullets[count].active == False
                                ):  # Find a 'free' bullet for the bottom ship
                                player_bullets[count].active = True
                                player_bullets[
                                    count].rect.top = player_bottom.rect.top
                                player_bullets[
                                    count].rect.left = player_bottom.rect.left + 12
                                player_bullets[count].vector_x = 0
                                player_bullets[count].vector_y = -9
                                player_fire_delay_left = 0
                                player_shoot_sound.play()
                                break
                    # Has side player fired
                    if event.key == pygame.K_x and player_fire_delay_right > player_fire_rate and game_over == False:
                        for count in range(PLAYER_BULLETS):
                            if (player_bullets[count].active == False):
                                player_bullets[count].active = True
                                player_bullets[
                                    count].rect.top = player_side.rect.top + 12
                                player_bullets[
                                    count].rect.left = player_side.rect.left
                                player_bullets[count].vector_x = -9
                                player_bullets[count].vector_y = 0
                                player_fire_delay_right = 0
                                player_shoot_sound.play()
                                break

                    if event.key == pygame.K_F9:
                        show_smiley = True

            if show_smiley:
                screen.blit(game_font_large.render("c:)", 0, ((255, 0, 0))),
                            (SCREEN_WIDTH / 2, 10))

            # Manage baddie creation...
            attack_timer += 1
            ufo_attack_timer += 1

            # Time for an attack?
            if attack_timer > attack_max and wave_break < 1 and baddies_killed < wave_target_kills and game_over == False:
                # Time for a new attack formation from the side... how many free baddies are there?
                attack_timer = 0
                # Which baddie? Pick randomly... 0 = Green Invader, 1 = Drone, 2 = Red Invader
                if game_wave > 2:
                    baddie_type = random.randint(0, 2)
                else:
                    baddie_type = random.randint(0, 1)

                direction = random.randint(0, 1)
                if baddie_type == 0:
                    for count in range(MAX_BADDIES):
                        if invaders[count].active == False:
                            if direction == 0:  # from left
                                invaders[count].rect.left = -32
                                invaders[count].rect.top = random.randint(
                                    0, (SCREEN_HEIGHT - 64) / 32) * 32
                                invaders[count].vector_x = max_baddie_speed
                                invaders[count].vector_y = 0
                                invaders[count].active = True
                                break
                            else:
                                # from top
                                invaders[count].rect.left = random.randint(
                                    0, (SCREEN_WIDTH - 64) / 32) * 32
                                invaders[count].rect.top = -32
                                invaders[count].vector_x = 0
                                invaders[count].vector_y = max_baddie_speed
                                invaders[count].active = True
                                break
                elif baddie_type == 1:
                    for count in range(MAX_BADDIES):
                        if drones[count].active == False:
                            if direction == 0:  # from left
                                drones[count].rect.left = -32
                                drones[count].rect.top = random.randint(
                                    0, (SCREEN_HEIGHT - 64) / 32) * 32
                                drones[count].vector_x = max_baddie_speed
                                drones[count].vector_y = 0
                                drones[count].active = True
                                drones[count].movement_type = 2
                                break
                            else:
                                # from top
                                drones[count].rect.left = random.randint(
                                    0, (SCREEN_WIDTH - 64) / 32) * 32
                                drones[count].rect.top = -32
                                drones[count].vector_x = 0
                                drones[count].vector_y = max_baddie_speed
                                drones[count].active = True
                                drones[count].movement_type = 1
                                break
                elif baddie_type == 2:
                    for count in range(MAX_BADDIES):
                        if red_invaders[count].active == False:
                            if direction == 0:  # from left
                                red_invaders[count].rect.left = -32
                                red_invaders[count].rect.top = random.randint(
                                    0, (SCREEN_HEIGHT - 64) / 32) * 32
                                red_invaders[count].vector_x = max_baddie_speed
                                red_invaders[count].vector_y = random.randint(
                                    0, 1) - random.randint(0, 1)
                                red_invaders[count].active = True
                                break
                            else:
                                # from top
                                red_invaders[count].rect.left = random.randint(
                                    0, (SCREEN_WIDTH - 64) / 32) * 32
                                red_invaders[count].rect.top = -32
                                red_invaders[count].vector_x = random.randint(
                                    0, 1) - random.randint(0, 1)
                                red_invaders[count].vector_y = max_baddie_speed
                                red_invaders[count].active = True
                                break

            # Handle ufo attacks
            for count in range(MAX_UFOS):
                if ufos[count].active == False and ufo_attack_timer > ufo_attack_max and wave_break < 1 and game_over == False:
                    ufo_attack_timer = 0
                    ufo_sound.play()
                    # Pick a random direction
                    if random.randint(0, 10) > 4:
                        # Attack the side player
                        if random.randint(0, 10) > 4:
                            ufos[count].rect.top = -32
                            ufos[count].rect.left = SCREEN_WIDTH - 32
                            ufos[count].vector_y = max_ufo_speed
                            ufos[count].vector_x = 0
                            ufos[count].active = True
                        else:
                            ufos[count].rect.top = SCREEN_HEIGHT + 32
                            ufos[count].rect.left = SCREEN_WIDTH - 32
                            ufos[count].vector_y = -max_ufo_speed
                            ufos[count].vector_x = 0
                            ufos[count].active = True
                    else:
                        # Attack the bottom player
                        if random.randint(0, 10) > 4:
                            ufos[count].rect.top = SCREEN_HEIGHT - 32
                            ufos[count].rect.left = -32
                            ufos[count].vector_x = max_ufo_speed
                            ufos[count].vector_y = 0
                            ufos[count].active = True
                        else:
                            ufos[count].rect.top = SCREEN_HEIGHT - 32
                            ufos[count].rect.left = SCREEN_WIDTH + 32
                            ufos[count].vector_x = 0 - max_ufo_speed
                            ufos[count].vector_y = 0
                            ufos[count].active = True

            # Process particles
            for count in range(MAX_PARTICLES):
                if particles[count].active == True:
                    particles[count].update()
                    screen.blit(particles[count].image, particles[count].rect)

            # Process the player objects
            player_bottom.update()
            player_side.update()

            # Is player recovering from damage?
            if player_flash_timer > 0:
                player_flash_timer -= 1
                if player_flash_on == True:
                    player_flash_on = False
                else:
                    player_flash_on = True
            else:
                player_flash_on = False

            if player_flash_on == False and game_over == False:
                screen.blit(player_bottom.image, player_bottom.rect)
                screen.blit(player_side.image, player_side.rect)

            # Handle all of the player projectiles
            for count in range(PLAYER_BULLETS):
                if (player_bullets[count].active):
                    player_bullets[count].update()
                    screen.blit(player_bullets[count].image,
                                player_bullets[count].rect)

            # Handle all of the baddie projectiles
            for count in range(MAX_BADDIE_BULLETS):
                if (baddie_bullets[count].active == True):
                    baddie_bullets[count].update()
                    screen.blit(baddie_bullets[count].image,
                                baddie_bullets[count].rect)

            # Slight delay for players fire rate
            player_fire_delay_left += 1
            player_fire_delay_right += 1

            # Move and draw the invaders
            for count in range(MAX_BADDIES):
                if invaders[count].active:
                    invaders[count].update()
                    screen.blit(invaders[count].image, invaders[count].rect,
                                (32 * invaders[count].anim_frame, 0, 32, 32))
                    # Has invader collided with a player bullet?
                    for collision_count in range(PLAYER_BULLETS):
                        if player_bullets[collision_count].active == True:
                            # Have to use a bit of jiggery pokery on the collision because the sprite.rect won't work as it is (too wide due to animation frames)
                            if player_bullets[
                                    collision_count].rect.colliderect(
                                        (invaders[count].rect.left,
                                         invaders[count].rect.top, 32, 32)):
                                invaders[count].active = False
                                player_score += 2000
                                player_bullets[collision_count].active = False
                                baddies_killed += 1
                                baddie_splosion.play()
                                create_particles(15,
                                                 invaders[count].rect.left + 8,
                                                 invaders[count].rect.top + 8,
                                                 green_particle_image)

            # Move and draw the red invaders
            for count in range(MAX_BADDIES):
                if red_invaders[count].active:
                    red_invaders[count].update()
                    screen.blit(
                        red_invaders[count].image, red_invaders[count].rect,
                        (32 * red_invaders[count].anim_frame, 0, 32, 32))
                    # Has invader collided with a player bullet?
                    for collision_count in range(PLAYER_BULLETS):
                        if player_bullets[collision_count].active == True:
                            # Have to use a bit of jiggery pokery on the collision because the sprite.rect won't work as it is (too wide due to animation frames)
                            if player_bullets[
                                    collision_count].rect.colliderect(
                                        (red_invaders[count].rect.left,
                                         red_invaders[count].rect.top, 32,
                                         32)):
                                red_invaders[count].active = False
                                player_score += 4750
                                player_bullets[collision_count].active = False
                                baddies_killed += 1
                                baddie_splosion.play()
                                create_particles(
                                    15, red_invaders[count].rect.left + 8,
                                    red_invaders[count].rect.top + 8,
                                    red_particle_image)

            # Time for red invaders to shoot?
            baddie_fire_timer += 1
            if baddie_fire_timer > baddie_fire_max and game_over == False:
                baddie_fire_timer = 0
                for count in range(MAX_BADDIES):
                    if red_invaders[count].active == True and red_invaders[
                            count].rect.top < SCREEN_HEIGHT - 50 and red_invaders[
                                count].rect.top > 50:
                        baddie_shoot_sound.play()
                        bullets = 0
                        for bullet_count in range(MAX_BADDIE_BULLETS):
                            if baddie_bullets[bullet_count].active == False:
                                if random.randint(0, 10) > 4:
                                    baddie_bullets[bullet_count].active = True
                                    baddie_bullets[
                                        bullet_count].rect.top = red_invaders[
                                            count].rect.top + 8
                                    baddie_bullets[
                                        bullet_count].rect.left = red_invaders[
                                            count].rect.left + 12
                                    baddie_bullets[bullet_count].vector_x = 7
                                    baddie_bullets[bullet_count].vector_y = 0
                                    break
                                else:
                                    baddie_bullets[bullet_count].active = True
                                    baddie_bullets[
                                        bullet_count].rect.top = red_invaders[
                                            count].rect.top + 16
                                    baddie_bullets[
                                        bullet_count].rect.left = red_invaders[
                                            count].rect.left + 8
                                    baddie_bullets[bullet_count].vector_x = 0
                                    baddie_bullets[bullet_count].vector_y = 7
                                    break

            # Move and draw the ufo
            for count in range(MAX_UFOS):
                if ufos[count].active == True:
                    ufos[count].update()
                    screen.blit(ufos[count].image, ufos[count].rect,
                                (32 * ufos[count].anim_frame, 0, 32, 32))
                    # Has invader collided with a ufo?
                    for collision_count in range(PLAYER_BULLETS):
                        if player_bullets[collision_count].active == True:
                            if player_bullets[
                                    collision_count].rect.colliderect(
                                        (ufos[count].rect.left,
                                         ufos[count].rect.top, 32, 32)):
                                ufos[count].active = False
                                player_score += 3250
                                player_bullets[collision_count].active = False
                                baddies_killed += 1
                                baddie_splosion.play()
                                create_particles(15, ufos[count].rect.left + 8,
                                                 ufos[count].rect.top + 8,
                                                 gray_particle_image)

            # Move and draw the drones
            for count in range(MAX_BADDIES):
                if drones[count].active:
                    drones[count].update()
                    screen.blit(drones[count].image, drones[count].rect,
                                (32 * drones[count].anim_frame, 0, 32, 32))
                    # Has invader collided with a player bullet?
                    for collision_count in range(PLAYER_BULLETS):
                        if player_bullets[collision_count].active == True:
                            # Have to use a bit of jiggery pokery on the collision because the sprite.rect won't work as it is (too wide due to animation frames)
                            if player_bullets[
                                    collision_count].rect.colliderect(
                                        (drones[count].rect.left,
                                         drones[count].rect.top, 32, 32)):
                                drones[count].active = False
                                player_score += 2500
                                player_bullets[collision_count].active = False
                                baddies_killed += 1
                                baddie_splosion.play()
                                create_particles(15,
                                                 drones[count].rect.left + 8,
                                                 drones[count].rect.top + 8,
                                                 blue_particle_image)

            # Check for baddie to player collisions
            if player_flash_timer < 1 and game_over == False:
                player_hit = False
                for collision_count in range(MAX_BADDIES):
                    # Have any invaders collided with player?
                    if invaders[collision_count].active == True:
                        if player_side.rect.colliderect(
                            (invaders[collision_count].rect.left + 5,
                             invaders[collision_count].rect.top + 5, 24, 24)):
                            invaders[collision_count].active = False
                            create_particles(
                                15, invaders[collision_count].rect.left + 8,
                                invaders[collision_count].rect.top + 8,
                                green_particle_image)
                            player_hit = True
                        if player_bottom.rect.colliderect(
                            (invaders[collision_count].rect.left + 5,
                             invaders[collision_count].rect.top + 5, 24, 24)):
                            invaders[collision_count].active = False
                            create_particles(
                                15, invaders[collision_count].rect.left + 8,
                                invaders[collision_count].rect.top + 8,
                                green_particle_image)
                            player_hit = True

                    # Have any drones collided with player?
                    if red_invaders[collision_count].active == True:
                        if player_side.rect.colliderect(
                            (red_invaders[collision_count].rect.left + 5,
                             red_invaders[collision_count].rect.top + 5, 24,
                             24)):
                            red_invaders[collision_count].active = False
                            create_particles(
                                15,
                                red_invaders[collision_count].rect.left + 8,
                                red_invaders[collision_count].rect.top + 8,
                                red_particle_image)
                            player_hit = True
                        if player_bottom.rect.colliderect(
                            (red_invaders[collision_count].rect.left + 5,
                             red_invaders[collision_count].rect.top + 5, 24,
                             24)):
                            red_invaders[collision_count].active = False
                            create_particles(
                                15,
                                red_invaders[collision_count].rect.left + 8,
                                red_invaders[collision_count].rect.top + 8,
                                red_particle_image)
                            player_hit = True

                    # Have any drones collided with player?
                    if drones[collision_count].active == True:
                        if player_side.rect.colliderect(
                            (drones[collision_count].rect.left + 5,
                             drones[collision_count].rect.top + 5, 24, 24)):
                            drones[collision_count].active = False
                            create_particles(
                                15, drones[collision_count].rect.left + 8,
                                drones[collision_count].rect.top + 8,
                                blue_particle_image)
                            player_hit = True
                        if player_bottom.rect.colliderect(
                            (drones[collision_count].rect.left + 5,
                             drones[collision_count].rect.top + 5, 24, 24)):
                            drones[collision_count].active = False
                            create_particles(
                                15, drones[collision_count].rect.left + 8,
                                drones[collision_count].rect.top + 8,
                                blue_particle_image)
                            player_hit = True

                # Have any ufos collided with player?
                for collision_count in range(MAX_UFOS):
                    if ufos[collision_count].active == True:
                        if player_side.rect.colliderect(
                            (ufos[collision_count].rect.left + 5,
                             ufos[collision_count].rect.top + 5, 24, 24)):
                            ufos[collision_count].active = 0
                            create_particles(
                                15, ufos[collision_count].rect.left + 8,
                                ufos[collision_count].rect.top + 8,
                                gray_particle_image)
                            player_hit = True
                        if player_bottom.rect.colliderect(
                            (ufos[collision_count].rect.left + 5,
                             ufos[collision_count].rect.top + 5, 24, 24)):
                            ufos[collision_count].active = 0
                            create_particles(
                                15, ufos[collision_count].rect.left + 8,
                                ufos[collision_count].rect.top + 8,
                                gray_particle_image)
                            player_hit = True

                # Have any enemy bullets collided with player?
                for collision_count in range(MAX_BADDIE_BULLETS):
                    if baddie_bullets[collision_count].active == True:
                        if player_side.rect.colliderect(
                            (baddie_bullets[collision_count].rect.left,
                             baddie_bullets[collision_count].rect.top, 8, 8)):
                            baddie_bullets[collision_count].active = 0
                            player_hit = True
                        if player_bottom.rect.colliderect(
                            (baddie_bullets[collision_count].rect.left,
                             baddie_bullets[collision_count].rect.top, 8, 8)):
                            baddie_bullets[collision_count].active = 0
                            player_hit = True

                # Has player been hit by anything nasty?
                if player_hit == True and game_over == False:
                    player_shield -= 1
                    create_particles(5, 85 + ((player_shield) * 11), 32,
                                     red_particle_image)
                    player_flash_timer = 50
                    player_boom_1.play()

                    if player_shield == 0:
                        player_boom_2.play()
                        create_particles(20, player_bottom.rect.left + 8,
                                         player_bottom.rect.top + 8,
                                         red_particle_image)
                        create_particles(20, player_bottom.rect.left + 8,
                                         player_bottom.rect.top + 8,
                                         yellow_particle_image)
                        create_particles(20, player_side.rect.left + 8,
                                         player_side.rect.top + 8,
                                         red_particle_image)
                        create_particles(20, player_side.rect.left + 8,
                                         player_side.rect.top + 8,
                                         yellow_particle_image)
                        game_over = True

            # Display hud stuff
            screen.blit(
                game_font.render("Score: " + str(player_score), 0,
                                 ((255, 206, 0))), (10, 10))
            screen.blit(
                game_font.render("High Score: " + str(high_score), 0,
                                 ((255, 206, 0))), (460, 10))

            # Beaten high score?
            if player_score > high_score:
                high_score = player_score
                # Make a little fuss of the player :)
                if beaten_high_score == False:
                    beaten_high_score = True
                    for count in range(5):
                        create_particles(5, 460 + (count * 15), 15,
                                         yellow_particle_image)

            if wave_break > 0:
                wave_break -= 1
                if game_over == False:
                    screen.blit(
                        game_font_large.render(
                            "Wave " + str(game_wave) + " of 9", 0,
                            ((255, 206, 0))), (240, SCREEN_HEIGHT / 2 - 36))

            for count in range(player_shield):
                screen.blit(game_font.render("Shields:", 0, ((255, 206, 0))),
                            (10, 30))
                screen.blit(player_health_image, (85 + (count * 11), 32))

            if game_over == True:
                # Loss or victory?
                if game_victory == False:
                    screen.blit(
                        game_font_large.render("GAME OVER", 0, ((176, 0, 0))),
                        (260, SCREEN_HEIGHT / 2 - 36))
                else:
                    screen.blit(
                        game_font_large.render("YOU ARE AWESOME!!!", 0,
                                               ((255, 206, 0))),
                        (160, SCREEN_HEIGHT / 2 - 36))
                    game_victory_particle_timer += 1
                    if game_victory_particle_timer > 10:
                        create_particles(30, random.randint(160, 450),
                                         random.randint(160, 300),
                                         red_particle_image)

                game_over_timer -= 1
                if game_over_timer == 0:
                    game_mode = TITLE_SCREEN_MODE

            # Time for a new wave? Only start new wave display when all baddies are dead
            baddies_onscreen = False
            for count in range(MAX_BADDIES):
                if invaders[count].active == True:
                    baddies_onscreen = True
                    break
                if red_invaders[count].active == True:
                    baddies_onscreen = True
                    break
                if drones[count].active == True:
                    baddies_onscreen = True
                    break

            for count in range(MAX_UFOS):
                if ufos[count].active == True:
                    baddies_onscreen = True

            if baddies_killed > wave_target_kills and baddies_onscreen == False and game_over == False:
                wave_break = 300
                wave_target_kills += 10
                game_wave += 1
                if game_wave == 10:
                    game_over = True
                    game_victory = True
                    game_over_timer = 700
                    win_sound.play()

                baddies_killed = 0

                # Make the next round a bit harder :)
                if attack_max > 30:
                    attack_max -= 10
                if ufo_attack_max > 0:
                    ufo_attack_max -= 50
                if game_wave > 6:
                    baddie_fire_rate = 10
                wave_sound.play()

        # Show the newly rendered screen
        pygame.display.flip()
        # Limit game speed
        clock.tick(FPS)

    # This is not strictly needed, but is included so that IDLE will play nice :)
    pygame.quit()