From 639ed421439c4adcd0a5a2be26d0570eb514672e Mon Sep 17 00:00:00 2001 From: papush! Date: Sat, 23 Nov 2019 10:46:25 +0100 Subject: [PATCH] archivage initial --- .gitignore | 2 + engine/components/__init__.py | 0 engine/components/collide_rect.py | 7 +++ engine/components/component.py | 14 ++++++ engine/components/script.py | 4 ++ engine/components/sprite.py | 16 +++++++ engine/entity.py | 18 +++++++ engine/game.py | 29 +++++++++++ engine/resources.py | 5 ++ engine/scene.py | 11 +++++ engine/scene_manager.py | 18 +++++++ engine/servers/__init__.py | 0 engine/servers/graphics.py | 23 +++++++++ engine/servers/input.py | 17 +++++++ engine/servers/physics.py | 10 ++++ engine/servers/script.py | 10 ++++ engine/servers/server.py | 20 ++++++++ engine/servers/sound.py | 9 ++++ engine/singleton.py | 23 +++++++++ engine/vec2.py | 4 ++ pac-man.py | 7 +++ res/lvl0.png | Bin 0 -> 12025 bytes scenes/lvl0.py | 77 ++++++++++++++++++++++++++++++ scenes/main_menu.py | 4 ++ 24 files changed, 328 insertions(+) create mode 100644 .gitignore create mode 100644 engine/components/__init__.py create mode 100644 engine/components/collide_rect.py create mode 100644 engine/components/component.py create mode 100644 engine/components/script.py create mode 100644 engine/components/sprite.py create mode 100644 engine/entity.py create mode 100644 engine/game.py create mode 100644 engine/resources.py create mode 100644 engine/scene.py create mode 100644 engine/scene_manager.py create mode 100644 engine/servers/__init__.py create mode 100644 engine/servers/graphics.py create mode 100644 engine/servers/input.py create mode 100644 engine/servers/physics.py create mode 100644 engine/servers/script.py create mode 100644 engine/servers/server.py create mode 100644 engine/servers/sound.py create mode 100644 engine/singleton.py create mode 100644 engine/vec2.py create mode 100755 pac-man.py create mode 100644 res/lvl0.png create mode 100644 scenes/lvl0.py create mode 100644 scenes/main_menu.py 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 0000000000000000000000000000000000000000..503e9b941b93768c767e76ca646138a8aa94dbea GIT binary patch literal 12025 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 E0FP6mA^-pY literal 0 HcmV?d00001 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()