class TileUndefined(Tile): Sprite = TL.load_sprite(get_path("wall/empty.png")) #replace wall/empty.png with your own undefined.png if you want def __init__(self): super(TileUndefined, self).__init__() self.set_sprite(TileUndefined.Sprite)
class TileWall(Tile): Sprite = TL.load_sprite(get_path("wall/wall.png")) def __init__(self): super(TileWall, self).__init__() self.set_sprite(TileWall.Sprite) def is_wall(self): return True
class TilePowerPellet(TileFood): Sprite = TL.load_sprite(get_path("food/powerpellet.png")) def __init__(self): super(TilePowerPellet, self).__init__() self.reset() def eat(self): self.set_sprite(TileEmpty.Sprite) self.score_value = 0 self.edible = False def reset(self): self.set_sprite(TilePowerPellet.Sprite) self.score_value = 50 self.edible = True
class TileFood(Tile): Sprite = TL.load_sprite(get_path("food/food.png")) def __init__(self): super(TileFood, self).__init__() self.reset() def eat(self): self.set_sprite(TileEmpty.Sprite) self.score_value = 0 self.edible = False def reset(self): self.set_sprite(TileFood.Sprite) self.score_value = 10 self.edible = True
def loadMap(self, path): self.maze = Maze() self.player = [] self.ghosts = [] self.maze.load_map(self, path, self.player, self.ghosts) self.player = self.player[-1] n = 100 c, r = self.maze.get_max_cols(), self.maze.get_max_rows() + 1 k = max(c, r) + 1 self.frame = TL.Frame().resize(n * k, n * k).set_tile_scale(n, n).set_pos( Vec(0.5, 0.5)) self.frame.set_renderer(self.renderer) self.icons_lives = [] x = 0 for i in ["player/0.png"] * 3: self.icons_lives.append( Icon(TL.load_sprite(get_path(i))).set_pos(Vec(x, r - 1))) x += 1 for i in [self.maze] + self.ghosts + [self.player] + self.icons_lives: self.frame.add_child(i) self.ghost_home = [] for i in self.ghosts: self.ghost_home.append(i.pos) self.update_player_search_matrix() self.home_search_matrix = search_dijkstra(self.ghost_home, self.maze.get_max_rows(), self.maze.get_max_cols(), self.maze.get_adj_nodes) self.respawn_entities()
class Ghost(Mover): dir_path = ["right", "up", "left", "down"] Sprite_Eyes = [ TL.load_sprite(get_path("eyes/eyes_" + i + ".png")) for i in dir_path ] Sprite_Edible = [ TL.load_sprite_animation(get_path("chase_" + i)).set_length(500) for i in dir_path ] CHASE = 0 EDIBLE = 1 EATEN = 2 def __init__(self, parent): super(Ghost, self).__init__(parent) self.mid = 350 self.len_interv = 400 self.chase_vel = 0.07 self.fright_vel = 0.04 self.scatter_vel = 0.04 self.home_vel = 0.30 self.score_value = 1000 self.t = 0 if not hasattr(self, 'sprite_normal'): k = ["blink", "ink", "clyde", "shadow"][random.randint(0, 3)] + "_" self.sprite_normal = [ TL.load_sprite_animation(get_path(k + i)).set_length(250) for i in Ghost.dir_path ] def respawn(self): self.update_scatter_matrix() self.pos = self.spawn_pos self.set_sprite(self.sprite_normal[-1]) self.state = Ghost.CHASE self._next_pos = Vec(0, 0) self.t = 0 return self def set_pos(self, pos=Vec(0, 0)): super(Ghost, self).set_pos(pos) self.spawn_pos = pos return self def get_angle_index(self): return int(abs(4 - round(2 * self.vel.angle() / math.pi))) % 4 def get_direction(self, search_matrix): ds = (self.pos - self._next_pos).apply(round).apply(abs) if (ds.x < 0.01 or 1 <= ds.x) and (ds.y < 0.01 or 1 <= ds.y): i, j = self.pos.apply(round).apply(int) pos_lst = search_matrix[i][j] if pos_lst != [] and pos_lst != None: if isinstance(pos_lst, list): i, j = pos_lst[0] else: i, j = pos_lst self._next_pos = Vec(i, j) else: self._next_pos = self.pos return (self._next_pos - self.pos).norm() def update_scatter_matrix(self): maze = self.parent.get_maze() r, c = maze.get_max_cols(), maze.get_max_rows() self.scatter_pos = self.pos while maze.get_tile(self.scatter_pos).is_wall() or ( self.pos - self.scatter_pos).mag_manhattan() < 1: self.scatter_pos = Vec(random.randint(0, r - 1), random.randint(0, c - 1)) self.scatter_matrix = search_dijkstra( [self.scatter_pos], c, r, self.parent.get_maze().get_adj_nodes) def chase(self): phase = self.t % self.len_interv vel = Vec(0, 0) if phase < self.mid: vel = self.get_direction( self.parent.player_search_matrix) * self.chase_vel elif phase == self.mid: self.update_scatter_matrix() else: if (self.scatter_pos - self.pos).mag_manhattan() < 1: self.update_scatter_matrix() vel = self.get_direction(self.scatter_matrix) * self.scatter_vel self.set_vel(vel) def retreat(self): if (self.scatter_pos - self.pos).mag_manhattan() < 1: self.update_scatter_matrix() self.set_vel( self.get_direction(self.scatter_matrix) * self.scatter_vel) def update(self): super(Ghost, self).update() if self.state == Ghost.CHASE: self.set_sprite(self.sprite_normal[self.get_angle_index()]) self.chase() elif self.state == Ghost.EDIBLE: self.set_sprite(Ghost.Sprite_Edible[self.get_angle_index()]) self.retreat() elif self.state == Ghost.EATEN: self.set_sprite(Ghost.Sprite_Eyes[self.get_angle_index()]) self.set_vel( self.get_direction(self.parent.home_search_matrix) * self.home_vel) if isinstance( self.parent.get_maze().get_tile(self.pos.apply(round)), TileGhostHome): self.state = Ghost.CHASE self.t += 1 def get_eaten(self, player): if (self.pos - self.parent.player.pos).mag_chebyshev() < 1: if self.state == Ghost.CHASE: player.get_eaten() elif self.state == Ghost.EDIBLE: self.state = Ghost.EATEN if not self.parent.sound_eatghost.isPlaying(): self.parent.sound_eatghost.rewind() self.parent.sound_eatghost.play() return 1000 return 0 def become_edible(self): if self.state == Ghost.CHASE: self.state = Ghost.EDIBLE return self def become_inedible(self): if self.state == Ghost.EDIBLE: self.state = Ghost.CHASE return self
class TileGhostHome(Tile): Sprite = TL.load_sprite(get_path("wall/empty.png")) def __init__(self): super(TileGhostHome, self).__init__() self.set_sprite(TileGhostHome.Sprite)