def __init__(self,level_file_name): self.level_name = level_file_name self.level = eval(level_file_name)() self.letter_map = self.level.letter_map self.tile_map = TileMap(self.letter_map) self.level_menu = LevelMenu() self.tower_list = [] #List of all towers currently on the screen
def __init__(self,level_file_name): pygame.mixer.init() self.player = PlayerModel(150, 5) self.level_name = level_file_name self.level = eval(level_file_name)() self.letter_map = self.level.letter_map self.tile_map = TileMap(self.letter_map) self.enemy_waves = self.level.enemy_waves self.current_enemy_wave_number = 0 self.total_enemy_waves = len(self.enemy_waves) self.current_enemy_wave = EnemyWave(self.tile_map,empty_wave) self.display_level = self self.level_menu = LevelMenu(self.display_level) self.tower_list = [] #List of all towers currently on the screen self.level_finished = False self.game_over = None #Game over screen self.placement_phase = True self.update_sound()
class DisplayLevel: def __init__(self,level_file_name): self.level_name = level_file_name self.level = eval(level_file_name)() self.letter_map = self.level.letter_map self.tile_map = TileMap(self.letter_map) self.level_menu = LevelMenu() self.tower_list = [] #List of all towers currently on the screen def display_towers(self): for tower in self.tower_list: tower.display_tower() def display_tile_map(self): self.tile_map.display_tile_map() def display_level_menu(self): self.level_menu.display_start_menu() def update(self): ##FOR TESTING: #Circles to emulate enemies on the board - solely for visual testing purposes #If the circles are within the towers' attack_radius, then the towers will shoot at them pygame.draw.circle(pygame.display.get_surface(), (145,255,255), (186,245), 5) pygame.draw.circle(pygame.display.get_surface(), (145,255,255), (184, 27), 5) #--------------------------------------------- #Tower shooting loop for tower in self.tower_list: if tower.placed == True: tower.attack_enemy() for event in pygame.event.get(MOUSEBUTTONUP): mouse_pos = pygame.mouse.get_pos() #If mouse_pos is within the tile map if ((mouse_pos[0] > 0 and mouse_pos[0] < self.tile_map.map_size) and (mouse_pos[1] > 0 and mouse_pos[1] < self.tile_map.map_size)): #if mouse is within the tile_map bounds self.tile_map_click(mouse_pos) #If mouse pos is within the level menu elif ((mouse_pos[0] > self.tile_map.map_size and mouse_pos[0] < self.tile_map.window.get_width()) and (mouse_pos[1] > 0 and mouse_pos[1] < self.tile_map.window.get_height())): if not (self.is_tower_being_placed()): #Only spawn a new tower if currently a tower is NOT being placed #The level_menu.clicked method returns none if player did not click on a button (e.g. whitespace) #This method is also passed the tile_size, so it can adjust the size of the tower according to the tile #Also passed is the map_size, so the tower knows the boundary of the tile_map newTower = self.level_menu.clicked(mouse_pos, self.tile_map.tile_size, self.tile_map.map_size) else: newTower = None if (isinstance(newTower, BaseTower)): self.tower_list.append(newTower) else: #Player clicked on level menu whitespace and NOT button #So if they are in the process of placing a tower, remove that tower for tower in self.tower_list: if tower.placed == False: self.tower_list.remove(tower) #Player clicked on tile map def tile_map_click(self, mouse_pos): selected_tile = self.tile_map.clicked(mouse_pos) #Gets the tile that has been clicked on for tower in self.tower_list: if tower.placed == False: #If a tower has not been placed yet selected_tile.place_tower(tower) #Assign the tower variable of the selected_tile break #Returns true if the player is in the process of placing a tower def is_tower_being_placed(self): for tower in self.tower_list: if (tower.placed == False): return True
class DisplayLevel: def __init__(self,level_file_name): pygame.mixer.init() self.player = PlayerModel(150, 5) self.level_name = level_file_name self.level = eval(level_file_name)() self.letter_map = self.level.letter_map self.tile_map = TileMap(self.letter_map) self.enemy_waves = self.level.enemy_waves self.current_enemy_wave_number = 0 self.total_enemy_waves = len(self.enemy_waves) self.current_enemy_wave = EnemyWave(self.tile_map,empty_wave) self.display_level = self self.level_menu = LevelMenu(self.display_level) self.tower_list = [] #List of all towers currently on the screen self.level_finished = False self.game_over = None #Game over screen self.placement_phase = True self.update_sound() def update_sound(self): if (pygame.mixer.music.get_busy()): pygame.mixer.music.stop() if (self.placement_phase == True): #Royalty-free music taken from incompetech.com #http://incompetech.com/music/royalty-free/index.html?isrc=USUAN1400005 pygame.mixer.music.load('Library\Assets\Music\Pippin_the_Hunchback.mp3') pygame.mixer.music.play() else: #Royalty-free music taken from bensound.com #http://www.bensound.com/royalty-free-music/track/epic pygame.mixer.music.load('Library\Assets\Music\Epic.mp3') pygame.mixer.music.set_volume(0.5) pygame.mixer.music.play() def get_next_wave(self): if (self.placement_phase == True): self.placement_phase = False self.update_sound() if(self.current_enemy_wave_number == self.total_enemy_waves): self.check_level_finished() return if(self.current_enemy_wave.dead_enemies == self.current_enemy_wave.num_enemies): self.current_enemy_wave = EnemyWave(self.tile_map, self.enemy_waves[self.current_enemy_wave_number]) self.current_enemy_wave_number += 1 self.update_tower_enemies() def update_tower_enemies(self): for tower in self.tower_list: tower.get_new_wave(self.current_enemy_wave.enemy_list) def display_towers(self): show_radii = False for tower in self.tower_list: tower.display_tower() if tower.placed == False: show_radii = True if show_radii: for tower in self.tower_list: tower.display_radius() def display_tile_map(self): self.tile_map.display_tile_map() def display_level_menu(self): self.level_menu.display_start_menu() def display_enemies(self): self.current_enemy_wave.tick() def check_collide(self): for tower in self.tower_list: for e in self.current_enemy_wave: for b in tower.bullet_list: if (pygame.sprite.collide_rect(e, b)): e.damage_enemy(tower.bullet_damage) tower.bullet_list.remove(b) #Royalty-Free sound effect from Adobe #http://offers.adobe.com/en/na/audition/offers/audition_dlc.html explodeSound = pygame.mixer.Sound('Library\Assets\Music\Explosion_C-4_01.wav') explodeSound.set_volume(0.4) explodeSound.play() def check_level_finished(self): if(self.current_enemy_wave.dead_enemies == self.current_enemy_wave.num_enemies): self.level_finished = True def update(self): self.check_collide() if (self.current_enemy_wave.dead_enemies == self.current_enemy_wave.num_enemies and self.placement_phase == False): self.placement_phase = True self.update_sound() #Update live counter by subtracting each enemy that reached the end self.player.lives -= self.current_enemy_wave.reached_end self.current_enemy_wave.reached_end = 0 self.player.wallet += self.current_enemy_wave.dead_cash_enemies * self.current_enemy_wave.cash_yield self.current_enemy_wave.dead_cash_enemies = 0 if (self.player.lives < 1): # So lives don't become negative when game over screen is displayed if (self.player.lives < 0): self.player.lives = 0 if (isinstance(self.game_over, GameOverScreen)): self.game_over.display_self() if (self.game_over.timer > 170): #Exit game #Make a method for proper quitting pygame.quit() sys.exit() else: self.game_over = GameOverScreen() #Tower shooting loop for tower in self.tower_list: if tower.placed == True: tower.attack_enemy() for event in pygame.event.get(MOUSEBUTTONUP): mouse_pos = pygame.mouse.get_pos() #If mouse position is within the tile map if ((mouse_pos[0] > 0 and mouse_pos[0] < self.tile_map.map_size)): self.tile_map_click(mouse_pos) #If mouse pos is within the level menu elif ((mouse_pos[0] > self.tile_map.map_size and mouse_pos[0] < self.tile_map.window.get_width())): if not (self.is_tower_being_placed()): #The level_menu.clicked method returns none if player did not click on a button (e.g. whitespace) clickedObj = self.level_menu.clicked() else: clickedObj = None #If the player clicked on the BaseTower button AND can afford a BaseTower if (isinstance(clickedObj, BaseTower) and self.player.wallet >= clickedObj.cost): self.tower_list.append(clickedObj) else: #Player clicked on level menu whitespace and NOT button self.stop_tower_placement() #Player clicked on tile map def tile_map_click(self, mouse_pos): selected_tile = self.tile_map.clicked(mouse_pos) #Gets the tile that has been clicked on if (selected_tile.type == "Path"): self.stop_tower_placement() return None for tower in self.tower_list: if (tower.placed == False): #If a tower has not been placed yet if (selected_tile.tower == None): self.player.wallet -= tower.cost selected_tile.place_tower(tower) #Assign the tower variable of the selected_tile break #Returns true if the player is in the process of placing a tower def is_tower_being_placed(self): for tower in self.tower_list: if (tower.placed == False): return True #If player is in the process of placing a tower, and decides against it, delete that tower def stop_tower_placement(self): for tower in self.tower_list: if tower.placed == False: self.tower_list.remove(tower)