Akkor lássunk is hozzá a programozáshoz! Indítsuk el a DB-t, és írjuk be az alábbi programot:
make object cube 1,5
do
yrotate object 1,object angle y(1)+2
loop
Futtassuk! [F5]
Az eredmény egy forgó kocka. Most nézzük, hogy működik a program!
1. sor: Egy 3 dimenziós objektumot készítünk, jelen esetben egy kockát. (Ha a súgóban megnézzük, láthatjuk, hogy többféle objektumot tudunk készíteni: téglatest, gömb, kúp, stb.) Az objektum sorszáma 1-es lesz, a mérete 5 (tehát 5*5*5-ös).
2. és 4. sor: A do és a loop egy végtelen ciklust egedményeznek. A közöttük található programsorok folyamatosan ismétlődnek.
3. sor: Az yrotate object a megadott számú objektumot a megadott szögre fordítja el az y tengey körül. A szöget úgy számítjuk ki, hogy lekérjük az objektumunk y szögét, és hozzáadunk 2-t.
Nekünk azonban nem tetszik ez a program, mert olyan lassú. Hogy gyorsítsunk rajta, meg kell ismerkednünk a Sync paranccsal. Alapállásban a DB frissíti a képet. Ha lassan dolgozik, akkor nem szabad rábízni ezt a fontos feladatot... Két dolgot tehetünk:
1, Megadjuk hogy hányszor frissítse a képet. Ezt a Sync Rate paranccsal tehetjük meg:
pl.: sync rate 100
60 fps-nél ne várjunk többet. (az fps itt a frame/sec rövidítése, nem a first person shooteré :) )
2, Mi mondjuk meg, hogy mikor frissítsen:
sync on <- vele beállíthatjuk a kézi képfrissítést: csak sync-re frissít a program
sync <- vele frissítjük a képet
Tehát:
sync rate 100
make object cube 1,5
do
yrotate object 1,object angle y(1)+2
loop
vagy:
sync on
make object cube 1,5
do
sync
yrotate object 1,object angle y(1)+2
loop
Most az 1. változat tűnik gyorsabbnak.
Na, ezzel is megvagyunk. Csináljuk látványosabbra ezt a programot! Színezgessük a hátteret! A háttér neve a DarkBasicben: backdrop. A backdropot színezhetjük, textúrázhatjuk (ezt lásd később). Alapból kék színű. Érdemes tudni róla, hogy folyamatosan frissül, tehát ha kiírunk valamit rá, az a következő frissítéskor eltűnik.
set display mode 800,600,16
make object cube 1,5
sync on
sync rate 60
do
sync
`Mivel az 'a' változó
`kezdőértéke 0, ezért a mod változó értéke 2 lesz (lásd 4. if kezdetű sor)
`Ha mod=2, akkor az a-t növeljük egészen addig, amíg 255 nem lesz. Ekkor
`a mod 1 lesz, és az 'a' változó értékét csökkenteni kezdjük. Egészen addig,
`amíg 0 nem lesz. Ekkor kezdődik az egész előről.
if mod=1 then a=a-1
if mod=2 then a=a+1
if a=255 then mod=1
if a=0 then mod=2
`Színezzük az (1-es) objektumot.
`Aztán a hátteret az ellentétes színnel.
`Az rgb paranccsal adhatunk meg színt.
color object 1,rgb(a,a,a)
color backdrop rgb(255-a,255-a,255-a)
`Elforgatjuk két tengely körül is az 1-es objektumot
yrotate object 1,object angle y(1)+2
xrotate object 1,object angle x(1)+2
`A szövegkiíratás helyét a 0,0 2D koordinátákra állítjuk.
set cursor 0,0
`A screen fps() függvény az fps-t adja vissza (remélem logikus...)
`Kombináljuk printtel, és így kiírja az fps-t.
print "FPS: ";screen fps()
loop
Magyarázat:
- A programban vannak megjegyzések, amik ` jellel kezdődnek [AltGr-7]. Ne keverjétek össze a normál aposztróffal [Shift-1]!
- A set display mode 800*600-ra és 16 bitre állítja a felbontást és színmélységet. (Alapból 640*480*16)
- Az RGB() értékei 0 és 255 között változhatnak.
- A printnél egyszerre két tipusú adatot használunk: (csak itt lehet ilyet)
1,string (szöveg)
2,egész szám (screen FPS())
Remélem minden érthető. Akkor most nézzük a kamera kezelését!
Változtassuk meg a kocka méretét! Azt tapasztaljuk, hogy megnövelt méret esetén is ugyanakkora a képernyőn. Ha még nagyobbra állítjuk, eltűnik a kocka. Ez azért van, mert új objektum készítésekor a DB a kamerát úgy állítja be, hogy az objektum beleférjen a képbe (autocam). Tegyük szabadon mozgathatóvá a kamerát! Ehhez először meg kell ismerkedni a beviteli eszközök kezelésével.
Egér kezelése:
A mouseclick() függvény értéke adja meg, hogy melyik gomb volt lenyomva. Íme egy példaprogram:
do
if mouseclick()=1 then print "Bal gomb"
if mouseclick()=2 then print "Jobb gomb"
if mouseclick()=3 then print "Mindkét gomb"
loop
A hide mouse parancs elrejti, a show mouse parancs megjeleníti az egeret.
Az egér elmozdulását képpontokban a mousemovex() és a mousemovey() függvények adják meg:
do
cls
set cursor 0,0
print "X elmozdulás: ";mousemovex();" Y elmozdulás: ";mousemovey()
loop
A billentyűzet főbb gombjait a controlkey(), shiftkey(), spacekey(), stb. függvényekkel kezelhetjük.
Visszatérve a kamera kezelésére, itt a kamera használatát bemutató program:
autocam off : sync on : hide mouse
randomize timer()
for i=1 to 200
make object cube i,5
position object i,rnd(1000),rnd(1000),rnd(1000)
next i
position camera 500,500,500
do
szogx=wrapvalue(szogx+mousemovex())
szogy=wrapvalue(szogy+mousemovey())
rotate camera szogy,szogx,0
if mouseclick()=1 then move camera 5
if mouseclick()=2 then move camera -5
sync
loop
Magyarázat:
1. sor: az autocam off parancs kikapcsolja a DB-nek azt a tulajdonságát, hogy egy objektum létrehozásakor ráfókuszáljon a kamera. Ez azért lesz fontos, mert sok objektummal lesz dolgunk. A sorban található másik két parancs már ismert.
2. sor: a véletlenszám-generátor kezdőértékét az órához állítja. Ez azért kell, mert a program minden induláskor ugyanazokat a "véletlen" értékeket generálná.
3. sor: ciklus eleje
4. sor: 200 kocka legyártása
5. sor: 200 kocka véletlenszerű elhelyezése. Az RND() függvénybe írt szám a véletlenül generált szám legmagasabb értéke, tehát itt 0 és 1000 között lesznek a számok. És 3 ilyen szám kell, mivel 3D-ben 3 koordináta van. (Ezeknek semmi közük a képernyő 2D-s koordinátáihoz! Azokból még mindig 2 van!)
6. sor: ciklus vége
7. sor: a kamerát berakjuk az egész kellős közepébe. Mivel 1 kamera van, nem kell kameraszám. De ha csinálunk egy másikat (csak DBpro-ban lehet) akkor kell.
8. sor: főciklus eleje
9. sor: az egér elmozdulását hozzáadjuk a szögX változóhoz. De mivel a szög 0 és 359 között lehet csak, ezért lekerekítjük a wrapvalue függvénnyel. (A wrapvalue az esetleges -10 -ből 350-et, 370-ből 10-et csinál)
10. sor: ugyanez az egér y koordinátájával
11. sor: kamera elforgatása: a szogx és a szogy fel van cserélve.
12. sor: Ha bal gombot nyomunk, előre megy a kamera
13. sor: Ha jobb gombot nyomunk, hátra
14. sor: Képfrissítés
15. sor: Főciklus vége
Ennyi. Vállalkozó szelleműek kombinálhatják az előző programmal! Azonban nem ártana, hogyha megállna a kamera, ha objektumhoz ér. Azt nem tudjuk vizsgálni, hogy egy kamera ütközik-e, de azt igen, hogy két objektum ütközik-e. Úgy kell tehát megoldani, hogy egy objektumot irányítunk, aminek eltároljuk a koordinátáit. Ha ütközik, visszaállítjuk a régi koordinátákat.
Ütközést az object collision(obj1,obj2) függvénnyel vizsgálhatjuk. "Egyet ad vissza, ha két megadott 3D objektum átfedésben van egymással. Ha a második bemenő paraméter nulla, a visszatérési éték annak az objektumnak a száma, mellyel az első objektum átfedésben van. A paramétereknek egész értékeknek kell lenniük." - idézet a súgóból.
autocam off : sync on : sync rate 60 : hide mouse
randomize timer
for i=1 to 100
make object cube i,15
position object i,rnd(1000),0,rnd(1000)
next i
make object plain 101,0,0
do
opx=object position x(101)
opz=object position z(101)
position camera opx,0,opz
szogx=wrapvalue(szogx+mousemovex())
rotate object 101,0,szogx,0
set camera to object orientation 101
if upkey()=1 then move object 101,5
if downkey()=1 then move object 101,-5
if object collision(101,0)<>0 then position object 101,opx,0,opz
sync
loop
A program eleje hasonlít az előzőre. 100 objektumot gyártunk. 3D-ben az y koordináta a magasság, azt most békén hagyjuk. Csinálunk egy 101-edik objektumot, őt fogjuk irányítani.
Fő ciklus:
Először is az opx és opz változókban eltároljuk az objektum koordinátáit. Ezután a helyére berakjuk a kamerát. Ezek után kiszámoljuk a szöget, elforgatjuk az objektumot. A set camera to object orientation parancs az újdonság, ahogy a neve is mondja, az objektumhoz állítja a kamera szögét. A fel és le nyíl nyomására mozgatjuk az objektumot. Ha ilyenkor ütközik, visszaállítjuk a régi helyére.
Ennyi! Ha ütközünk, megáll...
Ezzel véget is ért ennek a rovatnak a tartalma. Következő hónapban tovább ismerkedünk a 3D objektumokkal - na meg a kamerával, egy picit foglalkozunk a mátrixokkal, és összebarátkozunk a spriteokkal, ami most nem az üdítőt jelenti! :-)