La gravité en Pygame¶
Dans cette page, on va rendre le gameplay plus intéressant et plus naturel, en ajoutant :
- de la gravité
- un saut
- des collisions avec le sol et les murs
Bref, un vrai gameplay de plateformer.
La gravité¶
Dans la vraie vie, les objets tombent. Dans un jeu, c’est à nous de le coder.
Pour ça, le joueur va avoir une vitesse verticale.
Dans une approche orientée objet, cette vitesse appartient au joueur.
self.velocity_y = 0
self.gravity = 0.8
À chaque frame, on applique la gravité :
self.velocity_y += self.gravity
self.rect.y += self.velocity_y
Résultat : le joueur tombe de plus en plus vite.
Le saut¶
Pour sauter, on donne une impulsion vers le haut :
self.velocity_y = -15
Le nombre est négatif car l’axe y va vers le bas.
Si vous laissez ça comme ça, le joueur peut sauter à l’infini dans le vide. Il faut donc vérifier qu’il est au sol.
Détecter le sol¶
On va représenter le sol par un simple rectangle :
ground = pygame.Rect(0, 500, 800, 100)
Dans la classe du joueur, on va tester la collision avec le sol.
Quand le joueur touche le sol :
- on le replace correctement
- on annule la vitesse verticale
- on note qu’il est au sol
if self.rect.colliderect(ground) and self.velocity_y >= 0:
self.rect.bottom = ground.top
self.velocity_y = 0
self.on_ground = True
else:
self.on_ground = False
Autoriser le saut seulement au sol¶
Dans la méthode de gestion du clavier :
if keys[pygame.K_SPACE] and self.on_ground:
self.velocity_y = -15
Maintenant :
- le joueur tombe
- il touche le sol
- il peut sauter
- il retombe
Collisions avec les murs¶
On peut aussi empêcher le joueur de sortir de l’écran :
if self.rect.left < 0:
self.rect.left = 0
if self.rect.right > 800:
self.rect.right = 800
Exemple complet : mini plateformer en POO¶
import pygame
class Player:
def __init__(self):
self.rect = pygame.Rect(100, 100, 50, 50)
self.speed = 5
self.velocity_y = 0
self.gravity = 0.8
self.jump_power = 15
self.on_ground = False
def update(self, keys, ground):
# déplacement horizontal
if keys[pygame.K_LEFT]:
self.rect.x -= self.speed
if keys[pygame.K_RIGHT]:
self.rect.x += self.speed
# gravité
self.velocity_y += self.gravity
self.rect.y += self.velocity_y
# collision avec le sol
if self.rect.colliderect(ground) and self.velocity_y >= 0:
self.rect.bottom = ground.top
self.velocity_y = 0
self.on_ground = True
else:
self.on_ground = False
# saut
if keys[pygame.K_SPACE] and self.on_ground:
self.velocity_y = -self.jump_power
# limites écran
if self.rect.left < 0:
self.rect.left = 0
if self.rect.right > 800:
self.rect.right = 800
def draw(self, screen):
pygame.draw.rect(screen, (0, 200, 255), self.rect)
pygame.init()
screen = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()
player = Player()
ground = pygame.Rect(0, 500, 800, 100)
running = True
while running:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
keys = pygame.key.get_pressed()
player.update(keys, ground)
screen.fill((30, 30, 30))
pygame.draw.rect(screen, (100, 255, 100), ground)
player.draw(screen)
pygame.display.flip()
pygame.quit()
Rendre le mouvement plus agréable¶
Quelques idées simples :
- augmenter légèrement la gravité
- réduire la puissance du saut
- ajuster la vitesse horizontale
Il n’y a pas de bonnes valeurs universelles. Le ressenti est plus important que la précision.
Quizz¶
self.velocity_y += self.gravity
self.rect.y += self.velocity_y
Pourquoi la chute accélère-t-elle avec le temps ?
- Parce que `self.rect.y` augmente
- *Parce que `self.velocity_y` augmente à chaque frame
- Parce que la gravité est négative
- Parce que Pygame gère la physique tout seul
> La gravité augmente la vitesse verticale à chaque frame, ce qui accélère la chute.
Exercice pratique¶
Améliorez ce mini plateformer pour :
- Ajouter un plafond
- Ajouter un trou où le joueur tombe et MEURT !!!
En résumé¶
Vous savez maintenant :
- Ajouter une gravité artificielle
- Implémenter un saut
- Détecter le sol
- Gérer des collisions simples avec l’environnement
- Structurer un gameplay de plateformer avec une classe
Player
Dans la prochaine page, on va s’attaquer à quelque chose de très visible : l’interface et les menus.