Ceci est une ancienne révision du document !
Warning: Undefined array key 1 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 172
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Table des matières
Le joueur
Principe général
Première approche
Le mouvement gauche - droite ne pose pas de problème. C'est le mouvement vertical qu'il faut travailler.
Un mouvement vertical réaliste sera obtenu grâce à trois paramètres :
- la position $y$
- la vitesse $v_y$
- l'accélération de la pesanteur $g$.
Quand le joueur a les pieds sur terre, $y$ ne change pas, $v_y = 0$ et $g$ n'agit pas.
Quand le joueur saute, au début de sont saut, $v_y = V$, où $V$ est une vitesse de saut à choisir pour un saut réaliste. Puis à chaque période de temps, on a : $y \leftarrow y - v_y$ (tenant compte de ce que l'axe $y$ est à l'envers sur l'écran) et $v_y \leftarrow v_y - g$.
Ainsi quand $v_y > 0$, le sprite monte à l'écran et quand $v_y < 0$ il descend. L'action de $g$ est qu'au début du saut, le sprite monte. Puis il perd de la vitesse, atteint son sommet et se met à descendre.
<python code> def jump(self):
""" amorce un saut """ self.vy = self.JUMP_VELOCITY
…
def update_position(self, plateformes):
"""
Calcule la nouvelle position tenant compte de la vitesse
courante et sans dépasser les limites
"""
self.rect.centerx += self.vx
self.vy -= self.G #pesanteur
self.rect.centery -= self.vy
if self.rect.centerx > self.xmax:
self.rect.centerx = self.xmax
elif self.rect.centerx < self.xmin:
self.rect.centerx = self.xmin
self.vx *= 0.2
if abs(self.vx) < 1:
self.vx = 0
</code>
Détection de plate-forme
Si on fait ce qui précède, les plates-formes sont ignorées et le sprite tombe aussitôt à travers le sol.
Pour résoudre ce problème, on va détecter si les pieds du joueurs ont traversé la ligne supérieure d'une plate-forme en descendant.
- si
self.vy < 0… seulement si le sprite descend - pour chaque plate-forme
pf,- si le sprite était au-dessus de
pfau début de son mouvement
//c'est à dire //''self.rect.bottom + self.vy
# fichier player.py
import pygame
class Player(pygame.sprite.Sprite):
COLOR = (255, 255, 0)
VELOCITY = 10
JUMP_VELOCITY = 20
HEIGHT = 50
WIDTH = 20
G = 2
def __init__(self, x0, y0, xmin, xmax):
"""
x0, y0: position initiale du coin inférieur gauche
xmin, xmax: valeurs à ne pas dépasser
"""
super().__init__()
self.image = pygame.Surface((self.WIDTH, self.HEIGHT))
self.image.fill(self.COLOR)
self.rect = self.image.get_rect()
self.rect.left = x0
self.rect.bottom = y0
self.xmin = xmin
self.xmax = xmax
self.jumping = False
self.vx = 0
self.vy = 0
def move_left(self):
"""
amorce un mouvement vers la gauche
"""
self.vx = -self.VELOCITY
def move_right(self):
"""
amorce un mouvement vers la droite
"""
self.vx = self.VELOCITY
def jump(self):
"""
amorce un saut
"""
if not self.jumping:
self.vy = self.JUMP_VELOCITY
self.jumping = True
def put_on(self, pf) -> bool:
"""
place player les pieds sur la plateforme pf
à condition que les pieds de player en soit assez proche
et que player soit en train de descendre
renvoie True si self a été posé sur pf
"""
if self.vy > 0:
return
if pf.rect.bottom > self.rect.bottom + self.vy and self.rect.bottom > pf.rect.top:
self.vy = 0
self.rect.bottom = pf.rect.top
return True
def update_position(self, plateformes):
"""
plateformes: liste des plates-formes
Calcule la nouvelle position tenant compte de la vitesse
courante et sans dépasser les limites
"""
self.rect.centerx += self.vx
self.vy -= self.G #pesanteur
self.rect.centery -= self.vy
if self.rect.centerx > self.xmax:
self.rect.centerx = self.xmax
elif self.rect.centerx < self.xmin:
self.rect.centerx = self.xmin
self.vx *= 0.2
self.jumping = True
for pf in pygame.sprite.spritecollide(self, plateformes, False):
if self.put_on(pf):
self.jumping = False
break
if abs(self.vx) < 1:
self.vx = 0
