Kirjoittaja: hunajavohveli
Kirjoitettu: 22.06.2004 – 22.06.2004
Tagit: grafiikka, demo, koodi näytille, vinkki
Joskus vuosi sitten koodasin yhdellä vanhalla 486-koneella noin 25 erilaista harmaasävyistä efektiä. Valikoin niistä kymmenen, tein niihin parannuksia, joita en osannut vuosi sitten, ja koostin ne lyhyeksi demoksi. Osa on minusta todella hienoja, mutta joukossa myös muutama turha, jotka olisi kenties voinut korvata jollain muulla, tai jättää kokonaan pois. Myös efektien järjestystä olisi voinut kenties miettiä kauemmin.
Olen yrittänyt kommentoida koodia sen verran kuin siitä enää tajusin. Olen poistanut kaikki ihmeelliset GOTO-viritelmät, ja sisentänyt, mutta koodi on silti joissain paikoissa aika epäselkeää. Jos tajuaa koodista, kannattaa kokeilla muunnella sitä, niin voi saada aikaan yllättävän hienoja variaatioita. (katso esim. Rings-efektin kommenttit)
Efektien nimiä ei kannata ihmetellä. Ne eivät välttämättä näytä siltä, mitä niiden nimi antaa ymmärtää, eivätkä kaikki nimet johdukaan siitä, miltä efektit näyttävät.
Saatan joskus muokata tätä, kun saan aikaan hienompia variaatioita huonoimpien tilalle.
Efektejä on sitten testattu 600 Megahertsisellä koneella. Ne saattavat pyöriä joillain 3-Gigaisilla koneilla liiankin nopeasti. Speed-muuttujasta voi määrittää eräänlaisen nopeuden kokonaislukuna. 1 on pienin mahdollinen. Tätä kannataa siis muuttaa vain jos efektit ovat liian hitaita.
Jos kommentoit, ja viittaat kommentissa johonkin tiettyyn efektiin, kannattaa pistää eteen efektin numero.
DEFINT A-Z DECLARE SUB Block (Var AS INTEGER) DECLARE SUB Lines () DECLARE SUB LoadPalette () DECLARE SUB Rings () DECLARE SUB Snow () DECLARE SUB Spread () DECLARE SUB StarHaze () DECLARE SUB Strings () DECLARE SUB Slide () COMMON SHARED Speed AS INTEGER SCREEN 13 RANDOMIZE TIMER Speed = 1 'S??d? t?st? nopeutta (1 on hienoin mutta vaatii tehoja koneelta) PRINT "Paina jokaisen efektin aikana Enter kun" PRINT "haluat siirty? seuraavaan. Paina Enter" PRINT "aloittaaksesi." a$ = INPUT$(1) FOR Mode = 1 TO 10 CLS COLOR 63 PRINT "Efekti numero"; Mode a$ = INPUT$(1) CLS SELECT CASE Mode CASE 1 : Lines: a$ = INPUT$(1) CASE 2 Block 0 CASE 3 Block 1 CASE 4 Block 2 CASE 5 Spread CASE 6 StarHaze CASE 7 Snow CASE 8 Rings CASE 9 Strings CASE 10 Slide END SELECT NEXT Mode
SUB LoadPalette
'Luo harmaas?vypaletin
'V?rit 0-63 liukuvat mustasta valkoiseen
'V?rit 64-127 liukuvat valkoisesta mustaan
'V?rit 128-191 liukuvat mustasta valkoiseen
'V?rit 192-255 liukuvat valkoisesta mustaan
FOR i = 0 TO 63
OUT &H3C8, i: OUT &H3C9, i: OUT &H3C9, i: OUT &H3C9, i
NEXT i
FOR i = 64 TO 127
OUT &H3C8, i: OUT &H3C9, 127 - i: OUT &H3C9, 127 - i: OUT &H3C9, 127 - i
NEXT i
FOR i = 128 TO 191
OUT &H3C8, i: OUT &H3C9, i - 128: OUT &H3C9, i - 128: OUT &H3C9, i - 128
NEXT i
FOR i = 192 TO 255
OUT &H3C8, i: OUT &H3C9, 255 - i: OUT &H3C9, 255 - i: OUT &H3C9, 255 - i
NEXT i
END SUB
SUB Block (Var AS INTEGER)
'Samalla aliohjelmalla saa 3 variaatiota muuttamalla Var-muuttujaa
'Pohjana Lines-efekti, jonka luomia viivoja muokataan
Lines 'luodaan viivat
'T?m?n efektin toimintaan en juurikaan osaa selitt??. Parhaiten sen kai voi
'ymm?rt?? muuttamalla lausekkeet pseudoksi. Variaatioissa on ideana se, ett?
'kun Var on 1, k?sitell??n molempia kahta ensimm?ist? IF-lauseketta. Kun Var
'on 0, k?sitell??n vai ensimm?ist?, ja kun 2, vain toista.
FOR y = 0 TO 198
FOR x = 0 TO 319
DO
vari1 = POINT(x, y)
vari2 = POINT(x, y + 1)
IF Var < 2 AND vari1 < vari2 THEN vari3 = vari2 - vari1 'ensimm?inen...
IF Var > 0 AND vari2 < vari1 THEN vari3 = vari1 - vari2 'toinen IF-lauseke
IF vari3 > 1 THEN
vari = INT(RND * 16) + 16
PSET (x, y + 1), vari
ELSE
EXIT DO
END IF
LOOP
NEXT x
NEXT y
a$ = INPUT$(1)
END SUB
SUB Lines
'yksinkertaisia harmaas?vyisi? viivoja
vari = INT(RND * 16) + 16 'arvotaan aloitusv?ri
FOR y = 0 TO 199
FOR x = 0 TO 319
IF vari < 16 THEN vari = 16 'v?ri ei saa menn? yli
IF vari > 31 THEN vari = 31
PSET (x, y), vari
vari = vari - 1 + INT(RND * 3) 'liu'utetaan v?ri? satunnaiseen suuntaan
NEXT x
NEXT y
END SUBSUB Rings
'Liikuttaa pistett? trigonometrialla ja piirt?? t?hti? pikselin
'koordinaateista. T?hden koko m??r?ytyy pikselin v?rin mukaan.
STATIC x AS SINGLE, y AS SINGLE
STATIC k AS SINGLE, ks AS SINGLE
LoadPalette
DEF SEG = &HA000 'Suoraa n?ytt?muistin k?sittely?
x = 160: y = 100
s = 1: e = 35 'suunta ja pikselin et?isyys n?yt?n keskipisteest?
ks = .1 'Kokeile t?h?n eri arvoja (py?ritysnopeus)
DO
x = 160 + SIN(k) * e 'liikutetaan pikseli?
y = 100 - COS(k) * e
k = k + ks
e = e + s
IF e > 80 OR e < 35 THEN s = -s 'suunnan vaihto
vari = POINT(x, y) + Speed * 3 'v?ri
PSET (x, y), vari
FOR c = 0 TO vari 't?hden piirto
IF POINT(x - c, y) < vari - c THEN PSET (x - c, y), vari - c
IF POINT(x + c, y) < vari - c THEN PSET (x + c, y), vari - c
IF POINT(x, y - c) < vari - c THEN PSET (x, y - c), vari - c
IF POINT(x, y + c) < vari - c THEN PSET (x, y + c), vari - c
NEXT c
LOOP UNTIL INKEY$ <> ""
END SUB
SUB Slide
'Yksinkertainen liukumisefekti. Arvotaan pikseleit? ja piirret??n ne uusilla
'v?reill?. Uusi v?ri on (vasemmanpuoleisen pikselin v?ri + 1).
LoadPalette
DO
x = INT(RND * 320): y = INT(RND * 199) + 1
PSET (x, y), POINT(x - 1, y - 1 + INT(RND * 3)) + Speed
PSET (0, INT(RND * 200)), INT(RND * 16)
LOOP UNTIL INKEY$ <> ""
END SUB
SUB Snow
'Arvotaan kohta ja korostetaan sit? ymp?r?ivien satunnaisten pikselien v?rej?
LoadPalette
DO
x = INT(RND * 320)
y = INT(RND * 200)
vari = POINT(x, y) + Speed * 3
PSET (x, y), vari
c = 0
WHILE vari - c > 0
c = c + 1
FOR kertaus = 1 TO 10
apu = -c + (RND * (c * 2))
apu2 = -c + (RND * (c * 2))
IF POINT(x + apu, y + apu2) < vari - c THEN PSET (x + apu, y + apu2), vari - c
NEXT kertaus
WEND
LOOP UNTIL INKEY$ <> ""
END SUBSUB Spread
'Korostetaan v?ris?vy? arvotussa pikseliss? ja sen ymp?rill?.
LoadPalette
DO
x = INT(RND * 320)
y = INT(RND * 200)
PSET (x, y), POINT(x, y) + Speed
PSET (x - 1, y), POINT(x, y) + Speed
PSET (x + 1, y), POINT(x, y) + Speed
PSET (x, y - 1), POINT(x, y) + Speed
PSET (x, y + 1), POINT(x, y) + Speed
LOOP UNTIL INKEY$ <> ""
END SUB
SUB StarHaze
'T?htim?isest? efektist? luotu variaatio.
LoadPalette
DO
x = INT(RND * 320)
y = INT(RND * 200)
vari = POINT(x, y) + Speed 'muutetaan v?ri?
PSET (x, y), vari
FOR c = 1 TO vari 't?hden piirto
IF POINT(x - c, y) < vari - c THEN PSET (x - c, y), vari - c
IF POINT(x + c, y) < vari - c THEN PSET (x + c, y), vari - c
IF POINT(x, y - c) < vari - c THEN PSET (x, y - c), vari - c
IF POINT(x, y + c) < vari - c THEN PSET (x, y + c), vari - c
NEXT c
LOOP UNTIL INKEY$ <> ""
END SUB
SUB Strings
'Py?ritet??n renkaita trigonometrialla.
LoadPalette
DIM rad AS SINGLE
rad = ATN(1) * 4 / 180
DIM x AS SINGLE, y AS SINGLE
DIM k AS SINGLE
k = INT(RND * 360): s = 1
x = 160: y = 100
DO
x = x + SIN(k * rad) * 2
y = y - COS(k * rad) * 2
k = k + s
IF RND < .02 AND x < 300 AND y > 20 AND y < 180 AND x > 20 THEN s = -s
IF x >= 0 AND y >= 0 AND x <= 319 AND y <= 199 THEN
vari = POINT(x, y) + Speed
PSET (x, y), vari
c = 0
WHILE vari - c > 0
c = c + 1
IF POINT(x - c, y) < vari - c THEN PSET (x - c, y), vari - c
IF POINT(x + c, y) < vari - c THEN PSET (x + c, y), vari - c
IF POINT(x, y - c) < vari - c THEN PSET (x, y - c), vari - c
IF POINT(x, y + c) < vari - c THEN PSET (x, y + c), vari - c
WEND
END IF
LOOP UNTIL INKEY$ <> ""
END SUBÄlyttömän upeita! (lukuunottamatta muutamaa ekoista)
Muuta ei oikeen voi mykistyneenä sanoa.
Binääryä?
Hienoja efektejä!
En ole vielä kokeillut, mutta eikö nopeutta kannattaisi säätää seuraavalla koodilla, joka siis hidastaa ohjelmaa:
alkuaika = TIMER DO aika = TIMER LOOP UNTIL aika >= alkuaika + .1
Tämä siis tekee ohjelmaan aina sekunin sadasosan tauon aina kun koodi suoritetaan. Ei siis tarvitsisi jokaisen käyttäjän kokeilla aina alkuun juuri omalle koneelle sopivaa nopeutta.
Korjaan, koodini aiheuttaa sekuninkymmenesosan tauon.
Hieno!
Sä oot ihan sekopää kun tollaisia osaat! :D
Herkko: Viestejä voi muokatakin, ettei tarvitse lähettää uutta, jos tekee virheen. TIMER-tarkistus on toki sinänsä hyvä idea, ja olen sitä joskus soveltanutkin, mutta tähän käytän luultavasti pikemminkin koodia: WAIT &H3DA, 8
Edit: Binaryä en voi itse pistää nettiin, mutta jos joku haluaa pistää, niin ihan vapaasti. Huomasin vain, että QB:n exe-kääntö bugittaa taas, ja viimeinen efekti kaatuu aina overflowiin.
8 on älyttömän hieno. :)