From 9dac58f8bd5120e73a4ac879bfc3059dd7ef58c6 Mon Sep 17 00:00:00 2001 From: papush! Date: Mon, 9 Dec 2019 12:36:42 +0100 Subject: [PATCH] lol le retard --- engine/components/collide_rect.py | 18 ++-- engine/components/component.py | 9 +- engine/components/sprite.py | 4 +- engine/entity.py | 10 +- engine/game.py | 3 + engine/scene.py | 5 + engine/servers/physics.py | 8 +- res/pacman_1.png | Bin 0 -> 9817 bytes res/pacman_2.png | Bin 0 -> 739 bytes scenes/__init__.py | 0 scenes/game_objects/__init__.py | 0 scenes/game_objects/common.py | 1 + scenes/game_objects/ghost.py | 77 ++++++++++++++ scenes/game_objects/level.py | 39 +++++++ scenes/game_objects/pacdot.py | 34 ++++++ scenes/game_objects/pacman.py | 80 ++++++++++++++ scenes/lvl0.py | 170 ++---------------------------- 17 files changed, 282 insertions(+), 176 deletions(-) create mode 100644 res/pacman_1.png create mode 100644 res/pacman_2.png create mode 100644 scenes/__init__.py create mode 100644 scenes/game_objects/__init__.py create mode 100644 scenes/game_objects/common.py create mode 100644 scenes/game_objects/ghost.py create mode 100644 scenes/game_objects/level.py create mode 100644 scenes/game_objects/pacdot.py create mode 100644 scenes/game_objects/pacman.py diff --git a/engine/components/collide_rect.py b/engine/components/collide_rect.py index 3ca7d8d..39a6133 100644 --- a/engine/components/collide_rect.py +++ b/engine/components/collide_rect.py @@ -3,21 +3,23 @@ from ..servers.physics import PhysicsServer class CollideRect(Component): - def __init__(self, parent, rect, static=True, solid=True, cb=None): - super().__init__(parent) + def __init__(self, rect, static=True, solid=True, cb=None): + super().__init__() self.rect = rect - def x_change_cb(x): - self.rect.x = x - def y_change_cb(y): - self.rect.y = y - parent.subscribe('x', x_change_cb) - parent.subscribe('y', y_change_cb) self.static = static self.solid = solid self.cb = cb self.vx = 0 self.vy = 0 + def load(self): + def x_change_cb(x): + self.rect.x = x + def y_change_cb(y): + self.rect.y = y + self.parent.subscribe('x', x_change_cb) + self.parent.subscribe('y', y_change_cb) + def register(self): PhysicsServer().register_component(self) diff --git a/engine/components/component.py b/engine/components/component.py index 9da54ce..4e8a434 100644 --- a/engine/components/component.py +++ b/engine/components/component.py @@ -2,9 +2,12 @@ from abc import abstractmethod class Component: - def __init__(self, parent): - self.parent = parent - self.parent.add(self) + def __init__(self): + self.parent = None + + @abstractmethod + def load(self): + pass @abstractmethod def register(self): diff --git a/engine/components/sprite.py b/engine/components/sprite.py index 0fbfca4..f176b21 100644 --- a/engine/components/sprite.py +++ b/engine/components/sprite.py @@ -3,8 +3,8 @@ from ..servers.graphics import GraphicsServer class Sprite(Component): - def __init__(self, parent, surf, z): - super().__init__(parent) + def __init__(self, surf, z): + super().__init__() self.surf = surf self.width = self.surf.get_width() self.z = z diff --git a/engine/entity.py b/engine/entity.py index 8252e78..3b6a1c8 100644 --- a/engine/entity.py +++ b/engine/entity.py @@ -1,15 +1,23 @@ from .observer import Observer class Entity(Observer): - def __init__(self): + def __init__(self, name): super().__init__() self._components = [] + self.name = name + self.scene = None self.x = 0 self.y = 0 self.script = None + def load(self): + pass + def add(self, component): + component.parent = self + component.load() self._components.append(component) + return component def register(self): for component in self._components: diff --git a/engine/game.py b/engine/game.py index da21da4..3dae30f 100644 --- a/engine/game.py +++ b/engine/game.py @@ -8,6 +8,8 @@ from .scene_manager import SceneManager class Game: + cur_tick = 0 + def __init__(self, start_scene): self._graphics_server = GraphicsServer() self._sound_server = SoundServer() @@ -26,4 +28,5 @@ class Game: self._physics_server.step() self._sound_server.step() self._graphics_server.step() + Game.cur_tick += 1 clock.tick(60) diff --git a/engine/scene.py b/engine/scene.py index ede4c0f..7a7ae3e 100644 --- a/engine/scene.py +++ b/engine/scene.py @@ -2,6 +2,11 @@ class Scene: def __init__(self): self.entities = {} + def add(self, entity): + self.entities[entity.name] = entity + entity.scene = self + entity.load() + def unload(self): for entity in self.entities.values(): entity.unregister() diff --git a/engine/servers/physics.py b/engine/servers/physics.py index 4f3b55e..bdcc2de 100644 --- a/engine/servers/physics.py +++ b/engine/servers/physics.py @@ -34,7 +34,9 @@ class PhysicsServer(Server): c = self._check_collide(d) if c is not None: if c.cb: - c.cb() + c.cb(d) + if d.cb: + d.cb(c) if c.solid: d.parent.x -= x_step d.vx = 0 @@ -44,7 +46,9 @@ class PhysicsServer(Server): c = self._check_collide(d) if c is not None: if c.cb: - c.cb() + c.cb(d) + if d.cb: + d.cb(c) if c.solid: d.parent.y -= y_step d.vy = 0 diff --git a/res/pacman_1.png b/res/pacman_1.png new file mode 100644 index 0000000000000000000000000000000000000000..1357dcb2ec5feccc9f8707e46d5e6edcae56069c GIT binary patch literal 9817 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 VFL12=JV5{e002ovPDHLkV1f^_L|*^^ literal 0 HcmV?d00001 diff --git a/scenes/__init__.py b/scenes/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/scenes/game_objects/__init__.py b/scenes/game_objects/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/scenes/game_objects/common.py b/scenes/game_objects/common.py new file mode 100644 index 0000000..2d34628 --- /dev/null +++ b/scenes/game_objects/common.py @@ -0,0 +1 @@ +S = 20 diff --git a/scenes/game_objects/ghost.py b/scenes/game_objects/ghost.py new file mode 100644 index 0000000..63116c2 --- /dev/null +++ b/scenes/game_objects/ghost.py @@ -0,0 +1,77 @@ +from enum import Enum +from random import random, randint + +from pygame import Surface, draw, Rect, image + +from engine.entity import Entity +from engine.resources import res +from engine.components.collide_rect import CollideRect +from engine.components.sprite import Sprite + +from .common import S +from .pacdot import PacDot + + +class Direction(Enum): + UP = 1 + DOWN = 2 + LEFT = 3 + RIGHT = 4 + + +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.on_col) + self.add(self.phys) + self.script = Ghost.script + self.x = x + self.y = y + self.direction = Direction(randint(1, 4)) + + def on_col(self, c): + if isinstance(c.parent, PacDot): + 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): + if self.direction == Direction.UP: + self.phys.vy = -Ghost.SPEED + self.phys.vx = 0 + elif self.direction == Direction.DOWN: + self.phys.vy = Ghost.SPEED + self.phys.vx = 0 + elif self.direction == Direction.LEFT: + self.phys.vx = -Ghost.SPEED + self.phys.vy = 0 + elif self.direction == Direction.RIGHT: + self.phys.vx = Ghost.SPEED + self.phys.vy = 0 diff --git a/scenes/game_objects/level.py b/scenes/game_objects/level.py new file mode 100644 index 0000000..2bda6bd --- /dev/null +++ b/scenes/game_objects/level.py @@ -0,0 +1,39 @@ +from itertools import product + +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 +from .pacdot import PacDot + + +class Level(Entity): + def __init__(self, path): + super().__init__('level') + self.path = path + + def load(self): + desc = image.load(res(self.path)) + w, h = desc.get_size() + 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)) + for x, y in product(range(w), range(h)): + col = desc.get_at((x, y)) + if col == (0, 0, 255): + self.add(CollideRect(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 + self.scene.add(pc) + PacDot.tot += 1 + self.add(Sprite(self.surf, 0)) diff --git a/scenes/game_objects/pacdot.py b/scenes/game_objects/pacdot.py new file mode 100644 index 0000000..174179a --- /dev/null +++ b/scenes/game_objects/pacdot.py @@ -0,0 +1,34 @@ +from pygame import Surface, draw, Rect + +from engine.entity import Entity +from engine.components.collide_rect import CollideRect +from engine.components.sprite import Sprite + +from .common import S +from .pacman import PacMan + + +class PacDot(Entity): + tot = 0 + s = Surface((S, S)) + draw.circle(s, (255, 255, 0), (S//2, S//2), S//4) + + def __init__(self): + super().__init__(self.__repr__()) + self.add(CollideRect(Rect(0, 0, S, S), + static=True, solid=False, cb=self.cb)) + self.add(Sprite(PacDot.s, 1)) + self.dead = False + + def cb(self, c): + if c.parent.name != 'pacman': + return + if self.dead: + return + self.dead = True + PacDot.tot -= 1 + if PacDot.tot == 0: + print('Gagné !') + exit(0) + if c.parent.name == 'pacman': + self.unregister() diff --git a/scenes/game_objects/pacman.py b/scenes/game_objects/pacman.py new file mode 100644 index 0000000..7285708 --- /dev/null +++ b/scenes/game_objects/pacman.py @@ -0,0 +1,80 @@ +from pygame import Surface, draw, Rect, key, image, transform +from pygame.locals import K_UP, K_DOWN, K_LEFT, K_RIGHT + +from engine.entity import Entity +from engine.game import Game +from engine.resources import res +from engine.components.collide_rect import CollideRect +from engine.components.sprite import Sprite + +from .common import S + + +class PacMan(Entity): + SIZE = 1 + SPEED = 2 + + def __init__(self, x, y): + super().__init__('pacman') + + # surf = Surface((S//PacMan.SIZE, S//PacMan.SIZE)).convert() + # surf.fill((0, 0, 0)) + # draw.circle(surf, + # (255, 255, 0), + # (S//(2*PacMan.SIZE), S//(2*PacMan.SIZE)), + # S//(2*PacMan.SIZE)) + surf_1 = image.load(res('pacman_1.png')).convert() + surf_2 = image.load(res('pacman_2.png')).convert() + + self.surf = [[transform.rotate(surf_1, 90), + transform.rotate(surf_1, -90), + transform.flip(surf_1, True, False), + surf_1], + [transform.rotate(surf_2, 90), + transform.rotate(surf_2, -90), + transform.flip(surf_2, True, False), + surf_2]] + + self.cur_anim = 0 + + self.sprite = self.add(Sprite(self.surf[self.cur_anim][0], 2)) + + self.phys = self.add( + CollideRect(Rect(self.x, self.y, + self.sprite.width, self.sprite.width), + static=False)) + self.script = PacMan.update + self.x = x + self.y = y + + def update(self): + p = self.phys + s = self.sprite + + # Avance l’animation + if Game.cur_tick % 5 == 0: + self.cur_anim += 1 + self.cur_anim %= 2 + + # Nouvelle sprite + if p.vy < 0: + s.surf = self.surf[self.cur_anim][0] + elif p.vy > 0: + s.surf = self.surf[self.cur_anim][1] + elif p.vx < 0: + s.surf = self.surf[self.cur_anim][2] + elif p.vx > 0: + s.surf = self.surf[self.cur_anim][3] + + inputs = key.get_pressed() + if PacMan.SIZE > 1: + p.vx = 0 + p.vy = 0 + if inputs[K_UP]: + p.vy = -PacMan.SPEED + if inputs[K_DOWN]: + p.vy = PacMan.SPEED + if inputs[K_LEFT]: + p.vx = -PacMan.SPEED + if inputs[K_RIGHT]: + p.vx = PacMan.SPEED diff --git a/scenes/lvl0.py b/scenes/lvl0.py index 09e4614..de8aa9d 100644 --- a/scenes/lvl0.py +++ b/scenes/lvl0.py @@ -1,169 +1,19 @@ -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 +from .game_objects.common import S +from .game_objects.level import Level +from .game_objects.pacman import PacMan +from .game_objects.ghost import Ghost 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 - + 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()