ASM13S Partikkelisydän
Posted: Tue Aug 06, 2013 5:57 pm
Assyillä toteutin tälläisen. Apuja tuli mm. vieressä istuneelta atomilta & msqrt:ltä. Tässä on esimerkki/tutoriaali muodossa mitä tässä tapahtuu. Koodissa käytetään muistia yms nopeutuksia. Selitän tässä kuinka ne toimivat, sikälimikäli olen ymmärtänyt ne oikein.
Jos pelkän koodin perässä tulit niin selaile tämä viesti loppuun!
Koodi on ensin tehty, sen jälkeen optimoitu koonsa puolesta ja tämänjälkeen viimeistelty parilla nopeusmuunnoksella jotka lisäävät pari riviä ja muistikomennot.
Alustetaan näyttöruutu, tässä koodissa käytetään muuttujia ScreenHeight() & ScreenWidth() komentojen sijaan koodin lyhyyden vuoksi. sw2 muuttuja on sijoitettu alustettavaksi myöskin tänne. Toiminnaltaan kertoo vain näytön leveyden jaettuna kahtia, koska tämä toimii nopeammin ja lyhyemmin koodissa kuin jakaisi joka kohdassa arvon kahdella, jakolasku on hitaampi kuin muisti siirto. Ruudun koko on aika optimaalinen tähän, pienempää ei oikeastaan kannata kokeilla, suurempi kyllä toimii. Fullscreen palanen on kommentissa jotta se aukeaa windowedina, voi halutessaan säätää koon oman ruudun kokoiseksi.
Ladataan jokin satunnainen ( tässätapauksessa arial ) fontti muistiin koolla 1. Koko on tärkeä jotta printillä saadaan myöhemmin aikaan ruutubufferi siirto yhdellä ylöspäin.
Luodaan ja alustetaan väriarvotaulu. Jos koodi olisi tehty rivirajoitteisena tämä laskelma olisi suoritettu joka framessa, mutta koska rajoitusta ei tälläkertaa ole, voidaan se suorittaa ennen päälooppia & jokaista framea jolloin looppikoodi toimii nopeammin. Väriarvon hausta kiitokset msqrt:n tekemälle funktiolle josta tähän on koodi kutistettu suoritusnopeutta&kokoa hakiessa.
Luodaan ja alustetaan muistiblockki, tätä tullaan myöhemmin käyttämään type-esiintymän alustamiseen koska memcopy on nopeampi kuin alustaa 5 muuttujaa, vaikka alustuksia joudutaan muokkaamaan vähän on tämä ratkaisu tässätapauksessa nopeampi. Huomioi, että jos alustat useita type-esiintymiä samoilla arvoilla voi toimintaa nopeentaa tällätavoin.
Lisätään muuttujaan k 1 ja wrapangle kääntää muuttujan arvon 0-359 suoraan muuttujaan. Muuttujalla saadaan oikea väriarvo haettua väriarvo taulusta joka toteutetaan ennen type-esiintymä alustusmuisti luontia. Mikäli koodi olisi rivirajoitettu, tämän jälkeen, ilman seuraavaa pokeinttiä, olisi värilaskurikoodi tässä hidastamassa loopin pyörimistä.
Lisätään type-esiintymän alustusmuistiin väriarvo, jota myöhemmin käytetään pikselin piirtoon.
Koska cb, niin tuo on nopeampi kuin vastaava for looppi. kyseinen b arvo lisää joka framella uusia piirrettäviä pisteitä.
Eli ylemmän for->repeat kikan avulla toteutetun loopin sisältö:
Satunnoidaan 2 arvoa.
Luodaan uusi type-esiintymä partikkeli tyypistä.
Kopioidaan partikkelin arvot muistista type-esiintymään, koska useampi arvo, on tämä nopeampi.
Muokataan vähän äskeisellä muistisiirrolla toteutettuja arvoja, jos koodi olisi ollut jossain rivimäärä rajoitteisessa kisassa, olisi tässäkohin ollut tyyppialustus suoraan.
Koska loopissa piirretään pisteitä PutPixel2 komennolla lukitaan loopin ulkopuolella näyttöpuskuri.
Käydään jokainen pikseli for loopissa läpi ja piirretään taululle kahtena toisen ollessa kloonisijainti. Toisinkuin ylemmässä, tässä for loopissa ei ole niin kauheaa ongelmaa nopeuden kannalta, miksi? koska cb tekee ylimääräisen tarkistuksen numeroiden kanssa ja tästä aiheutuu että repeat on nopeampi.
Myöskin lasketaan vähän sijainteja ja sellaisia. Ja muistetaan poistaa näyttöpuskuri lukko! Tuossa tarkistetaan Iffissä ennen pikselien siirtoa onko pikseli tietyllä alueella käyttäen sw2 muuttujaa sw/2 jakolaskun sijaan, jakolaskun ollessa huomattavasti hitaampi kuin muuttujasiirron on tämä huomattavasti nopeampaa.
Ylempänä mainitsin fontista ja koon tärkeydestä. Eli tässäkohin ensin print siirtää taustabufferia fonttikoon verran ylöspäin, tämän jälkeen DrawScreen työntää taulun ruudulle, off komennon perässä meinaa ettei puskuria tyhjennetä, jolla saadaan aikaan tuo hieno sateenkaariefecti <3.
Ja tässä tämä koodi on kokonaisuudessaan, koodi on toteutettu Assembly 2013 summer tapahtuman aikana, rivimäärä on käynyt ~106?
Resoluutiosäätö on aika selvää, mutta for->repeat säädössä oleva "until b=150" vaikuttaa pikselimäärän luontiin, mitä isompi luku sitä useamman pikselin tämä luo, omalla koneella toimii tässä kohin "220" ilman drops laskuria pomppii fps ~58-61
Kysymyksiä, kommentteja ja ehdotuksia voi heitellä.
Ja viimeiseksi
http://www.youtube.com/watch?v=Yn6wz498Pzk
Jos pelkän koodin perässä tulit niin selaile tämä viesti loppuun!
Koodi on ensin tehty, sen jälkeen optimoitu koonsa puolesta ja tämänjälkeen viimeistelty parilla nopeusmuunnoksella jotka lisäävät pari riviä ja muistikomennot.
Code: Select all
Const sw=700'jos vaihdat, säädä myös sw2!
Const sh=1000
Const sw2=350'sw2=sw/2
SCREEN sw,sh',32,0
Code: Select all
SetFont LoadFont("arial",1)
Code: Select all
Dim c(359)
For i=0 To 359
h#=i/60.0
x#=1-Abs((h Mod 2)-1)
c(i)=(255 Shl 24)+((x*((h<2 And h>=1) Or (h>=4 And h<5))+(h<1 Or h>=5))*255 Shl 16)+((x*(h<1 Or (h>=3 And h<4))+(h>=1 And h<3))*255 Shl 8)+(x*(h=>5 Or (h>=2 And h<3))+(h>=3 And h<5))*255
Next i
Code: Select all
tb=MakeMEMBlock(20)
PokeFloat tb,0,sw2
PokeFloat tb,4,650.0
PokeFloat tb,12,6.0
PokeFloat tb,16,11.0
Code: Select all
k=WrapAngle(k+1)
Code: Select all
PokeInt tb,8,c(k)
Code: Select all
b=0
Repeat
b+1
Until b=150
Code: Select all
a=Rand(0,360)
l=Rand(1,12)
d.ds=New(ds)
MemCopy tb,0,ConvertToInteger(d),12,20
d\x=d\x+l*Sin(a)
d\y=d\y+l*Cos(a)
d\sX=d\sX+Rnd(-.7,.7)
d\sY=d\sY+Rnd(-.7,.7)
Satunnoidaan 2 arvoa.
Luodaan uusi type-esiintymä partikkeli tyypistä.
Kopioidaan partikkelin arvot muistista type-esiintymään, koska useampi arvo, on tämä nopeampi.
Muokataan vähän äskeisellä muistisiirrolla toteutettuja arvoja, jos koodi olisi ollut jossain rivimäärä rajoitteisessa kisassa, olisi tässäkohin ollut tyyppialustus suoraan.
Code: Select all
Lock
For d.ds=Each ds
d\l+1
d\sY-.4
If d\l>40 Then d\sX-.5
d\x+d\sX
d\y+d\sY
If d\x>sw2 And d\x<sw And d\y>0 And d\y<sh Then
PutPixel2 d\x,sh-d\y,d\c
PutPixel2 sw-d\x,sh-d\y,d\c
drops+2
Else
Delete d
EndIf
Next d
Unlock
Käydään jokainen pikseli for loopissa läpi ja piirretään taululle kahtena toisen ollessa kloonisijainti. Toisinkuin ylemmässä, tässä for loopissa ei ole niin kauheaa ongelmaa nopeuden kannalta, miksi? koska cb tekee ylimääräisen tarkistuksen numeroiden kanssa ja tästä aiheutuu että repeat on nopeampi.
Myöskin lasketaan vähän sijainteja ja sellaisia. Ja muistetaan poistaa näyttöpuskuri lukko! Tuossa tarkistetaan Iffissä ennen pikselien siirtoa onko pikseli tietyllä alueella käyttäen sw2 muuttujaa sw/2 jakolaskun sijaan, jakolaskun ollessa huomattavasti hitaampi kuin muuttujasiirron on tämä huomattavasti nopeampaa.
Code: Select all
Print ""
DrawScreen OFF
Code: Select all
Type ds
Field x#
Field y#
Field c
Field sX#
Field sY#
Field l As Byte
EndType
Const sw=1920
Const sh=1080
Const sw2=960'sw2=sw/2
SCREEN sw,sh,32,0
SetFont LoadFont("arial",1)
Dim c(359)
For i=0 To 359
h#=i/60.0
x#=1-Abs((h Mod 2)-1)
c(i)=(255 Shl 24)+((x*((h<2 And h>=1) Or (h>=4 And h<5))+(h<1 Or h>=5))*255 Shl 16)+((x*(h<1 Or (h>=3 And h<4))+(h>=1 And h<3))*255 Shl 8)+(x*(h=>5 Or (h>=2 And h<3))+(h>=3 And h<5))*255
Next i
tb=MakeMEMBlock(20)
PokeFloat tb,0,sw2
PokeFloat tb,4,650.0
PokeFloat tb,12,6.0
PokeFloat tb,16,11.0
drops=0
Repeat
SetWindow Str(FPS())+"drops: "+drops
k=WrapAngle(k+1)
PokeInt tb,8,c(k)
b=0
Repeat
b+1
a=Rand(0,360)
l=Rand(1,12)
d.ds=New(ds)
MemCopy tb,0,ConvertToInteger(d),12,20
d\x=d\x+l*Sin(a)
d\y=d\y+l*Cos(a)
d\sX=d\sX+Rnd(-.7,.7)
d\sY=d\sY+Rnd(-.7,.7)
Until b=150
drops=0
Lock
For d.ds=Each ds
d\l+1
d\sY-.4
If d\l>40 Then d\sX-.5
d\x+d\sX
d\y+d\sY
If d\x>sw2 And d\x<sw And d\y>0 And d\y<sh Then
PutPixel2 d\x,sh-d\y,d\c
PutPixel2 sw-d\x,sh-d\y,d\c
drops+2
Else
Delete d
EndIf
Next d
Unlock
Print ""
DrawScreen OFF
Forever
DeleteMEMblock tb
Resoluutiosäätö on aika selvää, mutta for->repeat säädössä oleva "until b=150" vaikuttaa pikselimäärän luontiin, mitä isompi luku sitä useamman pikselin tämä luo, omalla koneella toimii tässä kohin "220" ilman drops laskuria pomppii fps ~58-61
Kysymyksiä, kommentteja ja ehdotuksia voi heitellä.
Ja viimeiseksi
http://www.youtube.com/watch?v=Yn6wz498Pzk