lol le retard

This commit is contained in:
papush! 2019-12-09 12:36:42 +01:00
parent a7c1b606d3
commit 9dac58f8bd
17 changed files with 282 additions and 176 deletions

View File

@ -3,21 +3,23 @@ from ..servers.physics import PhysicsServer
class CollideRect(Component): class CollideRect(Component):
def __init__(self, parent, rect, static=True, solid=True, cb=None): def __init__(self, rect, static=True, solid=True, cb=None):
super().__init__(parent) super().__init__()
self.rect = rect 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.static = static
self.solid = solid self.solid = solid
self.cb = cb self.cb = cb
self.vx = 0 self.vx = 0
self.vy = 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): def register(self):
PhysicsServer().register_component(self) PhysicsServer().register_component(self)

View File

@ -2,9 +2,12 @@ from abc import abstractmethod
class Component: class Component:
def __init__(self, parent): def __init__(self):
self.parent = parent self.parent = None
self.parent.add(self)
@abstractmethod
def load(self):
pass
@abstractmethod @abstractmethod
def register(self): def register(self):

View File

@ -3,8 +3,8 @@ from ..servers.graphics import GraphicsServer
class Sprite(Component): class Sprite(Component):
def __init__(self, parent, surf, z): def __init__(self, surf, z):
super().__init__(parent) super().__init__()
self.surf = surf self.surf = surf
self.width = self.surf.get_width() self.width = self.surf.get_width()
self.z = z self.z = z

View File

@ -1,15 +1,23 @@
from .observer import Observer from .observer import Observer
class Entity(Observer): class Entity(Observer):
def __init__(self): def __init__(self, name):
super().__init__() super().__init__()
self._components = [] self._components = []
self.name = name
self.scene = None
self.x = 0 self.x = 0
self.y = 0 self.y = 0
self.script = None self.script = None
def load(self):
pass
def add(self, component): def add(self, component):
component.parent = self
component.load()
self._components.append(component) self._components.append(component)
return component
def register(self): def register(self):
for component in self._components: for component in self._components:

View File

@ -8,6 +8,8 @@ from .scene_manager import SceneManager
class Game: class Game:
cur_tick = 0
def __init__(self, start_scene): def __init__(self, start_scene):
self._graphics_server = GraphicsServer() self._graphics_server = GraphicsServer()
self._sound_server = SoundServer() self._sound_server = SoundServer()
@ -26,4 +28,5 @@ class Game:
self._physics_server.step() self._physics_server.step()
self._sound_server.step() self._sound_server.step()
self._graphics_server.step() self._graphics_server.step()
Game.cur_tick += 1
clock.tick(60) clock.tick(60)

View File

@ -2,6 +2,11 @@ class Scene:
def __init__(self): def __init__(self):
self.entities = {} self.entities = {}
def add(self, entity):
self.entities[entity.name] = entity
entity.scene = self
entity.load()
def unload(self): def unload(self):
for entity in self.entities.values(): for entity in self.entities.values():
entity.unregister() entity.unregister()

View File

@ -34,7 +34,9 @@ class PhysicsServer(Server):
c = self._check_collide(d) c = self._check_collide(d)
if c is not None: if c is not None:
if c.cb: if c.cb:
c.cb() c.cb(d)
if d.cb:
d.cb(c)
if c.solid: if c.solid:
d.parent.x -= x_step d.parent.x -= x_step
d.vx = 0 d.vx = 0
@ -44,7 +46,9 @@ class PhysicsServer(Server):
c = self._check_collide(d) c = self._check_collide(d)
if c is not None: if c is not None:
if c.cb: if c.cb:
c.cb() c.cb(d)
if d.cb:
d.cb(c)
if c.solid: if c.solid:
d.parent.y -= y_step d.parent.y -= y_step
d.vy = 0 d.vy = 0

BIN
res/pacman_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

BIN
res/pacman_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 739 B

0
scenes/__init__.py Normal file
View File

View File

View File

@ -0,0 +1 @@
S = 20

View File

@ -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

View File

@ -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))

View File

@ -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()

View File

@ -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 lanimation
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

View File

@ -1,169 +1,19 @@
from engine.resources import res
from engine.scene import Scene 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
from .game_objects.common import S
S=20 from .game_objects.level import Level
from .game_objects.pacman import PacMan
from .game_objects.ghost import Ghost
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): class Lvl0(Scene):
def load(self): def load(self):
T = 1 self.add(Level('lvl0.png'))
v = 2 self.add(PacMan(S, S))
self.add(Ghost(S*6, S*2))
pac_surf = Surface((S//T, S//T)).convert() self.add(Ghost(S*6, S*13))
pac_surf.fill((0, 0, 0)) self.add(Ghost(S*18, S*13))
draw.circle(pac_surf, (255, 255, 0), (S//(2*T), S//(2*T)), S//(2*T)) self.add(Ghost(S*8, S*23))
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() super().load()