Az előző két részben eljutottunk odáig, hogy van egy jó randa pattogó labdánk. Szebb lehetne, ha mondjuk nem méreteződne át a böngészőablakkal együtt, jó lenne a framerate-je, meg lenne valami mögötte. Nosza, az első két dologra a Stage osztály a gyógyír, a harmadik problémát pedig eddigi tudásunkkal is meg tudjuk oldani.
Először is importáljuk a Stage osztályt, és a hozzátartozó konstansokat tartalmazó osztályokat.
import flash.display.Stage; import flash.display.StageScaleMode; import flash.display.StageAlign;
Aztán már csak egy private változó kell alá, és lehet példányosítani.
private var myStage:Stage; // .. // myStage = new Stage( ); myStage.frameRate = 25; myStage.scaleMode = StageScaleMode.NO_SCALE; myStage.align = StageAlign.TOP; //
Amint látjátok, beállítottuk a framerate-et, a scalemode-ot, és az igazítást, ha most ráindítunk, már egy fokkal jobban fog kinézni.
Azért hányjunk mögé egy hátteret is, nem csak a dizájn miatt lesz hasznos ez a későbbiekben ( spoiler :) )
private var myBack:MovieClip; // .. // myBack = new MovieClip( ); myBack.graphics.beginFill( 0x900000 , 1 ); myBack.graphics.lineStyle( 2 , 0xffffff , 1 ); myBack.graphics.moveTo( 0 , 0 ); myBack.graphics.lineTo( 400 , 0 ); myBack.graphics.lineTo( 400 , 200 ); myBack.graphics.lineTo( 0 , 200 ); myBack.graphics.lineTo( 0 , 0 ); addChild( myBack );
Kircsi, most már van egy fehérkeretes bordó hátterünk is. Módosítsuk a BallClip osztályunkban néhány méretet és koordinátát, hogy ne tudjon kimenni a hátterünkből.
graphics.drawCircle( 0 , 0 , 20 ); .. if ( x + xspeed > 390 ) xspeed *= -1; if ( x + xspeed < 10 ) xspeed *= -1; if ( y + yspeed > 190 ) yspeed *= -1; if ( y + yspeed < 10 ) yspeed *= -1;
Most már egész jó. Akkor most jön a két karika: interakciót viszünk bele!!! Bizony!!! Modnjuk lehessen megfogni a lasztit, és lehessen dobálni egérrel, az tök jó lenne.
Izzíthatjuk is az új eseménykezelő modellt: a BallClip osztály figyelni fogja, hogy reá lett-e kattintva, és ha igen, akkor kiszól a vezérlő osztálynak, hogy mozgass már meg, meg szedjél valahonnan globális egérkoodinátákat, meg ilyenek.
Szükségünk lesz két új függvényre, amit az egéresemények triggerelnek, invokálnak, indukálnak, nincs erre magyar szó?
// // // public function mouseDownHandler ( eventOBJ:MouseEvent ):void { // father.dragBall( ); // } // // // public function mouseUpHandler ( eventOBJ:MouseEvent ):void { // father.releaseBall( ); // }
A konstruktorában meg hozzárendelünk két eseményt
// addEventListener( MouseEvent.MOUSE_DOWN , mouseDownHandler ); addEventListener( MouseEvent.MOUSE_UP , mouseUpHandler ); //
Ne feledkezzünk meg a flash.events.MouseEvent osztály importálásáról !
No, most már tudni fogja a BallClip, ha ráböktünk az egérrel, írjuk meg az apaosztályhoz tartozó függvényeket. Itt jön egy fontos dolog: ha akárhol létrehozunk egy új objektumot, rögtön, lehetőleg a konstruktorában tudassuk vele, hogy mi vagyunk az apja, így közvetlenül vissza tud ránk utalni amikor akar, ez irtó hasznos dolog. Tehát amikor a TestBall-on belül létrehozzuk a BallClip objektumot, csináljunk olyat, hogy
myBall = new BallClip( this );
A BallClip osztályban hozzunk létre egy privát father MovieClip típusú változót, és a konstruktor rögtön pakolja is bele az apa MoveiClipet vagy Objektumot:
public function BallClip ( myRoot:MovieClip ) { // father = myRoot;
Most már tudni fogja a mouseDownHandler meg a mouseUpHandler, hogy kinek szóljon egéreseménykor.
Kell tehát a vezérlő osztályba is dragBall fúggvény, ami ideiglenesen leállítja a labda mozgását, létrehoz egy egérmozgás-eseményfigyelőt, és mozgatja a labdát. Ezért két függvényre érdemes bontani: a dragBall-ra és a moveBall-ra. A moveBall végzi a tényleges mozgást, és ő jegyzi meg a labda előző állapotának koordinátáit is. A releaseBall pedig belövi a myBall új sebességértékeit, és indítja a mozgatást.
Még két fontos változtatás szükséges a kódhoz:
1. A moveTimer objektum eddig csak lokális változóként létezett a TestBall konstruktorában, őt globálissá kell tennünk, hogy más függvények is elérjék az osztályon belül.
2. A BallClip osztály xspeed és yspeed privát változóit publikussá kell tennünk, hogy a TestBall elérhesse őket.
Továbbá a Timer intervallumot is levettem 50 millisecről 20-ra, így folyamatosabb a mozgás.
A végleges kód:
//begin // // package { // // // import flash.utils.Timer; import flash.events.TimerEvent; import flash.events.MouseEvent; import flash.display.Stage; import flash.display.StageScaleMode; import flash.display.StageAlign; import flash.display.MovieClip; // // // public class TestBall extends MovieClip { // // // private var myStage:Stage; private var myBack:MovieClip; private var myBall:BallClip; private var moveTimer:Timer; // private var xspeed:Number = 0; private var yspeed:Number = 0; // private var oldx:Number; private var oldy:Number; // // // public function TestBall( ) { // myStage = new Stage( ); myStage.frameRate = 25; myStage.scaleMode = StageScaleMode.NO_SCALE; myStage.align = StageAlign.TOP; // myBack = new MovieClip( ); myBack.graphics.beginFill( 0x900000 , 1 ); myBack.graphics.lineStyle( 2 , 0xffffff , 1 ); myBack.graphics.moveTo( 0 , 0 ); myBack.graphics.lineTo( 400 , 0 ); myBack.graphics.lineTo( 400 , 200 ); myBack.graphics.lineTo( 0 , 200 ); myBack.graphics.lineTo( 0 , 0 ); addChild( myBack ); // myBall = new BallClip( this ); addChild( myBall ); // moveTimer = new Timer( 20 ); moveTimer.addEventListener( TimerEvent.TIMER , myBall.step ); moveTimer.start( ); // } // // // public function dragBall ( ):void { // addEventListener( MouseEvent.MOUSE_MOVE , moveBall ); moveTimer.stop( ); // } // // // public function releaseBall ( ):void { // removeEventListener( MouseEvent.MOUSE_MOVE , moveBall ); myBall.xspeed = xspeed; myBall.yspeed = yspeed; moveTimer.start( ); // } // // // public function moveBall ( eventOBJ:MouseEvent ):void { // myBall.x = mouseX; myBall.y = mouseY; // xspeed = mouseX - oldx; yspeed = mouseY - oldy; // oldx = mouseX; oldy = mouseY; // } // // // } // // // } // // // import flash.display.MovieClip; import flash.events.TimerEvent; import flash.events.MouseEvent; // // // class BallClip extends MovieClip { // // // private var father:MovieClip; public var xspeed:Number; public var yspeed:Number; // // // public function BallClip ( myRoot:MovieClip ) { // father = myRoot; // graphics.beginFill( 0xff0000 , 1 ); graphics.drawCircle( 0 , 0 , 20 ); graphics.endFill( ); // x = 20; y = 20; // xspeed = Math.random( )*5; yspeed = Math.random( )*5; // addEventListener( MouseEvent.MOUSE_DOWN , mouseDownHandler ); addEventListener( MouseEvent.MOUSE_UP , mouseUpHandler ); // } // // // public function step ( timeEvent:TimerEvent ):void { // if ( x + xspeed > 390 ) xspeed *= -1; if ( x + xspeed < 10 ) xspeed *= -1; if ( y + yspeed > 190 ) yspeed *= -1; if ( y + yspeed < 10 ) yspeed *= -1; // x += xspeed; y += yspeed; // } // // // public function mouseDownHandler ( eventOBJ:MouseEvent ):void { // father.dragBall( ); // } // // // public function mouseUpHandler ( eventOBJ:MouseEvent ):void { // father.releaseBall( ); // } // // // } // // //end
Így már állatfantasztikusinteraktív a cucc, de nekem nem tetszik a labda mozgása, miért nem pattog? Ezen könnyen lehet segíteni, a BallClip osztályba be kell vezetnünk egy gravity változót, aminek az értékét folyamatosan hozzáadjuk yspeed-hez , így életszerű lesz a labda mozgása:
private var gravity:Number = 0.5; // .. // // // public function step ( timeEvent:TimerEvent ):void { // yspeed += gravity; // if ( x + xspeed > 390 ) xspeed *= -1; if ( x + xspeed < 10 ) xspeed *= -1; if ( y + yspeed > 190 ) { yspeed -= gravity; yspeed *= -1; } if ( y + yspeed < 10 ) yspeed *= -1; // x += xspeed; y += yspeed; // } //
Na? Na? Mekkora királyság, ugye? A következő részben valami grafikát és hangot fogunk embeddelni a movie-ba, utána meg megcsináljuk hogy a kamera inputtal lehessen pattogtatni a labdát.
MilGra
A cikkhez kapcsolódó hozzászólásokat a fórum "Actionscript 3" topicjában várjuk.
Hali!
A következő sor
nekem nem működött ([Fault] exception, information=ArgumentError: Error #2012: Stage class cannot be instantiated. Fault, TestBall.as:40). Amikor a kezdeti pánikom elmúlt, rájöttem, hogy a TestBall a MovieClip-ből származik, annak van saját Stage referenciája.
Ez jónak tűnik: