Ako hocete mozete vi da dodajete nove tranzicione efekte, posto je to jednostavno. Evo npr kako se pravi jedan tranzicioni efekat:
1. prvo treba "osmisliti" efekat, tj kako ce da izgleda:
ja sam za ovaj primer odlucio da napravim jedan jednostavan efekat nalik na SlideIn i SlideOut efekte. naime, napomenuti efekti rade tako sto ili novi ekran (SlideIn) "ulece" na mesto starog i prekriva ga, ili stari (SlideOut) "izlece" i otkriva novi ekran. e sad, ovaj novi efekat, nazovimo ga Push, ce da izgleda tako da novi ekran "gura" stari (a ne samo da ga prekrije kao sto je slucaj sa SlideIn), dakle ukoliko je direction = FromLeft onda ce novi ekran da ulazi sa leve strane dok ce stari da izlazi sa desne. (ako vam ipak nije jasno kako sam zamislio efekat videcete kad ga dodate u EGE :p)
2. zatim treba dodati taj efekat u
TransitionEffect enum, ova enumeracija se nalazi u
/ege/engine.bi fajlu (21. linija trenutno), dakle dodajmo
Push u ovaj enum (posle
SlideOut, da ne bi morali da menjate kod u test projektu)
3. sada nam treba novi fajl
push.bas koji cemo da smestimo u
/ege/transitions/ folder, za pocetak u taj fajl moramo da stavimo "zastitu" od visestrukih #include-ovanja (ovo nije obavezno ali posto svi fajlovi postuju to pravilo onda ce i ovaj) i
PushEffect namespace:
Code:
'
' -------------------------------------------------------------------------------------------------
'
' This file is part of EliteGameEngine source distribution
'
' -------------------------------------------------------------------------------------------------
'
#Ifndef __EGE_TRANSITIONS_PUSH_BAS__
#Define __EGE_TRANSITIONS_PUSH_BAS__
Namespace PushEffect
End Namespace
#EndIf
za svaki efekat su potrebne tri funkcije:
Init (ovde inicijalizujemo parametre potrebne za nas efekat),
onFrame (ovo se poziva na svaki game frame, i ovde je uglavnom isti kod za sve efekte) i
onPaint (ovde iscrtavamo trenutni frejm), evo tih fja ("praznih", odma' cemo da ih popunimo):
Code:
Sub Init(easing As Effect.Easing, duration As Single)
End Sub
Function onFrame(fElapsed As Single) As Elite.Boolean
End Function
Sub onPaint(dest As Bitmap)
End Sub
(naravno ovo ubacite unutar
PushEffect namespace-a)
sada sledi implementacija
Init f-je, kao sto sam rekao tu inicijalizujemo potrebne parametre, e sad, posto svaki efekat koristi easing efekte onda nam treba i Animation objekat (ovaj objekat sluzi za easing-driven animacije, tj postavite pocetnu vrednost, krajnju vrednost i duzinu trajanja efekta (u sekundama) i na osnovu izabranog easing efekta cete u tih n sekundi doci sa pocetne vrednosti na krajnju - Animation objekat moze istovremeno da "animira" vise od 1 vrednosti - broj tih vrednosti se prosledjuje konstruktoru prilikom kreiranja objekta) dakle, dodajte sledecu deklaraciju pre ove tri f-je (a unutar namespace-a):
Code:
Dim Shared As Effect.Animation Pointer anim
(deklarisana je kao Pointer da bi mogli da koristimo New/Delete)
Sada sledi kompletna
onInit f-ja:
Code:
Sub Init(easing As Effect.Easing, duration As Single)
anim = New Effect.Animation(4)
anim->StartValue(1) = 0
anim->StartValue(2) = 0
anim->StartValue(3) = 0
anim->StartValue(4) = 0
anim->EndValue(1) = 0
anim->EndValue(2) = 0
anim->EndValue(3) = 0
anim->EndValue(4) = 0
Select Case direction
Case FromLeft
anim->StartValue(1) = -CDbl(newBitmap.Width)
anim->EndValue(3) = CDbl(newBitmap.Width)
Case FromRight
anim->StartValue(1) = CDbl(newBitmap.Width)
anim->EndValue(3) = -CDbl(newBitmap.Width)
Case FromTop
anim->StartValue(2) = -CDbl(newBitmap.Height)
anim->EndValue(4) = CDbl(newBitmap.Height)
Case FromBottom
anim->StartValue(2) = CDbl(newBitmap.Height)
anim->EndValue(4) = -CDbl(newBitmap.Height)
Case FromTopLeft
anim->StartValue(1) = -CDbl(newBitmap.Width)
anim->StartValue(2) = -CDbl(newBitmap.Height)
anim->EndValue(3) = CDbl(newBitmap.Width)
anim->EndValue(4) = CDbl(newBitmap.Height)
Case FromTopRight
anim->StartValue(1) = CDbl(newBitmap.Width)
anim->StartValue(2) = -CDbl(newBitmap.Height)
anim->EndValue(3) = -CDbl(newBitmap.Width)
anim->EndValue(4) = CDbl(newBitmap.Height)
Case FromBottomLeft
anim->StartValue(1) = -CDbl(newBitmap.Width)
anim->StartValue(2) = CDbl(newBitmap.Height)
anim->EndValue(3) = CDbl(newBitmap.Width)
anim->EndValue(4) = -CDbl(newBitmap.Height)
Case FromBottomRight
anim->StartValue(1) = CDbl(newBitmap.Width)
anim->StartValue(2) = CDbl(newBitmap.Height)
anim->EndValue(3) = -CDbl(newBitmap.Width)
anim->EndValue(4) = -CDbl(newBitmap.Height)
End Select
anim->Play duration, easing
End Sub
ok mozda izgleda da je komplikovano ali nije, ovo je samo dodeljivanje pocetnih i rajnjih pozicija oba ekrana. Znaci kao sto ste videli prvo kreiramo Animation objekat i prilikom kreiranja navedemo koliko parametara zelimo da animiramo (1 je podrazumevan, tj ako se samo jedan parametar menja onda nemorate da navodite
New Animation(1) vec moze samo
New Animation), za ovj
Push efekat 4 parametra nam se menjaju to su (X,Y) koordinate novog ekrana (1. i 2. parametar) i (X,Y) koordinate starog ekrana (3. i 4. parametar) i u zavisnosti od
direction promenljive (koja je deklarisana u
/ege/transitions.bas) podesavamo pocetne i krajnje vrednosti ova 4 parametra. pored
direction promenljive (koja je tipa
TransitionDirection) postoje jos dve promenljive koje su nam na raspolaganju (i koje moramo da koristimo) to su
newBitmap i
oldBitmap (obe tipa
Bitmap) koje su "screenshotovi" novog, odnosno starog ekrana (njih koristimo za iscrtavanje, to je ocigledno). i na kraju, kada smo podesili parametre animacije sa
anim->Play duration, easing pokrecemo animaciju.
Sada sledi kod za
onFrame f-ju (ovo je isto za sve efekte u 99% slucajeva):
Code:
Function onFrame(fElapsed As Single) As Elite.Boolean
Repaint
If anim->TargetReached Then
Delete anim
Return Elite.True
EndIf
Return Elite.False
End Function
Dakle, na svaki frejm prvo pozivamo
Repaint cime obavestavamo Engine da je napravljena promena i da treba podici
onPaint dogadjaj, zatim proveravamo da li je animacija zavrsena i ukoliko jeste brisemo
anim objekat i vracamo
True, a ukoliko nije vracamo
False sto znaci da nastavljamo sa izvrsavanjem efekta.
I na kraju nam je ostala
onPaint f-ja, ona izlgeda ovako:
Code:
Sub onPaint(dest As Bitmap)
Line dest.Handle, (0, 0) - Step (newBitmap.Width, newBitmap.Height), Color.Black, BF
newBitmap.DrawTo dest, anim->Value(1), anim->Value(2), , , , , fbPSet
oldBitmap.DrawTo dest, anim->Value(3), anim->Value(4), , , , , fbPSet
End Sub
kao sto vidite veoma je jednostavna, crtamo
newBitmap na koordinatama koje odgovaraju prva dva parametra animacije, a
oldBitmap na koordinatama koje odgovaraju 3. i 4. parametru animacije. a
Line sluzi da "ocistimo" ekran pre crtanja
newBitmap i
oldBitmap slika (poslednji parametar,
BF, znaci "box filled", tj da nam ne crta dijagonalnu liniju nego pravougaonik). i jos jedna vazna napomena, default metod za iscrtavanje (mislim na
DrawTo fju) je
fbAlpha ali za tranzicione efekte moramo da koristimo
fbPSet iz dva razloga: brze je, i (sto je jos vaznije)
fbAlpha moze da izazove neke cudne efekte ponekad (kada se koristi za tranzicione efekte)
4. kada je
push.bas gotov ostalo je da "povezemo" taj efekat sa
MakeTransition funkcijom, prvo treba da #include-ujemo fajl, u
/ege/transitions/transitions.bas fajlu dodajte
#Include "push.bas" odma posle ostalih #include linija (to je 33. linija trenutno), zatim (u istom fajlu) u
MakeTransition f-ji primecujete
Select Case, sada kao poslednji
Case dodajte ovo:
Code:
Case Push
PushEffect.Init easing, duration
TransFrameProc = ProcPtr(PushEffect.onFrame)
TransPaintProc = ProcPtr(PushEffect.onPaint)
i to je to, kompajlirajte test projekat (screen trans test), pokrenite exe i dobicete "push" efekat (verovatno ne odmah posto je nasumicno biranje efekata)
jednostavno, zar ne? :)
dakle ako je neko od vas dokon i ima ideju za neki efekat neka prati ova 4 koraka i ako dobije nesto zanimljivo nek okaci ovde taj *.bas fajl da ubacim u projekat
i jos nesto, posto se efekti biraju random (u ovom test projektu) kada testirate nov tranzicioni efekat mozete izmeniti kod u
/screen trans test/main.bas u f-ji
ShowScreen (linija 81) u ovaj:
Code:
Sub ShowScreen(scr As Engine.GameScreenHandle)
Dim transEffect As Engine.TransitionEffect = Engine.Push ' ovde taj vas efekat
Dim transDir As Engine.TransitionDirection = Math.Random(Engine.FromLeft, Engine.FromBottomRight)
Dim easingEffect As Effect.Easing = Math.Random(Effect.Linear, Effect.CubicInOut)
Engine.Show scr, transEffect, transDir, easingEffect, 2
End Sub
to ce rezultovati u pozivanju samo tog efekta dok ce se pravac i easing efekti birati nasumicno...