Une pause curseur, c’est un événement !

Ce titre racoleur (:p) ne fait qu’annoncer 3 choses : le retour du curseur (qui m’a fait paniquer un instant), le retour des événements et le système de pause.

Commençons par le système de pause, même si sujet technique, si vous changez de fenêtre ou d’onglet de votre navigateur, le système (canvas) se met en pause technique, et à votre retour il recommence. Jusque là ok, sauf qu’on boucle en déterminant le temps qui passe entre 2 images pour faire avancer de manière fluides les animations et autres. Du coup quand on revient c’est le bordel, tout s’excite et essaye de rattraper le temps perdu, mais vous n’étiez pas là et pour vous ça aurait juste dû s’arrêter et reprendre à votre retour.

Autre phénomène d’exemple, une vidéo, vous arrivez, on joue un son ou vidéo, vous changez d’onglet, ça serait souvent préférable de stopper l’ensemble. Évidemment ceci est soumis à une somme de variables dépend de ce que vous en faites. Un jeu se met en pause c’est sympa, ça vous préserve, mais un MMO ne se met pas en pause, même s’il faut stopper techniquement le rendu et peut-être les sons. Il y a matière à réflexion, et c’est pas demain que j’aurais les réponses, et encore moins de manière générique.

Ensuite nous avons le retour des événements, pris par le service Navigator, qui fait le pont entre le composant Angular et le programme/jeu et ses besoins. Et donc le curseur !

Pour le curseur c’est devenu très simple, il suffit d’avoir un Element, le charger et le dessiner aux coordonnées reçues par l’événement mouseMove (quand on passe la souris sur l’écran). Le truc c’est que rien ne charge le curseur, ses images, ni ne définit son animation par défaut (même si une seule image c’est une animation figée). Il y a encore de quoi améliorer bien sur. Du coup là on charge le curseur définit dans la conf de la scène, ne serait-ce que pour le Sprite et son type, sait-on jamais, ça ne coûte pas grand chose actuellement, on verra sur la durée.

Là où j’ai paniqué c’est au rendu… car j’avais pas tilté directement qu’on avait l’empilement et donc la gestion de hauteur et donc un sol au dessus du niveau 0. du coup notre curseur est dessous, mais dessiné par dessus.

Avant

Encore plus de question, où devrait apparaître le curseur, ou est-ce que le sol devrait être descendu pour rendre l’idée d’origine ? La seconde option me plait, mais il faudra voir en fonction des élévation, et là on retombe sur l’idée de déplacer le curseur en fonction de la position du Ground (l’Element sol, qui n’existe pas encore comme tel). Mais dès lors, vous risque de voir votre curseur bouger verticalement alors que votre souris fait juste un passage de gauche à droit simple, car le curseur voudra s’adapter au terrain. Dilemme donc !

Il existe aussi la méthode du Raycasting (lancé de rayon), qui consiste à partir de la position du curseur de la souris à déterminer quel élément on touche. On parcoure les Elements du plus près au plus lointain (l’inverse exacte du rendu) et si la hit box 2D (= on touche le dessin ?) de l’Element attrape le curseur alors on s’arrête et on dit qu’on est là. On part donc du rendu visuel pour déterminer où on est, sans suivre la grille réelle technique. À peu de chose près.

Pour les détails, l’événement clavier a été raccordé pour désactiver la pause automatique quand on change d’onglet. Même si le débat demeure sur cette gestion de pause. De plus toutes les scènes n’ont pas besoin de l’infos de pause non plus (ex.: menu).

La suite ?

Comme dit dans le précédent article, un Element capable des 4 directions NESW et le pathfinding. Et peut-être des réponses à mes interrogations précédentes. Le nombre de TODOs ne cesse d’augmenter… ^^.

J’aimerais également sauver le code sur un git maison pour préserver tout ça, même si on enchaîne les POCs.

Et ainsi font, font, font, les petites barres


Tadaaa.. l’animation fonctionne !

Merci POC Sonic 🙂 ! Ceci dit, cela démontre également l’importance d’un Sprite Packer, ce n’est pas rien, mais tant qu’on est pas plus avancé je ne vais pas investir, et continuer de bricoler un peu. Quand on sera plus avant, il sera toujours temps de regarder les options (shoebox, texturepacker, …).

Comme vous pouvez le voir dans ce gif tout pourri (pas merci OBS et convertio), tout est rendu avec la nouvelle technique utilisant l’animation. Il reste a optimiser update() et draw() des objets sans animation, mais quand on y pense, ils auront tous au minimum les 4 directions NESW, mais on a pas encore décidé si Sprite divisé ou non, imaginez la composition du truc…

Quand on parle d’animation on oublie qu’il y a plusieurs genres, ici c’est l’animation des Sprites, mais il y a également le mouvement (déplacement en Z par exemple ou variance de x,y), ainsi que des particules ou effets par exemple, qui combineraient les 2.

La suite ?

Ayant récemment mis au point sur papier le pathfinding (trouver son chemin suite à un clic sur la carte), c’est la direction suivante que je vais prendre. Ceci comprendra l’orientation NESW, faire un élément Hero, regard suivant la souris, réactiver le clic, le curseur et les événements avec propagation, le déplacement en évitant les obstacles, du coup le zoom aussi tant qu’à faire (même si c’est réservé à l’éditeur, donc à voir).

Allez encore 25 TODOs sans cette liste précédente ^^…

Empilement de dessins

Petite victoire suite à l’article précédent, j’ai réussi à déplacer la fonction de dessin au sein d’un Element, proprement en supprimant la dépendance cyclique, tout en affinant les objets de bout en bout. Ce qui est amusant c’est que j’ai supprimé 50-80 lignes de code pour un résultat amélioré et identique au rendu, c’est toujours agréable.

Notez qu’on avait déjà refait le subset (portion de la carte à rendre à l’écran – optimisation), en considérant la somme du Tile suivit des Items à la même coordonnée ([Tile, Element, Element, …]) et ainsi faciliter le rendu tout en corrigeant la notion de couverture d’un Tile sur un Element : un morceau de terre recouvre l’ombre du second arbre dans l’image ci-dessous, sans ça l’arbre était dessiné après et donc l’ombre recouvrait le bloc de terre qui n’a rien à voir. Ainsi c’est plus juste visuellement tout en ayant une boucle plus facile à traiter.

Du coup map (contenant tout le monde chargé) a subit le même lifting que subset (le schéma de données d’entrées aussi), soit la somme directe de tous les Elements et on supprime Tile qui perd de sens si on donne Z à Element (c’était la seule différence). Du coup on pourra étendre Element pour les objets composés.

Ensuite, étant lancé, on (avec Boudine) a continué sur l’empilement et donc la notion d’animation, toujours dans la fonction draw de Element. Le résultat comique quand oublie qu’un objet a une taille, c’est qu’ils s’écrasent au niveau 0. Ensuite, si vous oubliez que initialement vous considériez le haut du sol comme point de base, et qu’ensuite vous mélangez la nouvelle notion de taille avec les ancienne valeur de base, vous avez un sol à l’ancienne place et des arbres qui volent ^^, car eux ont suivit l’élévation incrémentée et le sol non.

En résumé un Sprite contient la notion de taille de l’objet représentée, selon la frame d’animation (ou la seule image par défaut), et le système de rendu sur base d’une hauteur de base donnée, incrémentera de la taille de l’objet rendu, additionné de son élévation Z. Ainsi vous pouvez avoir un arbre sur un arbre comme dans l’image ci-avant. Et pour illustrer l’élévation vous avez les blocs de terre qui montent ou descendent, ce qui est dessus suivra naturellement.

Tout fini bien quand les petits correctifs sont appliqués. On a donc un rendu avec code mieux réparti (le bon endroit), une mécanique d’initialisation et de rendu améliorée, des lignes et procédures inutiles retirées et le sentiment de progresser dans le bon sens.

La suite ?

On a ouvert la porte à la structure d’animation, le système de rendu de Element doit encore être amélioré pour traiter ça complètement, car Element n’a pas encore de gestion des ses animations. Pour cela le code du POC Sonic servira de base car il couvrait pas mal de possibilités variables. Il restera à faire un cas de test. Notez que je sais qu’un logiciel libre existe pour composer lui-même sur base d’image un Sprite, me reste à le trouver et voir s’il rend en sortie également les références de positionnements, ça aiderait grandement.

Sinon, on peut également repartir sur l’intégration des events, qui doivent transiter par Game ou directement aux Scene actives, à voire, et ainsi reprendre le dessin du curseur et le zoom. Reste à savoir où mettre tout ça et comment raccorder.

Nahyan, 18 ans plus tard

Nahyan, ça fait un bout de temps dis donc et en en reparlant avec certains membres de l’équipe originale, ça n’a pas prit une ride (Merci K-you). Ça tombe bien j’ai toujours pas abandonné !

Reprenons la situation

Reprenons quelques instant un mini résumé de la situation : « Seul je ne sais pas faire le jeu tel que pensé et il faut arrêter de croire que je serai aidé ».

Ensuite, dans l’optique « j’y arriverais malgré tout », il faut reprendre ce qu’on a comme acquis permettant de démarrer : je suis développeur web et pas illustrateur. Il faut donc que j’amoindrisse mon ambition, sans casser le projet ou perdre l’envie de le faire, rester motivé et prendre du plaisir à le faire.

Du coup on repars un an en arrière, j’étais développeur web en mission pour Auchan et j’ai développé, entre autre, un éditeur de plan de masse (en gros la vue du haut des meubles d’un étage de magasin). Ceci a été fait sous Angular en Canvas et c’était bien amusant de le faire. Du coup quand c’est sympa on explore et on chipote, on fait ça encore mieux, etc. Ce qui donne ceci :

Vue partielle de l’éditeur

En gros on a comme possibilité de sélectionner, drag/droper d’une liste vers le plan ou du plan vers le plan (déplacer un meuble), molette de souris pour faire une rotation du meuble ou zoom du plan (min-max), visibilité de la sélection dans une liste sur plan ou inversement au survol, etc… Le tout avec les optimisation possible pour ne dessiner que ce qui est nécessaire tout en se faisant plaisir avec les petites ombres par exemple.

Exemple de rendu d’objets : 3 meubles de différents type, une caisse et un escalator

Ici on a un exemple de certains éléments graphiques créés directement en code.

Tant qu’on y est…

J’étais lancé et je ne pouvais pas explorer plus avant les possibilités de cet éditeur, du coup je me suis créé un petit projet perso pour tester les animations en sprite. En fouillant un peu j’ai retrouvé ce bon vieux Sonic.

Ainsi j’ai pu chercher comment découper, afficher, animer, retourner, etc. notre petit héro bleu. Ensuite, me casser les dents sur la physique de déplacement du personnage mais ça on va zapper…

Oui mais ensuite ?

Ensuite la mission s’est terminée et j’ai eu quelques jours au bench. Du coup je me suis occupé en tentant de renforcer mes compétences Angular, surtout sur la partie mise en place d’un nouveau projet. Car c’est facile d’utiliser ce qui a été mis en place par d’autres, mais le faire soit même c’est de la découverte casse-gueule…

Coder c’est joli, mais un rendu c’est mieux, Canvas c’était sympa et comme j’avais déjà fait un POC (preuve de concept) isométrique en canvas à la maison, je me suis dit que mélanger les deux rendrait la chose plus amusant, Angular et Canvas pour un moteur isométrique. Il manquait un truc : les éléments graphiques, et c’est pas le plus simple.

En fouillant je suis tombé sur l’excellent site opengameart.org, fait par un développeur, Clint Bellanger, d’un jeu gratuit et open-source nommé Flare, de lien en lien je suis également tombé sur son blog partageant ses études du sujet isométrique et de son jeu et moteur graphique.

C’est dans la même suite de recherches que je suis tombé sur le magnifique logiciel MagicaVoxel. Ce truc est terrible, pas évident au début mais très agréable. C’est là que je me suis dit :  » tu n’es peut-être pas graphiste/illustrateur, mais t’as les notions et la créativité pour faire de ce logiciel l’instrument qui te manquait « .

Du coup j’ai fait ça :

Un morceau de terrain isométrique
Oui c’est un arbre

Ok je me suis bien amusé, j’ai chipoté et fait un rendu isométrique par le logiciel et puis ?

Ensuite j’ai transposé mes précédents essais et morceaux de code du projet Auchan, Sonic et compagnies en un POC de rendu isométrique. Ce qui donne, après de nombreux chipotages et réflexions sur les calculs de rapports entre écran et monde, monde et écran, en incluant les notions de zoom, d’offset et d’élévation :

Tadaaa… ok ça ressemble à rien mais en une matinée c’était pas mal (une demi journée de recherche à tourner en rond sur le net et un début de rendu). Évidemment ce n’est pas suffisant, il nous faut un objet et un curseur pour contrôler et vérifier les formules de positionnement, de zoom etc.

Et avec un objet pour vérifier la superposition, l’ombrage et l’élévation :

Du coup ça fonctionne, un POC de +650 lignes, données incluses, ça fait plaisir, et on est à 1 jour et demi. Puis en chipotant sur des dessins et en repensant au plan de masse d’Auchan, je me suis dit, qu’est-ce que ça donnerait en isométrique ? Il m’a suffit de dessiner un meuble au l’autre, changer la carte de données, corriger des superpositions et ordonnancement pour avoir ce petit magasin :

Vue isométrique test d’un plan de masse

Ça a fait beaucoup rire les collègues 🙂 .

On s’arrête au POC ?

Bien entendu non, j’ai réussi une étape, c’est bien, je l’avais déjà fait mais là c’est plus abouti. La base est là et vérifiée, on peut continuer ! Cependant c’est un POC tout dans un seul fichier, c’est pas propre et continuer là dedans c’est pas une bonne idée. Du coup, on décompose le code en morceaux, on crée des classes, on structure son code, on découvre les joies des inclusions cycliques, des prises de têtes de  » Où mettre ça ??? « , etc… Il m’aura fallu presque une semaine pour transposer le code et en arriver presque au même point qu’au POC :

Test de rendu d’un terrain variable avec objets

Là on a une version complète et fortement améliorée pour son côté structuré et flexible. Manque le curseur et le zoom qui n’ont pas encore été recâblé pour la simple et bonne raison que je me suis concentré sur le système de rendu, la structuration des données, simplification/factorisation du code et correctifs divers.

En parallèle

À coté de ça, j’ai tenté de m’installer un espace de travail propre, un petit GitLab sur le serveur daaboo, mais quand on a la moitié de RAM que nécessaire… et pas de redmine encore car GitLab pourrait peut-être suffire. Mais on est loin du compte encore. Le top serait d’avoir le moteur graphique séparé de l’usage Nahyan, on lui a trouvé un nom  » TARS « , je vous laisse chercher pourquoi.

La suite ?

Là ça fait une semaine que je m’échine à refondre la structuration Sprite et Element, suite de ce que je disais avant, fondre et refondre pour trouver le bon équilibre de séparation des concepts, stockage des données, etc. J’y suis presque, l’idée est d’avoir un Sprite qui s’occupe de stocker l’image et les infos descriptives de cette image (points de référence, hauteur/largeur, frames d’animations, …) et de l’autre un Element faisant référence à un Sprite tout en ayant ses valeurs propres. Ainsi 2 Elements « brin d’herbe » utilisant le même Sprite pourront être animé séparément et ne pas avoir cet effet ringard de tous les mêmes élément animés en même temps.

Dans cette refonte j’essaye d’inclure directement la notion d’animation et d’objet composé.

Il y a encore pas mal de travail avant d’avoir à nouveau une base propre, stable et bien pensée, même si on sait d’avance que ce n’est pas le dernier refactoring du code de base.

Pour détails du jour

Pour ceux que ça intéresse ou pour le souvenir :

  • Usage de la classe Bloc au lieu de l’interface périmée
  • Suppression de Tile au profit de Element contenant une propriété Z (élévation).
  • Nettoyage et fixes suite à la disparition tragique de Tile
  • La grande question est… (non pas celle là) comment transférer Draw de Scene dans Element vu qu’on a un Camera, un incrément de bloc et des coordonnées d’écran
  • Stacking mis en place au niveau du subset
  • Hero est un set de données x, y en dur
  • Cursor désactivé, mouse event aussi
  • Autre question est comment mélanger Iso et rendu standard au sein d’une scène, mélange de méthode et de services

Pour info il y a 30 TODOs qui traînent dont 19 rien que dans Iso…

Nahyan, on ne tue pas une idée

Une semaine bloqué dans mon travail m’a donné l’occasion de jouer avec canvas la balise HTML5 et javascript.

J’ai conçus un petit test abordant divers principe pour une base de jeu.

http://killan.daaboo.net/nahyan/test/, le code est dans la source, profitez-en. (Firefox et Chrome, contrôle via les flèches du clavier)

Les principes abordés sont :

– élaborer une grille, au final codé en JSON. L’affichage tiens compte de l’ordre pour la profondeur,
– chaque élément de la grille est un objet graphique (objet Image) avec paramètres,
– un personnage se déplace sur la grille,
– des éléments de la grille sont animé via la technique des sprites.

Outre l’aspect rudimentaire du graphisme la base est là, un personnage se déplaçant dans un monde.

Voilà donc la seule différence avec l’ancien Nahyan, la profondeur du jeu reste inchangé et tout aussi permise, on y gagne en technique, maitrise et temps de développement. Qui sait qu’un jour Bethesda décide de prendre notre projet pour faire celui que j’espérais faire naître 🙂 .

Dans un premier temps je réunis les anciens membres et vais continuer mes tests et implémentations de fonctionnalités, tout en sachant qu’une fois le projet démarré il me faudra recommencer de meilleure manière.

Développer une éditeur de zones et fixer les modalités de fonctionnement du « moteur ».

Des idées d’optimisation sont déjà élaborées ainsi que le système de construction (objets et bâtiments). Le compositing de l’équipement des persos ainsi que le terrain « vivant » ont également étés adaptés.

Donc il me reste à attendre la prochaine (première) réunion pour cette version et avancer sur le développement du système.

714_g

Quand le plan A ne marche, réessaye, plus fort !

Mais au contraire de ce dicton orc, Nahyan, seul, est impossible…

J’ai proposé une version web, intermédiaire, permettant de développé tout sauf l’aspect vision 3D et l’interactivité de ce mode. Le web permettant de développer toute la logique et la profondeur primaire du jeu, tout en gardant les infinies possibilité, bien qu’illustré et joué différemment.

Ainsi donc, sans personne à mes côtés, je (Killan) ne poursuis pas cette aventure qui m’a déjà trop déçus au niveau humain.

Je n’abandonne certes pas et met ce ‘bébé’ de côté, au chaud, en attendant une possibilité de réalisation.

J’ai perdu une autre bataille, pas la guerre !

Tout le monde en place… action !

Les acteurs principaux de Nahyan ont pris place dans la nouvelle direction web du projet.

Ainsi nous pouvons démarrer l’esprit tranquille et assuré d’une reprise.

2 personnes aux commandes, un backup et les autres restent attentifs à la moindre progression.

Un nouveau forum fraichement installé va remplacer FDEV qui commence à se faire vieux mais restera notre archiviste.

Lecteurs curieux de suivre notre aventure, je vous propose de découvrir ce forum.

La venue d’un prêcheur

Après 8 ans de rêves, de travaux, de recherches et de temps consacré, j’arrête le projet Nahyan dans sa version actuelle à savoir un jeu en 3D à télécharger.

La communauté à faillit au plan d’un an débuté l’été passé. Ainsi il s’avère que le projet n’est pas viable dans ce contexte.

Nahyan n’est pas mort pour autant. Je suis développeur web et je n’ai pas dit mon dernier mot. Le web sera ma solution, là où les problèmes techniques surgissaient et où les connaissances manquaient dans la réalisation 3D du jeu.

Du coup, je vire tout le monde et on repart, mais pas à zéro, il suffit d’adapter le gameplay à un site web, tout ce qui a été pensé reste, ce qui est le plus gros.

De ce fait, on va ré-équiper, re-planifier, revoir des points, etc. prochainement.

Sparky est dans la danse pour le graphisme, la majorité de la communauté restante passe la main. Pas d’autre nouvelle actuellement.

Rendez-vous donc prochainement pour plus de nouvelles concernant cette réorientation de Nahyan.

Retour vers le futur

Tout d’abord, Anémone 2009 !

Ensuite voyons ce qui s’est passé depuis décembre : l’éditeur monoDevelop nous est insuffisant : pas de pas à pas et d’introspection de dll étrangères, ce qui est fort gênant voir handicapant.

Pourquoi, Comment ?

Maintenant que Igloo est prêt et que son contenu est suffisant pour l’éditeur de terrains, j’ai voulu commencer à découvrir OpenGL de SDL.net, ou comment y accéder correctement. BAM ! pas d’accès, pas d’objet trouvé, rien, nada.

Pour les raisons citées plus haut pas moyen de démonter les dll de SDL.net pour voir pourquoi et comment.

Solution ?

On vire le Linux, monoDevelop et on met Windows XP avec Visual Studio Express. On oublie pas d’installer les runtime SDL.net (oui j’avais oublié…) et on recompile pour être sûr que tout va et, ouf, ça marche 🙂

Reste à résoudre le problème principal… Sinon on est encore bon pour recommencer et NON il n’en est pas question.

Suite prochainement j’espère !

Qui vivra verra les pissenlits pousser

Ça y est la théorie du Sol est fixée ! Non je n’y crois pas, mais si !

Suite à une discussion du codage du sol avec K-you, une idée survint, puis une longue marche après la suite est venue et j’ai clôturé la théorie du sol 🙂

Techniquement elle respecte toutes nos attentes ! Reste plus qu’à coder… ça c’est une autre pair de manches, mais faisable !

Avant Noël faut pas rêver mais la traduction du code existant de NTerrain v11 peut commencer : les zones en premier, puis le système de pinceau et enfin l’importation de terrain préfabriqué.

Voilà donc une excellente nouvelle pour cette fin d’année 🙂 !