By Mik | 16 octobre 2015 | 0 Comment
Cliquer pour commencer, plus cliquer pour lancer une bombe.
En ce moment j’ai eu un peu de temps et je me suis remémoré un jeu auquel j’avais joué dans mon enfance, avec des graphismes HD de l’époque (je ne suis même pas sûr qu’il y avait plus de 2 couleurs).
Il s’agissait d’un avion passant en dessus d’une ville, qui passait de gauche à droite en larguant une bombe à chaque passage, ce qui détruisait entièrement un building.
Le problème c’est qu’il perdait de l’altitude à chaque passage, ce qui fait qu’au bout d’un moment, il risquait d’entrer en collision avec un building. C’est la dure vie d’un monde en 2D : on ne peut pas passer entre les immeubles.
Bref, ça m’a rappelé des souvenirs, et je me suis demandé comment le refaire dans la techno du moment, j’ai nommé Angular (pousse-toi React, c’est pas encore ton tour).
Premier jet des tâches prévues :
Puis dans la V2 :
On est parti!
Commençons par l’initialisation du repo git dans un coin du disque dur.
On passe par l’interface github et on fait notre tout nouveau repo.
Puis on récupère le repo vide, lié au repo distant github automatiquement.
git clone git@github.com:grafmik/angular-bomber.git
Et voilà, il n’y aura plus qu’à faire des pushs en temps voulu.
Faisons un premier commit avec un README, ce sera fait.
echo "# building-destroyer-angular" >> README.md git add . git commit -m "Initial commit" git push origin master
Les graphismes vont être simplistes, faisons-les rapidement avec un fichier html5 et un fichier css rattaché.
Je conçois les graphismes en premier car cela montrera le design du jeu. Il est toujours sympa de voir à quoi ressemblera le projet le plus tôt possible, plutôt que de travailler sur la plomberie invisible. Ca permet de mieux comprendre le projet. Pour moi c’est quelque chose qu’il vaut mieux faire pour tous les projets, surtout pour les POC (proof of concept), les maquettes et les MVP (minimum viable products).
Je vais travailler « à l’ancienne », avec des cases : l’avion tient sur une case, un étage d’un immeuble est une case, une bombe est une case. Ca donnera l’effet (très!) rétro que je souhaite, et simplifiera également la programmation.
Voilà! La version 0.1 alpha du jeu sera le sublime « dessin » sur la gauche. Le carré blanc est l’avion qui passe de gauche à droite, le carré noir est la bombe, de la même taille que l’avion 😉 et les immeubles en bas, avec des couleurs choisies avec goût. Et derrière, le ciel, cyan bien évidemment.
On pourra reprendre les graphismes plus tard, mais je ne vois pas vraiment trop comment améliorer cette perfection 😉
Blague à part, je laisse tout dans un style de carré brut. Il serait facile de rajouter des images ou bien de détailler les graphismes en ajoutant des règles css.
Le html va être le premier à bénéficier de ce changement en perdant pas mal de lignes et en devenant dynamique :
<div class="game" ng-app="angularbomber" ng-controller="BomberController" ng-click="mainClic()"> <div ng-repeat="buildingFloor in buildingsToDisplay" class="sprite building-floor" ng-style="buildingFloor.style"></div> <div ng-if="plane.active" class="sprite plane" ng-class="{crashed: plane.crashed}" ng-style="plane.style"></div> <div ng-if="bomb.active" class="sprite bomb" ng-style="bomb.style"></div> <div ng-if="isMessageDisplayed()" ng-bind="getMessageDisplayed()" class="mainmessage"></div> </div>
On voit déjà assez simplement qu’il va y avoir des immeubles, un avion, une bombe, et également un message global pour le game over ou la fin du niveau. Oui il n’y a qu’un seul niveau pour l’instant, et je pense qu’il faudra attendre la version 2 pour des niveaux supplémentaires. Je prévois la livraison de cette version en 2040 s’il n’y a pas de retard 😉
Pour ce qui est des css, on utilise du relative-absolute pour placer les sprites comme il faut.
Une des difficultés est de transformer le modèle des immeubles en modèle Angular.
En gros, transformer un objet building avec un attribut hauteur en une série de blocs (étages de l’immeubles) qu’on affichera avec la directive ng-repeat
.
Une itération de jeu se fait à intervalle de temps donné.
setInterval(function() { $scope.gameengine(); }, 150);
La fonction contient toute la logique du jeu : elle fait avancer l’avion, le fait se crasher, fait tomber la bombe, rase les immeubles, etc.
Quelques problèmes rencontrés, dont certains non résolus, notamment des problèmes de rafraichissement de $scope
, il faudra que je m’y penche.
J’étais parti sur une syntaxe « controller as » mais je me suis ravisé car il me semblait que les problèmes de $scope
venaient de là, en fait j’ai tout remplacé par $scope et ça n’a rien changé.
J’avais également utilisé des $watch
, qui malgré le 3e paramètre à true pour le deep watch, ne se déclenchaient pas lors d’un changement de l’objet. Du coup j’ai fait plus simple en rafraichissant directement les données quand j’en avais vraiment besoin.
Je ne vais pas regarder en détail tout cela par manque de temps, bien que les problématiques sont intéressantes.
Voici pour le premier article de ce blog.
J’avais très envie de réaliser ce petit jeu ces derniers jours, donc voilà, c’est fait!
Je me suis bien amusé 😉
Le jeu marche pas trop mal, c’est ce que je voulais.
Bien sûr il pourrait être tellement amélioré. Cependant, le voir tourner si rapidement (une soirée de code) est vraiment gratifiant 🙂
Si j’ai du temps un jour, je repasserai peut-être dessus. D’ici là, pas mal de boulot m’attend ailleurs, on ne peut pas faire que jouer…
A la prochaine!