Enfin!

Je vous l’avoue humblement, je viens de me sortir d’un de mes plus difficiles tests de programmation jusqu’à maintenant!

250 petites lignes de codes qui sont passées proches me rendre fou, je vous le dis.

Comme quoi des fois ce n’est pas la grosseur qui compte… 😉

Dans les précédentes démonstrations  »in game », mon héros est toujours localisé en plein centre de l’écran, ce qui cause un problème de jouabilité à mon avis.  Le joueur voit autant en arrière qu’en avant du personnage, alors que, par définition, le gros de l’action se déroule à l’avant du héros.  Dans ce cas, me direz-vous, on a qu’à déplacer le centre un peu vers la gauche pour laisser plus de champs libre à la droite du héros.  Comme ça on voir les ennemis venir et c’est tant mieux.

Ok, mais si mon héros se déplace tout à coup vers la gauche dans le monde en 2D dans lequel il est contraint?  Là, on ne voit plus rien…

Je voulais donc modifier ma class Camera (qui n’est pas une caméra du tout en fait, mais plutôt une matrice qui calcul la position relative du héros par rapport au monde du jeu, mais bon) pour la transformer en CameraDynamic.  Une caméra qui se placerait au bon endroit en fonction de la direction que le héros emprunterait.

L’idée n’est pas nouvelle.  Les Marios et autres platerformers modernes ont pour la plupart implémenté différentes solutions à ce problème.  Voici ce que mon approches donne:

 

En bonus, si on ne touche à rien, la caméra se recentre tranquillement sur le héros!

Nice, non?

4 réflexions sur “Enfin!

    1. Je tente de ne pas trop entrer dans les détails techniques en général, parce que, d’après moi, la majorité des lecteurs (à partir de 2 lecteurs, ont dit  »des », hein?) s’y intéresse peu. Mais j’avoue devoir faire habituellement un effort pour ne pas trop techniciser dans le blog.
      Merci pour le prétexte! 🙂

      Bon, ma class Camera originale se servait d’une matrice de calcul (qui vient de la librairie xna, mais qui sert pour les jeux en 3D. Je garde le Z à 0 et ça fait la job en 2D!) pour placer le background en fonction du déplacement du bonhomme. Sauf exceptions, je me sers du centre de l’écran comme point de référence. L’autre feature de cette class, est qu’elle prend en paramètre un float que j’appelle  »parallaxeFactor ». À 1, c’est le tableau sur lequel le héros se déplace. Entre 0 et 1, c’est l’arrière plan qui se déplace plus lentement. Ce n’est pas le cas pour le moment, mais je pourrais placer un ForeGround avec un parallaxeFactor supérieur à 1 et il déroulerait plus rapidement que le tableau (ça risque d’être fait un jour, mais pas prochainement 🙂
      L’idée en créant la CameraDynamique, était de ne plus avoir le héros comme point de référence pour le déplacement de tout ces éléments, mais un point abstrait invisible placé à l’avant du bonhomme. C’est là que les problèmes sont apparus. Le code que j’avais gossé en wordpad faisait justement ça, et ça fonctionnait très bien pour le plan à 1 de parallaxeFactor (le tableau en soi), mais le background faisait des free games solides! Le problème provenait, il me semblait évident à ce moment, d’une erreur de calcul générée justement par cet effet parallaxe et j’ai passé des heures à tenter d’écrire différentes méthodes qui corrigeaient ce dysfonctionnement. Je me suis approché plusieurs fois d’une solution acceptable, mais il y avait toujours un glitch et le tout me donnais l’horrible sentiment de bricolage (tu dois vivre ça des fois, j’imagine?) avec des  »magic numbers » et tout.
      Il y a quelques jours, j’étais aux toilettes (tu voulais des détails!) et la vérité m’est apparue. La class CameraDynamic gère déjà l’effet parallaxe (feature provenant de sa petite soeur Camera), il n’y a aucune raison, que ce soit ou non le héros le point de référence, que l’effet ne fonctionne pas. Ce ne sont que des coordonnés bordel, pas un héros pour vrai!
      Pour déplacer le point de mire de la caméra, je me servais de l’état du héros. Genre, si le héros isRunnigRight, déplace le point de mire vers la droite. Et c’est ça qui mélangeait tout.
      Les différents états du héros de contenaient pas assez de définitions pour que la caméra réagisse de façon adéquate. Retour à la base, on utilise l’état du clavier à la place! Maintenant, c’est comme si je déplaçais un autre petit personnage invisible dans l’écran pour placer la caméra au bon endroit. C’était tellement simple, que s’en était compliqué.
      Bon dieu, c’est comme dans Mario 64, quand on pouvait déplacer la caméra avec les ti-pitons jaunes! Sauf que là les paramètres sont beaucoup plus contraignant (à droite, maximum 400 pixels en avant du joueur, et même chose vers la gauche, le tout seulement sur l’axe des X).

      Et voilà l’histoire!
      Après ce wall of text, j’ai peur que tu ne laisses plus de commentaires…
      Mais te ne gènes pas 🙂

      Bon, maintenant je dessine le premier méchant, et on attaque un autre morceau de code intéressant : hitscan!

      J’aime

  1. Bravo! Je trouve l’effet parallaxe bien réussi et l’ambiance du niveau prometteuse. J’ai hâte d’en voir plus! Aussi perso je ne suis pas contre un peu de technique, mais je comprends que ça peut devenir lourd. Lâche pas!

    J’aime

Laisser un commentaire