Marquer des points
Étape 5
Gestion de l'extension de la queue du serpent.
Gestion et affichage du score.
Quand le serpent s'allonge...
On va maintenant s'intéresser à la progression du jeu et à l'accroissement de la difficulté, qui est corrélée à l'allongement de la queue du serpent. Ce phénomène se produit à chaque fois que le serpent avale une pomme.
Commençons par écrire une fonction extendSnakeTail()
qui va gérer l'allongement de la queue :
# ----------------------------------------------------------
# Snake management
# ----------------------------------------------------------
def extendSnakeTail():
i = snake['head']
n = snake['len']
i = (i + 1) % n
x = snake['x'][i]
y = snake['y'][i]
for _ in range(SNAKE_EXTENT):
snake['x'].insert(i, x)
snake['y'].insert(i, y)
snake['len'] += SNAKE_EXTENT
Cette fonction s'appuie sur une nouvelle variable globale qui détermine la longueur de queue supplémentaire, c'est-à-dire le nombre de tronçons qu'on va ajouter au serpent :
# ----------------------------------------------------------
# Global variables
# ----------------------------------------------------------
SNAKE_EXTENT = 2
La fonction extendSnakeTail()
est relativement simple :
On commence par se positionner sur l'extrémité de la queue du serpent (qui se trouve être la case qui suit immédiatement la tête) au niveau des listes snake['x']
et snake['y']
:
i = snake['head']
n = snake['len']
i = (i + 1) % n
On pioche alors la position (x,y)
de l'extrémité de la queue :
x = snake['x'][i]
y = snake['y'][i]
Puis on va insérer, toujours à l'extrémité de la queue, des copies de x
et y
(SNAKE_EXTENT
copies plus précisément) :
for _ in range(SNAKE_EXTENT):
snake['x'].insert(i, x)
snake['y'].insert(i, y)
Enfin, on met à jour la propriété qui caractérise la longueur des listes snake['len']
:
snake['len'] += SNAKE_EXTENT
Voilà un schéma qui résume la succession des opérations effectuées :
Par conséquent, les 2
tronçons supplémentaires occupent initialement la même position que celui de l'extrémité de la queue (puisque ce sont des copies). Ils se « dérouleront » progressivement au fur et à mesure que le serpent avancera sur la grille.
Il ne reste plus qu'à intégrer cette routine au niveau de l'ordonnanceur :
# ----------------------------------------------------------
# Game management
# ----------------------------------------------------------
def tick():
if game['mode'] == MODE_START:
resetSnake()
spawnApple()
game['mode'] = MODE_READY
elif game['mode'] == MODE_READY:
handleButtons()
moveSnake()
if snakeHasMoved():
game['mode'] = MODE_PLAY
elif game['mode'] == MODE_PLAY:
handleButtons()
moveSnake()
if didSnakeEatApple():
extendSnakeTail()
spawnApple()
if didSnakeBiteItsTail() or didSnakeHitTheWall():
game['mode'] = MODE_START
draw()
L'extension de la queue s'effectue pendant la phase MODE_PLAY
lorsque le serpent avale une pomme :
if didSnakeEatApple():
extendSnakeTail()
spawnApple()
Et voilà ! Démonstration :
Parfait ! Maintenant, on va pouvoir s'occuper du score du joueur...
Gestion du score
Pour mémoriser le score au fur et à mesure de la progression du jeu, on va le stocker au niveau du moteur de jeu game
:
# ----------------------------------------------------------
# Initialization
# ----------------------------------------------------------
game = {
'mode': MODE_START,
'score': 0
}
Ensuite, on va l'incrémenter à chaque fois que le serpent avale une pomme. Et il ne faut pas oublier de le réinitialiser à chaque fois que le jeu passe en phase MODE_START
:
# ----------------------------------------------------------
# Game management
# ----------------------------------------------------------
def tick():
if game['mode'] == MODE_START:
resetSnake()
spawnApple()
game['mode'] = MODE_READY
game['score'] = 0
elif game['mode'] == MODE_READY:
handleButtons()
moveSnake()
if snakeHasMoved():
game['mode'] = MODE_PLAY
elif game['mode'] == MODE_PLAY:
handleButtons()
moveSnake()
if didSnakeEatApple():
game['score'] += 1
extendSnakeTail()
spawnApple()
if didSnakeBiteItsTail() or didSnakeHitTheWall():
game['mode'] = MODE_START
draw()
Réinitialisation du score en début de partie :
if game['mode'] == MODE_START:
resetSnake()
spawnApple()
game['mode'] = MODE_READY
game['score'] = 0
Augmentation du score à chaque fois que le serpent avale une pomme :
if didSnakeEatApple():
game['score'] += 1
extendSnakeTail()
spawnApple()
Il ne reste plus qu'à afficher le score ! Pour cela on va définir une nouvelle variable globale pour déterminer sa couleur d'affichage :
# ----------------------------------------------------------
# Global variables
# ----------------------------------------------------------
COLOR_SCORE = 0xffff
Puis on va ajouter une fonction drawScore()
qui sera chargée de l'afficher à l'écran, qu'on appellera à partir de la méthode principale draw()
, responsable de l'affichage global de la scène de jeu :
# ----------------------------------------------------------
# Graphic display
# ----------------------------------------------------------
def draw():
clearScreen()
drawWalls()
drawSnake()
drawScore()
drawApple()
def drawScore():
display.setColor(COLOR_SCORE)
display.print(2, 2, game['score'])
Le score est affiché aux coordonnées (2,2)
.
Allez !... On sauve le script et on peut maintenant admirer le résultat :
On a pratiquement terminé notre Snake !
Il nous reste à optimiser un peu les choses et à apporter quelques touches de finitions pour terminer la partie en beauté.
Direction la prochaine étape !