from itertools import product from enum import Enum, auto from pygame import Surface, Rect, image from engine.entity import Entity from engine.resources import res from engine.servers.graphics import GraphicsServer from engine.components.collide_rect import CollideRect from engine.components.sprite import Sprite from .common import S, Direction from .pacdot import PacDot, EnsmallmentDot class Node(): cpt = 0 def __init__(self): self.id = self.__class__.cpt self.__class__.cpt += 1 self.neighbors = [None for dir in Direction] @property def children(self): children = [] for direction in Direction: node = self.neighbors[direction.value] if node is not None: children.append((node, direction)) return children class Level(Entity): class Tile(Enum): AIR = auto() WALL = auto() def __init__(self, path): super().__init__('level') self.path = path colors = {(0, 0, 0): Tile.AIR, # empty (0, 0, 255): Tile.WALL, # wall (255, 0, 0): Tile.AIR, # tele (255, 255, 0): Tile.WALL, # idk (255, 0, 255): Tile.WALL, # inside cage (0, 255, 0): Tile.WALL, # cage entrance (0, 255, 255): Tile.WALL, # cage wall (139, 139, 139): Tile.AIR, # pac-dot (193, 193, 193): Tile.AIR} # ensmallment dot def load(self): desc = image.load(res(self.path)) w, h = desc.get_size() self.w = w * S self.h = h * S GraphicsServer().resize((w * S, h * S)) self.surf = Surface((w * S, h * S)).convert() self.surf.fill((0, 0, 0)) wall = Surface((S, S)).convert() wall.fill((0, 0, 255)) self.graph = [[None for x in range(w)] for y in range(h)] for x, y in product(range(w), range(h)): col = desc.get_at((x, y))[:3] if Level.colors[col] == Level.Tile.AIR: self.graph[y][x] = Node() elif Level.colors[col] == Level.Tile.WALL: self.add(CollideRect(Rect(x * S, y * S, S, S))) wall.fill(col) self.surf.blit(wall, (x * S, y * S)) if col == (139, 139, 139): # pac-dot pc = PacDot() pc.x = x * S pc.y = y * S self.scene.add(pc) PacDot.tot += 1 elif col == (193, 193, 193): # ensmallment dot pc = EnsmallmentDot() pc.x = x * S pc.y = y * S self.scene.add(pc) self.add(Sprite(self.surf, 0)) for y, line in enumerate(self.graph): for x, node in enumerate(line): if node is None: continue node.neighbors[Direction.LEFT.value] = \ self.graph[y][(x-1) % w] node.neighbors[Direction.RIGHT.value] = \ self.graph[y][(x+1) % w] node.neighbors[Direction.UP.value] = \ self.graph[(y-1) % h][x] node.neighbors[Direction.DOWN.value] = \ self.graph[(y+1) % h][x]