Archive for August, 2008

Event’ai ( PART III )

// August 11th, 2008 // 2 Comments » // AS3

Garbage Collection

Pažodžiui išvertus skamba nelabai skaniai, bet kiek kaitinėjausi kiek bandžiausi, AS3 GC yra labai naudingas dalykas. Jį galima pavadinti Eventų prižiūrėtoju, tvarkytoju. Visų pirmą – su kuo ir kaip jis yra valgomas:

Jis yra įkomponuojamas į bet kurį addEventListener veiksmą:

eventTarget.addEventListener ( EventType.EVENT_NAME, eventResponse, useCapture : Boolean, priority : int, weakReference : Boolean );

useCapture – taip ir nesupratau normaliai kam jis reikalingas, jeigu jam duodi parametrą false, tai EventListener’is suveikia, jeigu duodi true – neveikia.

priority - eiliškumas, jeigu vienas objektas turi kelis to pačio tipo EventListener’ius:

stage.addEventListener ( MouseEvent.CLICK, onMouseClick_1, false, 99, true );
stage.addEventListener ( MouseEvent.CLICK, onMouseClick_2, false, 100, true );

juos galime surikiuoti. Default’inis eiliškumas yra toks kokia tvarka mes EventListener’ius užregistruojame, bet šiuo atveju ( 99, 100 ) onMouseClick_2 bus įvykdytas pirmas. Kuo didesnis priority skaičius tuo reikšmingesnis tas EventListener’is yra.

weakReference – šito irgi dalinai nepagavau. Priėjau išvados kad šis kintamasis sumažina atminties apkrovimą, ir padeda tuo atveju jeigu po EventLisener’io įvykdymo, EventListener’is nėra pašalinamas. Default’inė jo reikšmė yra false, kiek perėjau forumus, straipsnius tai visi norėtų kad ji kaip būtų true., ir rekomenduoja šitą reikšmę keisti į true.

Dirbtinis Event’as

Įsivaizduokite jūs kūriate žaidimą, kuriame jeigu žaidėjas surenka N taškų turi įvykti sekantys veiksmai:

  • Žaidėjas gauna papildomą gyvybę,
  • Turi sumirksėti fonas,
  • Turi pasigirsti tam tikras garsas
  • Žaidėjas gauna kokį nors bonus’ą

Žinoma visą tai galima būtų sugrūsti į vieną funkciją ir viskas atrodytų gerai, bet… Jeigu kiekvienas iš šių veiksmų turi atskrias funkcijas su visais skaičiavimais ir pan… Vėl gi galima sukurti fukciją kuri iškvietų visas funkcijas ir vėl atrodytų kad mes vis dėl to esame genijai :) . Bet yra paprstensi būdas – dirbtiniai event’ai.

Jie atrodo taip:

addEventListener ( "eventoPavadinimas", eventoFunkcija );

Mūsų atvejų reikėtų idėti kelis eventListener’ius:

myGame.addEventLisener ( "20000points", lvlUp, false, 0, true );
myGame.addEventLisener ( "20000points", playBackground, false, 0, true );
myGame.addEventLisener ( "20000points", playLvlUpSound, false, 0, true );
myGame.addEventLisener ( "20000points", giveRandomStuff, false, 0, true );

taigi visi jie suveiks tada kai bus pasiekta 20000 taškų ir kai bus iškviestas event’as 20000points. Kaip jis iškviečiamas? Šiuo, žaidimo atveju, turi vykti kažkokia tai funkciją kuri skaičiuoja taškus už vieną ar kitą žaidėjo padarytą veiksmą. Ir turės tikrinti aržaidėjas pasiekė tinkamą

private function countScore ( diff : int ) : void {

totalScore += diff;

if ( totalScore >= 20000 ) {

dispatchEvent ( new Event (“20000points”) );

myGame.removeEventListener ( "20000points", lvlUp );
myGame.removeEventListener ( "20000points", playBackground );
myGame.removeEventListener ( "20000points", playLvlUpSound );
myGame.removeEventListener ( "20000points", giveRandomStuff );

}
}

Po to kai yra iššaukiamas ( dispatch ) įvykis ( Event ), visi eventListener’iai kurie buvo užregistruoti bus įvykdyti, tokia eiliškumo tvarka kokia mes juos užregistravome.
Sekančios dvi komandos yra pritaikytos patikrinti ar tam tikras Event’as yra užregistruotas arba kam jis priklauso.

hasEventListener
Patikrina objektą ar jis turi kažkokį tai konkretų Event’ą ( tikrinamas yra objektas ):

myGame.hasEventListener ( "20000points" );

Gražinama reikšmė yra true arba false.

willTrigger
Patikrina ar kažkoks konkretus Event’as yra užregistruotas ( tikrinama yra viskas ):
willTrigger ( "20000points" );

Gražinama reikšmė yra true arba false.

Event’ai ( Part II )

// August 3rd, 2008 // No Comments » // AS3

Key Events

Toliau peržvelgsime dar kelis Event’us:

stage.addEventListener( KeyboardEvent.KEY_DOWN, onKeyPressed );
stage.addEventListener( KeyboardEvent.KEY_UP, onKeyReleased );

Funkcijai bus peduodama informaciją apie mygtuko paspaudimą, priklausomai nuo to ko jums reikės galite naudoti kelis parametrus:

keyCode – kiekvieno mygtuko kodas, “S” ir “s” duos tą pati rezultatą.

charCode – jeigu reikia išsiaiškinti ar paspaustas mygtukas yra “S” ar “s”.

keyCode ne tik gali savyje laikyti numeruotą mygtuko kodą bet taip pat ir tiesioginį mygtuko pavadinimą:

function onKeyPressed ( evt:KeyboardEvent ) : void {

switch ( evt.keyCode ) {

case Keyboard.ENTER:
myMovie.gotoAndPlay ( "pradzia" );
break;

case Keyboard.BACKSPACE:
myMovie.stop ();
break;

case Keyboard.LEFT:
myMovie.prevFrame ();
break;

case Keyboard.RIGHT:
myMovie.nextFrame ();
break;

case Keyboard.SPACE:
myMovie.gotoAndStop ( "pabaiga" );
break;

default:
trace ( “keyCode : ”, evt.keyCode );
}
}

Frame Events

FrameĘvent’as turėtų būti žinomas kiekvienam, kuris programuoja Flash AS2. Taigi šis mažas stebuklas liko ir AS3 tik truputėlį patobulintas.

Tiems kas nežino kas tai yra:

FrameEvent’ai yra vykdymi skirtingu principu negu MouseEvent’ai arba KeyEvent’ai. Jie suveikia naturaliai kaip tik flash dokumentas pradeda veikti ( aišku galima pasidaryti kad jie FrameEvent’as pradėtų veiksmą tik po to kai bus įvykdyta kokia nors sąlyga ( pvz.: mygtuko paspaudimas ) ). Taigi funkcija kuri bus priskirta prie FrameEvent’o suveiks kas kartą kai flash dokumentas įeis į naują Frame’ą. Priklausomai nuo to kiek FPS jūsų SWF nustatytą. Jeigu 12, reiškia funkcija bus įvykdomą 12 kartų, jeigu 30, reiškia 30 kartų ir t.t.

Jeigu seniau ( ant AS2 ) vienam objektui galima buvo prikabinti tik 1-ą onEnterFrame veiksmą, tai dabar galime prikabinti kiek tik norime ENTER_FRAME Event’ų.

public var ball    : MovieClip;

public function TimerEvents() {

ball = this["ballMC"];

ball.addEventListener ( Event.ENTER_FRAME, rotateObject );
ball.addEventListener ( Event.ENTER_FRAME, moveObject );

}

public function rotateObject ( evt : Event ) : void {

evt.target.rotation++;

}

public function moveObject ( evt : Event ) : void {

evt.target.x++;

}

Timer Events

Tai yra alternatyva ENTER_FRAME eventui. AS2 – ame buvo naudojamas setInterval() metodas, AS3 tam dalykui turi visiškai naują klasę – Timer.

var timer : Timer = new Timer ( uzlaikymas : Number, kartojimasis : int );

Timer klasė reikalauja dviejų kintamųjų: kas kiek laiko bus įvykdoma funkciją ( p.s. pirmas įvykdymas irgi įvyks po tiek laiko ), kartojimasis – kiek kartų kartosis dabartiniai klasei priskirta funkciją. Taip pat yra labai patogus dalykėlis – start, Timer klasės metodas kuris paleidžia skaitliuką.

var timer : Timer = new Timer ( 1000 );

timer.addEventListener ( TimerEvent.TIMER, onTimer );

timer.start ();

function onTimer ( evt : TimerEvent ) : void {

laikrodis.sRodykle.rotation += 6;

}

Objekto eksportavimas į klasę ( arba klasės pririšimas prie objekto ):

Pirmas žingsnis: Library paspaudžiame ant objekto kurį norime eksportuoti klasei – Linkage…

Tada prie Class nurodome pilną kelia iki tos klasės ( be galūnės ).

ir viskas, turime objektą pririšta prie klasės.

Parsisiųsti: TimerEvents

EventListener’ių pašalinimas

Palikti EventListener’į, tada kai jau nereikalingas nėra labai protingas dalykas. Tvarka turi būti!

Taigi po to kai EventListeneris atliko davo darbą, tarkim patikrino per kiek laiko nuo puslapio užkrovimo vartotojas pirmą kartą spregtelėjo pelės klaviša.

stage.addEventListener ( MouseEvent.CLICK, onFirstMouseClick );

Jis tampa nereikalingas, nes užduotis yra įvykdyta. Taigi mums reikia jį pašalinti. Jis yra pašalinamas tokiu pat būdu kaip ir uždedamas ( turi išlikti tas pats objektas, tas pats Event’as kurio mes klausėmes, ta pati funkcija kurią mes buvome priskirę  )

stage.removeEventListener ( MouseEvent.CLICK, onFirstMouseClick );

Visa tai yra skirta tam kad valdytume atminties užkrovimą, įsivaizduokite kad pas jus yra kelios dešimtys Event.ENTER_FRAME listener’ių, kurių kiekvienas atlieka po kelius šimtus eilučių kodo. Visa tai stabdys CPU ir apkraus atmintį, nors iš visų listener’ių, konkrečiu momentu mums reikės tik po vieną.