diff --git a/scenes/lvl0_fantome.py b/scenes/lvl0_fantome.py new file mode 100644 index 0000000..4e809b4 --- /dev/null +++ b/scenes/lvl0_fantome.py @@ -0,0 +1,171 @@ +from engine.scene import Scene + + +S=20 + + +entities=[] + + +class PacDot(Entity): + s = Surface((S, S)) + draw.circle(s, (255, 255, 0), (S//2, S//2), S//4) + + def __init__(self): + super().__init__() + CollideRect(self, Rect(0, 0, S, S), + static=True, solid=False, cb=self.cb) + Sprite(self, PacDot.s, 1) + + def cb(self): + self.unregister() + + +def path(start, tgt, x, y, trace, length): + if start == tgt: + return length + if start is None or trace[y][x]: + return False + trace[y][x] = True + u = path(start.up, tgt, x, y-1, trace, length + 1) + d = path(start.down, tgt, x, y+1, trace, length + 1) + l = path(start.left, tgt, x-1, y, trace, length + 1) + r = path(start.right, tgt, x+1, y, trace, length + 1) + best = None + for subpath in (u, d, l, r): + if subpath and (best is None or subpath < best): + best = subpath + return best + + +class Node(): + cpt = 0 + def __init__(self): + self.id = self.__class__.cpt + self.__class__.cpt += 1 + self.up = None + self.down = None + self.left = None + self.right = None + def children(self): + children = [] + for direction in ("up", "down", "left", "right"): + node = getattr(self, direction) + if node is not None: + children.append((node, direction)) + return children + + + +graph = None + + +class Level(Entity): + def __init__(self, path): + global graph + super().__init__() + desc = image.load(res(path)) + w, h = desc.get_size() + GraphicsServer().resize((w * S, h * S)) + graph = [[None for x in range(w)] for y in range(h)] + self.surf = Surface((w * S, h * S)).convert() + self.surf.fill((0, 0, 0)) + wall = Surface((S, S)).convert() + wall.fill((0, 0, 255)) + for x, y in product(range(w), range(h)): + col = desc.get_at((x, y)) + if col == (0, 0, 255): + CollideRect(self, Rect(x * S, y * S, S, S)) + self.surf.blit(wall, (x * S, y * S)) + elif col == (139, 139, 139): + pc = PacDot() + pc.x = x * S + pc.y = y * S + entities.append(pc) + graph[y][x] = Node() + elif col == (0, 0, 0) or col == (255, 0, 0): + graph[y][x] = Node() + for y, line in enumerate(graph): + for x, node in enumerate(line): + if node is None: + continue + node.left = graph[y][(x-1)%w] + node.right = graph[y][(x+1)%w] + node.up = graph[(y-1)%h][x] + node.down = graph[(y+1)%h][x] + Sprite(self, self.surf, 0) + + +class MovingEntity(Entity): + def __init__(self, surf): + super().__init__() + sprite = Sprite(self, surf, 2) + self.phys = CollideRect( + self, + Rect(self.x, self.y, sprite.width, sprite.width), + static=False) + + +class Ghost(MovingEntity): + def __init__(self): + super().__init__(image.load(res('ghost.png')).convert()) + self.script = Ghost.script + + def script(self): + cur_node = graph[self.y//S][self.x//S] + print(self.y//S, self.x//S) + pacman = SceneManager().scene.entities['pacman'] + # pacman_node = graph[pacman.y//S][pacman.x//S] + x_dist = pacman.x - self.x + y_dist = pacman.y - self.y + s = 1 + # self.phys.vx = s if x_dist > 0 else -s + # self.phys.vy = s if y_dist > 0 else -s + p = self.find_shortest_path(graph[pacman.y//S][pacman.x//S]) + print([x[1] for x in p]) + cur_dir = p[0][1] + if cur_dir == "up": + self.phys.vx = 0 + self.phys.vy = -1 + elif cur_dir == "down": + self.phys.vx = 0 + self.phys.vy = 1 + elif cur_dir == "left": + self.phys.vx = -1 + self.phys.vy = 0 + else: + self.phys.vx = 1 + self.phys.vy = 0 + def find_shortest_path(self, final_node): + cur_node = graph[self.y//S][self.x//S] + # pacman_node = graph[pacman.y//S][pacman.x//S] + children = cur_node.children() + trace = [cur_node] + [x[0] for x in children] + # if self.phys.vx < 0: cur_dir = "left" + # elif self.phys.vx > 0: cur_dir = "right" + # elif self.phys.vy < 0: cur_dir = "up" + # else: cur_dir = "down" + paths = [[x] for x in children] + while 1: + cur_len = len(paths) + for path in paths[:cur_len]: + for child in path[-1][0].children(): + if child[0] is not None and child[0] not in trace: + trace.append(child[0]) + paths.append(path + [child]) + if child[0] == final_node: + return path + paths = paths[cur_len:] + +class Lvl0(Scene): + def load(self): + self.add(Level('lvl0.png')) + self.add(PacMan(S, S)) + self.add(Ghost(S*6, S*2)) + self.add(Ghost(S*6, S*13)) + self.add(Ghost(S*18, S*13)) + self.add(Ghost(S*8, S*23)) + super().load() + + +scene = Lvl0()