Aujourd'hui, nous programmons un petit jeu dans lequel on contrôle un petit satellite tournant autour d'une étoile. Commencez par créer un nouveau répertoire, et y extraire cette archive.
Si vous êtes sur votre ordinateur personnel, il vous faudra installer les paquets vg, lwt et js_of_ocaml(ce dernier en version 2.8.4 , sinon il faudra peut-être modifier les sources fournies, priori simplement en ajoutant le package js_of_ocaml-lwt dans le fichier _tags, mais je ne garantis rien). Vous pouvez forcer la version de js_of_ocaml avec la commande opam pin add js_of_ocaml 2.8.4 (et attendre la réinstallation).
En plus des fichiers de configurations, on trouve dans cette archive :
Les deux premiers modules ne sont pas très compliqués, vous pouvez regarder rapidement le code et vous convaincre qu'avec un peu plus de temps, vous auriez pu le faire. Ils utilisent une fonctionnalité pas encore introduite en cours : les enregistrements. Ils s'utilisent d'une façon assez proche des structures en C. Par exemple, voici le type Body.t :
Pour créer une valeur de ce type, il suffit de donner une valeur à chaque champ :
Pour accéder à la valeur d'un champ :
Il n'est pas possible de modifier les valeurs d'une structure, mais on peut créer une copie en changeant uniquement un ou plusieurs champs ainsi :
Pour commencer, on va créer l'architecture du jeu, mais au début, il ne se passera rien dans le jeu. Un jeu (dans notre moteur simplifié) est décrit par :
Tout cela est défini par le type paramétré par le modèle :
Il nous faut donc définir une telle description du jeu. Ensuite, la fonction run de Engine se charge du reste.
Nous compilerons le jeu en javascript, il s'exécutera dans un navigateur en ouvrant la page index.html.
Créez un nouveau fichier game.ml.
Définissez un type model, un enregistrement qui pour l'instant ne contient qu'un seul champ : un entier. Définisser une valeur model valant 1 .
Définissez une valeur event_handlers qui est la liste vide.
Définissez une fonction show prenant un modèle, et dessinant un disque centré en 0 , de rayon égal à l'entier du modèle. Pour cela, on utilise la librairie Vg dont la documentation est ici. Par exemple, pour créer un disque :
Définissez dt valant 0.0 2 (5 0 franes par secondes).
Définissez stop une fonction du modèle retournant vrai si l'entier est au moins 10 .
Finalement, définissez l'application et le main ainsi :
Pour compiler :
Vérifier que index.html pointe vers le bon fichier javascript, et ouvrez-le dans un navigateur. Un cercle devrait s'afficher.
Pour l'instant le jeu n'est pas intéressant, il ne se passe rien. On va donc ajouter des événements.
Dans evant_handlers ajoutez une paire dans la liste. La première composante est l'événement tick défini dans Engine.Event. On lui associe une fonction qui prend le modèle et augmente le champ entier de 1 .
Ajoutez une deuxième paire dans la liste, pour l'événement click, décrémentant le modèle de 1 s'il est positif.
Compiler et vérifiez ce qu'il se passe.
Ce premier exemple vous a permis de comprendre comment fonctionne ce moteur de jeu. On peut maintenant faire un vrai jeu avec. Celui-ci consistera en contrôler un satellite en rotation autour d'une étoile.
Créer un fichier satellite.ml et définir un type t. Un satellite est un corps physique, le type doit donc avoir un champ de type Body.t. Ajoutez-lui aussi une couleur.
Ajoutez des fonctions pour :
Modifiez le modèle du jeu pour que ce soit un champ contenant un satellite. Supprimer l'événement click. Modifier l'événement tick pour que le satellite se déplace.
Enfin modifiez la fonction d'affichage du jeu, pour afficher l'étoile et le satellite, sur fond noir. Utilisez Vg.I.blend pour coller les images les unes sur les autres.
On voudra pouvoir contrôler le satellite, donc il sera intéressant de pouvoir connaître sa direction.
Ajoutez un champ direction au satellite. La direction est un vecteur unitaire, on utilise le type Gg.v2. Au début, la direction est la même que la vélocité.
Voici le schéma du satellite, la grille étant alignés sur les vecteurs horizontaux et verticaux (vous pouvez personnaliser votre satellite si vous vous sentez un peu artiste) :
On dessine le satellite en position (0,0 ) allant vers la droite, puis on le tourne, puis on le déplace.
Les modules Gg et Vg contiennent les fonctions nécessaires :
À nouveau, testez !
On veut pouvoir contrôler les mouvements du satellite, soit en activant son moteur, soit en tournant le satellite sur lui-même.
Ajoutez des champs au satellite :
Pour manipuler les valeurs de ce type, on peut utiliser cette construction (c'est une exemple, ne convertissez par les rotations en chaînes de caractères) :
Ajoutez ensuite trois fonctions :
Puis ajoutez des fonctions permettant d'allumer/éteindre le moteur, et initier ou terminer une rotation.
Il faut maintenant lier les actions du joueur sur le clavier avec ces fonctions. Utilisez les événements claviers Engine.Event.key_up et Engine.Event.key_down, en donnant en argument le code de la touche ('a' pour la touche A par exemple). (Dans la console javascript accessible via Ctrl-Maj-i, vous pouvez voir la chaîne encodant une touche).
Testez !
Modifier la fonction de test de fin du jeu. Le jeu s'arrête si le satellite rentre dans l'étoile, ou quitte la fenêtre du jeu.
Le jeu est encore très basique, mais vous trouverez facilement des idées pour le rendre plus intéressant. Vous pouvez aussi :