def start_level(self, level_index): self.time_offset = 0.0 self.current_level = self.Maps[level_index] self.gold = self.current_level.starting_gold self.lives = 3 self.score = self.current_level.score self.sidebar.update_gold(self.gold) self.sidebar.update_lives(self.lives) self.sidebar.update_score(self.score) self.hovered = None self.wave_in_progress = None self.change_selection() self.current_level.kickstart(self) self.kickstart_screens() self.unlocked_towers = self.current_level.unlocked_towers if self.current_level.new_tower: new_tower = self.current_level.new_tower self.set_tip_screen(new_tower) self.tip_screen.kickstart() self.phase = "tip" else: self.phase = "game" self.subtitle = Subtitle()
class Game(tools._State): def __init__(self): tools._State.__init__(self) self.screen = pg.display.get_surface() self.screen_rect = self.screen.get_rect() self.pause_button = generals.GFX["misc"]["pause"] self.pause_button_rect = self.pause_button.get_rect(bottomright=(990, 790)) self.move_on = True self.sidebar = Sidebar() self.foundations = pg.sprite.Group() self.tower_buttons = pg.sprite.Group() self.towers = pg.sprite.Group() self.bullets = pg.sprite.Group() self.monsters = pg.sprite.Group() self.ground_tiles = pg.sprite.Group() self.tooltip = None # (tower_button, its base's rect) self.set_screens() self.current_level = None self.wave_in_progress = None self.selected = None self.set_Maps() self.bg = self.tile_surface(generals.SCREEN_SIZE, generals.GFX["terrain"]["ground"]) def set_Maps(self): self.Maps = [] for level in levels_list: self.Maps.append(Map(*level)) def set_screens(self): buttons_list = [ ("RESUME", (0, 75), self.action_resume), ("RESTART", (0, 150), self.action_restart), ("QUIT", (0, 225), self.action_quit), ] self.menu_screen = MenuScreen(buttons_list) text_list = [("You lost! :(", (0, 60))] buttons_list = [("RESTART", (0, 160), self.action_restart), ("QUIT", (0, 235), self.action_quit)] self.lost_screen = MenuScreen(buttons_list, text_list) text_list = [("You won! :D", (0, 60))] buttons_list = [("AWESOME!", (0, 215), self.action_win)] self.won_screen = MenuScreen(buttons_list, text_list) def kickstart_screens(self): self.menu_screen.kickstart() self.lost_screen.kickstart() self.won_screen.kickstart() def set_tip_screen(self, new_tower): tower_name = tower_kinds[new_tower]["name"] text_list = [(tower_name, (0, 60)), ("is unlocked!".format(tower_name), (0, 95))] buttons_list = [("OK", (0, 190), self.action_ok)] self.tip_screen = MenuScreen(buttons_list, text_list) def tile_surface(self, size, tile): surface = pg.Surface(size).convert() tile_size = tile.get_size() for i in range(0, tile_size[0] + size[0], tile_size[0]): for j in range(0, tile_size[1] + size[1], tile_size[1]): surface.blit(tile, (i, j)) return surface def start_level(self, level_index): self.time_offset = 0.0 self.current_level = self.Maps[level_index] self.gold = self.current_level.starting_gold self.lives = 3 self.score = self.current_level.score self.sidebar.update_gold(self.gold) self.sidebar.update_lives(self.lives) self.sidebar.update_score(self.score) self.hovered = None self.wave_in_progress = None self.change_selection() self.current_level.kickstart(self) self.kickstart_screens() self.unlocked_towers = self.current_level.unlocked_towers if self.current_level.new_tower: new_tower = self.current_level.new_tower self.set_tip_screen(new_tower) self.tip_screen.kickstart() self.phase = "tip" else: self.phase = "game" self.subtitle = Subtitle() def clear_everything(self): self.current_level = None self.wave_in_progress = None self.foundations.empty() self.tower_buttons.empty() self.towers.empty() self.bullets.empty() self.monsters.empty() self.hovered = None self.change_selection() self.sidebar.clear() def get_tower_button_rects(self, tower_rect, num, side): width = height = 30 y_distance = 10 if num == 1: space = 0 x = tower_rect.left + 10 elif num == 2: space = 20 x = tower_rect.left - 15 elif num == 3: space = 10 x = tower_rect.left - 30 if side == "top": y = tower_rect.top - height - y_distance elif side == "bottom": y = tower_rect.bottom + y_distance rects = [] for _ in range(num): rect = pg.rect.Rect(x, y, width, height) x += width + space rects.append(rect) return rects def build_tower(self, foundation, kind): self.change_selection() if self.gold >= tower_kinds[kind]["price"][0] and kind in self.unlocked_towers: self.gold -= tower_kinds[kind]["price"][0] self.sidebar.update_gold(self.gold) rect = foundation.rect foundation.kill() self.towers.add(Tower(rect, kind)) def pause(self): self.phase = "pause" def unpause(self): self.phase = "game" self.time_offset = self.current_time - self.actual_time def startup(self, current_time, persistant): self.actual_time = current_time self.persist = persistant level_index = self.persist["level_index"] self.start_level(level_index) return tools._State.startup(self, current_time, persistant) def cleanup(self): self.done = False if self.next == "CHOOSE" or self.next == "LOST": self.persist["level_index"] = self.Maps.index(self.current_level) self.persist["move_on"] = self.move_on self.clear_everything() return self.persist def get_event(self, event): if event.type == pg.KEYDOWN: if event.key == pg.K_ESCAPE: if self.phase == "game": self.pause() elif self.phase == "pause": self.unpause() elif event.type == pg.MOUSEBUTTONUP: if self.phase == "game": self.click(event.pos) elif self.phase == "pause": self.menu_screen.click(event.pos) elif self.phase == "lost": self.lost_screen.click(event.pos) elif self.phase == "won": self.won_screen.click(event.pos) elif self.phase == "tip": self.tip_screen.click(event.pos) elif event.type == pg.MOUSEMOTION: if self.phase == "game": for tower_button in self.tower_buttons: if tower_button.rect.collidepoint(event.pos): if self.hovered: self.hovered.unhover(self) self.hovered = tower_button self.hovered.hover(self) break else: for foundation in self.foundations: if foundation.rect.collidepoint(event.pos): if self.hovered: self.hovered.unhover(self) self.hovered = foundation self.hovered.hover(self) break else: if self.hovered: self.hovered.unhover(self) self.hovered = None elif self.phase == "pause": self.menu_screen.hover(event.pos) elif self.phase == "lost": self.lost_screen.hover(event.pos) elif self.phase == "won": self.won_screen.hover(event.pos) elif self.phase == "tip": self.tip_screen.hover(event.pos) def change_selection(self, obj=None): self.hovered = None self.sidebar.update_selection(self, obj) if self.selected: self.selected.unselect(self) if obj: self.selected = obj self.selected.select(self) else: self.selected = None def click(self, pos): if self.pause_button_rect.collidepoint(pos): self.pause() return for tower_button in self.tower_buttons: if tower_button.rect.collidepoint(pos): tower_button.do_action(self) return everything = pg.sprite.Group(self.towers, self.foundations, self.monsters, self.sidebar.monsters_images) for obj in everything: if obj.rect.collidepoint(pos): self.change_selection(obj) break else: self.change_selection() def action_ok(self): self.unpause() def action_resume(self): self.unpause() def action_restart(self): level_index = self.current_level.number - 1 self.clear_everything() self.start_level(level_index) def action_quit(self): self.next = "CHOOSE" tools.write_scores("scores.txt", self.score) self.move_on = False self.done = True def action_win(self): if self.current_level.number == TOTAL_LEVELS: self.next = "WIN_SCREEN" else: self.next = "CHOOSE" self.move_on = True self.done = True def draw(self): self.screen.blit(self.bg, (0, 0)) self.current_level.draw(self.screen) self.foundations.draw(self.screen) for tower in self.towers: tower.draw(self.screen, self) self.monsters.draw(self.screen) self.bullets.draw(self.screen) self.tower_buttons.draw(self.screen) if self.hovered in self.tower_buttons: self.hovered.draw(self.screen, self) self.sidebar.draw(self.screen) self.screen.blit(self.pause_button, self.pause_button_rect) if self.subtitle: self.subtitle.draw(self.screen) if self.phase == "pause": self.menu_screen.draw(self.screen) elif self.phase == "lost": self.lost_screen.draw(self.screen) elif self.phase == "won": self.won_screen.draw(self.screen) elif self.phase == "tip": self.tip_screen.draw(self.screen) def update(self, surface, keys, current_time, time_delta): self.current_time = current_time if self.phase == "game": self.actual_time = self.current_time - self.time_offset if self.subtitle: self.subtitle.update(self) if self.phase == "game" or self.phase == "tip": if self.lives <= 0: self.phase = "lost" elif self.current_level.done: self.phase = "won" else: self.current_level.update(self) self.bullets.update(self) self.monsters.update(self) self.towers.update(self) if self.wave_in_progress: self.wave_in_progress.update(self) self.draw()