Développer un jeu de serpent en Scratch

Mohamed Slim

Scratch est un logiciel libre conçu à la base pour initier les enfants à la programmation.
Je vous présente cet article dans lequel j'explique comment on peut créer un jeu de serpent en Scratch dans sa version 2.

Commentez

- Titre : Développer un jeu de serpent en Scratch

- Auteur : Mohamed Slim

- Parution : 30 avril 2016

- Mise à jour : 7 mai 2016

- Public visé :

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2016 Mohamed Slim . Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Présentation

- II. Avant de commencer

- III. Étude de cas

- III-A. Création des scripts

- III-A-1. Gestion des mouvements de la tête

- III-A-2. Augmenter la longueur du serpent à chaque fois qu'il mange un repas.

- III-A-3. Ajouter des objets à des emplacements aléatoires de la scène

- IV. Téléchargement

- V. Documentation

- VI. Conclusion

- VII. Remerciement

I - Présentation

Scratch est un logiciel destiné aux enfants pour leur apprendre comment programmer des jeux, comment faire des animations ou tout autre contenu multimédia en utilisant des graphiques créés directement avec Scratch ou importés, et en élaborant des scripts à l'aide d'une suite d'instructions paramétrables.
D’autres fonctionnalités sont possibles en Scratch comme la programmation des cartes Arduino et des cartes Raspberry Pi.
Le slogan de Scratch est « Imagine - Programme - Partage ! ». Le partage est en effet un fondamental de la pédagogie.

II - Avant de commencer

Pour découvrir l'interface du logiciel ainsi que les différents outils offerts par Scratch, vous devez commencer par la lecture de cet article officiel rédigé par les auteurs du logiciel.
Vous pouvez aussi voir ma présentation sur le logiciel.

III - Étude de cas

Dans cet article, je vais vous expliquer comment créer un serpent qui se déplace et qui augmente de taille dès qu'il attrape un objet.

Figure 0 : interface du jeu

Généralement, la conception des jeux passe par deux étapes dont la première est la création des graphiques nécessaires pour le jeu, alors que la deuxième est la création des scripts, c'est-à-dire la programmation.
Pour notre cas, nous n'avons pas grand-chose à faire graphiquement à part la création des trois composants suivants :

On appelle chaque objet dans Scratch : un lutin (en anglais, sprite).
Chaque lutin est repéré par ses deux coordonnées x et y :

Pour créer ces lutins, on doit activer l'onglet Costumes dans l'interface du logiciel. Vous aurez un éditeur de dessin accompagné d'une boite à outils basique.

Cependant, vous pouvez importer des images plus représentatives pour la tête et le corps du serpent ou bien utiliser un logiciel de dessin plus sophistiqué pour créer vos dessins et les inclure à votre jeu Scratch.

III-A - Création des scripts

Avant de commencer la programmation, il faut prévoir les problèmes à résoudre pour réaliser votre jeu. Vous pouvez faire un petit graphique comme celui-là :

Figure 1 : problématiques à résoudre

D'après le schéma, on doit résoudre quatre problématiques pour bien déplacer le serpent vers un objet repas figurant sur la scène pour augmenter notre score.

Dans la suite de l'article, je vais traiter chaque problématique à part et je vais vous expliquer les scripts que j'ai élaborés pour résoudre chacune d’entre elles.

III-A-1 - Gestion des mouvements de la tête

Au début du jeu, la tête du serpent est fixe.
Quand le joueur clique sur une touche de direction,

la tête du serpent se déplace selon cette direction jusqu'à ce que le joueur change de sens en appuyant sur une autre touche de direction.
Nous devons donc connaitre durant le jeu, la direction (le sens) de la tête afin de bien déplacer le serpent sur la scène selon cette direction.
Pour conserver le sens de mouvement, on doit utiliser la notion de variable. En effet, une variable est une zone mémoire qui admet un nom et dans laquelle on peut mettre une valeur de type textuel ou numérique. Pour récupérer par la suite cette valeur, on utilise juste le nom de la variable.
En Scratch comme en algorithmique, une variable peut être locale ; donc locale à un lutin et par conséquent sa valeur ne peut être utilisée que par ce lutin.

Pour notre jeu et afin de gérer le mouvement du serpent, on doit créer une variable qui a comme nom sens avec quatre valeurs possibles :

Et suivant la touche de direction utilisée par le joueur, la valeur de cette variable est comme le montre la figure suivante :

Les lutins du corps du serpent doivent suivre sa tête. Ils doivent alors connaitre la direction de déplacement indiqué ainsi par la variable sens.
Par conséquent, notre variable sens doit être globale et donc partagée par tous les lutins du jeu.

Ce script doit gérer le déplacement de la tête du serpent à droite.
Quand on appuie sur la flèche droite du clavier, alors le sens est 1, et la tête doit avancer vers la droite

et la valeur de l'avancement doit être la même que la taille de l'objet graphique corps , qui va être stockée dans la variable largeurT. Le serpent sera toujours en mouvement dans un sens donné par la dernière touche de direction enfoncée par le joueur jusqu'à ce que ce dernier appuie sur une autre touche. On doit alors clôturer le script de déplacement du serpent par une boucle :

répéter
...
Jusqu’à (changement de direction)

Cette instruction est ajoutée dans le script pour diminuer la vitesse de déplacement du serpent.
Si on prend une valeur supérieure à 0.3 s, le déplacement du serpent sera de plus en plus lent.
Pour les autres sens, vous devez suivre le même principe et modifier soit l'abscisse x, soit l'ordonnée y de la tête par cette instruction

qui a pour effet d'ajouter à la position verticale du serpent une valeur de largeurT.

En algorithmique, on écrit .

Concernant les instructions suivantes :

Elles concernent la troisième problématique de la figure 1 qui sera expliquée par la suite.
Finalement, le script permettant de gérer les quatre boutons de direction est le suivant :

III-A-2 - Augmenter la longueur du serpent à chaque fois qu'il mange un repas.

Notre serpent est constitué d’une tête et d’une queue, et entre les deux le corps qui va être représenté par les lutins jaunes.

Le corps est la partie du serpent qui va augmenter de taille, c'est-à-dire que le nombre de lutins jaunes qui constituent le corps va augmenter.

Les lutins repas sont des graphiques (carreau jaune) créés au préalable et enregistrés dans la bibliothèque sans figurer sur la scène du jeu.
Un lutin repas quand il est attrapé par la tête du serpent, devient un objet faisant partie du corps du serpent. Il devient alors un lutin corps.
Pour augmenter la longueur du serpent, il faut dessiner un lutin corps supplémentaire derrière la tête.
On peut imaginer que la tête crée une trajectoire lors de son déplacement sur la scène.

La trajectoire de la tête est un ensemble de points p(x, y) parcourus par la tête lors de son déplacement continu.
» Tout d'abord, il faut enregistrer ces points p(xp , yp) :

» Par la suite, on doit attribuer ces valeurs xp et yp aux lutins repas mangés qui feront partie du corps dès qu'ils seront mangés par la tête.

Chaque lutin corps doit avoir un numéro d'ordre.

Par exemple, un lutin corps ayant le numéro 1 a été un lutin repas mangé en premier lieu.
Un autre lutin corps de numéro 2 a été un lutin repas mangé en deuxième lieu.
Il faut comprendre alors que chaque lutin corps sera placé à un point p(xp,yp) de position i dans une trajectoire.

Les deux variables tabXt et tabYt sont deux tableaux (list en Scratch) dans lesquels on va enregistrer les points p de la trajectoire de la tête. Les deux coordonnées x et y de chaque point p(x,y) atteint par la tête, seront ajoutés dans ces deux tableaux respectivement comme le montre la figure suivante.

Si on prend la figure ci-dessus, on remarque que le point de coordonnées (8,4) présente la position actuelle de la tête tandis que les autres points sont les anciennes positions de la tête.
Dans ce cas de figure, le serpent se déplace vers la droite de façon rectiligne sans changer sa hauteur, ce qui explique la valeur 4 dans toutes les cases du tableau tabYt.
Les anciennes positions de la tête seront les positions des lutins qui constituent le corps du serpent jusqu'à la queue.

Revenons maintenant à la première problématique (figure 1) dont le script est le suivant :

Remarquez les deux instructions en rouge qui permettent ainsi d'ajouter à chaque déplacement dans les quatre sens, l'abscisse x et l'ordonnée y de chaque point p de la trajectoire parcourue par la tête.

Finalement, pour ajouter à notre serpent un lutin repas qui vient d'être mangé, on doit attribuer à son abscisse x et à son ordonnée y les deux valeurs contenues respectivement dans les tables tabXt etabYt comme le montre le script ci-dessous. On comprend alors que la trajectoire de la tête est représentée par un tableau (liste) tabXt pour les abscisses et un tableau tabYt pour les ordonnées.

Le remplissage de ces deux tableaux est tel que l'abscisse actuelle de la tête se trouve dans la dernière case du tableau tabXt (même principe pour tabYt).

Le numéro d'ordre du lutin corps est enregistré dans une variable maPos qui présente le nombre de lutins corps actuels +1 dans le serpent.
Le script qui doit être placé dans un lutin repas est présenté par la figure ci-dessous :

Figure 2 : Script positionné sur les lutins repas

Un lutin repas peut passer par deux états, un état où il est un repas et un autre état quand il est mangé et participait au corps du serpent. De ce fait, le script est composé de deux parties comme le montre la figure 2.
La première partie présente le traitement à faire quand le lutin repas est devenu désormais un lutin corps. Lors de ce changement ; de lutin repas à un lutin corps ; ce dernier doit à chaque déplacement du serpent trouver son emplacement dans le corps.
Comme j'ai expliqué plus haut, la position d'un lutin corps sur la scène est fournie par les deux tableaux tabXt et tabYt à la position correspondante au numéro d'ordre du lutin.
Dans ce script (figure 2), j'ai utilisé la variable nbCorp pour stocker le nombre d'objets corps actuel (i.e. la longueur actuelle du serpent) mangés à un instant donné.
D'une autre coté, la variable CorpTouché permet de tester si le lutin repas actuel est mangé (donc touché ; devient alors un lutin corps) par la tête ou non.
Alors si le lutin est touché, il doit suivre la trajectoire de la tête au point p(x,y) qui existe à la position calcPos définie par de tabxT pour l'abscisse et même position pour l'ordonnée dans le tableau tabYt. La partie deux du script de la figure 2 correspond aux traitements à faire lorsque le lutin repas n'est pas encore touché par la tête du serpent.
Donc on vérifie à chaque déplacement si le lutin repas a touché la tête du serpent ou non.
Si c'est le cas, on va jouer un son (un tambour).
On augmente le nombre de lutins corps, on augmente la taille du serpent avec ce script .

Le numéro d'ordre de ce lutin sera le nombre de lutins corps actuel.

III-A-3 - Ajouter des objets à des emplacements aléatoires de la scène

Passons maintenant à la résolution de la dernière problématique de notre jeu.

Comme déjà mentionné, les lutins repas sont créés au préalable, mais ne figurent pas directement sur la scène. Ils sont ajoutés au fur et à mesure d'une façon aléatoire. Vous devez donc dessiner vos lutins repas

et y ajouter le script de la figure 2.
Par la suite, vous devez placer ces lutins à des positions de votre choix sur la scène, puis grâce à cette instruction

les lutins seront cachés pour ne pas figurer sur la scène au début du jeu.
Ensuite, au lancement du jeu en appuyant sur le drapeau vert

et après un certain nombre de secondes tiré aléatoirement grâce à l'instruction

, chaque lutin sera affiché sur la scène et mis en attente pour être touché (mangé) par la tête du serpent. On complète alors le script de la figure 2 pour avoir la version finale du code que vous devez placer sur chaque lutin repas :

Figure 3 : version finale du script du lutin repas

IV - Téléchargement

Actuellement, Scratch est en version 2.0 et peut être utilisé en ligne en créant un compte sur son site officiel.
Cependant, il est possible de télécharger le logiciel et l'installer pour travailler en local.
Le jeu expliqué dans cet article est réalisé avec la version 2 du logiciel. Vous pouvez récupérer la source ici.

V - Documentation

Vous pouvez découvrir de plus Scratch à travers ces liens :

- Ces bonnes  ressources en français.

- Ce site sur Scratch et Squeak.

- Ce livre intitulé Scratch pour les Kids

VI - Conclusion

Dans cet article, j'ai présenté les problématiques qu'un « scratcheur » doit résoudre pour arriver à faire fonctionner son jeu de serpent convenablement.
En effet, mon but par cet article n'était pas de vous apprendre comment créer un jeu 2D en Scratch, mais plutôt de vous faire découvrir les atouts de ce logiciel pour l'apprentissage de la programmation.
Tout cela ne présente en fait qu'un nombre infime des possibilités de ce magnifique logiciel.
Concernant notre jeu, il n’est pas complet. Vous devez ajouter des fonctionnalités pour le finaliser et prévoir le cas où le serpent touche son corps ou enfonce la bordure. Vous pouvez aussi ajouter des niveaux (augmenter la vitesse du déplacement à chaque niveau) et afficher un score.
Enfin, si cela vous intéresse, vous pouvez m’envoyer vos essais sur le forum à cette adresse.

VII - Remerciement

Je tiens à remercier zoom61 pour ses remarques et ses recommandations qui m'ont permis d'améliorer la qualité de cet article.

Un grand merci aussi à f-leb pour ses relectures orthographiques et ses corrections.