136 lines
4.1 KiB
Python
136 lines
4.1 KiB
Python
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.scene_manager import SceneManager
|
||
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 EnsmallmentDot
|
||
|
||
|
||
class PacMan(Entity):
|
||
SPEED = 2
|
||
|
||
def __init__(self, x, y):
|
||
super().__init__('pacman')
|
||
self.x = x
|
||
self.y = y
|
||
|
||
# Surface quand on est petit.
|
||
self.smol_surf = Surface((S//2, S//2)).convert()
|
||
self.smol_surf.fill((0, 0, 0))
|
||
draw.circle(self.smol_surf,
|
||
(255, 255, 0),
|
||
(S//4, S//4),
|
||
S//4)
|
||
|
||
# Surfaces pour chaque direction, pour chaque état de
|
||
# l’animation.
|
||
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]]
|
||
|
||
# État d’animation courant.
|
||
self.cur_anim = 0
|
||
|
||
self.sprite = self.add(Sprite(self.surf[self.cur_anim][0], 2))
|
||
|
||
# Rectangle quand on est petit.
|
||
self.smol_rect = Rect(self.x, self.y,
|
||
self.sprite.width//2, self.sprite.width//2)
|
||
|
||
self.rect = Rect(self.x, self.y,
|
||
self.sprite.width, self.sprite.width)
|
||
|
||
self.phys = CollideRect(self.rect,
|
||
static=False,
|
||
cb=self.cb)
|
||
|
||
self.add(self.phys)
|
||
|
||
self.script = PacMan.update
|
||
self.smol = False
|
||
self.smol_since = None
|
||
|
||
def cb(self, c):
|
||
if not isinstance(c.parent, EnsmallmentDot):
|
||
return
|
||
# On a mangé une graine de rapetissement.
|
||
if not self.smol:
|
||
# Décalage au milieu du couloir
|
||
self.x += S//4
|
||
self.y += S//4
|
||
|
||
PacMan.SPEED *= 2
|
||
self.smol_rect.x = self.x
|
||
self.smol_rect.y = self.y
|
||
self.phys.rect = self.smol_rect
|
||
self.smol = True
|
||
self.smol_since = Game.cur_tick
|
||
|
||
def update(self):
|
||
p = self.phys
|
||
s = self.sprite
|
||
|
||
level = SceneManager().scene.entities['level']
|
||
if self.x >= level.w:
|
||
self.x = 0
|
||
if self.x < 0:
|
||
self.x = level.w-1
|
||
|
||
# Expiration du rapetissement.
|
||
if self.smol and Game.cur_tick - self.smol_since > 60*2:
|
||
# On se réaligne dans le couloir.
|
||
self.x -= self.x % S
|
||
self.y -= self.y % S
|
||
|
||
self.rect.x = self.x
|
||
self.rect.y = self.y
|
||
self.phys.rect = self.rect
|
||
self.smol = False
|
||
PacMan.SPEED = PacMan.SPEED//2
|
||
|
||
# Avance l’état d’animation.
|
||
if Game.cur_tick % 5 == 0:
|
||
self.cur_anim += 1
|
||
self.cur_anim %= 2
|
||
|
||
# Choix de la surface en fonction de la direction effective.
|
||
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]
|
||
|
||
if self.smol:
|
||
s.surf = self.smol_surf
|
||
|
||
inputs = key.get_pressed()
|
||
if self.smol:
|
||
# Quand on est petit on n’a pas de maintient de la
|
||
# vitesse.
|
||
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
|