Écraser ou se faire toucher
Fait partie de la section Les mondes du Journey Pygame de Coddy. Leçon 25 sur 35.
Toucher un blob doit avoir des conséquences, de deux façons. Atterrissez dessus et le blob est vaincu. Marchez dessus et le joueur est blessé.
La différence tient à la façon dont le joueur est arrivé. Il vient d'en haut s'il est en train de tomber, vel_y > 0, et que ses pieds sont encore au-dessus du milieu du blob :
for blob in blobs:
if player.colliderect(blob.rect):
if vel_y > 0 and player.bottom < blob.rect.centery:
blob.kill()
vel_y = -8
else:
player.midbottom = start
vel_y = 0blob.kill() retire le sprite du groupe : il n'est donc plus mis à jour ni dessiné. vel_y = -8 produit un petit rebond, qui indique au joueur que l'écrasement a fonctionné et lui permet d'enchaîner avec un saut. Tout autre contact vient du côté ou d'en dessous, et le joueur retourne au point de départ, comme après une chute.
Parcourez le groupe pour tester chaque blob. kill() à l'intérieur de la boucle ne pose pas de problème ici, car la boucle parcourt les sprites du groupe tels qu'ils étaient au début.
Défi
Moyen- Après le déplacement des blobs, parcours
blobs. - Lorsque le joueur entre en collision avec le Rect d’un blob : si
vel_y > 0etplayer.bottom < blob.rect.centery, appelleblob.kill()et définisvel_y = -8. - Sinon, définis
player.midbottom = startetvel_y = 0.
Essayez vous-même
import pygame
TILE = 36
SPEED = 4
GRAVITY = 1
JUMP = -15
MAX_FALL = 12
LEVEL = [
"................",
"................",
"................",
"................",
"..........####..",
"................",
"...####.........",
"................",
"#.P............#",
"################",
]
pygame.init()
screen = pygame.display.set_mode((576, 360))
pygame.display.set_caption("Stomp")
clock = pygame.time.Clock()
background = pygame.image.load("assets/backgrounds/clouds.png").convert_alpha()
block_img = pygame.image.load("assets/images/block.png").convert_alpha()
player_img = pygame.image.load("assets/images/player.png").convert_alpha()
blob_img = pygame.image.load("assets/images/blob.png").convert_alpha()
class Blob(pygame.sprite.Sprite):
def __init__(self, midbottom):
super().__init__()
self.image = blob_img
self.rect = pygame.Rect(0, 0, 30, 26)
self.rect.midbottom = midbottom
self.direction = 1
def update(self):
self.rect.x += self.direction
if self.direction > 0:
ahead = self.rect.right
else:
ahead = self.rect.left - 1
hit_wall = any(self.rect.colliderect(wall) for wall in walls)
ground_ahead = any(wall.collidepoint(ahead, self.rect.bottom) for wall in walls)
if hit_wall or not ground_ahead:
self.rect.x -= self.direction
self.direction = -self.direction
walls = []
for row, line in enumerate(LEVEL):
for col, char in enumerate(line):
if char == "#":
walls.append(pygame.Rect(col * TILE, row * TILE, TILE, TILE))
elif char == "P":
start = (col * TILE + TILE // 2, row * TILE + TILE)
blobs = pygame.sprite.Group(Blob((432, 144)), Blob((432, 324)))
player = player_img.get_rect(midbottom=start)
vel_y = 0
on_ground = False
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN and event.key in (pygame.K_SPACE, pygame.K_UP):
if on_ground:
vel_y = JUMP
elif event.type == pygame.KEYUP and event.key in (pygame.K_SPACE, pygame.K_UP):
if vel_y < -4:
vel_y = -4
keys = pygame.key.get_pressed()
dx = 0
if keys[pygame.K_LEFT]:
dx -= SPEED
if keys[pygame.K_RIGHT]:
dx += SPEED
player.x += dx
for wall in walls:
if player.colliderect(wall):
if dx > 0:
player.right = wall.left
elif dx < 0:
player.left = wall.right
vel_y = min(vel_y + GRAVITY, MAX_FALL)
player.y += vel_y
on_ground = False
for wall in walls:
if player.colliderect(wall):
if vel_y > 0:
player.bottom = wall.top
on_ground = True
elif vel_y < 0:
player.top = wall.bottom
vel_y = 0
blobs.update()
for y in range(0, 360, 72):
for x in range(0, 576, 72):
screen.blit(background, (x, y))
for wall in walls:
screen.blit(block_img, wall)
for blob in blobs:
screen.blit(blob.image, blob.image.get_rect(midbottom=blob.rect.midbottom))
screen.blit(player_img, player)
pygame.display.flip()
clock.tick(60)
pygame.quit()
Toutes les leçons de Les mondes
1Des cartes à partir de texte
Un niveau en texteLignes et colonnesDes lettres qui ont un sensOù commence le joueurUn écran à la fois4Collisions avec les plateformes
Murs à gauche et à droiteAtterrir sur les plateformesSe cogner la têteTomber hors du niveauUn axe à la fois3Gravité et saut
Tomber avec la gravitéSauter depuis le solPetits sautsUne vitesse de chute maximaleTampon de saut6Des ennemis en patrouille
Un blob en patrouilleÉcraser ou se faire toucherUn cycle de marcheDes ennemis issus de la carteEntraînez-vous par vous-même : Playground Pygame