Salut les gens !
Cette fois-ci, avec les automates cellulaires nous allons simuler du feu !
Brûler un endroit précis de l'écran
Le principe
Le principe ici est simple :
- On teste si un pixel est allumé
- Dans tous les cas, on éteint le pixel au-dessus
- Si oui, on tire un nombre aléatoire entre 0 et une valeur au choix, et s'il est différent de 0 on rallume le pixel au-dessus
- Si non on laisse éteint le pixel du dessus
- Et ce, pour tous les pixels composant l'aire à "brûler"
Alors allons-y, appliquons dans la joie :] !
Application
On a donc (bien sûr) notre boucle-conteneur, un sprite et ses coordonnées.
- Code: Select all
:.FIRE
:
:[FFFFFFFFFFFFFFFF→Pic1
:28→Y+16→X
:
:Repeat getKey(15)
:
:End
Et on a juste à appliquer les étapes bêtement ! Que diriez-vous de faire brûler la ligne du sommet de notre sprite ?
- Code: Select all
:.FIRE
:
:[FFFFFFFFFFFFFFFF→Pic1
:28→Y+16→X
:
:Repeat getKey(15)
: Pt-On(X,Y,Pic1
:
: For(A,X,X+7)
: .Pour une flamme de 14 pixels de haut
: For(B,Y-14,Y)
: Pxl-Off(A,B-1 → Règle 1
: If pxl-Test(A,B
: If rand^6 → Règle 2
: Pxl-On(A,B-1
: End → Règle 3
: End
: End
: End
:
: DispGraph
:End
Résultat :
Cette méthode a pourtant quelques inconvénients : elle est lente (oooh si, pas tant les boucles For que les routines agissant sur les pixels) et la flamme risque de donner des résultats indésirables si le sprite à brûler se déplace. C'est pour pallier à tout ça qu'on va utiliser une autre méthode !
Brûler tout(e une partie de) l'écran
Le principe
Là, c'est légèrement plus compliqué : on va utiliser deux des aires de RAM pour faire brûler tout ça. L6 si on utilise le buffer, ou L3 pour le back-buffer.
On va donc avoir nos aires libres (qui sont une suite de 768 octets avec un octet = 8 pixels, un par bit) et on va les masquer : c'est à dire leur appliquer un masque dont le but est, comme son nom l'indique, modifier son apparence.
Ce masque, je vous le donne tout de suite, le voici :
- Code: Select all
[7FBFDFEFF7FBFDFE→Str1
Que fait ce masque ? Hé bien il va petit à petit éteindre chaque pixel d'une ligne de 8, ou mettre à 0 chaque bit d'un octet, jusqu'à ce que tout soit éteint / désactivé. En plus de ça, on va copier notre octet sur l'octet au-dessus pour simuler une flamme.
Nous allons appliquer notre masque avec la commande AND.
Application
Allons-y tout de go, on a toutes les clés en main :
- Code: Select all
:.FIRE2
:[7FBFDFEFF7FBFDFE→Str1
:
:Repeat getKey(15)
:.Tous les pixels de l'écran
:For(A,0,767)
:{A+L6} and {rand^8+Str1}→{A-12+L6}
:Il y a 12 octets sur une ligne (96 / 8), donc l'octet du dessus est A - 12
:End
:DispGraph
:End
C'est tout ! Pas compliqué, si ?
MAIS on a oublié quelque chose ! Pour brûler, le feu doit avoir une base, un combustible !
- Code: Select all
:.FIRE2
:[7FBFDFEFF7FBFDFE→Str1
:
:.On rajoute la ligne qui va brûler
:Line(0,63,95,63
:Repeat getKey(15)
:.Tous les pixels de l'écran
:For(A,0,767)
:{A+L6} and {rand^8+Str1}→{A-12+L6}
:Il y a 12 octets sur une ligne (96 / 8), donc l'octet du dessus est A - 12
:End
:DispGraph
:End
Résultat :
Cette fois-ci, chaque particule flambante est indépendante, on peut donc remplacer la ligne par un sprite, qu'on pourra déplacer ! Je vous laisse le loisir d'essayer, mais sachez juste que <b>tout ce qui se trouvera à l'écran lors de l'exécution de la boucle For va brûler !</b> Donc si vous voulez tout cramer sauf un seul sprite, veillez à l'afficher après la boucle et à l'effacer avant (avec Pt-Change par exemple).
Sachez aussi que si vous remplacez L6 par L3 et DispGraph par DispGraphr, vous aurez du feu en grayscales puisque c'est le back-buffer que vous manipulez !
Autre astuce : remplacez le code précédent par celui-ci :
- Code: Select all
:.FIRE2
:[8040201008040201→Str1
:
:.On rajoute la ligne qui va brûler
:Line(0,63,95,63
:.On inverse l'écran
:DrawInv
:Repeat getKey(15)
:.Tous les pixels de l'écran
:For(A,0,767)
:{A+L6} or {rand^8+Str1}→{A-12+L6}
:Il y a 12 octets sur une ligne (96 / 8), donc l'octet du dessus est A - 12
:End
:DispGraph
:End
Et vous aurez du feu blanc sur un fond noir ! Essayez pour voir !
Cet effet peut très bien rendre sur un menu, ou même une animation où tout brûle à l'écran ! Vous pouvez aussi changer la zone qui brûle en manipulant les 2 valeurs de la boucle For !
Faites bon usage de cet effet, et bonne programmation !