Un plancher pour l’écart
Fait partie de la section Règles du jeu du Journey Pygame de Coddy. Leçon 16 sur 29.
Les rochers tombent plus vite, mais ils continuent d’arriver toutes les 800 ms. Des rochers qui arrivent plus souvent rendent aussi le jeu plus difficile. Commence par un intervalle d’une seconde et réduis-le au fil du temps :
interval = 1000 - seconds * 60Après 10 secondes, l’intervalle est de 400 ms ; après 17 secondes, il est inférieur à 0, et un minuteur dont l’intervalle est de 0 ou moins s’arrête. Le jeu a besoin d’un plancher : un intervalle minimum qu’il ne dépasse jamais à la baisse. max renvoie la plus grande de ses valeurs, de sorte que l’intervalle ne descend jamais en dessous de la première :
interval = max(400, 1000 - seconds * 60)Un minuteur conserve l’intervalle avec lequel il a été lancé. Pour le modifier, relance-le : chaque fois qu’un rocher tombe, calcule le nouvel intervalle et appelle set_timer en lui passant cette valeur. Le rocher suivant arrive après cet intervalle.
if event.type == SPAWN and state == "play":
rocks.append(...)
seconds = (pygame.time.get_ticks() - start_time) // 1000
interval = max(400, 1000 - seconds * 60)
pygame.time.set_timer(SPAWN, interval)Défi
Moyen- Dans
reset(), démarre le minuteurSPAWNà 1000 ms. - Chaque fois qu’une météorite tombe, définis
interval = max(400, 1000 - seconds * 60)et redémarre le minuteurSPAWNavec cette valeur.
Essayez vous-même
import random
import pygame
pygame.init()
screen = pygame.display.set_mode((480, 360))
pygame.display.set_caption("Meteor Dodge")
clock = pygame.time.Clock()
heart = pygame.image.load("assets/images/heart.png").convert_alpha()
heart_empty = pygame.image.load("assets/images/heart_empty.png").convert_alpha()
font = pygame.font.Font("assets/fonts/pixel.ttf", 24)
big_font = pygame.font.Font("assets/fonts/pixel.ttf", 48)
WHITE = (240, 240, 240)
PLATE = (60, 60, 90)
POINT = pygame.USEREVENT + 1
SPAWN = pygame.USEREVENT + 2
def reset():
global player, rocks, score, lives, start_time
player = pygame.Rect(220, 300, 40, 40)
rocks = []
score = 0
lives = 3
start_time = pygame.time.get_ticks()
pygame.time.set_timer(POINT, 1000)
pygame.time.set_timer(SPAWN, 800)
def draw_menu():
screen.fill((30, 30, 46))
title = big_font.render("Meteor Dodge", True, WHITE)
title_rect = title.get_rect(center=(240, 140))
pygame.draw.rect(screen, PLATE, title_rect.inflate(24, 12))
screen.blit(title, title_rect)
hint = font.render("Press Enter to play", True, WHITE)
screen.blit(hint, hint.get_rect(center=(240, 200)))
def draw_game():
screen.fill((30, 30, 46))
pygame.draw.rect(screen, (255, 196, 0), player)
for rock in rocks:
pygame.draw.rect(screen, (235, 80, 80), rock)
score_text = font.render(f"{score:05}", True, WHITE)
score_rect = score_text.get_rect(topright=(470, 10))
pygame.draw.rect(screen, PLATE, score_rect.inflate(12, 8))
screen.blit(score_text, score_rect)
for i in range(3):
if i < lives:
screen.blit(heart, (10 + i * 40, 10))
else:
screen.blit(heart_empty, (10 + i * 40, 10))
def play_frame():
global rocks, lives, state
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
player.x -= 6
if keys[pygame.K_RIGHT]:
player.x += 6
player.clamp_ip(screen.get_rect())
seconds = (pygame.time.get_ticks() - start_time) // 1000
speed = 3 + seconds // 5
kept = []
for rock in rocks:
rock.y += speed
if rock.colliderect(player):
lives -= 1
elif rock.top <= 360:
kept.append(rock)
rocks = kept
if lives <= 0:
state = "over"
draw_game()
def draw_over():
draw_game()
message = big_font.render("Game over", True, WHITE)
screen.blit(message, message.get_rect(center=(240, 160)))
hint = font.render("Press R to play again", True, WHITE)
screen.blit(hint, hint.get_rect(center=(240, 200)))
reset()
state = "menu"
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == POINT and state == "play":
score += 1
if event.type == SPAWN and state == "play":
rocks.append(pygame.Rect(random.randint(0, 456), -24, 24, 24))
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN and state == "menu":
reset()
state = "play"
elif event.key == pygame.K_r and state == "over":
reset()
state = "play"
if state == "menu":
draw_menu()
elif state == "play":
play_frame()
else:
draw_over()
pygame.display.flip()
clock.tick(60)
pygame.quit()
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Règles du jeu
Entraînez-vous par vous-même : Playground Pygame