voilà les fantômes dans lvl0_fantome.py avec le plus court chemin mais problème car il se détecte dans la case courante alors qu'il devrait prendre en compte la case en fonction de sa direction - si vers le haut; case courante = [(y-taille_fantome)//S][x//S]
This commit is contained in:
parent
4214c5819c
commit
5c6f690a98
171
scenes/lvl0_fantome.py
Normal file
171
scenes/lvl0_fantome.py
Normal file
@ -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()
|
Reference in New Issue
Block a user