Particules venant du grenier :D

Programmation avancée de jeux en PureBasic
Avatar de l’utilisateur
Polux
Messages : 440
Inscription : mer. 21/janv./2004 11:17
Localisation : france
Contact :

Message par Polux »

c'est très bien réalisé en tout cas! ;)
bravo, l'effet est très joli! Que le code soit simple c'est encore mieux :) ( je filerai mes routines de particules sur mon futur site pour pure, fin septembre ).
Avatar de l’utilisateur
Crystal Noir
Messages : 892
Inscription : mar. 27/janv./2004 10:07

Message par Crystal Noir »

Je suis en train de finaliser la création des procédures du moteur en ajoutant quelques fonctionnalités.

Voici un autre exemple que j'ai fait par la même occasion qui met directement en situation le moteur dans le cadre de la création d'un shoot'em up. On y voit un vaisseau spacial, le moteur de particule se chargeant de simuler les réacteurs à l'arrière du vaisseau.

Vous pouvez bouger le vaisseau à la souris, voici l'exemple :

http://crystalnoir.free.fr/Creations/Pu ... ceship.zip
hackotedelaplaque
Messages : 121
Inscription : mer. 21/janv./2004 22:18

Message par hackotedelaplaque »

Un mot : magnifique 8O
Impressionant... ok ça fait deux mots. :D
10 CLS
20 PRINT "Vive PureBasic"
30 GOTO 20
Avatar de l’utilisateur
Ar-S
Messages : 9539
Inscription : dim. 09/oct./2005 16:51
Contact :

Message par Ar-S »

Super !

Allez maintenant tu es obligé de nous faire un R-TYPE 3000
Avatar de l’utilisateur
Crystal Noir
Messages : 892
Inscription : mar. 27/janv./2004 10:07

Message par Crystal Noir »

merci :)

pour le shoot em up j'vais appeler polux à mon secours mdr :D

J'avance tout doucement, il me reste encore quelques procedures à voir.

voici néanmoins les instructions déjà disponibles qui permettent de gérer l'ensemble du moteur simplement.

Instructions moteur

ParticleSetup() : C'est celle qui contient le plus de paramètre, elle permet de configurer un flot de particule

Particleupdate() : Obligatoire, elle se charge de mettre à jour les particules, elle a en paramètre la zone minimale et maximale d'affichage.

DisplayParticle() : permet d'afficher le flot de particules. Elle prend en paramètre l'image 2D et l'image 3D définies par l'utilisateur.

Instructions de renvoies

ParticleX() : renvoie la position X d'une particule

ParticleY() : idem mais pour la position Y

ParticleID() : renvoie l'id de la particule. Chaque particule est identifié par un ID, toutes les particules ayant la même ID constitue un flot de particules. On peut gérer avec ce système autant de flot de particules et de particules qu'on veut. Le moteur contrairement à d'autres, ne fonctionnent pas avec un emitteur qu'on met à jour, ici on contrôle chaque particules simplement, cela permet d'avoir une plus grand liberté d'effets.

Au lieu de modifier un emetteur qui se chargera de modifier toutes les particules de la même manière, on peut modifier certaines particules en particuliers avec des conditions une simple condition if else endif. Par ex sur 400 particules on peut choisir de modifier uniquement celles qui ont un comportement particulier, on agit sur les particules même et non sur un emetteur qui modifierait tout l'ensemble.

Il est aussi possible de contrôler avec une seule boucle while nextelement() / wend l'ensemble de tous les flots de particules. On peut imaginer un flot de 200 particules de feu où chacune a une ID de 0 et un flot de 200 particules de fumée où chacune à une ID de 1, ce qui fait au total 400 particules mais deux effets différent et contrôlable via la même liste de particule (l'ID faisant la différence).

ParticleVel() : renvoie la vélocité d'une particule

ParticleVit() : renvoie la vitesse d'une particule

ParticleGrav() : renvoie la gravité d'une particule

ParticleVie() : renvoie la vie d'une particule

ParticleAlpha() : renvoie la valeur alpha pour affichage d'une paticule

ParticleEchX() : renvoie la largeur de la particule

ParticleEchY() : idem mais pour la hauteur

ParticleXoff1() : renvoie la valeur 1 de l'offset de la particule

ParticleXoff2() : idem pour la seconde valeur. Ces valeurs couplées à la force permettent de les faire virer à droite ou à gauche.

ParticleRouge() : renvoie la valeur de couleur rouge

ParticleVert() : idem pour le vert

ParticleBleu() : idem pour le bleu

Instructions SET :

ParticleSetX() : permet de fixer la position X d'une particule

ParticleSetY() : idem pour la position Y


Voilà comme vous voyez il me reste à finir la liste des instructions de SET et à modifier quelques procedures moteur.

Avec toutes les intructions disponibles on pourra tout contrôler et ce particule par particule via une boucle while nextelement() / wend et quelques conditions IF.

J'ai voulu faire de chaque particule une entité modifiable. et non un emetteur qui gère tout l'ensemble :)

avec le code évidemment je mettrai les exemples et une doc complète pour l'utiliser :)

Je vous tiens au courant de son avancement.
hackotedelaplaque
Messages : 121
Inscription : mer. 21/janv./2004 22:18

Message par hackotedelaplaque »

ParticleVie() : renvoie la vie d'une particule
A quoi sert exactement cette procédure ?
Elle renvoie 0 si la particule n'existe pas et 1 sinon ?
10 CLS
20 PRINT "Vive PureBasic"
30 GOTO 20
ATHOW
Messages : 226
Inscription : mer. 29/déc./2004 16:54

Message par ATHOW »

J'ai idée qu'il s'agit plutôt de la durée de vie de la particule : combien de temps il reste avant qu'elle ne s'efface. C'est ça ?
Avatar de l’utilisateur
Crystal Noir
Messages : 892
Inscription : mar. 27/janv./2004 10:07

Message par Crystal Noir »

Absolument cette instruction renvoie la valeur de vie en cours d'une particule.

Si cette valeur arrive à 0 la particule est détruite. A chaque tour le moteur enlève 1 à la vie d'une particule. Cela permet de tester la valeur et d'agir en conséquence si par exemple on veut prolonger la vie de certaines particules.

La vie d'une particule a plusieurs facteurs : la valeur de la vie, et l'alpha. Une particule dont la vie est à 0 ou dont la valeur alpha (transparence) arrive à 0 est considérée comme "morte" et donc est détruite.
Avatar de l’utilisateur
Polux
Messages : 440
Inscription : mer. 21/janv./2004 11:17
Localisation : france
Contact :

Message par Polux »

cette façon est vraiment très interessante ( de beaux effets en perspective ). Félicitations Crystal du très beau boulot! Comme je te l'ai dit via msn, si y a moyen je l'utiliserais volontier ;)
Avatar de l’utilisateur
Crystal Noir
Messages : 892
Inscription : mar. 27/janv./2004 10:07

Message par Crystal Noir »

Voici l'exemple de la bougie qui utilise le CPS que je vous commente. Vous comprendrez mieux comment cela marche et derrière je vous donne quelques exemples de variations possibles.

Code : Tout sélectionner

;Initialisation des composants 
InitSprite() 
InitSprite3D()
InitKeyboard() 
InitMouse()
UsePNGImageDecoder()
UseJPEGImageDecoder()

Enumeration
  #Flamme
EndEnumeration

;Création de la fenêtre principale 
SetRefreshRate(60) 
MaFenetre = OpenScreen(800,600,32,"Test") 
If MaFenetre  = 0 
  MessageRequester("Erreur", "Impossible d'ouvrir une fenêtre DirectX", #PB_MessageRequester_Ok) 
EndIf 

Part2D = LoadSprite(#PB_Any,"flare.png",#PB_Sprite_Texture)
Part3D = CreateSprite3D(#PB_Any,Part2D)

Bougie = LoadSprite(#PB_Any,"candle.jpg")

IncludeFile("CPS.pb")


;Boucle Principale
Repeat
  ClearScreen(RGB(0,0,0))
  ExamineMouse()
  DisplaySprite(Bougie,334,255)
 
  For i = 1 To 10  ParticleSetup(#Flamme,400,300,0,0,-Random(70),Random(600),Random(30),Random(30),255,255,255,Random(50),"light",255,-8,0.2,0.2,0)
  Next   
 
  ResetList(MesParticules())
  While NextElement(MesParticules())
    ParticleUpdate(0,800,0,600)
    DisplayParticle(Part2D,Part3D)
  Wend
  
  ExamineKeyboard()
  FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
Regardons ce qui nous interesse à savoir la boucle principale. On commence par donner le nombre de particules qu'on veut pour l'effet, avec une boucle For Next et l'instruction ParticleSetup().

Le premier paramètre représente l'id des particules ici #Flamme. Cela signifie que je pourrais très bien créer un autre flot de particules en même temps avec un ID #Fumee par exemple pour faire la fumée en plus.

Les autres paramètres concernent directement les propriétés des particules (vitesse, gravite, velocite, offsets etc...).

Ensuite dans une boucle While NextElement() on teste les particules. Le moteur utilise une liste unique qui s'appelle MesParticules() et qui peut contenir autant de flot de particules que vous voulez différencié par leur ID.

Dans cette boucle on peut faire tous les tests qu'on veut. Ici on fait simple on appelle l'instruction ParticleUpdate() qui met à jour les particules et DisplayParticle() qui permet leur affichage.

Prenons un exemple bidon où je veux par exemple afficher les particules uniquement si leur vie est inférieure à 20. La boucle While NextElement deviendrait comme ceci :

Code : Tout sélectionner

  ResetList(MesParticules())
  While NextElement(MesParticules())
    ParticleUpdate(0,800,0,600)
    If ParticleVie() < 20
      DisplayParticle(Part2D,Part3D)
    EndIf
  Wend
Maintenant imaginons que j'ai deux flots de particules, c'est à dire qu'en plus de la flamme j'ai ajouté de la fumée. Les particules qui font la fumée ont un ID = #Fumee.

De plus imaginons maintenant que la condition que j'ai ajouté au dessus, je veux qu'elle s'applique uniquement aux particules gérant la fumée. C'est à dire que les particules s'afficheront si leur vie est inférieure à 20 mais je veux que cette condition ne soit vérifié que pour les particules de la fumée uniquement, je ferais ainsi la boucle :

Code : Tout sélectionner

  ResetList(MesParticules())
  While NextElement(MesParticules())
    ParticleUpdate(0,800,0,600)
    If ParticleID() = #Fumee And ParticleVie() < 20
      DisplayParticle(Fumee2D,Fumee3D)
    ElseIf ParticleID() = #Flamme
      DisplayParticle(Part2D,Part3D)
    EndIf
  Wend
Ainsi la condition ne sera testé que si la particule testé fait partie du flot de fumée uniquement. De plus vous remarquerez que j'utilise deux images différentes, une pour chaque flot de particules : Part2D/Part3D pour les flammes et Fumee2D/Fumee3D pour la fumée (qu'il faudra évidemment préalablement charger avec loadsprite et compagnie là je l'ai mis comme ca pour l'exemple).

Dans cette condition si la vie des particules de fumée est inferieur à 20 on les affiche sinon on les affiche pas et dans tous les cas si l'id = #Flamme on affiche les particules de flamme avec leur image.

Ce système de test permet d'agir sur toutes les particules directement ou sur celles qu'on veut et on pas sur un ensemble de particules comme un "emetteur".

Dans la version finale il sera également possible de changer l'id d'une particule lui permettant de passer dans un autre groupe de particules (ou un nouveau). On peut imaginer créer 400 particules et les partager en groupe de 200 pour effectuer à un moment donné certains effets...
Avatar de l’utilisateur
Crystal Noir
Messages : 892
Inscription : mar. 27/janv./2004 10:07

Message par Crystal Noir »

Voici un petit exemple qui montre très bien cette manière de pouvoir modifier une partie des particules parmi un flot et non toutes les particules d'un coup si on avait utilisé un emetteur.

Il s'agit d'une petite flamme. Dans la réalité, une flamme est bleutée à sa base puis, plus on monte plus la flamme devient orange. Une flamme est bleue à sa base car c'est à sa base que la température est la plus basse.

Il est tout à fait possible de simuler ceci avec le moteur simplement. Voici un exemple compilé qui montre une flamme tel que je l'ai décrite :

http://crystalnoir.free.fr/Creations/Pu ... ugibic.zip

Cet effet est simplement traduit en testant la vie de la particule, ainsi si la vie de la particule est inférieur à une certaine valeur, je commence à faire varier les couleurs de la particules en influant directement sur sa structure, ce qui se traduit tout simplement par un couleurSet dans le moteur, une instruction toute simple.
Dernière modification par Crystal Noir le jeu. 02/août/2007 14:16, modifié 1 fois.
Avatar de l’utilisateur
Crystal Noir
Messages : 892
Inscription : mar. 27/janv./2004 10:07

Message par Crystal Noir »

ou encore cette nébuleuse qui montre la gestion des couleurs par particule :

http://crystalnoir.free.fr/Creations/Pu ... uleuse.zip

(attention aux petites configs).
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

Crystal Noir a écrit :Une flamme est bleue à sa base car c'est à sa base que la température est la plus élevée.
8O 8O heu t'es sur la ? :D

le bleu est une couleur de temperature froide, plus on va vers le rouge et les infra rouges, plus la temperature monte en principe, il ne m'etonnerai pas partant de ce constat, qu'au contraire la base d'une flame est plus froide que le haut !! :D

ça m'interresse, je cherche ... :D

je me disais aussi :D

http://www.bougies.info/article_printvi ... D=WICK0007
Vous remarquerez que, à la base de la mèche, la flamme est transparente. C'est la zone la plus "froide" de la flamme (600°C)
Juste au-dessus de la mèche, la flamme est orange. L'oxygène, là aussi, a du mal à arriver. La température dans cette zone atteint les 800°C.
Au-dessus, c'est la zone de combustion: la flamme est jaune. C'est dans cette zone que les particules de suie brûlent comme du charbon et produisent de la lumière, au même titre que le filament d'une ampoule électrique. La température dans cette zone tourne autour des 1200°C. Plus on s'approche de l'extérieur de la flamme, plus l'oxygène est présent et plus la température est haute.
:D
Avatar de l’utilisateur
Crystal Noir
Messages : 892
Inscription : mar. 27/janv./2004 10:07

Message par Crystal Noir »

oui j'ai inversé me suis gourré je rectifie :D :lol: j'ai droit à l'erreur na !
Dernière modification par Crystal Noir le jeu. 02/août/2007 14:21, modifié 2 fois.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

Crystal Noir a écrit :oui j'ai inversé me suis gourré je rectifie :D :lol: j'ai droit à l'erreur na !
:lol: pas de problemes :D
Répondre