Dans ce petit tutoriel je vais vous montrer comment faire de la fumée sur la casio prizm, à la fin de ce tutoriel vous serez normalement capable de refaire ceci :
Il existe plusieurs méthodes pour faire de la fumée, dans ce tutoriel je vais vous montrer qu'une seule méthode, cette méthode est très facile à refaire. Vous trouverez en fichier joint les codes sources et le .g3a
Avant de commencer il faut savoir que
Cliquez pour découvrir
Cliquez pour recouvrir
La fumée est composée de petites particules, plus il y a de particule, plus la fumée est opaque
Lorques les particules gagnent en hauteurs, il commencent à se propager un peu partout, la fumée devient donc de moins en moins opaque.
étant donné que la prizm est une calculatrice qui n'est pas très performante, on ne va pas afficher les particules pixel par pixel, ça serait beaucoup trop lent, mais on va plutôt afficher un sprite, moi j'ai utilisé ce sprite :
Voici comment on va coder cette algorithme :
Cliquez pour découvrir
Cliquez pour recouvrir
chaque sprite sera affiché avec une valeur de transparence très élevé, les sprites sont donc presques invisible, mais si on superpose les sprites on obtient un résultat plus opaque, ceci n'est pas très diffile à programmer
chaque particule à une durée de vie, entre chaque frame on va baisser la durée de vie de chaque particule, lorsque la durée de vie est égale à 0 on supprime cette sprite , pour plus de réalisme on peut aussi varier le niveau de transparence de chaque sprite en fonction de sa durée de vie actuelle
Maintenant on passe à la partie programmation
chaque particule sera représenté par une variable de type tParticule
typedef [purple]struct[/purple] tParticule
{
bool estPresent; [green]//lorque estPresent=true, on affiche notre sprite[/green]
[purple]int[/purple] x; [green]//position en x du sprite[/green]
[purple]int[/purple] y; [green]//position en y du sprite[/green]
[purple]int[/purple] dureeDeVie; [green]//durée de vie, si dureeDeVie=[maroon]0[/maroon], alors estPresent=false[/green]
} tParticule;
on va créer maintenant un tableau de type tParticule, dans l'exemple ci-dessous le tableau contient 70 éléments, donc il y aura au maximum 70 sprites visible à l'écran
[brown]#define TAILLETAB 70[/brown]
[green]//j'ai mis la taille du tableau dans un define, ainsi il sera beaucoup plus simple de paramétrer la fumée ;)[/green]
[purple]int[/purple] main()
{
tParticule particule[TAILLETAB];
[b][blue]return[/blue][/b] 0;
}
maintenant il faudrait initialiser notre tableau, pour faire ça j'ai créé la fonction
int main()
{
tParticule particule[TAILLETAB];
Init_tParticule(particule);
[b][blue]return[/blue][/b] 0;
}
maintenant on va créer une boucle et dans cette boucle on va afficher un fond noir
int main()
{
tParticule particule[TAILLETAB];
Init_tParticule(particule);
[b][blue]do[/blue][/b]
{
BgColor(0x0000); [green]//ici on affiche le fond noir, vous pouvez retrouver cette fonction en fichier joint[/green]
Bdisp_PutDisp_DD();
}while (!keydown(47)); [green]//vous pouvez mettre ce que vous voulez comme cas d'arrêt[/green]
[b][blue]return[/blue][/b] 0;
}
à chaque fois que l'on tourne en boucle, on va rajouter des particules dans le tableau 'particule', puis on va les afficher
[b][blue]for[/blue][/b] (i=[maroon]0[/maroon];i<TAILLETAB;i++)
{
[b][blue]if[/blue][/b] (particule[i ].estPresent)
{
CopySpriteNbitMaskedAlpha(smoke,particule[i ].x-30,particule[i ].y-30,[maroon]60[/maroon],[maroon]60[/maroon],smoke_palette,[maroon]0[/maroon]xa254,[maroon]2[/maroon],(particule[i ].dureeDeVie*NIVEAUOPACITE)/DUREEDEVIE);
}
}
}while (!keydown(47)); [green]//vous pouvez mettre ce que vous voulez comme cas d'arrêt[/green]
[b][blue]return[/blue][/b] 0;
}
Quelques explications :
Cliquez pour découvrir
Cliquez pour recouvrir
Je rajoute 4 sprites à chaque fois que le programme tourne en boucle à l'aide de la fonction Add_tParticule, j'ai mis le nombre de particule dans un #define, ainsi il sera plus facile de paramétrer la fumée, plus la valeur de NOMBREPARTICULEARAJOUTER sera élevé, plus la fumée sera dense, mais le programme sera ralenti et il faudrait augmenter la taille du tableau, sinon le tableau sera vite plein
void Add_tParticule(tParticule * particule)
{
[purple]int[/purple] i = [maroon]0[/maroon];
[b][blue]while[/blue][/b] (particule[i ].estPresent && i<TAILLETAB) [green]//on tourne en boucle tant qu[gray]'on n'[/gray]a pas trouver de place de libre[/green]
{
i++;
}
[b][blue]if[/blue][/b] (i <TAILLETAB) [green]// si on a trouver une place de libre[/green]
{
particule[i ].estPresent = true;
particule[i ].x = Rand32(XMIN,XMAX);[green]//on rajoute les particules aléatoirements sur toute la longueur de l'écran, XMIN et XMAX sont des define[/green]
particule[i ].y = [maroon]236[/maroon];
particule[i ].dureeDeVie = DUREEDEVIE;
}
}
DUREEDEVIE est un #define, plus la durée de vie est élevé, plus les particules monteront haut.
à la place de #define DUREEDEVIE 15 vous pouvez aussi mettre #define DUREEDEVIE Rand32(10,30) par exemple, ainsi il y aura des particules qui disparaitront plus vite que les autres
Plus la durée de vie est élevé, plus il y aura de particules, car il y aura des particules sur une plus grande surface.
Passons maintenant à l'affichage, pour afficher des sprites avec un canal alpha j'ai utilisé la fonction CopySpriteNbitMaskedAlpha, c'est la fonction CopySpriteNbitMasked que j'ai légèrement modifié à l'aide de la fonction SetPixelAlpha de Pierrotll
Les paramètres de la fonction CopySpriteNbitMaskedAlpha
Les paramètres de la fonction CopySpriteNbitMaskedAlpha
les paramètres:
1)nom du sprite (dans mon exemple c'est smoke)
2)coordonnée en x
3)coordonnée en y
4)taille du sprite en x (dans mon exemple c'est 60*60)
5)taille du sprite en y
6)palette (smoke_palette)
7)couleur transparent (dans mon exemple le violet est la couleur transparente)
8)nombre de bits (dans mon exemple le sprite des particules est codé en 2 bits)
9)la valeur d'opacité (0= transparent, 31=opaque) dans mon exemple j'ai mis (particule[i ].dureeDeVie*NIVEAUOPACITE)/DUREEDEVIE), c'est un simple produit en croix.
Plus la valeur de NIVEAUOPACITE sera élevé, plus la fumée sera dense, ainsi on pourra baisser un peu la valeur de NOMBREPARTICULEARAJOUTER, ce qui accélèrera légèrement le programme
Maintenant il ne nous reste plus qu'à déplacer chaque sprite et de modifier la durée de vie
[b][blue]for[/blue][/b] (i=[maroon]0[/maroon];i<TAILLETAB;i++)
{
[b][blue]if[/blue][/b] (particule[i ].estPresent)
{
particule[i ].y -=[maroon]4[/maroon]; [green]//les sprites montent[/green]
particule[i ].x +=Rand32(1,[maroon]6[/maroon])-3+VENT; [green]//les sprites se déplacent légèrement vers la droite ou vers la gauche[/green]
particule[i ].dureeDeVie-=Rand32(0,[maroon]2[/maroon]); [green]//on diminue la duree de vie, on aurait pû aussi mettre particule[i ].dureeDeVie-=[maroon]1[/maroon];[/green]
[b][blue]if[/blue][/b] (particule[i ].dureeDeVie<=[maroon]0[/maroon] || particule[i ].y<10) [green]//on supprime le sprite si la durée de vie vaut 0 ou si le sprite sort de l'écran[/green]
particule[i ].estPresent = false;
}
}
VENT est un define, si VENT=0 alors il n'y a pas de vent
Voilà !
L'algorithme n'est pas trop difficile, la seule difficulté reste le paramétrage, car il est très difficile de faire de la fumée réaliste sans trop ralentir le programme, libre à vous d'adapter l'algorithme selon vos besoin
Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd