This repository has been archived on 2019-12-09. You can view files and clone it, but cannot push or open issues or pull requests.
pacman2/scenes/game_objects/level.py

98 lines
3.2 KiB
Python

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]