Créer le scrolling d'un fond étoilé en perspective

Par Crystal Noir

L'idée est de créer un scrolling étoilé mais en fausse 3D, c'est à dire en perspective. Cet effet donne l'impression que les étoiles viennent de loin pour “sortir” de l'écran.

Ce type d'effet peut très bien être utilisé pour des jeux type shoot'em'up. Dans un premier temps nous aborderons le principe de cet effet, et nous analyserons le code (assez court) qui permet sa réalisation sous GDevelop.

Vous trouverez in fine, les sources téléchargeables afin de tester chez vous.

Il s'agit d'un moteur “fait maison” sans l'utilisation de l'extension “particules” de GDevelop.

Vous êtes prêts ? Alors c'est parti !

Principes généraux

Le but ici n'est pas de vous bombarder de formules ou autres (de toute façon je ne suis pas mathématicien) mais de vous donner une idée générale et simplifiée. Car en réalité les formules qui permettent de calculer des perspectives sont compliquées et je ne les connais pas forcément, mais je vais vous donner la formule de base facile à mettre en oeuvre et qui marche bien.

Les coordonnnées

Quand on développe un jeu ou n'importe quoi en 2D, on affiche nos sprites via des coordonnées simples qui sont x et y.

Dans le cas de la 3D il faut ajouter une coordonnée : z, qui est la profondeur. Seulement ici nous n'avons qu'un système à deux coordoonées (x,y) alors comment faire une perspective dans un plan 2D ?

Il va falloir faire une projection. C'est à dire qu'en quelque sorte on va créer un nouveau plan de coordonnées, et créer ainsi le z manquant.

Oui mais dans une plan 2D on peut pas ajouter une autre coordonnée, même en la créant car par définition en 2D on a x et y c'est tout. Mais il n'y a jamais de problème, que des solutions : nous allons “intégrer” z aux deux autres coordonnées. C'est à dire que x et y seront calculés en fonction de la coordonnée z que nous aurons créée.

Au final on aura bien une coordonnée x et y mais qui intégrera la formule qui permet de simuler la perspective. z sera en quelque sorte un élément essentiel dans le calcul de la position de nos étoiles en x et y.

Quelle perspective ?

Il existe plusieurs types de perspective. Il y a la perspective cavalière, centrale ou parallèle, je vous suggère une petite recherche google pour avoir quelques infos à ce sujet.

Ici nous allons utiliser le principe de la perspective centrale. C'est à dire qu'on va avoir l'impression que les étoiles partent du centre et sortent de l'écran, donnant comme un point de fuite vers le centre.

La formule simple générale

Certaines formules de perspective enlèvent tout bonnement la coordonnée z, hop on en parle plus. Mais nous n'allons pas utiliser cela, car nous, nous voulons une profondeur.

Nous allons tout simplement utiliser :

  • x = x * champs / z
  • y = y * champs / z

Nous allons tout simplement diviser les coordonnées par z. champs étant une constante qui définit en fait la taille du champs d'étoiles. Plus la valeur est grande plus les étoiles seront écartées et vice versa.

Pratiquons sous GDevelop

Les Sprites

Dans un premier temps, il faut prendre l'image d'un flare par exemple de ce type :

Il faut la redimensionner de manière ce qu'elle soit toute petite. Il est intéressant d'utiliser des images comme celle là ou même plus belles, car cela permet après d'ajouter des effets de blend (changement de couleur, luminosité add etc…).

Et….C'est tout. Il ne reste plus qu'à créer un objet associé à cette image, et même pas besoin de poser l'objet sur la scène, le code s'en chargera plus tard.

Vous pouvez cependant déclarer pour cette objet “étoile” quelques variables comme ceci :

Il suffit de cliquer avec le bouton droit sur l'objet puis de choisir Modifier les variables initiales.

Les variables _x et _y et _z vont nous permettre de calculer les vraies coordonnées de nos étoiles, avec la formule qu'on a vu tout à l'heure. Les variables _sx et _sy contiendront le résultat de nos calculs et donc les coordonnées que devra utiliser GDevelop pour afficher nos étoiles.

Les variables globales

On y est presque, il nous faut d'abord initialiser quelques variables supplémentaires qui seront cette fois globale à toute l'application. Pour rappel il suffit de faire un clic droit sur le nom du projet et de choisir Modifier les variables globales.

La variable spread correspond au champs d'étoiles, plus il sera grand, plus les étoiles seront écartées. Vous pouvez essayer en changeant la valeur à 100 ou 32 pour avoir l'effet inverse.

La variable vitesse nous permettra de calculer notre coordonnée z et sera bien sur la variable qui permettra de faire varier la vitesse de notre scrolling, plus elle sera élevée, plus les étoiles iront vite.

Enfin les variables cx et cy définissent les coordonnées du point central de l'écran pour une fenêtre en 800 X 600 soit 400, 300

Nous avons fini le paramétrage il n'y a plus qu'à créer les évènements et actions !

Coder les évènements et actions

Créer les étoiles

Dans un premier temps il faut créer notre objet étoile dans la scène. Souvenez vous nous n'avons rien ajouté à notre scène tout à l'heure, c'est donc le moment de le faire :

Dans un premier temps on demande à GDevelop de créer 500 étoiles au lancement de la scène aux coordonnées -100, 100. Oui, vous avez bien lu, cela permet de créer une étoile en dehors de la scène. Après le calcul elles seront toutes positionnées correctement comme par magie et cela a son importance, vous verrez pourquoi tout à l'heure.

Maintenant il est temps de calculer la position de nos étoiles

Positionner les étoiles

Pour cela nous allons appliquer la formule que nous avons vu tout à l'heure et utiliser les variables globales à l'application :

Si vous vous souvenez de la formule de tout à l'heure : x = x / z et pareil pour y en fait on applique cette formule.

on multiplie la variable x par spread qui est la valeur de champs (voir plus haut) et qu'on divise par _z et on y ajoute la variable cx ! Souvenez vous, cx prend la valeur de 300 en début de scène, c'est le point centrale de la scène c'est ce qui va nous permettre de faire notre perspective.

La variable z quant à elle est calculée très simplement on lui soustrait la vitesse, _z étant la coordonnée représentant la profondeur, quand on retranche la vitesse, c'est ce qui donne l'impression que l'étoile va sortir de l'écran, si _z devient inférieur à la vitesse mise en variable globale, alors c'est que l'étoile est “sortie de l'écran” entre guillemet bien sur car n'oubliez pas que ce n'est pas réél :).

D'ailleurs plus la vitesse sera élevée plus les étoiles iront vite.

Enfin le résultat de ces calculs est stocké dans la variable _sx pour la coordonnée finale x et _sy pour la coordonnée finale y.

Vous remarquerez que l'évènement est testé pour chaque étoile et c'est important. Chaque étoiles est traitée de manière indépendante l'une de l'autre. Si ce n'était pas le cas, les étoiles bougeraient toutes en même temps, et auraient les mêmes modifications en même temps, ce qui donnerait l'impression d'un “tas” d'étoiles qui se déplacent, ce n'est pas ce que nous voulons.

A ce stade vous avez codé 95 % du moteur, c'est simple non ?

Alors vous allez me dire, oui mais il y a un petit problème on a initialisé toutes les variables des étoiles (c'est à dire _x, _y, _z) à 0 donc les calculs, quand on multiplie par 0 ca fait 0 donc comment cela peut marcher ?

On y arrive regardez en dessous :

On commence par tester la variable _z, si elle est plus petite que la vitesse c'est que l'étoile est en dehors de l'écran (profondeur, comme si elle était sortie de l'écran). A ce moment là on applique de nouvelles coordonnées _x, _y et _z en utilisant un Random pour générer un nombre aléatoire. Pourquoi ces valeurs ? Nous avons en quelque sorte redéfini un système de coordonnées avec notre formule de toute à l'heure. Je vous propose de tester différentes valeurs pour voir les variations :)

Ensuite on teste tout simplement si l'étoile sort de l'écran à gauche ou à droite, ou en haut ou en bas, en appliquant les mêmes calculs. Je vous rappelle que ce sont les variables _sx et _sy qui ont au final les coordonnées réelles de nos étoiles. En clair, on fait nos calculs avec _x, _y et _z et on stocke le résultat dans _sx et _sy.

Donc dans notre exemple, si _sx > 800 c'est que l'étoile et sortie par la droite :) à l'inverse si _sx < 0 c'est qu'elle est sortie par la gauche.

Vous comprenez maintenant pourquoi cela n'avait pas d'importance d'initialiser les variables des étoiles à 0. Car dès le début de la scène, ces conditions sont vérifiées et donc les étoiles ont directement une nouvelle position.

L'avantage de ce système est aussi qu'on est pas obligé de créer et recréer des étoiles ! ce sont toujours les mêmes repositionnées à chaque tour !

Afficher les étoiles

Il ne reste plus qu'à afficher nos étoiles :

Et voilà on dit à GDevelop de positionner les étoiles aux coordonnées finales _sx et _sy et c'est fini !

Vous avez plus qu'à admirer le résultat :)

Vous pouvez essayer de changer les valeurs des variables pour voir les variantes, notamment les variables globales vitesse et spread.

Happy GD !