commit 639ed421439c4adcd0a5a2be26d0570eb514672e Author: papush! Date: Sat Nov 23 10:46:25 2019 +0100 archivage initial diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7a60b85 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +__pycache__/ +*.pyc diff --git a/engine/components/__init__.py b/engine/components/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/engine/components/collide_rect.py b/engine/components/collide_rect.py new file mode 100644 index 0000000..bdc118e --- /dev/null +++ b/engine/components/collide_rect.py @@ -0,0 +1,7 @@ +from .component import Component + + +class CollideRect(Component): + def __init__(self, rect): + super().__init__() + self.rect = rect diff --git a/engine/components/component.py b/engine/components/component.py new file mode 100644 index 0000000..fb3c5e6 --- /dev/null +++ b/engine/components/component.py @@ -0,0 +1,14 @@ +from abc import abstractmethod + + +class Component: + def __init__(self): + self.parent = None + + @abstractmethod + def register(self): + pass + + @abstractmethod + def unregister(self): + pass diff --git a/engine/components/script.py b/engine/components/script.py new file mode 100644 index 0000000..431a5b6 --- /dev/null +++ b/engine/components/script.py @@ -0,0 +1,4 @@ +class Script: + def __init__(self, parent, func): + super().__init__(parent) + self.func = func diff --git a/engine/components/sprite.py b/engine/components/sprite.py new file mode 100644 index 0000000..c506a66 --- /dev/null +++ b/engine/components/sprite.py @@ -0,0 +1,16 @@ +from .component import Component +from ..servers.graphics import GraphicsServer + + +class Sprite(Component): + def __init__(self, surf, z): + super().__init__() + self.surf = surf + self.width = self.surf.get_width() + self.z = z + + def register(self): + GraphicsServer().register_component(self) + + def unregister(self): + GraphicsServer().register_component(self) diff --git a/engine/entity.py b/engine/entity.py new file mode 100644 index 0000000..8e0571e --- /dev/null +++ b/engine/entity.py @@ -0,0 +1,18 @@ +class Entity: + def __init__(self): + self._components = [] + self.x = 0 + self.y = 0 + self.script = None + + def add(self, component): + self._components.append(component) + component.parent = self + + def register(self): + for component in self._components: + component.register() + + def unregister(self): + for component in self._components: + component.unregister() diff --git a/engine/game.py b/engine/game.py new file mode 100644 index 0000000..da21da4 --- /dev/null +++ b/engine/game.py @@ -0,0 +1,29 @@ +from pygame.time import Clock + +from .servers.graphics import GraphicsServer +from .servers.sound import SoundServer +from .servers.physics import PhysicsServer +from .servers.input import InputServer, StopException +from .scene_manager import SceneManager + + +class Game: + def __init__(self, start_scene): + self._graphics_server = GraphicsServer() + self._sound_server = SoundServer() + self._physics_server = PhysicsServer() + self._input_server = InputServer() + self._scene_manager = SceneManager(start_scene) + + def run(self): + clock = Clock() + while True: + try: + self._input_server.step() + except StopException: + break + self._scene_manager.step() + self._physics_server.step() + self._sound_server.step() + self._graphics_server.step() + clock.tick(60) diff --git a/engine/resources.py b/engine/resources.py new file mode 100644 index 0000000..db82627 --- /dev/null +++ b/engine/resources.py @@ -0,0 +1,5 @@ +from os.path import join + + +def res(filename): + return join('res', filename) diff --git a/engine/scene.py b/engine/scene.py new file mode 100644 index 0000000..7f2bbe2 --- /dev/null +++ b/engine/scene.py @@ -0,0 +1,11 @@ +class Scene: + def __init__(self): + self.entities = [] + + def unload(self): + for entity in self.entities: + entity.unregister() + + def load(self): + for entity in self.entities: + entity.register() diff --git a/engine/scene_manager.py b/engine/scene_manager.py new file mode 100644 index 0000000..9d6e339 --- /dev/null +++ b/engine/scene_manager.py @@ -0,0 +1,18 @@ +from .singleton import Singleton + + +class SceneManager(metaclass=Singleton): + def __init__(self, scene): + super().__init__() + self._scene = scene + self._scene.load() + + def change_scene(self, new_scene): + self._scene.unload() + self._scene = new_scene + self._scene.load() + + def step(self): + for entity in self._scene.entities: + if entity.script is not None: + entity.script(entity) diff --git a/engine/servers/__init__.py b/engine/servers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/engine/servers/graphics.py b/engine/servers/graphics.py new file mode 100644 index 0000000..6d0af28 --- /dev/null +++ b/engine/servers/graphics.py @@ -0,0 +1,23 @@ +from .server import Server + +from pygame import display + + +class GraphicsServer(Server): + def __init__(self, size=(640, 480)): + super().__init__() + display.init() + self.window = display.set_mode(size) + + def register_component(self, component): + super().register_component(component) + self._components.sort(key=lambda e: e.z) + + def step(self): + for component in self._components: + self.window.blit(component.surf, + (component.parent.x, component.parent.y)) + display.flip() + + def resize(self, new_size): + self.window = display.set_mode(new_size) diff --git a/engine/servers/input.py b/engine/servers/input.py new file mode 100644 index 0000000..116df35 --- /dev/null +++ b/engine/servers/input.py @@ -0,0 +1,17 @@ +from .server import Server + +from pygame import event +from pygame.locals import QUIT + + +class StopException(RuntimeError): pass + + +class InputServer(Server): + def __init__(self): + super().__init__() + + def step(self): + for e in event.get(): + if e.type == QUIT: + raise StopException diff --git a/engine/servers/physics.py b/engine/servers/physics.py new file mode 100644 index 0000000..0f1f234 --- /dev/null +++ b/engine/servers/physics.py @@ -0,0 +1,10 @@ +from .server import Server + + +class PhysicsServer(Server): + def __init__(self): + super().__init__() + + def step(self): + for component in self._components: + pass diff --git a/engine/servers/script.py b/engine/servers/script.py new file mode 100644 index 0000000..81f7b8b --- /dev/null +++ b/engine/servers/script.py @@ -0,0 +1,10 @@ +from .server import Server + + +class ScriptServer(Server): + def __init__(self): + super().__init__() + + def step(self): + for component in self._components: + component.func(component.parent) diff --git a/engine/servers/server.py b/engine/servers/server.py new file mode 100644 index 0000000..ed0b856 --- /dev/null +++ b/engine/servers/server.py @@ -0,0 +1,20 @@ +from abc import abstractmethod + +from ..singleton import Singleton + + +class Server(metaclass=Singleton): + def __init__(self): + super().__init__() + self._components = [] + + def register_component(self, component): + self._components.append(component) + + def unregister_component(self, component): + self._components.remove(component) + + + @abstractmethod + def step(self): + pass diff --git a/engine/servers/sound.py b/engine/servers/sound.py new file mode 100644 index 0000000..7537730 --- /dev/null +++ b/engine/servers/sound.py @@ -0,0 +1,9 @@ +from .server import Server + + +class SoundServer(Server): + def __init__(self): + super().__init__() + + def step(self): + pass diff --git a/engine/singleton.py b/engine/singleton.py new file mode 100644 index 0000000..53b0b87 --- /dev/null +++ b/engine/singleton.py @@ -0,0 +1,23 @@ +class Singleton(type): + def __init__(cls, name, bases, dict): + super(Singleton, cls).__init__(name, bases, dict) + cls.instance = None + + def __call__(cls,*args,**kw): + if cls.instance is None: + cls.instance = super(Singleton, cls).\ + __call__(*args, **kw) + return cls.instance + + +# class Singleton(): +# instance = None + +# def __init__(self): +# self.__class__.instance = self + +# def get_instance(): +# if self.__class__.instance == None: +# raise RuntimeError('Server has not been initialized.') +# else: +# return self.__class__.instance diff --git a/engine/vec2.py b/engine/vec2.py new file mode 100644 index 0000000..fb62a6b --- /dev/null +++ b/engine/vec2.py @@ -0,0 +1,4 @@ +class Vec2: + def __init__(self, x=0, y=0): + self.x = x + self.y = y diff --git a/pac-man.py b/pac-man.py new file mode 100755 index 0000000..5e93b5f --- /dev/null +++ b/pac-man.py @@ -0,0 +1,7 @@ +#!/bin/python3 + +from engine.game import Game +from scenes.lvl0 import scene + + +Game(scene).run() diff --git a/res/lvl0.png b/res/lvl0.png new file mode 100644 index 0000000..503e9b9 Binary files /dev/null and b/res/lvl0.png differ diff --git a/scenes/lvl0.py b/scenes/lvl0.py new file mode 100644 index 0000000..17e6815 --- /dev/null +++ b/scenes/lvl0.py @@ -0,0 +1,77 @@ +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 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 + +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)) + 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)): + if desc.get_at((x, y)) == (0, 0, 255): + self.add(CollideRect(Rect(x * S, y * S, S, S))) + self.surf.blit(wall, (x * S, y * S)) + self.add(Sprite(self.surf, 0)) + + +class MovingEntity(Entity): + def __init__(self, surf): + super().__init__() + sprite = Sprite(surf, 1) + self.add(sprite) + self.add(CollideRect(Rect(self.x, self.y, + sprite.width, sprite.width))) + + +class Ghost(MovingEntity): + def update_ghost(): + pass + + def __init__(self): + super().__init__(image.load(res('ghost.png')).convert()) + self.script = update_ghost() + + +class Lvl0(Scene): + def load(self): + pac_surf = Surface((S, S)).convert() + pac_surf.fill((0, 0, 0)) + draw.circle(pac_surf, (255, 255, 0), (S//2, S//2), S//2) + pacman = MovingEntity(pac_surf) + def pacman_script(entity): + inputs = key.get_pressed() + if inputs[K_UP]: + entity.y -= 2 + if inputs[K_DOWN]: + entity.y += 2 + if inputs[K_LEFT]: + entity.x -= 2 + if inputs[K_RIGHT]: + entity.x += 2 + pacman.script = pacman_script + + self.entities.append(pacman) + self.entities.append(Level('lvl0.png')) + + super().load() + + +scene = Lvl0() diff --git a/scenes/main_menu.py b/scenes/main_menu.py new file mode 100644 index 0000000..afe6b75 --- /dev/null +++ b/scenes/main_menu.py @@ -0,0 +1,4 @@ +class MainMenu(Scene): + pass + +scene = MainMenu()