Un cœur pour les jeux rétro programmés maison
J’ai programmé un jeu pour le Commodore 64. En Basic – le langage de programmation du C64. C’était beaucoup de travail, mais je dois avouer que je me suis vraiment bien amusé.
L’idée doit vous paraître folle. Développer un jeu soi-même, okay. Mais pour le Commodore 64, et en plus en Basic ? C’est la mélancolie qui m’a inspiré ce projet, la nostalgie de mes premières expériences avec les ordinateurs. Et je remarque vite que j’y prends autant de plaisir qu’à l’époque, c’est-à-dire à la fin des années 80.
Autrefois, je ne programmais pas sur un Commodore 64, mais sur un ordinateur pour enfants qui ne pouvait afficher que du texte. Les graphismes n’étaient qu’un rêve lointain. La programmation d’un jeu avec des graphiques est donc pour moi la réalisation d’un rêve d’enfant.
De la première idée vague au jeu fini, d’innombrables heures s’écoulent. Je sacrifie une grande partie de mon temps libre pendant près d’un mois. Bien que le jeu soit très simple, je n’ai pas l’impression d’avoir perdu mon temps. J’éprouve même une once de fierté en regardant le résultat.
Le principe du jeu est simple : les touches WASD permettent de contrôler un cœur. L’objectif ? Atteindre la sortie qui se trouve en bas à droite, en évitant les adversaires et les obstacles.
Difficile d’expliquer la fascination qu’exerce mon projet. La nostalgie ne joue qu’un rôle marginal. Beaucoup plus important : un tel programme est un grand travail de réflexion divisé en plusieurs petites tâches. Chaque tâche résolue me rapproche de l’objectif et est immédiatement visible et jouable. C’est motivant.
Il faut aussi dire que créer quelque chose de A à Z est assez gratifiant. Sans parties ou outils tout prêts, comme ce serait le cas sur un ordinateur moderne. J’ai vraiment tout fait.
Je vous montre ici comment l’idée initiale s’est petit à petit transformée en jeu fini.
Conditions préalables : saisie et placement des touches
Tout d’abord, le programme doit reconnaître quand vous appuyez sur une certaine touche et y réagir immédiatement. C’est à cela que sert la commande Basic GET K$
. Elle enregistre la touche actuellement pressée dans la variable K$. Quand j’étais enfant, je ne connaissais que la commande INPUT
. Elle ne permet cependant pas de jouer en temps réel, car l’ordinateur ne réagit que lorsque vous avez appuyé sur la touche retour après avoir tapé.
Placer l’élément librement
La deuxième condition est que je puisse placer librement un élément sur l’écran. Même avec du texte, cela ne va pas de soi. La commande PRINT
écrit le texte là où se trouve le curseur – le C64 ne connaît pas de commande de base pour placer le curseur. Je dois donc utiliser l’instruction POKE
pour modifier une adresse spécifique dans le banc de registres de la puce.
Graphique sous forme de texte
Ironiquement, ma première tentative de jeu graphique n’est autre que du texte. Seuls deux caractères spéciaux en forme de cœur sont visibles. Le cœur bleu doit attraper le rouge.
Si le cœur se déplace, il doit non seulement être affiché au nouvel endroit, mais aussi être effacé de l’ancien. Je résous ce problème en mettant d’abord un espace à chaque passage du programme – pour ainsi dire à chaque image – puis en plaçant le cœur à sa nouvelle position, d’où le scintillement des petits cœurs.
Cette version préliminaire du jeu ne comprend que 41 lignes de code. Le cœur rouge se déplace de manière aléatoire et est donc facile à attraper.
Des graphismes corrects avec des sprites
Un sprite est un élément graphique qui se déplace librement sur l’écran. Contrairement à mon cœur de texte, l’ordinateur actualise l’arrière-plan de lui-même. Cela signifie que je ne dois pas supprimer le sprite à chacun de ses déplacements.
De plus, je peux le concevoir librement. Sur le C64, un sprite monochrome est composé de 504 pixels (21 lignes et 24 colonnes). Il existe aussi des sprites multicolores, mais je préfère commencer light.
Sans outils, la création d’un sprite est extrêmement laborieuse. Pour le faire apparaître à l’écran, je dois à nouveau éditer les adresses mémoire du C64 et calculer les valeurs pixel par pixel. Heureusement, le Wiki du C64 et le super manuel d’utilisation du C64 me fournissent les informations nécessaires.
Un éditeur de sprites serait d’une grande aide pour dessiner et calculer. Mais je suis impatient et je veux mon premier sprite tout de suite. C’est pourquoi je le crée manuellement.
En fait, je voulais dessiner un cœur brisé, mais il ressemble plus à un derrière... Cela dit, ça fait aussi l’affaire.
Ce qui ne me convient pas, c’est que le jeu tourne atrocement lentement, même s’il est d’une simplicité extrême. Je peux par conséquent difficilement l’améliorer ou le rendre plus intéressant, car il en deviendrait encore plus lent.
Compilation en code informatique
La solution est étonnamment simple : les programmes Basic peuvent être traduits automatiquement en langage machine à l’aide d’un compilateur. Ce qui rend le programme beaucoup plus rapide. J’essaie le compilateur Basic Boss et, surprise, ça marche du premier coup.
Le problème : même à une vitesse acceptable, le jeu ne me procure aucun plaisir. Il est encore plus ennuyeux qu’avec la version texte : le cœur ne se déplace plus au hasard, mais me fuit et peut aussi sauter de l’autre côté de l’écran. Le jeu n’en est pas plus intéressant pour autant.
Je décide donc d’inverser les rôles : en tant que joueur, je ne dois plus attraper, mais fuir. Pour que cela ne soit pas trop simple, je dois éviter non pas un, mais deux personnages. Et comme ça fait bizarre avec tous ces cœurs, il me faut un nouveau sprite pour l’ennemi. Et peut-être aussi un nouveau pour le cœur brisé qui ressemble à des fesses.
La compilation rend le jeu beaucoup plus rapide qu’en Basic, mais il reste lent. Dès que je le complexifie, il perd en vitesse. Les directives de compilation m’apportent le coup de pouce nécessaire. Ce sont des indications pour le compilateur, placées sous forme de lignes de commentaires dans le programme Basic. Je peux par exemple déclarer des petites variables entières comme telles, ce qui rend les calculs beaucoup plus rapides. Entre-temps, j’ai tellement optimisé la vitesse que je n’arrive même plus à jouer au jeu. Mais peut-être que vous y arriverez, vous. Vous pouvez le télécharger ici. Faites glisser le fichier .d64 dézippé dans le champ glisser / déposer de l’émulateur en ligne.
Je bricole un éditeur de sprites
Comme je n’ai pas envie de calculer un autre graphique à la main, je décide sans hésiter de programmer un éditeur de sprites. Cela représente certes beaucoup plus de travail, mais c’est un plaisir.
Même si ce morceau de logiciel est loin d’être parfait, il remplit son objectif. Il n’a fallu qu’un week-end complet pour le programmer. Ce faisant, j’ai beaucoup appris sur le chargement et la sauvegarde sur le C64. Et je sais maintenant comment mettre en mémoire tampon l’écran complet pour le restaurer plus tard. Je suis sûr que ça me servira plus tard.
Contrôle des collisions
Comme le but du jeu n’est plus d’attraper un cœur, mais de s’échapper, le jeu a besoin d’un nouvel objectif. Là encore, je me simplifie la tâche autant que possible : le personnage doit atteindre une petite porte sans se faire attraper. Je place quelques obstacles pour augmenter le niveau de difficulté.
Le C64 dispose d’une détection intégrée de collision. En interrogeant la valeur de deux registres de mémoire spécifiques, mon programme sait si le personnage entre en collision avec un adversaire, respectivement avec les obstacles.
Plusieurs niveaux et plusieurs vies
Ensuite, je veux faire plusieurs niveaux. Cela devrait être un jeu d’enfant. En principe, il me suffit de modifier quelques variables comme la position de départ du personnage ou des obstacles, puis de relancer le programme.
Il est beaucoup plus difficile d’ajuster les niveaux de manière à ce qu’ils ne soient ni trop faciles ni insolubles. En effet, je ne peux jouer au jeu à la vitesse correcte qu’une fois compilé, et je dois donc recompiler après chaque modification pour pouvoir l’essayer. Dans l’émulateur, je peux certes accélérer le CPU, mais cela n’apporte qu’une impression grossière, ce n’est pas la même chose.
Avec huit niveaux, il est juste que le joueur reçoive plusieurs vies. Celles-ci s’affichent à droite sous forme de petits cœurs ; le cœur de texte est de retour !
Le jeu a aussi besoin d’un écran de début et d’un écran de fin de partie. Là encore, je fais simple et je gonfle la taille des sprites ; le C64 est programmé pour. Lorsque vous avez terminé les huit niveaux, une petite animation apparaît. Le jeu possède ainsi tous les éléments de base.
Bilan : pas si simple que ça
Tel qu’il est présenté ici, le programme compte environ 240 lignes. Même le plus simple des jeux demande déjà beaucoup de travail, de réflexion et de concepts. Du moins, si vous le créez entièrement vous-même. Maintenant que j’ai la base, je peux l’étendre relativement facilement : ajouter des niveaux, intégrer d’autres sprites et programmer de nouveaux ennemis avec des parcours différents. Des extensions plus complexes seraient également possibles : par exemple, que les ennemis évitent les obstacles ou s’écrasent contre eux, ou que les personnages changent d’apparence lorsqu’il se passe certaines choses. Il ne me reste plus qu’à m’occuper de la musique et des effets sonores.
Je ne risque pas de m’ennuyer. J’espère seulement que toute cette folie se terminera en même temps que l’hiver.
Voici à nouveau le lien de téléchargement du jeu : Cœur brisé pour le C64
Mon intéret pour l'informatique et l'écriture m'a mené relativement tôt (2000) au journalisme technique. Comment utiliser la technologie sans se faire soi-même utiliser m'intéresse. Dans mon temps libre, j'aime faire de la musique où je compense mon talent moyen avec une passion immense.