def __init__(self, root, controller): self.controller = controller root.wm_title("PacMan") self.windowsystem = root.call('tk', 'windowingsystem') self.frame = root self.canvas = Canvas(self.frame, width=CANVAS_WIDTH, height=CANVAS_HEIGHT, bg="black") self.canvas.pack(side = LEFT, fill=BOTH, expand=FALSE) self.__init_fonts() self.__init_score() self.__messages_displayed = [False, False] self.__text = [None, None] self.lives = 0 self.lives_pacmen = [] self.__ghost_views = [] self.__pacman_views = [] self.__food = {} # we use a dict to store food, indexed by grid coordinates self.__powerpills = {} # also a dict self.__tags = [] self.audio = Audio() #Load all the images from files self.__pacman_pngs = [] for i in range(0, 3): self.__pacman_pngs.append(PhotoImage(file = './assets/pacman' + str(i) + '.gif').zoom(2)) self.__pacman_dying_pngs = [] for i in range(1, 11): self.__pacman_dying_pngs.append(PhotoImage(file = './assets/pacman_dying' + str(i) + '.gif').zoom(2)) self.__ghost_left_pngs = [] for i in range(0, 4): self.__ghost_left_pngs.append(PhotoImage(file = './assets/ghost' + str(i) + '.gif').zoom(2)) self.__ghost_up_pngs = [] for i in range(0, 4): self.__ghost_up_pngs.append(PhotoImage(file = './assets/ghost' + str(i) + 'up.gif').zoom(2)) self.__ghost_down_pngs = [] for i in range(0, 4): self.__ghost_down_pngs.append(PhotoImage(file = './assets/ghost' + str(i) + 'down.gif').zoom(2)) self.__ghost_scared_pngs = [] self.__ghost_scared_pngs.append(PhotoImage(file = './assets/ghostscared.gif').zoom(2)) self.__ghost_scared_pngs.append(PhotoImage(file = './assets/ghostscaredending.gif').zoom(2)) self.__ghost_eyes_pngs = [] for i in range(0,4): self.__ghost_eyes_pngs.append(PhotoImage(file = './assets/eyes' + str(i) + '.gif').zoom(2)) self.__food_png = PhotoImage(file = './assets/food.gif').zoom(2) self.__powerpill_png = PhotoImage(file = './assets/powerpill.gif').zoom(2)
class View(Frame): def __init__(self, root, controller): self.controller = controller root.wm_title("PacMan") self.windowsystem = root.call('tk', 'windowingsystem') self.frame = root self.canvas = Canvas(self.frame, width=CANVAS_WIDTH, height=CANVAS_HEIGHT, bg="black") self.canvas.pack(side = LEFT, fill=BOTH, expand=FALSE) self.__init_fonts() self.__init_score() self.__messages_displayed = [False, False] self.__text = [None, None] self.lives = 0 self.lives_pacmen = [] self.__ghost_views = [] self.__pacman_views = [] self.__food = {} # we use a dict to store food, indexed by grid coordinates self.__powerpills = {} # also a dict self.__tags = [] self.audio = Audio() #Load all the images from files self.__pacman_pngs = [] for i in range(0, 3): self.__pacman_pngs.append(PhotoImage(file = './assets/pacman' + str(i) + '.gif').zoom(2)) self.__pacman_dying_pngs = [] for i in range(1, 11): self.__pacman_dying_pngs.append(PhotoImage(file = './assets/pacman_dying' + str(i) + '.gif').zoom(2)) self.__ghost_left_pngs = [] for i in range(0, 4): self.__ghost_left_pngs.append(PhotoImage(file = './assets/ghost' + str(i) + '.gif').zoom(2)) self.__ghost_up_pngs = [] for i in range(0, 4): self.__ghost_up_pngs.append(PhotoImage(file = './assets/ghost' + str(i) + 'up.gif').zoom(2)) self.__ghost_down_pngs = [] for i in range(0, 4): self.__ghost_down_pngs.append(PhotoImage(file = './assets/ghost' + str(i) + 'down.gif').zoom(2)) self.__ghost_scared_pngs = [] self.__ghost_scared_pngs.append(PhotoImage(file = './assets/ghostscared.gif').zoom(2)) self.__ghost_scared_pngs.append(PhotoImage(file = './assets/ghostscaredending.gif').zoom(2)) self.__ghost_eyes_pngs = [] for i in range(0,4): self.__ghost_eyes_pngs.append(PhotoImage(file = './assets/eyes' + str(i) + '.gif').zoom(2)) self.__food_png = PhotoImage(file = './assets/food.gif').zoom(2) self.__powerpill_png = PhotoImage(file = './assets/powerpill.gif').zoom(2) def __init_fonts(self): self.__bigfont = font.nametofont("TkDefaultFont") self.__bigfont.configure(size=48) self.__scorefont = font.nametofont("TkDefaultFont") self.__scorefont.configure(size=20) def __init_score(self): self.__score_text = self.canvas.create_text(5, 5, anchor="nw") self.canvas.itemconfig(self.__score_text, text="Score:", font=self.__scorefont, fill="white") def update_maze(self, maze): s = "" y = 0 for tag in self.__tags: self.canvas.delete(tag) self.__tags.clear() for row in maze: for x in range(0, len(row)//3): c = row[x*3:(x+1)*3] sx = x + 0.5 # x and y give the middle of the square, # so sx, sy give the top left corner sy = y - 0.5 if c == " /-": tag = self.canvas.create_arc(L_OFF + x * GRID_SIZE, T_OFF + y * GRID_SIZE, L_OFF + (x+1) * GRID_SIZE, T_OFF + (y+1) * GRID_SIZE, start=90, extent=90, style=ARC, width=2, outline = "blue") s += " /-" elif c == "-/ ": tag = self.canvas.create_arc(L_OFF + (x-1) * GRID_SIZE, T_OFF + (y-1) * GRID_SIZE, L_OFF + x * GRID_SIZE, T_OFF + y * GRID_SIZE, start=270, extent=90, style=ARC, width=2, outline= "blue") s += "-/ " elif c == "---": tag = self.canvas.create_line(L_OFF + (x-0.5) * GRID_SIZE, T_OFF + y * GRID_SIZE, L_OFF + (x+0.5) * GRID_SIZE, T_OFF + y * GRID_SIZE, width = 2, fill= "blue") s += "---" elif c == "-\\ ": tag = self.canvas.create_arc(L_OFF + (x-1) * GRID_SIZE, T_OFF + y * GRID_SIZE, L_OFF + x * GRID_SIZE, T_OFF + (y+1) * GRID_SIZE, start=0, extent=90, style=ARC, width=2, outline= "blue") s += "-\\ " elif c == " \\-": tag = self.canvas.create_arc(L_OFF + x * GRID_SIZE, T_OFF + (y-1) * GRID_SIZE, L_OFF + (x+1) * GRID_SIZE, T_OFF + y * GRID_SIZE, start=180, extent=90, style=ARC, width=2, outline= "blue") s += " \\-" elif c == " | ": tag = self.canvas.create_line(L_OFF + x * GRID_SIZE, T_OFF + (y-0.5) * GRID_SIZE, L_OFF + x * GRID_SIZE, T_OFF + (y+0.5) * GRID_SIZE, width = 2, fill= "blue") s += " | " elif c == " ": s += " " elif c == "###": s += " " elif c == " . ": s += " . " elif c == " * ": s += " * " elif c == " A ": s += " A " elif c == " B ": s += " B " else: s += "ERROR>>>" + c + "<<<" self.__tags.append(tag) s += "\n" y += 1 #print(s) def register_pacman(self, pacman_model): self.__pacman_views.append(PacmanView(self.canvas, pacman_model, self.__pacman_pngs, self.__pacman_dying_pngs)) def unregister_pacman(self, pacman_model): #print("unregister_pacman") for view in self.__pacman_views: if view.pacman == pacman_model: #print("foound view to unregister") #print("status", view.pacman.status) view.cleanup() self.__pacman_views.remove(view) return def register_ghost(self, ghost_model): ghostnum = ghost_model.ghostnum pngs = [] pngs.append(self.__ghost_up_pngs[ghostnum]) pngs.append(self.__ghost_left_pngs[ghostnum]) pngs.append(self.__reflect_image(self.__ghost_left_pngs[ghostnum])) pngs.append(self.__ghost_down_pngs[ghostnum]) self.__ghost_views.append(GhostView(self.canvas, ghost_model, pngs, self.__ghost_eyes_pngs, self.__ghost_scared_pngs)) def register_food(self, coord_list): for coords in coord_list: food = Food(self.canvas, coords, self.__food_png) self.__food[coords] = food def register_powerpills(self, coord_list): for coords in coord_list: # we use a Food object with a powerpill image powerpill = Food(self.canvas, coords, self.__powerpill_png) self.__powerpills[coords] = powerpill def eat(self, coords, is_powerpill): if is_powerpill: self.eat_powerpill(coords) else: self.eat_food(coords) def eat_food(self, coords): food = self.__food[coords] food.eat() self.__food.pop(coords) self.audio.play(0) def eat_powerpill(self, coords): powerpill = self.__powerpills[coords] powerpill.eat() self.__powerpills.pop(coords) self.audio.play(0) def ghost_died(self): self.audio.play(3) def unregister_objects(self): for view in self.__ghost_views: view.cleanup() self.__ghost_views.clear() for coords,food in self.__food.items(): food.cleanup() self.__food.clear() for coords,pp in self.__powerpills.items(): pp.cleanup() self.__powerpills.clear() def display_score(self): myscore, theirscore = self.controller.get_scores() self.canvas.itemconfig(self.__score_text, text="Level: " + str(self.controller.get_level()) + " Player 1: " + str(myscore) + " Player 2: " + str(theirscore), font=self.__scorefont) self.update_lives() def __reflect_image(self, img): w, h = img.width(), img.height() newimg = PhotoImage(width=w, height=h) for x in range(w): for y in range(h): rgb = '#%02x%02x%02x' % get_tuple(img.get(x, y)) newimg.put(rgb, (w-x, y)) return newimg def update_lives(self): lives = self.controller.get_lives() if lives != self.lives: self.lives = lives for pacman_view in self.lives_pacmen: pacman_view.cleanup() self.lives_pacmen.clear() y = GRID_SIZE * 32 # 16 rows down is where we show the lives remaining life_pngs = [self.__pacman_pngs[2]] for i in range(0, self.lives - 1): x = 2 * GRID_SIZE * (i + 1) dummy = DummyPacman(x, y) self.lives_pacmen.append(PacmanView(self.canvas, dummy, life_pngs, [])) def died(self, pacman, clear_ghosts): for view in self.__pacman_views: if view.pacman == pacman: view.died() self.audio.play(2) if clear_ghosts: for ghost in self.__ghost_views: ghost.cleanup() self.__ghost_views.clear() def reset_level(self): self.clear_messages() self.audio.play(1) def game_over(self): self.display_msg_line1("GAME OVER!") self.display_msg_line2("Press r to play again.") def display_msg(self, msg): self.clear_messages() print("display_msg", msg) self.display_msg_line1(msg) def display_msg_line1(self, msg): x = 14 * GRID_SIZE + L_OFF y = 11 * GRID_SIZE + T_OFF self.__text[0] = self.canvas.create_text(x, y, anchor="c") self.canvas.itemconfig(self.__text[0], text=msg, font=self.__bigfont, fill="white") self.__messages_displayed[0] = True def display_msg_line2(self, msg): x = 14 * GRID_SIZE + L_OFF y = 17 * GRID_SIZE + T_OFF self.__text[1] = self.canvas.create_text(x, y, anchor="c") self.canvas.itemconfig(self.__text[1], text=msg, font=self.__scorefont, fill="white") self.__messages_displayed[1] = True def clear_messages(self): for line in range(0, 2): if self.__messages_displayed[line]: self.canvas.delete(self.__text[line]) self.__messages_displayed[line] = False def update(self, now): for view in self.__pacman_views: view.redraw(now, self.frame) for view in self.__ghost_views: view.redraw(now, self.frame) self.display_score()
class View(Frame): def __init__(self, root, controller, name, zoom): self.zoom = zoom self.controller = controller self.name = name root.wm_title("PacMan") self.windowsystem = root.call('tk', 'windowingsystem') self.frame = root div = 2//zoom self.canvas = Canvas(self.frame, width=(CANVAS_WIDTH-L_OFF)//div+L_OFF, height=CANVAS_HEIGHT//div, bg="black") self.canvas.pack(side = LEFT, fill=BOTH, expand=FALSE) self.__init_fonts() self.__init_score() self.__messages_displayed = [False, False] self.__text = [None, None] self.mylives = 0 self.mylives_pacmen = [] self.theirlives = 0 self.theirlives_pacmen = [] self.__ghost_views = [] self.__pacman_views = [] self.__food = {} # we use a dict to store food, indexed by grid coordinates self.__powerpills = {} # also a dict self.__tags = [] self.audio = Audio() #Load all the images from files self.__pacman_pngs = [[],[]] for i in range(0, 3): self.__pacman_pngs[0].append(PhotoImage(file = './assets/pacman' + str(i) + '.gif').zoom(self.zoom)) self.__pacman_pngs[1].append(PhotoImage(file = './assets/pacman' + str(i) + 'p.gif').zoom(self.zoom)) self.__pacman_dying_pngs = [[],[]] for i in range(1, 11): self.__pacman_dying_pngs[0].append(PhotoImage(file = './assets/pacman_dying' + str(i) + '.gif').zoom(self.zoom)) self.__pacman_dying_pngs[1].append(PhotoImage(file = './assets/pacman_dying' + str(i) + 'p.gif').zoom(self.zoom)) self.__ghost_left_pngs = [] for i in range(0, 4): self.__ghost_left_pngs.append(PhotoImage(file = './assets/ghost' + str(i) + '.gif').zoom(self.zoom)) self.__ghost_up_pngs = [] for i in range(0, 4): self.__ghost_up_pngs.append(PhotoImage(file = './assets/ghost' + str(i) + 'up.gif').zoom(self.zoom)) self.__ghost_down_pngs = [] for i in range(0, 4): self.__ghost_down_pngs.append(PhotoImage(file = './assets/ghost' + str(i) + 'down.gif').zoom(self.zoom)) self.__ghost_scared_pngs = [] self.__ghost_scared_pngs.append(PhotoImage(file = './assets/ghostscared.gif').zoom(self.zoom)) self.__ghost_scared_pngs.append(PhotoImage(file = './assets/ghostscaredending.gif').zoom(self.zoom)) self.__ghost_eyes_pngs = [] for i in range(0,4): self.__ghost_eyes_pngs.append(PhotoImage(file = './assets/eyes' + str(i) + '.gif').zoom(self.zoom)) self.__food_png = PhotoImage(file = './assets/food.gif').zoom(self.zoom) self.__powerpill_png = PhotoImage(file = './assets/powerpill.gif').zoom(self.zoom) def __str__(self): return "view-"+self.name def __init_fonts(self): # fonts are global, so don't set font in small window if self.name == "local": self.__bigfont = font.nametofont("TkDefaultFont") self.__bigfont.configure(size=24*self.zoom) self.__scorefont = font.nametofont("TkDefaultFont") self.__scorefont.configure(size=10*self.zoom) def __init_score(self): if self.name == "local": self.__score_text = self.canvas.create_text(5, 5, anchor="nw") self.canvas.itemconfig(self.__score_text, text="", font=self.__scorefont, fill="white") def update_maze(self, maze): s = "" y = 0 for tag in self.__tags: self.canvas.delete(tag) self.__tags.clear() gridsize = (GRID_SIZE *self.zoom)//2 for row in maze: for x in range(0, len(row)//3): c = row[x*3:(x+1)*3] sx = x + 0.5 # x and y give the middle of the square, # so sx, sy give the top left corner sy = y - 0.5 if c == " /-": tag = self.canvas.create_arc(L_OFF + x * gridsize, T_OFF + y * gridsize, L_OFF + (x+1) * gridsize, T_OFF + (y+1) * gridsize, start=90, extent=90, style=ARC, width=2, outline = "blue") s += " /-" elif c == "-/ ": tag = self.canvas.create_arc(L_OFF + (x-1) * gridsize, T_OFF + (y-1) * gridsize, L_OFF + x * gridsize, T_OFF + y * gridsize, start=270, extent=90, style=ARC, width=2, outline= "blue") s += "-/ " elif c == "---": tag = self.canvas.create_line(L_OFF + (x-0.5) * gridsize, T_OFF + y * gridsize, L_OFF + (x+0.5) * gridsize, T_OFF + y * gridsize, width = 2, fill= "blue") s += "---" elif c == "-\\ ": tag = self.canvas.create_arc(L_OFF + (x-1) * gridsize, T_OFF + y * gridsize, L_OFF + x * gridsize, T_OFF + (y+1) * gridsize, start=0, extent=90, style=ARC, width=2, outline= "blue") s += "-\\ " elif c == " \\-": tag = self.canvas.create_arc(L_OFF + x * gridsize, T_OFF + (y-1) * gridsize, L_OFF + (x+1) * gridsize, T_OFF + y * gridsize, start=180, extent=90, style=ARC, width=2, outline= "blue") s += " \\-" elif c == " | ": tag = self.canvas.create_line(L_OFF + x * gridsize, T_OFF + (y-0.5) * gridsize, L_OFF + x * gridsize, T_OFF + (y+0.5) * gridsize, width = 2, fill= "blue") s += " | " elif c == " ": s += " " elif c == "###": s += " " elif c == " . ": s += " . " elif c == " * ": s += " * " elif c == " A ": s += " A " elif c == " B ": s += " B " else: s += "ERROR>>>" + c + "<<<" self.__tags.append(tag) s += "\n" y += 1 def register_pacman(self, pacman_model): if pacman_model.name == "Pacman1": ix = 0 else: ix = 1 self.__pacman_views.append(PacmanView(self.canvas, pacman_model, self.__pacman_pngs[ix], self.__pacman_dying_pngs[ix], self.zoom)) def unregister_pacman(self, pacman_model): for view in self.__pacman_views: if view.pacman == pacman_model: view.cleanup() self.__pacman_views.remove(view) return def register_ghost(self, ghost_model): ghostnum = ghost_model.ghostnum pngs = [] pngs.append(self.__ghost_up_pngs[ghostnum]) pngs.append(self.__ghost_left_pngs[ghostnum]) pngs.append(self.__reflect_image(self.__ghost_left_pngs[ghostnum])) pngs.append(self.__ghost_down_pngs[ghostnum]) self.__ghost_views.append(GhostView(self.canvas, ghost_model, pngs, self.__ghost_eyes_pngs, self.__ghost_scared_pngs, self, self.zoom)) def unregister_ghosts(self): for ghost in self.__ghost_views: ghost.cleanup() self.__ghost_views.clear() def register_food(self, coord_list): for coords in coord_list: food = Food(self.canvas, coords, self.__food_png, self.zoom) self.__food[coords] = food def register_powerpills(self, coord_list): for coords in coord_list: # we use a Food object with a powerpill image powerpill = Food(self.canvas, coords, self.__powerpill_png, self.zoom) self.__powerpills[coords] = powerpill def eat(self, coords, is_powerpill): if is_powerpill: self.eat_powerpill(coords) else: self.eat_food(coords) def eat_food(self, coords): food = self.__food[coords] food.eat() self.__food.pop(coords) self.audio.play(0) def eat_powerpill(self, coords): powerpill = self.__powerpills[coords] powerpill.eat() self.__powerpills.pop(coords) self.audio.play(0) def ghost_died(self): self.audio.play(3) def unregister_objects(self): for view in self.__ghost_views: view.cleanup() self.__ghost_views.clear() for coords,food in self.__food.items(): food.cleanup() self.__food.clear() for coords,pp in self.__powerpills.items(): pp.cleanup() self.__powerpills.clear() def display_score(self): if self.name == "remote": return myscore, theirscore = self.controller.get_scores() self.canvas.itemconfig(self.__score_text, text="Level: " + str(self.controller.get_level()) + " Player 1: " + str(myscore) + " Player 2: " + str(theirscore), font=self.__scorefont) self.update_lives() def __reflect_image(self, img): w, h = img.width(), img.height() newimg = PhotoImage(width=w, height=h) for x in range(w): for y in range(h): rgb = '#%02x%02x%02x' % get_tuple(img.get(x, y)) newimg.put(rgb, (w-x, y)) return newimg def update_lives(self): mylives, theirlives = self.controller.get_lives() if mylives != self.mylives: self.mylives = mylives for pacman_view in self.mylives_pacmen: pacman_view.cleanup() self.mylives_pacmen.clear() y = GRID_SIZE * 32 # 16 rows down is where we show the lives remaining life_pngs = [self.__pacman_pngs[0][2]] for i in range(0, self.mylives - 1): x = 2 * GRID_SIZE * (i + 1) dummy = DummyPacman(x, y) self.mylives_pacmen.append(PacmanView(self.canvas, dummy, life_pngs, [], self.zoom)) if theirlives != self.theirlives: self.theirlives = theirlives for pacman_view in self.theirlives_pacmen: pacman_view.cleanup() self.theirlives_pacmen.clear() y = (GRID_SIZE + 1) * 32 # 16 rows down is where we show the lives remaining life_pngs = [self.__pacman_pngs[1][2]] for i in range(0, self.theirlives - 1): x = 2 * GRID_SIZE * (i + 1) dummy = DummyPacman(x, y) self.theirlives_pacmen.append(PacmanView(self.canvas, dummy, life_pngs, [], self.zoom)) def died(self, pacman, clear_ghosts): for view in self.__pacman_views: if view.pacman == pacman: view.died() self.audio.play(2) if clear_ghosts: for ghost in self.__ghost_views: ghost.cleanup() self.__ghost_views.clear() def reset_level(self): self.clear_messages() self.audio.play(1) def game_over(self): self.display_msg_line1("GAME OVER!") self.display_msg_line2("Press r to play again.") def display_msg(self, msg): self.clear_messages() self.display_msg_line1(msg) def display_msg_line1(self, msg): x = 14 * GRID_SIZE + L_OFF y = 11 * GRID_SIZE + T_OFF self.__text[0] = self.canvas.create_text(x, y, anchor="c") self.canvas.itemconfig(self.__text[0], text=msg, font=self.__bigfont, fill="white") self.__messages_displayed[0] = True def display_msg_line2(self, msg): x = 14 * GRID_SIZE + L_OFF y = 17 * GRID_SIZE + T_OFF self.__text[1] = self.canvas.create_text(x, y, anchor="c") self.canvas.itemconfig(self.__text[1], text=msg, font=self.__scorefont, fill="white") self.__messages_displayed[1] = True def clear_messages(self): for line in range(0, 2): if self.__messages_displayed[line]: self.canvas.delete(self.__text[line]) self.__messages_displayed[line] = False def update(self, now): for view in self.__pacman_views: view.redraw(now, self.frame) for view in self.__ghost_views: view.redraw(now, self.frame) self.display_score()