Mål
Studenten skall efter avslutat laboration…
- …ha grundläggande kunskaper i rendering
- …ha praktiserat spelfysik-simulering
Teori
Exempel på partikelsystem:
Partikel-system är grunden till många effekter i datorspel. Partikelsystem bygger på att vi simulerar rörelser och beteende på en mängd partiklar och tillsammans bildar de en helhet som kan visualisera en mängd fenomen som annars är svåra att visualisera med andra tekniker.
Enskild partikels rörelse
En partikels rörelse genom rummet kan simuleras på två olika sätt, med tillstånd(statefull) och utan tillstånd(stateless). För att räkna ut partikelns position och hastighet gör vi en integrering. Den metod vi kommer beskriva först kallas Euler metoden och är en av de enklaste metoderna för integrering men inte speciellt exakt.
Vi börjar med en statefull partikel som har en position och hastighet och som inte påverkas av någon acceleration.
x0 = Partikelns position från början
v0 = Partikelns hastiget
dt = tiden som förflutit i sekunder
x1 = partikelns position efter “dt” sekunder
För att räkna ut partikelns nya position efter att tiden förflutit gör vi då
x1 = x0 + v0 * dt
i kod
newPosition.x = elapsedTime * velocity.x + position.x; newPosition.y = elapsedTime * velocity.y + position.y;
En sådan partikel kommer då röra sig i samma riktning hela tiden. För att få in acceleration exempelvis gravitation bör vi utöka modellen till.
a = Accelerationen
v1 = Partikelns nya hastighet efter “dt” sekunder
Vi räknar då ut den nya hastigheten genom:
v1 = v0 + a * dt
Den nya positionen får vi genom
x1 = x0 + v1 * dt
i kod
newVelocity.x = elapsedTime * acceleration.x + velocity.x; newVelocity.y = elapsedTime * acceleration.y + velocity.y; newPosition.x = elapsedTime * newVelocity.x + position.x; newPosition.y = elapsedTime * newVelocity.y + position.y; position = newPosition; velocity= newVelocity;
Uppgift 1. Splitter & Gravitation
Your browser does not support the video tag.
Första uppgiften blir att skapa 100 partiklar som alla startar i samma position men med slumpmässig hastighet. De skall alla påverkas av en acceleration nedåt (gravitation).
Tips:
- Koordinaterna som du räknar fram bör vara logiska koordinater. För att omvandla till visuella koordinater för utritning använder du såklart metoderna från Laboration 1
- Dela upp lösningen i två klasser. SplitterSystem och SplitterParticle, där systemklassen innehåller en array av SplitterParticle objekt
- Ordna så att SplitterSystem kan återstartas som i min video
-
Följande kod skapar slumpvisa riktningar mellan -maxspeed och maxspeed
Vector2 randomDirection = new Vector2((float)rand.NextDouble() - 0.5f, (float)rand.NextDouble() - 0.5f); //normalize to get it spherical vector with length 1.0 randomDirection.Normalize(); //add random length between 0 to maxSpeed randomDirection = randomDirection * ( (float)rand.NextDouble() * maxSpeed);
Filer
Uppgift 2. Rök & Interpolation
Your browser does not support the video tag.
Andra uppgiften handlar om två saker mer avancerad rendering av partiklar och att kunna interpolera mellan två värden. Ni ska skapa en simulering av rök som i videon.
Tittar ni noga på videon ovan ser ett par saker som skiljer sig från föregående simulering:
- Röken accelereras uppåt
- Röken växer i storlek(interpoleras mellan 0 -> Max) och samtidigt blir den mer genomskinlig (interpoleras mellan Max -> 0).
- Mindre tydligt är att partiklarna roterar.
- Partiklarna återvinns. Dvs en partikel som vuxit och blivit helt genomskinlig “återföds” som en ny partikel i rökens centrum.
Tips
- Interpolationen hanteras enklast genom att partikeln får en livslängd. När partikeln uppdateras håller vi reda på hur lång tid som partikeln existerat och får då en procentsats vi kan använda för att räkna ut storleken och genomskinligheten.
timeLived += elapsedTime; lifePercent = timeLived / maxTimeToLive; size = minSize + lifePercent * maxSize;
-
För att interpolera färgen skapar jag en egen färg utifrån RGBA som jag sätter värden på en float fade som går mellan 1.0 och 0.0f.
//color fades to 0 Color color = new Color(fade, fade, fade, fade);
-
För att rita ut använder jag följande draw commando på XNAs SpriteBatch klass
a_batch.Draw(a_texture, a_viewPos, srcRect, color, a_rotation, origin, size, SpriteEffects.None, 0);
Filer
Uppgift 3. 2D animering
Att hantera massor av partiklar kan både vara processorkrävande och ta tid att skapa. Förr var det vanligt att istället rendera explosionen som ett antal bildrutor och animera dem.
Använd följande textur för att skapa en animerad explosion:
Explosionen skall gå att köra i olika takt exempelvis:
Vi har 24 bilder(frames) och vill animera explosionen på 0.5 sekunder. Vi får då 48 bilder per sekund och ca 0,021 sekunder per bild. Precis som i tidigare uppgift kan vi accumulera tiden för att kunna välja ut vilken bildruta som visas.
timeElapsed += elapsedTime; float percentAnimated = timeElapsed / maxTime; int frame = (int)(percentAnimated * numberOfFrames);
För att sedan få reda på texturkoordinaterna kan vi använda modulo-operatorn (%) och delat med (/).
frameX = frame % numFramesX; frameY = frame / numFramesX;
Filer
Uppgift 4. Eld & Explosioner
Tredje uppgiften blir nu mer fri, skapa ett partikelsystem som genererar en explosion med minst tre olika partikelsystem med olika sprites och beteenden.
Exempelvis.
- Splitter flyger slumpmässigt påverkas av gravitation och roteras
- Ett rökmoln stiger från platsen, röken stiger och utvidgas och förtunnas
- En shockvåg går från platsen, en enda partikel som ökar i storlek
För att inspireras titta på följande sida på gamedev.net som visar 3D partiklar.
Nästa laboration kommer vi använda detta partikelsystem som effekt när en användaren interagerar med applikationen, därför bör explosionen kunna skalas till olika storlekar och placeras på olika platser på skärmen.