from engine.resources import res from engine.scene import Scene from engine.entity import Entity from engine.components.sprite import Sprite from engine.components.collide_rect import CollideRect from engine.servers.graphics import GraphicsServer from engine.scene_manager import SceneManager from pygame import Rect from pygame import image from pygame import Surface from pygame import draw from pygame.locals import * from pygame import key from itertools import product 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(): def __init__(self): self.up = None self.down = None self.left = None self.right = None graph = None class Level(Entity): def __init__(self, path): 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) # elif col == (0, 0, 0): # graph[y][x] = Node() # for y, line in enumerate(graph): # for x, node in enumerate(line): # if node is None: # continue # if x > 0: # node.left = graph[y][x-1] # if x < w: # node.right = graph[y][x+1] # if y > 0: # node.up = graph[y-1][x] # if y < h: # node.down = graph[y+1][y] 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] 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 class Lvl0(Scene): def load(self): T = 1 v = 2 pac_surf = Surface((S//T, S//T)).convert() pac_surf.fill((0, 0, 0)) draw.circle(pac_surf, (255, 255, 0), (S//(2*T), S//(2*T)), S//(2*T)) pacman = MovingEntity(pac_surf) def pacman_script(entity): p = pacman.phys inputs = key.get_pressed() if T > 1: p.vx = 0 p.vy = 0 if inputs[K_UP]: p.vy = -v if inputs[K_DOWN]: p.vy = v if inputs[K_LEFT]: p.vx = -v if inputs[K_RIGHT]: p.vx = v pacman.script = pacman_script pacman.x = pacman.phys.rect.x = S*1 pacman.y = pacman.phys.rect.y = S*1 pacman.phys.rect.w = S//T pacman.phys.rect.h = S//T self.entities['level'] = Level('lvl0.png') for i, entity in enumerate(entities): self.entities[f'pacdot-{i}'] = entity self.entities['pacman'] = pacman self.entities['ghost'] = Ghost() self.entities['ghost'].x = S*6 self.entities['ghost'].y = S*2 super().load() scene = Lvl0()