def construct(self): """Show's tower building animation, un-destroys tower""" # Count down construction duration (in game frames) if self.construct_countdown > 0: self.construct_countdown -= 1 # Count down duration (in game frames) on current image of hammer if self.frame_counter > 0: self.frame_counter -= 1 # Switch to next hammer image else: self.construct_image = hammer_list[self.frame][0] self.frame += 1 if self.frame > len(hammer_list) - 1: self.frame = 0 self.frame_counter = self.frames_to_picswap # Show wooden plank gameDisplay.blit(wood[0], (int(self.x - 0.5 * self.construct_width), int(self.y - .8 * self.construct_height))) # Show hammer image gameDisplay.blit(self.construct_image, (int(self.x - 0.3 * self.construct_width), int(self.y - 1 * self.construct_height))) # Call (show) construction_bar() self.construction_bar() # Un-destroy tower and stop construction else: self.destroy = False self.constructing = False
def set_text(self, x, y, msg, msg_color, is_main): """Draw text inside of option circle if specified""" if is_main: font = pygame.font.SysFont(self._font, self._font_size, bold=True) else: font = pygame.font.SysFont(self._font, int(self._font_size * .6), bold=True) text_surface = font.render(msg, True, msg_color) text_rect = text_surface.get_rect() text_rect.center = (x, y) gameDisplay.blit(text_surface, text_rect)
def set_text(self): """Overlays text on top of button, if text exists""" if self.selected: text_surface = self._font.render(self._message, True, self.selected_text_color) else: text_surface = self._font.render(self._message, True, self._message_color) text_rect = text_surface.get_rect() text_rect.center = ((self.x + self._width // 2), (self.y + self._height // 2)) gameDisplay.blit(text_surface, text_rect)
def show_stun(self): """Shows stun attached to enemy""" gameDisplay.blit( stun_list[self.stun_frame][0], (self.x + self.stun_loc[self.direction_index][0], self.y + self.stun_loc[self.direction_index][1])) self.stun_framecounter -= 1 if self.stun_framecounter < 1: self.stun_framecounter = self.stun_frameswap_rate self.stun_frame += 1 if self.stun_frame == len(stun_list[0]): self.stun_frame = 0
def show(self): """Shows enemy, health bar, and calls elemental effects functions""" if not self.destroy: if self.poison1 or self.poison2: self.show_poison() if self.fire1 or self.fire2: self.show_fire() if self.stun: self.show_stun() if self.ice1 or self.ice2: self.show_ice() gameDisplay.blit(self.image, (self.x - self.image_width // 2, self.y - self.image_height // 2)) self.health_bar()
def sell(self): """Shows money earned from tower sale, un-destroys tower""" # Counts down time of sale (from game frames) if self.sell_countdown > 0: self.sell_countdown -= 1 # Define and display sale text text_surface = self.sell_font.render( '$' + str(self.previous_sell_value), True, black) text_rect = text_surface.get_rect() text_rect.center = (self.x, self.y) gameDisplay.blit(text_surface, text_rect) # When sale ends, un-destroy tower and stop selling else: self.destroy = False self.selling = False
def intro_loop(): """First loop seen, explains game story with links to other loops Note: Texts stored in gameText.py """ play_button = generalClass.Button( (450, display_height - 250), message="Play", action=game_loop, font_size=40, width=300, height=60) quit_button = generalClass.Button( (450, display_height - 180), message="Quit", action=sys.exit, font_size=40, width=300, height=60, color1=red, color2=bright_red) tower_info_button = generalClass.Button( (100, display_height - 320), message="Tower Types", action=tower_info_loop, font_size=40, width=300, height=60, color1=teal, color2=bright_teal) enemy_info_button = generalClass.Button( (100, display_height - 250), message="Enemy Types", action=enemy_info_loop, font_size=40, width=300, height=60, color1=yellow, color2=bright_yellow) settings_button = generalClass.Button( (100, display_height - 180), message="Difficulty", action=settings_loop, font_size=40, width=300, height=60, color1=orange, color2=bright_orange) font = pygame.font.SysFont('Comic Sans MS', 20, bold=True) title_font = pygame.font.SysFont('Comic Sans MS', 72, bold=True) while True: # Activate quit button for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() # Draw background gameDisplay.blit(backgroundImage.image, backgroundImage.rect) # Draw title and intro text helpers.blit_text(gameDisplay, title, (100, 25), title_font, margin=50) helpers.blit_text(gameDisplay, intro_text, (100, 150), font, margin=100) # Draw buttons play_button.draw() quit_button.draw() enemy_info_button.draw() tower_info_button.draw() settings_button.draw() # Update game display pygame.display.update() clock.tick(30)
def draw(self, win_loss): """Draws all message displays and buttons, calls set_text()""" pygame.mixer.music.fadeout(750) if win_loss == "lose": pygame.mixer.music.load('music/Hero_Down.mp3') pygame.mixer.music.play(-1, start=1.5) if win_loss == "win": pygame.mixer.music.load('music/Amazing_Plan_Silent_Film_Dark.mp3') pygame.mixer.music.play(-1) # Define time for display minutes_elapsed = self.time_elapsed // minutes remaining_seconds = (self.time_elapsed % minutes) // seconds while True: # Check for quit for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() # Show background gameDisplay.blit(backgroundImage.image, backgroundImage.rect) # Draw "Defeat/Victory" text if win_loss == "lose": self.set_text(self.center_x, self.game_y, "Defeat!", self.game_font) if win_loss == "win": self.set_text(self.center_x, self.game_y, "Victory!!", self.game_font) # Draw "Score" text self.set_text(self.center_x, self.score_y, "score: {}".format(self.score), self.score_font) # Draw "Time elapsed" text self.set_text( self.center_x, self.time_y, "Time: {0}:{1:02}".format(minutes_elapsed, remaining_seconds), self.time_font) # Draw quit button self.quit_button.draw() # Draw play button play = self.play_button.draw() if play == "play": return play # Draw main button main = self.main_button.draw() if main == "main": return main # Update game pygame.display.update() clock.tick(30)
def set_text(self): """Writes text to stat display""" # Update how text to display self.update_stat() # Add prefix if there is one and then render text surface if self.prefix: text_surface = self._font.render(self.prefix + self.displayed_stat, True, self.text_color) else: text_surface = self._font.render(self.displayed_stat, True, self.text_color) # Get rectangle for text and center text in it text_rect = text_surface.get_rect() text_rect.center = ((self.x + self._width // 2), (self.y + self._height // 2)) # Display text on screen gameDisplay.blit(text_surface, text_rect)
def settings_loop(): """Allow user to adjust difficulty settings with buttons and explanations Note: Texts located in gameText.py """ # Set buttons for difficulty selection and return to into_loop return_button = generalClass.Button( (50, 50), message="Return", action=intro_loop, font_size=40, width=200, height=60, color1=orange, color2=bright_orange) easy_button = generalClass.Button( (50, 200), message="Easy", action=easy_settings, font_size=40, width=200, height=60, color1=green, color2=bright_green, linked=True) medium_button = generalClass.Button( (50, 285), message="Medium", action=medium_settings, font_size=40, width=200, height=60, color1=yellow, color2=bright_yellow, linked=True) hard_button = generalClass.Button( (50, 370), message="Hard", action=hard_settings, font_size=40, width=200, height=60, color1=red, color2=bright_red, linked=True) # Set font for difficulty explanations font = pygame.font.SysFont('Comic Sans MS', 24, bold=True) while True: # Activate quit button for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() # Draw background gameDisplay.blit(backgroundImage.image, backgroundImage.rect) # Draw setting descriptions helpers.blit_text(gameDisplay, easy_text, (275, 190), font, margin=-50) helpers.blit_text(gameDisplay, medium_text, (275, 275), font, margin=50) helpers.blit_text(gameDisplay, hard_text, (275, 360), font, margin=50) # Draw buttons return_button.draw() easy_button.draw(medium_button, hard_button) medium_button.draw(easy_button, hard_button) hard_button.draw(easy_button, medium_button) # Update game display pygame.display.update() clock.tick(30)
def game_loop(): """Play the game This function sets up several buttons and texts to give info for game, then calls several other functions to run the game logic. """ # Game crashes if loading new music while music is paused pygame.mixer.music.unpause() # Start main game music pygame.mixer.music.fadeout(100) pygame.mixer.music.load('music/main_music_mesh2.wav') pygame.mixer.music.play(0) # Set static buttons pause_button = generalClass.Button( (20, 50), message="Pause", width=120, color1=gray, color2=white, action=pause_game) # Set game settings start_cash = settings.starting_gold enemy_spawn_rate = settings.spawn_rate passive_money_rate = settings.gold_generation difficulty = settings.difficulty # Set up game rules with several stat trackers score = generalClass.Tracker( (140, 20), start_stat=0, width=120, height=30, background_color=green, font="Comic Sans MS", font_size=20, text_color=black, prefix="Score: ") game_clock = generalClass.Tracker( (20, 20), start_stat=0, width=120, height=30, background_color=black, font="Comic Sans MS", font_size=20, text_color=white, special="clock") funds = generalClass.Tracker( (20, display_height - 90), start_stat=start_cash, width=100, height=30, background_color=black, font="Comic Sans MS", font_size=20, text_color=white, prefix="$") castle = generalClass.Tracker( (20, display_height - 60), start_stat=20, width=250, height=50, background_color=red, front_color=green, font="Comic Sans MS", font_size=30, text_color=white, special="castle") # Set the end screen end_screen = generalClass.EndScreen() # Set blank enemies list enemies_list = [] # # enemies_list.extend( # [enemies.Lizard(), enemies.Lizard(), enemies.Wolf(), # enemies.Wolf(), enemies.Orc(), enemies.Orc(), # enemies.Turtle(), enemies.Turtle(), enemies.Spider(), # enemies.Spider(), enemies.Spider(), enemies.Spider(), # enemies.Spider(), enemies.Spider()]) # Set towers' and missiles' lists bot_tower_list = [] bot_missile_list = [] top_tower_list = [] top_missile_list = [] # Call function to set up towers and missiles set_towers(bot_tower_locations, bot_tower_list, bot_missile_list) set_towers(top_tower_locations, top_tower_list, top_missile_list) # Set mage (for end game sequence) mage = enemies.Mage() # Actual game loop while True: # Set quit button and pause game listeners for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: pause_game() # Update game_clock by 1 per frame game_clock.stat += 1 # Draw background gameDisplay.blit(backgroundImage.image, backgroundImage.rect) # Periodically add money if game_clock.stat % passive_money_rate == 0: funds.adjust(1) # Call function to add enemies if not mage.stop_spawn: add_enemies(game_clock.stat, enemies_list, enemy_spawn_rate, difficulty) # Call function to draw top-side towers draw_towers(top_tower_list, top_missile_list, funds, score, enemies_list) # Call function to draw enemies draw_enemies(enemies_list, castle) # Call function to draw bottom-side towers draw_towers(bot_tower_list, bot_missile_list, funds, score, enemies_list) # Call function to draw mage (end of game sequence) draw_mage(mage, game_clock, score, funds, enemies_list) # Draw game info panels tower_costs_display() funds.draw() castle.draw() score.draw() game_clock.draw() pause_button.draw() # Check for win/lose conditions win_lose(mage, end_screen, score, game_clock, castle) # Update game pygame.display.update() clock.tick(30)
def show_tower_image(self): """Shows the tower image""" gameDisplay.blit(self.image, (int(self.x - 0.5 * self.image_width), int(self.y - .8 * self.image_height)))
def show_poison(self): """Show poison cloud attached to enemy""" gameDisplay.blit( poison_list[self.direction_index][0], (self.x + self.poison_loc[self.direction_index][0], self.y + self.poison_loc[self.direction_index][1]))
def show_fire(self): """Shows fire attached to enemy""" gameDisplay.blit( fire_pic[0], (self.x + self.fire_loc[0], self.y + self.fire_loc[1]))
def show_ice(self): """Shows ice attached to enemy""" gameDisplay.blit( ice_pic[0], (self.x + self.ice_loc[self.direction_index][0], self.y + self.ice_loc[self.direction_index][1]))
def draw(self, game_frames): # Sequence takes ~ 32 seconds until all enemies dead # Sequence takes ~ 58 seconds until game end if game_frames == int((5 * minutes) + (2 * seconds)): self.walking = True if game_frames > int((5 * minutes) + (2 * seconds)): gameDisplay.blit(self.image, (self.x - self.image_width // 2, self.y - self.image_height // 2)) # Walk south if self.walking: # Animation if self.frame_counter > 0: self.frame_counter -= 1 else: self.image = mage_list[0][self.frame] self.frame += 1 if self.frame > len(mage_list[0]) - 1: self.frame = 0 self.frame_counter = self.frames_to_picswap # Motion if self.y < self.end_y: self.y += 1 else: self.walking = False self.wait = True self.image = magestanding if self.wait: self.wait_counter -= 1 if self.wait_counter == 0: self.wait = False self.speech1 = True self.frame = 0 if self.speech1: if self.speech_counter > 0: self.speech_counter -= 1 else: if self.speech_index < len(mage_speech1) - 1: self.speech_index += 1 self.speech_counter = self.speech_timer if self.speech_index == 3 and self.speech_counter == 0.5 * seconds: self.crystal_show = True if self.speech_index == 7 and self.speech_counter == 2 * seconds: grumbling_sound.play() if self.speech_index == 7 and self.speech_counter == 0: self.crystal_away = True if self.speech_index == 9 and \ self.speech_counter == int(3.25 * seconds): pygame.mixer.music.fadeout(2500) if self.speech_index == 9 and self.speech_counter == 0: self.speech1 = False self.start_spell = True self.frame = 0 # White talking bubble pygame.draw.polygon(gameDisplay, white, ( (self.x + 5, self.y - 15), (380, 5), (420, 5), (420, 57), (410, 15), (380, 15))) pygame.draw.rect(gameDisplay, white, (420, 5, 250, 52)) # Text helpers.blit_text(gameDisplay, mage_speech1[self.speech_index], (425, 6), self.font, margin=190) if self.crystal_show: if self.frame_counter > 0: self.frame_counter -= 1 else: self.image = mage_list[1][self.frame] self.frame += 1 self.frame_counter = self.frames_to_picswap if self.frame > 6: self.crystal_show = False if self.crystal_away: if self.frame_counter > 0: self.frame_counter -= 1 else: self.image = mage_list[1][self.frame] self.frame += 1 self.frame_counter = self.frames_to_picswap if self.frame > 18: self.crystal_away = False self.image = magestanding if self.start_spell: if self.frame_counter > 0: self.frame_counter -= 1 else: if self.frame < len(mage_list[2]) - 1: self.frame += 1 self.frame_counter = self.frames_to_picswap self.image = mage_list[2][self.frame] if self.image == mage_list[2][5] and self.frame_counter == 1: mage_spell_sound.play() if self.image == mage_list[2][10]: pygame.mixer.music.load('music/Fall_of_the_Solar_King2.wav') pygame.mixer.music.play() self.stop_spawn = True self.spell_cast = True self.start_spell = False if self.radius < 1000 and self.spell_cast: self.radius += 20 # Draw the expanding spell (4 circles of increasing thickness) # thickness = 0 if self.radius > self.thickness: pygame.draw.circle(gameDisplay, blue, (self.x, self.y), self.radius, self.thickness) # thickness = 1 if self.radius - self.thickness > self.thickness * 2: pygame.draw.circle( gameDisplay, bright_blue, (self.x, self.y), self.radius-self.thickness, self.thickness * 2) # thickness = 1 + 2 = 3 if self.radius - self.thickness * 3 > self.thickness * 3: pygame.draw.circle( gameDisplay, teal, (self.x, self.y), self.radius - self.thickness * 3, self.thickness * 3) # thickness = 1 + 2 + 3 = 6 if self.radius - self.thickness * 6 > self.thickness * 6: pygame.draw.circle( gameDisplay, bright_teal, (self.x, self.y), self.radius - self.thickness * 6, self.thickness * 6) if self.radius >= 1000: self.spell_cast = False self.speech2 = True self.speech_counter = self.speech_timer self.speech_index = 0 self.radius = 0 self.image = magestanding if self.stop_spawn and self.pop_enemies_counter > 0: self.pop_enemies_counter -= 1 if self.speech2: if self.speech_counter > 0: self.speech_counter -= 1 else: if self.speech_index < len(mage_speech2) - 1: self.speech_index += 1 self.speech_counter = self.speech_timer if self.speech_index == 9 and self.speech_counter == 1: self.win = True # White talking bubble pygame.draw.polygon(gameDisplay, white, ( (self.x + 5, self.y - 15), (380, 5), (420, 5), (420, 57), (410, 15), (380, 15))) pygame.draw.rect(gameDisplay, white, (420, 5, 250, 52)) # Text helpers.blit_text(gameDisplay, mage_speech2[self.speech_index], (425, 6), self.font, margin=190)
def tower_info_loop(): """Shows and explains towers with buttons to navigate Note: Texts located in gameText.py """ # Set buttons return_button = generalClass.Button( (50, 50), message="Return", action=intro_loop, font_size=40, width=200, height=60, color1=orange, color2=bright_orange) previous_button = generalClass.Button( (50, display_height - 100), message="Previous", action="backward", font_size=40, width=200, height=60, color1=red, color2=bright_red) next_button = generalClass.Button( (600, display_height - 100), message="Next", action="forward", font_size=40, width=200, height=60, color1=green, color2=bright_green) # Set font font = pygame.font.SysFont('Comic Sans MS', 18, bold=True) # Set towers basic = towerClass.BasicTower((160, 400), destroy=False) ice1 = towerClass.IceTower1((155, 250), destroy=False) ice2 = towerClass.IceTower2((155, 530), destroy=False) fire1 = towerClass.FireTower1((155, 250), destroy=False) fire2 = towerClass.FireTower2((155, 530), destroy=False) poison1 = towerClass.PoisonTower1((155, 250), destroy=False) poison2 = towerClass.PoisonTower2((155, 530), destroy=False) dark1 = towerClass.DarkTower1((155, 250), destroy=False) dark2 = towerClass.DarkTower2((155, 530), destroy=False) # Define index for navigating pages info_index = 0 while True: # Activate quit button for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() # Draw background gameDisplay.blit(backgroundImage.image, backgroundImage.rect) pygame.draw.rect(gameDisplay, white, (100, 125, 650, 525)) # Draw buttons return_button.draw() next_tower = next_button.draw() previous_tower = previous_button.draw() # Define page navigation with index if next_tower: info_index += 1 if previous_tower: info_index -= 1 if info_index > 4: info_index = 0 if info_index < 0: info_index = 4 # Draw towers and tower info, pages indicated by index if info_index == 0: basic.draw() helpers.blit_text(gameDisplay, basic_tower_text, (225, 300), font, margin=125) if info_index == 1: ice1.draw() ice2.draw() helpers.blit_text(gameDisplay, ice1_text, (225, 135), font, margin=125) helpers.blit_text(gameDisplay, ice2_text, (225, 400), font, margin=125) pygame.draw.rect(gameDisplay, black, (150, 385, 550, 5)) if info_index == 2: fire1.draw() fire2.draw() helpers.blit_text(gameDisplay, fire1_text, (225, 135), font, margin=125) helpers.blit_text(gameDisplay, fire2_text, (225, 400), font, margin=125) pygame.draw.rect(gameDisplay, black, (150, 385, 550, 5)) if info_index == 3: poison1.draw() poison2.draw() helpers.blit_text(gameDisplay, poison1_text, (225, 135), font, margin=125) helpers.blit_text(gameDisplay, poison2_text, (225, 400), font, margin=125) pygame.draw.rect(gameDisplay, black, (150, 385, 550, 5)) if info_index == 4: dark1.draw() dark2.draw() helpers.blit_text(gameDisplay, dark1_text, (225, 135), font, margin=125) helpers.blit_text(gameDisplay, dark2_text, (225, 400), font, margin=125) pygame.draw.rect(gameDisplay, black, (150, 385, 550, 5)) # Update game display pygame.display.update() clock.tick(30)
def enemy_info_loop(): """Show and explain enemies with buttons to navigate Note: Texts located in gameText.py """ # Set buttons for page navigation return_button = generalClass.Button( (50, 50), message="Return", action=intro_loop, font_size=40, width=200, height=60, color1=orange, color2=bright_orange) previous_button = generalClass.Button( (50, display_height - 100), message="Previous", action="backward", font_size=40, width=200, height=60, color1=red, color2=bright_red) next_button = generalClass.Button( (600, display_height - 100), message="Next", action="forward", font_size=40, width=200, height=60, color1=green, color2=bright_green) # Set font font = pygame.font.SysFont('Comic Sans MS', 18, bold=True) # Set enemies, indicating stationary=True and destroy=False spider = enemies.Spider((180, 250), (190, 250), True, False) lizard = enemies.Lizard((180, 530), (190, 530), True, False) wolf = enemies.Wolf((180, 250), (190, 250), True, False) turtle = enemies.Turtle((180, 530), (190, 530), True, False) orc = enemies.Orc((180, 250), (190, 250), True, False) dragon = enemies.Dragon((180, 530), (190, 530), True, False) # Define index for page navigation info_index = 0 while True: # Activate quit button for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() # Draw background gameDisplay.blit(backgroundImage.image, backgroundImage.rect) pygame.draw.rect(gameDisplay, white, (100, 125, 650, 525)) # Draw buttons return_button.draw() next_enemy = next_button.draw() previous_enemy = previous_button.draw() # Define page navigation with index if next_enemy: info_index += 1 if previous_enemy: info_index -= 1 if info_index > 2: info_index = 0 if info_index < 0: info_index = 2 # Draw enemies and enemy info, pages indicated by index if info_index == 0: spider.draw() lizard.draw() helpers.blit_text(gameDisplay, spider_text, (275, 135), font, margin=125) helpers.blit_text(gameDisplay, lizard_text, (275, 400), font, margin=125) pygame.draw.rect(gameDisplay, black, (150, 385, 550, 5)) if info_index == 1: wolf.draw() turtle.draw() helpers.blit_text(gameDisplay, wolf_text, (275, 135), font, margin=125) helpers.blit_text(gameDisplay, turtle_text, (275, 400), font, margin=125) pygame.draw.rect(gameDisplay, black, (150, 385, 550, 5)) if info_index == 2: orc.draw() dragon.draw() helpers.blit_text(gameDisplay, orc_text, (275, 135), font, margin=125) helpers.blit_text(gameDisplay, dragon_text, (275, 400), font, margin=125) pygame.draw.rect(gameDisplay, black, (150, 385, 550, 5)) # Update game display pygame.display.update() clock.tick(30)
def set_text(self, x, y, message, font): """Displays texts for message displays""" text_surface = font.render(message, True, self.text_color) text_rect = text_surface.get_rect() text_rect.center = (x, y) gameDisplay.blit(text_surface, text_rect)
def draw(self): """Calls manipulates enemy and calls associated functions Moves enemy unless stunned, changing image to show walking motion. Checks for special (elemental) attributes and calls associated functions if it find them. If enemy is dead, shows corpse and stat loot and removes elemental effects. No args Returns: self.castle_damage(int): if enemy reaches last node (castle), else None """ if not self.destroy: if not self.stun: if not self.stationary: # Move towards node by self.speed. if self.x < self.next_node[0] - 5: self.x += self.speed self.right = True if self.x > self.next_node[0] + 5: self.x -= self.speed self.left = True if self.y < self.next_node[1] - 5: self.y += self.speed self.down = True if self.y > self.next_node[1] + 5: self.y -= self.speed self.up = True # Change walking frame if frame_counter reaches 0 if self.frame_counter < 1: # Determine direction_index self.direction_index = 2 # Default is right if self.down and not self.right: self.direction_index = 0 if self.down and self.right: self.direction_index = 1 if self.right and not (self.up or self.down): self.direction_index = 2 if self.up and self.right: self.direction_index = 3 if self.up and not self.right: self.direction_index = 4 self.walk() self.frame_counter = self.frames_to_picswap if self.frame_counter > 0: self.frame_counter -= self.speed if self.stun: if self.stun_duration_countdown == 0: self.stun = False if self.stun_duration_countdown > 0: self.stun_duration_countdown -= 1 # Check for special attributes if self.ice1 or self.ice2: self.iced() if self.poison2: self.poisoned(self.poison2) if self.poison1 and not self.poison2: self.poisoned(self.poison1) if self.fire1 or self.fire2: self.burning() if self.fireball1 > 0: self.fireball1 -= 1 if self.fireball2 > 0: self.fireball2 -= 1 else: self.fire_radius = self.initial_fire_radius # Show self.show() # Switch to next node in path if at current node goal if self.next_node[0] - 10 < self.x < self.next_node[0] + 10: if self.next_node[1] - 10 < self.y < self.next_node[1] + 10: if self.node_index < len(path_nodes) - 2: self.node_index += 1 # see lists.py node_x, node_y = path_nodes[self.node_index] # Introduce some randomness to node locations node_x += random.randrange(-10, 10) node_y += random.randrange(-15, 15) self.next_node = (node_x, node_y) # See lists else: # Destroy and remove all affects, move to start of path self.destroy = True self.poison1 = None self.poison2 = None self.poison_tick = 0 self.poison_charges = 0 self.ice1 = False self.ice2 = False self.speed = self.base_speed self.fire1 = None self.fire2 = None self.fireball1 = 0 self.fireball2 = 0 self.x, self.y = path_nodes[0] # Return damage to castle return self.castle_damage # If enemy is dead if self.destroy: # Show body if self.dead_image_countdown > 0: gameDisplay.blit( self.dead_image, (self.dead_x - self.image_width // 2, self.dead_y - self.image_height // 2)) self.dead_image_countdown -= 1 # Show money earned if self.dead_image_countdown > 3 * seconds: text_surface = self.dead_font.render( "${}".format(self.cash), True, yellow) text_rect = text_surface.get_rect() text_rect.center = (self.dead_x, self.dead_y - 30) gameDisplay.blit(text_surface, text_rect) # Start respawn timer countdown if self.spawn_countdown > 0: self.spawn_countdown -= 1 # If respawn timer reaches 0, respawn enemy and reset timer elif self.spawn_countdown <= 0: self.lives -= 1 self.poison1 = None self.poison2 = None self.poison_tick = 0 self.poison_charges = 0 self.fire1 = None self.fire2 = None self.fireball1 = 0 self.fireball2 = 0 self.burned_counter = 0 self.ice1 = False self.ice2 = False self.speed = self.base_speed self.destroy = False self.x, self.y = path_nodes[0] self.node_index = 0 self.next_node = path_nodes[0] self.hp = self.max_hp self.spawn_countdown = self.spawn_timer self.right = False self.left = False self.up = False self.down = False