from random import random, randint from pygame import Rect, image from engine.entity import Entity from engine.game import Game from engine.scene_manager import SceneManager from engine.resources import res from engine.components.collide_rect import CollideRect from engine.components.sprite import Sprite from .common import S, Direction class Ghost(Entity): SPEED = 1 def __init__(self, x, y): super().__init__(self.__repr__()) sprite = Sprite(image.load(res('ghost.png')).convert(), 2) self.add(sprite) self.phys = CollideRect(Rect(self.x, self.y, sprite.width, sprite.width), static=False, solid=False, cb=self.cb) self.add(self.phys) self.script = Ghost.script self.x = x self.y = y self.direction = Direction(randint(0, 3)) def cb(self, c): if not c.solid: return if c.parent.name == 'pacman': print('Perdu !') exit(0) if self.direction == Direction.UP: self.direction = Direction.RIGHT if random() < .5 \ else Direction.LEFT return if self.direction == Direction.RIGHT: self.direction = Direction.DOWN if random() < .5 \ else Direction.UP return if self.direction == Direction.DOWN: self.direction = Direction.LEFT if random() < .5 \ else Direction.RIGHT return if self.direction == Direction.LEFT: self.direction = Direction.UP if random() < .5 \ else Direction.DOWN return def script(self): graph = SceneManager().scene.entities['level'].graph if self.x % S != 0 or self.y % S != 0: return cur_node = graph[self.y//S][self.x//S] # print(self.y//S, self.x//S) pacman = SceneManager().scene.entities['pacman'] x_dist = pacman.x - self.x y_dist = pacman.y - self.y s = 1 # print(pacman.y//S, pacman.x//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 == Direction.UP: self.phys.vx = 0 self.phys.vy = -1 elif cur_dir == Direction.DOWN: self.phys.vx = 0 self.phys.vy = 1 elif cur_dir == Direction.LEFT: self.phys.vx = -1 self.phys.vy = 0 else: self.phys.vx = 1 self.phys.vy = 0 # if self.direction == Direction.UP: # self.phys.vy = -Ghost.SPEED # self.phys.vx = 0 # elif self.direction == Direction.DOWN: # self.phys.vy = Ghost.SPEED # self.phys.vx = 0 # elif self.direction == Direction.LEFT: # self.phys.vx = -Ghost.SPEED # self.phys.vy = 0 # elif self.direction == Direction.RIGHT: # self.phys.vx = Ghost.SPEED # self.phys.vy = 0 def find_shortest_path(self, final_node): if final_node is None: print('oups') exit(1) graph = SceneManager().scene.entities['level'].graph cur_node = graph[self.y//S][self.x//S] children = cur_node.children child_ok = list(filter(lambda c: c[0] == final_node, children)) if child_ok: return [child_ok[0]] trace = [cur_node] + [x[0] for x in children] 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:]