Kirjoittaja: peki (2004).
Plasma on hyvin yksinkertainen efekti. Se perustuu suureen taulukkoon, joka täytetään "satunnaisella" kaavalla. Tämän jälkeen se animoidaan paletilla. Usein taulukko on myös varsinaista efektiä suurempi, jotta taulukkoa voidaan liikutella. Useimmiten näitä taulukoita on kaksi tai useampia, ja ne yhdistetään käyttämällä keskiarvoa.
Tällaista yritämme saada aikaan:
Ensiksi tarvitsemme kaavan, jolla toteuttaa taulukko.
Tässä esimerkki:
func1[i, j] = 64 + 63 * Sin(i / [40 + 10 * Cos(j / 74)]) * Cos(j / [50 + 10 * Sin(i / 60)])
Kaava on täysin tuulestatemmattu ja sen voi korvata omalla. Sen tarkoitus on vain luoda harmaasävykartta, jossa on pehmeitä väriliukuja.
Hyvän funktion pohjana voit käyttää vaikka tätä äsken esittelemääni kaavaa. Jos muutat arvoja edes hiukan, saat aivan uudennäköisen kartan. Variaatioita on siis lähes loputtomasti. Tietysti voit luoda myös alusta oman funktiosi, mutta hienosäätämisessä saattaa silloin kestää kauan.
Perussääntönä kartan luomiseen voin sanoa, että kannattaa käyttää mahdollisimman paljon "aaltoilevia" funktioita kuten siniä ja kosinia.
Luodaan neljä kertaa isompi kartta kuin ruutu on. Voidaan siis liikutella karttaa hienomman efektin aikaansaamiseksi
for (i = 0; i <= ruudunleveys * 4; i++) for (j = 0; j <= ruudunkorkeus * 4; j++) // satunnainen kaava, jolla saa aikaan pehmeän kartan func1[i, j] = 64 + 63 * Sin(i / (40 + 10 * Cos(j / 74))) * Cos(j / (50 + 10 * Sin(i / 60)))
Yksinkertainen paikallaanpysyvä harmaa väriliukujen kokelma ei ole hirveän hieno. On siis tarpeen tehdä palettianimaatio.
Tarvitaan 256 värinen paletti, jonka alku- ja loppupää "sopivat yhteen"
Tämä kuva selventää asiaa:
Paletin luominen pseudokoodina. Tämä gradientti on hieman erilainen ja tummempisävyinen kuin kuvassa, mutta sen ei ole tarkoituskaan olla samanlainen.
Aika-muuttuja sisältää plasman päivityskerrat. Sen voi nollata, mutta olen sen jättänyt tässä pois:
for (i = 0; i <= 255; i++) { punainen = 72 + 71 * Cos(i * pii / 128 + aika / 74) // punaisen värin määrä vihreä = 72 + 71 * Sin(i * pii / 128 + aika / 63) // vihreän värin määrä sininen = 72 - 71 * Cos(i * pii / 128 + aika / 81) // sinisen värin määrä paletti[i] = RGB(punainen, vihreä, sininen) // laitetaan palettiin }
Piirtäminen hoituu asettamalla paletin avulla kuvan jokainen pikseli vastaamaan kaavalla luotua taulukkoa. Jos taulukoita on useampi kuin yksi, käytetään keskiarvoa. Tässä esimerkissä on kaksi taulukkoa.
Siirtäminen tapahtuu pyörittämällä toista karttaa myötäpäivään ja toista vastapäivään.
while (true) { aika += 20; // tätä lukua saa muokata mielinmäärin, mitä pienempi se on // sen sulavampi efektistä tulee. for (i = 0; i <= 255; i++) { punainen = 72 + 71 * Cos(i * pii / 128 + aika / 74) // punaisen värin määrä vihreä = 72 + 71 * Sin(i * pii / 128 + aika / 63) // vihreän värin määrä sininen = 72 - 71 * Cos(i * pii / 128 + aika / 81) // sinisen värin määrä paletti[i] = RGB(punainen, vihreä, sininen) // laitetaan palettiin } // jokainen pikseli käydään läpi for (x = 0; x < ruudunleveys; x++) { for (y = 0; y < ruudunkorkeus; y++) { // pyöritetään func1:n sisältämää taulukkoa liikutettufunc1 = func1[ruudunleveys * 2 + x + 100 * Cos(aika * pii / 360), ruudunkorkeus * 2 + y + 100 * Sin(aika * pii / 360)] // pyöritetään func2:n sisältämää taulukkoa eri suuntaan liikutettufunc2 = func2[ruudunleveys * 2 + x + 100 * Sin(aika * pii / 360), ruudunkorkeus * 2 + y + 100 * Cos(aika * pii / 360)] // lasketaan keskiarvo arvo = (liikutettufunc1 + liikutettufunc2) / 2 // varmistetaan, ettei tule virhettä If (arvo > 255) arvo = 255 // pikseli näytölle näytto[x, y] = paletti[arvo] } } }
Linkki toimivaan exeen: http://koti.mbnet.fi/peku1/Plasma.exe
Vaatii windows XP/2000 tai vähintään .net framework 1.0 asennettuna.
Koodissa on hyvin paljon optimoimisen varaa. Esimerkiksi kaikki trigonometriset funktiot voisi laskea etukäteen ja sijoittaa taulukkoon.
Kaavaa hiemankin muuttamalla efekti muuttuu täysin. Erilaisia muunnoksia on kiva kokeilla.
Toivottavasti pidit tästä oppaasta ja se oli sinulle hyödyllinen.
Olisi varmasti mukavaa katsella muiden versioita tästä efektistä. Jos saat hienon version aikaan, voisitko linkittää sen tähän kommentiksi?
Kielellä ei luonnollisestikaan ole merkitystä.
Pekka Järvinen, 7.7.2004
Peki tha graffapro. Onpas hieno. Sun pseudokoodi vaan näyttää olevan aika c++:aa :)
Hyvä opas =) Tuon paletin ei kai tarvi olla päistään yhteensopiva?
Ei välttämättä, mutta se tekee efektistä paremman näköisen.
64 + 63 * Sin(i / [40 + 10 * Cos(j / 74)]) * Cos(j / [50 + 10
* Sin(i / 60)]) ... Kaava antaa lukuja väliltä [1, 127]
joten paletista käytetään vain alkuosaa. "Yhteensopivuudella"
ei siis ole merkitystä efektin näyttävyyden kannalta.
Eri asia on tilanteet missä luodaan taulukoita jossa luvut kiertää
niin että 255 jälkeen tulee 0...
Totta. Olet oikeassa. Tuo kaava, joka muodostaa pohjafunktion siis kannattaa tehdä välille 0-255. Se on tuosta suhteellisen helppo muokata.
Edit: Mutta oppaan tarkoitus ei olekkaan antaa muille täysin valmista koodia, vaan idea, jonka avulla muut voivat tehdä omia versioitaan efektistä.
Olet silti oikeassa. Minun olisi pitänyt olla tarkempi.
Onhan tuo oppaan paletti kyllä hirveän käyttökelpoinen
monissa efekteissä=)
Tällasta opasta oon oottanuki :)
vb on kakke :8
Teinpä vic20:lle jonkulaisen (aika huonon) plasman, http://koodaa.mine.nu/tvt/plasma.prg
(jos koodaa.mine.nu -osoite ei toimi, kokeilkaa esim. tejeez.ath.cx )
367 tavua, mutta saisko screenshotin? en omista vic20:ta...
Voihan sitä yrittää emuloida :)
Grr. En löydä mistään toimivaa emulaattoria. Pfau Zeh kaatuu aina virheeseen. Sitten jossain oli korruptoitunut paketti. Kaikkialla on vain Pfau Zehiin viittauksia. Ja yhdellä sivulla oli juttua jostain emulaattorista, mutta EI LATAUSLINKKIÄ!
:D nyt pitäs toimia
päivää herra moptim
Huomio! Kommentoi tässä ainoastaan tämän oppaan hyviä ja huonoja puolia. Älä kirjoita muita kysymyksiä tähän. Jos koodisi ei toimi tai tarvitset muuten vain apua ohjelmoinnissa, lähetä viesti keskusteluun.