Menu et meilleur score
Fait partie de la section Règles du jeu du Journey Pygame de Coddy. Leçon 29 sur 29.
Sky Runner tire ses règles de cette section : un menu, une nouvelle partie déclenchée par une touche et le meilleur score.
reset() crée un nouveau personnage et un groupe vide, réinitialise le score et la vitesse, puis redémarre les deux minuteurs. Le jeu commence sur "menu", et best est défini une seule fois, en dehors de reset().
La barre d’espace a maintenant trois fonctions, une par état :
if state == "play":
runner.jump()
elif state == "menu":
reset()
state = "play"
elif pygame.time.get_ticks() - over_time > 500:
reset()
state = "play"La barre d’espace sert à sauter ; le joueur est donc souvent en train d’appuyer dessus au moment d’un crash. Sans délai, le jeu redémarrerait avant qu’il ait pu voir le résultat. Mémorise le moment du crash dans over_time et n’accepte la barre d’espace sur l’écran de fin de partie qu’après 500 ms.
Une petite fonction show(text, text_font, y) dessine une ligne centrée en x 320, car le menu et l’écran de fin de partie en nécessitent cinq.
Défi
Difficile- Écris
reset()pour le coureur, le groupe,speed,scoreet les deux minuteurs ; appelle cette fonction avant la boucle et définisstate = "menu",best = 0etover_time = 0. - Dans le menu, affiche
Sky Runner(taille 48) etPress Space to start; la touche Espace ou Flèche haut démarre une partie. - En cas de collision, mets à jour
bestet définisover_time. - Sur l’écran de fin de partie, affiche
Game over,Best: 00120(cinq chiffres) etPress Space to play again; la touche Espace démarre une nouvelle partie, mais seulement 500 ms après la collision. - Affiche le score uniquement pendant la partie et sur l’écran de fin de partie.
Essayez vous-même
import random
import pygame
pygame.init()
screen = pygame.display.set_mode((640, 320))
pygame.display.set_caption("Sky Runner")
clock = pygame.time.Clock()
font = pygame.font.Font("assets/fonts/pixel.ttf", 32)
SKY = (140, 200, 240)
GROUND = (90, 160, 80)
GROUND_Y = 260
GRAVITY = 1
SPAWN = pygame.USEREVENT + 1
POINT = pygame.USEREVENT + 2
class Runner(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.frames = [
pygame.image.load("assets/images/player.png").convert_alpha(),
pygame.image.load("assets/images/player_walk.png").convert_alpha(),
]
self.image = self.frames[0]
self.step = 0
self.rect = self.image.get_rect(midbottom=(100, GROUND_Y))
self.vy = 0
def jump(self):
if self.rect.bottom == GROUND_Y:
self.vy = -16
def update(self):
self.vy += GRAVITY
self.rect.y += self.vy
if self.rect.bottom >= GROUND_Y:
self.rect.bottom = GROUND_Y
self.vy = 0
if self.rect.bottom == GROUND_Y:
self.step += 1
self.image = self.frames[self.step // 8 % 2]
else:
self.image = self.frames[1]
class Obstacle(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = random.choice(obstacle_images)
self.rect = self.image.get_rect(midbottom=(664, GROUND_Y))
def update(self):
self.rect.x -= speed
if self.rect.right < 0:
self.kill()
obstacle_images = [
pygame.image.load("assets/images/spike_ball.png").convert_alpha(),
pygame.image.load("assets/images/blob.png").convert_alpha(),
]
runner = Runner()
obstacles = pygame.sprite.Group()
speed = 6
pygame.time.set_timer(SPAWN, 1500)
pygame.time.set_timer(POINT, 100)
score = 0
state = "play"
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN and event.key in (pygame.K_SPACE, pygame.K_UP):
if state == "play":
runner.jump()
if event.type == SPAWN and state == "play":
obstacles.add(Obstacle())
pygame.time.set_timer(SPAWN, random.randint(1000, 2000))
if event.type == POINT and state == "play":
score += 1
if state == "play":
speed = min(14, 6 + score // 100)
runner.update()
obstacles.update()
if pygame.sprite.spritecollideany(runner, obstacles, pygame.sprite.collide_mask):
state = "over"
screen.fill(SKY)
pygame.draw.rect(screen, GROUND, (0, GROUND_Y, 640, 60))
screen.blit(runner.image, runner.rect)
obstacles.draw(screen)
score_text = font.render(f"{score:05}", True, (40, 50, 80))
screen.blit(score_text, score_text.get_rect(topright=(630, 10)))
if state == "over":
message = font.render("Game over", True, (40, 50, 80))
screen.blit(message, message.get_rect(center=(320, 140)))
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
3Minuteurs et vagues
En sécurité après un impactUn événement de minuterieUn rocher toutes les 800 msDes vagues qui grandissentCompte à rebours avant le départ6Coureur du ciel
Le coureurSauterEntraînez-vous par vous-même : Playground Pygame