Tässä pieni animaatio, jonka huvikseni väsäsin EppaBasicilla. Siinä pienet pyramidinmalliset sirut lentävät käyttäjää päin. Ne piirretään käyttäen hyväksi kirjastoa, jonka nimesin "EppaGL":ksi.
Alunperin tarkoituksenani oli tehdä jotain isompaa kuten esimerkiksi peli tai monimutkaisempi demo, mutta kielen rajoitukset tulivat taas vastaan: kieli ei tue taulukkoparametreja eikä edes funktion sisällä määriteltyjä paikallisia taulukoita, joten pistejoukkojen käsittely on vähintäänkin hankalaa. En jaksanut tällä erää miettiä mitään hyvää tapaa niitä varten.
Koska EB ei tue vaihtelevankokoisia tauluja, sisältää tämä ohjelma oman toteutukseni niistä (taulut EGL_KOLMIOT
ja EGL_VAPAAT
). Toisessa taulussa säilytetään itse dataa ja toinen on pino käyttämättömistä indekseistä ensimmäisessä taulussa.
Puutteistaan huolimatta kieli sopii kuitenkin jo nyt kehitysvaiheessaan hyvin pienten pelien väsäämiseen, joten saatan silti jossakin vaiheessa julkaista vielä jonkin hienomman 3D-ohjelman, kunhan ratkon ongelmat pistejoukkojen kanssa.
Ohjelmaa voi kokeilla osoitteessa http://eppabasic.fi/#ZZ7LHP tai kopioimalla koodin suoraan editoriin, jos ensimmäinen linkki ei toimi.
' Animaatio EppaBasicilla ' (c) Iikka Hauhio 2016 ' Tiedosto koostuu kahdesta osasta: EppaGL-grafiikkakirjastosta ja sitä hyödyntävästä animaatiosta '''''''''''''''''''''''''''''''''''''''''' ''' EppaGL - 3D-kirjasto EppaBasicille ''' '''''''''''''''''''''''''''''''''''''''''' '' Muuttujadeklaraatiot '' Dim EGL_H As Number = 100 ' Kameran sijainti Dim EGL_VX As Number = 0 Dim EGL_VY As Number = 0 Dim EGL_VZ As Number = 0 ' Kameran kulma Dim EGL_KX As Number = 0 Dim EGL_KY As Number = 0 '' Apufunktiot '' Function EGL_KäännäXY(xy As Number, z As Number, kulma As Number) As Number Return xy*Cos(kulma)-z*Sin(kulma) End Function Function EGL_KäännäZ(xy As Number, z As Number, kulma As Number) As Number Return xy*Sin(kulma)+z*Cos(kulma) End Function Function EGL_LaskeSiirrosSyvyydessä(x_tai_y As Number, z As Number) As Number Return EGL_H*x_tai_y/z End Function ' Laskee pisteen ruudulle tehdyn projektion X-koordinaatin Function EGL_LaskeSiirrosX(x As Number, z As Number) As Number Dim uusiX = x-EGL_VX Dim uusiZ = z-EGL_VZ uusiX = EGL_KäännäXY(uusiX, uusiZ, EGL_KY) uusiZ = EGL_KäännäZ(uusiX, uusiZ, EGL_KY) Return CanvasWidth()/2+EGL_LaskeSiirrosSyvyydessä(uusiX, uusiZ) End Function ' Laskee pisteen ruudulle tehdyn projektion Y-koordinaatin Function EGL_LaskeSiirrosY(y As Number, z As Number) As Number Dim uusiY = y-EGL_VY Dim uusiZ = z-EGL_VZ uusiY = EGL_KäännäXY(uusiY, uusiZ, EGL_KX) uusiZ = EGL_KäännäZ(uusiY, uusiZ, EGL_KX) Return CanvasHeight()/2-EGL_LaskeSiirrosSyvyydessä(uusiY, uusiZ) End Function '' Varsinainen rajapinta '' ' Siirtää kameraa Sub EGL_Kamera(x As Number, y As Number, z As Number, kulmaX As Number, kulmaY As Number) EGL_VX = x EGL_VY = y EGL_VZ = z EGL_KX = kulmaX EGL_KY = kulmaY End Sub ' Kolmioiden maksimimäärä DIM EGL_KPL_LKM = 200 ' Kolmiot sisältävä taulu Dim EGL_KOLMIOT As Number[EGL_KPL_LKM, 9] ' Indeksejä eri arvoille kolmiotaulussa Dim EGL_X1 = 1 Dim EGL_Y1 = 2 Dim EGL_Z1 = 3 Dim EGL_X2 = 4 Dim EGL_Y2 = 5 Dim EGL_Z2 = 6 Dim EGL_X3 = 7 Dim EGL_Y3 = 8 Dim EGL_Z3 = 9 ' Lista vapaista paikoista taulussa uusia kolmioita varten Dim EGL_VAPAAT As Number[EGL_KPL_LKM] EGL_VAPAAT[1] = 1 Dim EGL_LASKURI As Integer = 1 ' Etsii vapaan paikan taulusta Function EGL_UusiId() As Integer Dim id = EGL_VAPAAT[EGL_LASKURI] If EGL_LASKURI = 1 Then EGL_VAPAAT[1] = EGL_VAPAAT[1]+1 Else EGL_LASKURI = EGL_LASKURI-1 End If Return id End Function ' Luo ja alustaa uuden kolmion Function EGL_LisääKolmio() As Integer Dim id = EGL_UusiId() EGL_MuutaKolmiota(id, 0, 0, 0, 0, 0, 0, 0, 0, 0) Return id End Function ' Muuttaa kolmion sijaintia Sub EGL_MuutaKolmiota(id As Integer, x1 As Number, y1 As Number, z1 As Number, x2 As Number, y2 As Number, z2 As Number, x3 As Number, y3 As Number, z3 As Number) EGL_KOLMIOT[id, EGL_X1] = x1 EGL_KOLMIOT[id, EGL_Y1] = y1 EGL_KOLMIOT[id, EGL_Z1] = z1 EGL_KOLMIOT[id, EGL_X2] = x2 EGL_KOLMIOT[id, EGL_Y2] = y2 EGL_KOLMIOT[id, EGL_Z2] = z2 EGL_KOLMIOT[id, EGL_X3] = x3 EGL_KOLMIOT[id, EGL_Y3] = y3 EGL_KOLMIOT[id, EGL_Z3] = z3 End Sub ' Poistaa kolmion ja vapauttaa kohdan taulussa Sub EGL_PoistaKolmio(id As Integer) EGL_MuutaKolmiota(id, 0, 0, 0, 0, 0, 0, 0, 0, 0) EGL_LASKURI = EGL_LASKURI + 1 EGL_VAPAAT[EGL_LASKURI] = id End Sub ' Piirtää kolmiot ruudulle Sub EGL_PiirräKolmiot() For id = 1 To EGL_VAPAAT[1] - 1 Dim x1 = EGL_LaskeSiirrosX(EGL_KOLMIOT[id, EGL_X1], EGL_KOLMIOT[id, EGL_Z1]) Dim y1 = EGL_LaskeSiirrosY(EGL_KOLMIOT[id, EGL_Y1], EGL_KOLMIOT[id, EGL_Z1]) Dim x2 = EGL_LaskeSiirrosX(EGL_KOLMIOT[id, EGL_X2], EGL_KOLMIOT[id, EGL_Z2]) Dim y2 = EGL_LaskeSiirrosY(EGL_KOLMIOT[id, EGL_Y2], EGL_KOLMIOT[id, EGL_Z2]) Dim x3 = EGL_LaskeSiirrosX(EGL_KOLMIOT[id, EGL_X3], EGL_KOLMIOT[id, EGL_Z3]) Dim y3 = EGL_LaskeSiirrosY(EGL_KOLMIOT[id, EGL_Y3], EGL_KOLMIOT[id, EGL_Z3]) DrawTriangle x1, y1, x2, y2, x3, y3 Next id End Sub '''''''''''''''''''''' ''' SIRU-ANIMAATIO ''' '''''''''''''''''''''' ' Vaihda vastaamaan oman näyttösi mittoja Dim WIN_SIZE_X = 1600 Dim WIN_SIZE_Y = 800 ' Sirujen liikkumisnopeus Dim NOPEUS = 0.5 ' Sirujen kokonaismäärä. Tämän kasvattaminen saattaa vaatia myös ' kolmiomäärän kasvattamista eli muuttujan EGL_KPL_LKM muuttamista Dim SIRUJA = 50 ' Taulukko siruista Dim SIRUT As Number[SIRUJA, 8] ' Alustetaan kaikki sirut satunnaisiin paikkoihin For i = 1 To SIRUJA SIRUT[i, 1] = EGL_LisääKolmio() ' Sivu 1 SIRUT[i, 2] = EGL_LisääKolmio() ' Sivu 2 SIRUT[i, 3] = EGL_LisääKolmio() ' Sivu 3 SatunnaistaSiru i Next i ' Arvotaan annetulle sirulle uusi paikka Sub SatunnaistaSiru(id As Integer) ' Siruja asetetaan siten, että niitä esiintyy vain näytön keskellä olevan ' suorakulmion sisällä, jonka reunat ovat kolmasosa ikkunan reunoista Dim areaSizeX = WIN_SIZE_X*0.3 Dim areaSizeY = WIN_SIZE_Y*0.3 SIRUT[id, 4] = Rnd()*areaSizeX-areaSizeX/2 ' X SIRUT[id, 5] = Rnd()*areaSizeY-areaSizeY/2 ' Y SIRUT[id, 6] = 100 + Rnd()*100 ' Z SIRUT[id, 7] = Rnd() ' Kulma X SIRUT[id, 8] = Rnd() ' Kulma Y End Sub ' Siirtää sirun kolmioita Sub Siirrä(id As Integer) ' Sirun 3D-malli Skaalaus Dim p1x As Number = -0.5 *2 Dim p1y As Number = -0.44 *2 Dim p1z As Number = 0 *2 Dim p2x As Number = 0.5 *2 Dim p2y As Number = -0.44 *2 Dim p2z As Number = 0 *2 Dim p3x As Number = 0 *2 Dim p3y As Number = 0.44 *2 Dim p3z As Number = 0 *2 Dim p4x As Number = 0 *2 Dim p4y As Number = 0 *2 Dim p4z As Number = 0.44 *2 ' Nykyinen sijainti Dim x = SIRUT[id, 4] Dim y = SIRUT[id, 5] Dim z = SIRUT[id, 6] Dim kx = SIRUT[id, 7] Dim ky = SIRUT[id, 8] ' Pyöritetään 3D-mallia p1x = EGL_KäännäXY(p1x, p1z, ky) p2x = EGL_KäännäXY(p2x, p2z, ky) p3x = EGL_KäännäXY(p3x, p3z, ky) p4x = EGL_KäännäXY(p4x, p4z, ky) p1y = EGL_KäännäXY(p1y, p1z, kx) p2y = EGL_KäännäXY(p2y, p2z, kx) p3y = EGL_KäännäXY(p3y, p3z, kx) p4y = EGL_KäännäXY(p4y, p4z, kx) p1z = EGL_KäännäZ(p1x, p1z, ky) p2z = EGL_KäännäZ(p2x, p2z, ky) p3z = EGL_KäännäZ(p3x, p3z, ky) p4z = EGL_KäännäZ(p4x, p4z, ky) p1z = EGL_KäännäZ(p1y, p1z, kx) p2z = EGL_KäännäZ(p2y, p2z, kx) p3z = EGL_KäännäZ(p3y, p3z, kx) p4z = EGL_KäännäZ(p4y, p4z, kx) ' Asetetaan koordinaatit oikein EGL_MuutaKolmiota SIRUT[id, 1], x+p1x, y+p1y, z+p1z, x+p2x, y+p2y, z+p2z, x+p3x, y+p3y, z+p3z EGL_MuutaKolmiota SIRUT[id, 2], x+p1x, y+p1y, z+p1z, x+p2x, y+p2y, z+p2z, x+p4x, y+p4y, z+p4z EGL_MuutaKolmiota SIRUT[id, 3], x+p1x, y+p1y, z+p1z, x+p4x, y+p4y, z+p4z, x+p3x, y+p3y, z+p3z End Sub WindowSize WIN_SIZE_X, WIN_SIZE_Y CanvasSize WIN_SIZE_X, WIN_SIZE_Y DrawColor 255, 255, 255 ' Pääsilmukka Do ' Liikutetaan kaikkia siruja For id = 1 To SIRUJA Dim z = SIRUT[id, 6] ' Jos siru on mennyt ohi kamerasta, siirretään takaisin alkuun satunnaiseen paikkaan If z < 2 Then z = z + 100 SatunnaistaSiru id End If ' Liikutetaan syvyydessä SIRUT[id, 6] = z - NOPEUS Siirrä id Next id ' Piirretään sirut näytölle ClearScreen EGL_PiirräKolmiot DrawScreen Loop
Aihe on jo aika vanha, joten et voi enää vastata siihen.