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: