105 lines
3.4 KiB
Python
105 lines
3.4 KiB
Python
from random import random, randint
|
||
|
||
from pygame import Rect, image
|
||
|
||
from engine.entity import Entity
|
||
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):
|
||
level = SceneManager().scene.entities['level']
|
||
if self.x >= level.w:
|
||
self.x = 0
|
||
if self.x < 0:
|
||
self.x = level.w-1
|
||
|
||
if self.x % S != 0 or self.y % S != 0:
|
||
return
|
||
graph = SceneManager().scene.entities['level'].graph
|
||
pacman = SceneManager().scene.entities['pacman']
|
||
p = self.find_shortest_path(graph[pacman.y//S][pacman.x//S])
|
||
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
|
||
|
||
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:]
|