Logique principale du jeu
Dans cette étape, nous allons implémenter la logique principale du jeu Flappy Bird.
def mainGame(movementInfo):
score = playerIndex = loopIter = 0
playerIndexGen = movementInfo["playerIndexGen"]
playerx, playery = int(SCREENWIDTH * 0.2), movementInfo["playery"]
basex = movementInfo["basex"]
baseShift = IMAGES["base"].get_width() - IMAGES["background"].get_width()
## obtenir 2 nouveaux tuyaux pour ajouter à la liste upperPipes lowerPipes
newPipe1 = getRandomPipe()
newPipe2 = getRandomPipe()
## liste des tuyaux supérieurs
upperPipes = [
{"x": SCREENWIDTH + 200, "y": newPipe1[0]["y"]},
{"x": SCREENWIDTH + 200 + (SCREENWIDTH / 2), "y": newPipe2[0]["y"]},
]
## liste des tuyaux inférieurs
lowerPipes = [
{"x": SCREENWIDTH + 200, "y": newPipe1[1]["y"]},
{"x": SCREENWIDTH + 200 + (SCREENWIDTH / 2), "y": newPipe2[1]["y"]},
]
dt = FPSCLOCK.tick(FPS) / 1000
pipeVelX = -128 * dt
## vitesse du joueur, vitesse maximale, accélération vers le bas, accélération lors du battement d'ailes
playerVelY = -9 ## vitesse du joueur le long de Y, par défaut la même que playerFlapped
playerMaxVelY = 10 ## vitesse maximale le long de Y, vitesse maximale de descente
playerMinVelY = -8 ## vitesse minimale le long de Y, vitesse maximale d'ascension
playerAccY = 1 ## accélération vers le bas du joueur
playerRot = 45 ## rotation du joueur
playerVelRot = 3 ## vitesse angulaire
playerRotThr = 20 ## seuil de rotation
playerFlapAcc = -9 ## vitesse du joueur lors du battement d'ailes
playerFlapped = False ## True lorsque le joueur bat des ailes
while True:
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
pygame.quit()
sys.exit()
if event.type == KEYDOWN and (event.key == K_SPACE or event.key == K_UP):
if playery > -2 * IMAGES["player"][0].get_height():
playerVelY = playerFlapAcc
playerFlapped = True
## vérifier s'il y a eu un crash ici
crashTest = checkCrash(
{"x": playerx, "y": playery, "index": playerIndex}, upperPipes, lowerPipes
)
if crashTest[0]:
return {
"y": playery,
"groundCrash": crashTest[1],
"basex": basex,
"upperPipes": upperPipes,
"lowerPipes": lowerPipes,
"score": score,
"playerVelY": playerVelY,
"playerRot": playerRot,
}
## vérifier le score
playerMidPos = playerx + IMAGES["player"][0].get_width() / 2
for pipe in upperPipes:
pipeMidPos = pipe["x"] + IMAGES["pipe"][0].get_width() / 2
if pipeMidPos <= playerMidPos < pipeMidPos + 4:
score += 1
## changement de playerIndex basex
if (loopIter + 1) % 3 == 0:
playerIndex = next(playerIndexGen)
loopIter = (loopIter + 1) % 30
basex = -((-basex + 100) % baseShift)
## tourner le joueur
if playerRot > -90:
playerRot -= playerVelRot
## mouvement du joueur
if playerVelY < playerMaxVelY and not playerFlapped:
playerVelY += playerAccY
if playerFlapped:
playerFlapped = False
## plus de rotation pour couvrir le seuil (calculé dans la rotation visible)
playerRot = 45
playerHeight = IMAGES["player"][playerIndex].get_height()
playery += min(playerVelY, BASEY - playery - playerHeight)
## déplacer les tuyaux vers la gauche
for uPipe, lPipe in zip(upperPipes, lowerPipes):
uPipe["x"] += pipeVelX
lPipe["x"] += pipeVelX
## ajouter un nouveau tuyau lorsque le premier tuyau est sur le point de toucher la gauche de l'écran
if 3 > len(upperPipes) > 0 and 0 < upperPipes[0]["x"] < 5:
newPipe = getRandomPipe()
upperPipes.append(newPipe[0])
lowerPipes.append(newPipe[1])
## supprimer le premier tuyau s'il est hors de l'écran
if len(upperPipes) > 0 and upperPipes[0]["x"] < -IMAGES["pipe"][0].get_width():
upperPipes.pop(0)
lowerPipes.pop(0)
## dessiner les sprites
SCREEN.blit(IMAGES["background"], (0, 0))
for uPipe, lPipe in zip(upperPipes, lowerPipes):
SCREEN.blit(IMAGES["pipe"][0], (uPipe["x"], uPipe["y"]))
SCREEN.blit(IMAGES["pipe"][1], (lPipe["x"], lPipe["y"]))
SCREEN.blit(IMAGES["base"], (basex, BASEY))
## afficher le score pour que le joueur recouvre le score
showScore(score)
## La rotation du joueur a un seuil
visibleRot = playerRotThr
if playerRot <= playerRotThr:
visibleRot = playerRot
playerSurface = pygame.transform.rotate(
IMAGES["player"][playerIndex], visibleRot
)
SCREEN.blit(playerSurface, (playerx, playery))
pygame.display.update()
FPSCLOCK.tick(FPS)
- Nous définissons la fonction
mainGame
, qui contient la logique principale du jeu Flappy Bird.
- La fonction gère l'entrée utilisateur, met à jour l'état du jeu, vérifie les collisions et suit le score.
- La boucle de jeu tourne en continu, mettant à jour l'affichage et la logique du jeu.
- Les contrôles du joueur sont gérés via des événements clavier (espace ou flèche du haut).
- La fonction vérifie également les collisions avec les tuyaux et le sol, met à jour le score et gère l'animation de l'oiseau.
- La boucle de jeu continue jusqu'à ce que le joueur ait un crash ou quitte le jeu.