Drop_and_Catch classes
fruit class
package { import flash.display.MovieClip; import flash.events.*; public class fruit extends MovieClip { var ySpeed; var points; public function fruit() { } function INIT() { position(); addEventListener(Event.ENTER_FRAME, update); } function update(e:Event) { y+=ySpeed; if (y>stage.stageHeight) { position(); } } function position() { y=0; x=Math.random()*stage.stageWidth-width; ySpeed=(Math.random()*10)+2; } function EXIT() { removeEventListener(Event.ENTER_FRAME, update); } } }
basket class
package { import flash.display.MovieClip; import flash.events.*; public class basket extends MovieClip { public function basket() { INIT(); } function INIT() { addEventListener(Event.ENTER_FRAME, update); } function update(e:Event) { x=stage.mouseX; y=stage.stageHeight-height; } function EXIT() { removeEventListener(Event.ENTER_FRAME, update); } } }
doc class
package { import flash.display.MovieClip; import flash.events.*; import flash.ui.Mouse; public class doc extends MovieClip { var hart=new fruit ; var knife=new fruit ; var ourBasket=new basket ; var score:int=0; public function doc() { stop(); INIT(); buttonMode=true; } function INIT() { score=0; Mouse.hide(); addChild(hart); hart.gotoAndStop("hart"); hart.points=10; hart.INIT(); addChild(knife); knife.gotoAndStop("knife"); knife.points=-10; knife.INIT(); addChild(ourBasket); ourBasket.INIT(); addEventListener(Event.ENTER_FRAME, update); } function update(e:Event) { testCollision(hart); testCollision(knife); } function testCollision(someFruitName) { if (someFruitName.hitTestObject(ourBasket)) { score+= someFruitName.points; someFruitName.position(); result(); } } function result() { trace("Du har " + score + " points"); if (score>20) { EXIT(); gotoAndStop("win"); } if (score<-20) { EXIT(); gotoAndStop("lose"); } } function EXIT() { Mouse.show(); removeEventListener(Event.ENTER_FRAME, update); removeChild(hart); hart.EXIT(); removeChild(knife); knife.EXIT(); removeChild(ourBasket); ourBasket.EXIT(); } function goGame(e:MouseEvent) { gotoAndStop("game"); INIT(); }/**/ } }
Created: 20 October 2008 • by admin
Categories: classes • oevelse
Comments: be the first to comment
Bat_Ball classes
bat class
package { import flash.display.MovieClip; import flash.events.*; public class bat extends MovieClip { public function bat() { //INIT(); } function INIT() { addEventListener(Event.ENTER_FRAME, update); } function update(e:Event) { y= stage.stageHeight-(height/2); x= stage.mouseX; } function EXIT() { removeEventListener(Event.ENTER_FRAME, update); } } }
ball class
package { import flash.display.MovieClip; import flash.events.*; public class ball extends MovieClip { var xSpeed=10; var ySpeed=10; var margin=width/2; public function ball() { //INIT(); } function INIT() { y=0+margin; addEventListener(Event.ENTER_FRAME, update); } function update(e:Event) { if (x<0+margin) { x=0+margin; xBounce(); } if (x>stage.stageWidth-margin) { x=stage.stageWidth-margin; xBounce(); } if (y<0+margin) { y=0+margin; yBounce(); } if (y>=stage.stageHeight) { y=0+margin; } x+=xSpeed; y+=ySpeed; } function xBounce() { xSpeed=xSpeed*-1; gotoAndPlay("pong"); } function yBounce() { ySpeed=ySpeed*-1; gotoAndPlay("pong"); } function EXIT() { removeEventListener(Event.ENTER_FRAME, update); } } }
doc class
package { import flash.display.MovieClip; import flash.events.*; import flash.text.*; public class doc extends MovieClip { var ourBat = new bat(); var ourBall = new ball(); var score:int; var points:int=1; var scoreMIN:int=-2; var scoreMAX:int=2; public function doc() { stop(); //INIT(); back_but.addEventListener(MouseEvent.CLICK, goGame); } function INIT() { score=0; score_txt.text=score+" points yet"; addChild(ourBat); ourBat.INIT(); addChild(ourBall); ourBall.INIT(); addEventListener(Event.ENTER_FRAME, update); } function update(e:Event) { if (ourBall.hitTestObject(ourBat)) { ourBall.yBounce(); score+=points; } if (ourBall.y>stage.stageHeight) { score-=points; } result(); } function result() { //trace("Du har " + score + " points"); score_txt.text="points: "+score+" out of "+scoreMAX ; if (score==scoreMAX) { EXIT(); gotoAndStop("win"); } if (score==scoreMIN) { EXIT(); gotoAndStop("lose"); } } function EXIT() { removeEventListener(Event.ENTER_FRAME, update); removeChild(ourBat); ourBat.EXIT(); removeChild(ourBall); ourBall.EXIT(); } function goGame(e:MouseEvent) { gotoAndStop("game"); INIT(); }/**/ } }
Created: 20 April 2008 • by admin
Categories: classes • oevelse
Comments: be the first to comment
Load presentation
Tilgængelige variabler defineret øverst.
I en class, skal de stå i class definitionen, før constructer’en (hoved-functionen).
var film1:URLRequest = new URLRequest("undermappenavn/anim_playback.swf"); var film2:URLRequest = new URLRequest("undermappenavn/bat_ball_2a.swf"); var film3:URLRequest = new URLRequest("undermappenavn/fruit_extra_new_b.swf");
I en class, vil denne typisk stå i constructor’en:
var ldr:Loader = new Loader();
I nedenstående script loades og vises hver film i hver sin knap-funktion:
film1_but.addEventListener(MouseEvent.MOUSE_DOWN,film1_Handler); function film1_Handler(e:MouseEvent):void { SoundMixer.stopAll(); ldr.load(film1); box_mc.addChild(ldr); stage.frameRate=12; } film2_but.addEventListener(MouseEvent.MOUSE_DOWN,film2_Handler); function film2_Handler(e:MouseEvent):void { SoundMixer.stopAll(); ldr.load(film2); box_mc.addChild(ldr); stage.frameRate=32; } film3_but.addEventListener(MouseEvent.MOUSE_DOWN,film3_Handler); function film3_Handler(e:MouseEvent):void { SoundMixer.stopAll(); ldr.load(film3); box_mc.addChild(ldr); stage.frameRate=32; }
Nedenstående knap-funktioner tømmer loaderen, ændrer boksens egenskaber, og til sidst ‘taler’ direkte til den loadede swf’s egen tidslinie :
unload_but.addEventListener(MouseEvent.MOUSE_DOWN,unload_Handler); function unload_Handler(e:MouseEvent):void { SoundMixer.stopAll(); ldr.unload(); stage.frameRate=12; } distort_but.addEventListener(MouseEvent.MOUSE_DOWN,distort_Handler); function distort_Handler(e:MouseEvent):void { box_mc.scaleX = box_mc.scaleY = .6; box_mc.rotation=9; } normal_but.addEventListener(MouseEvent.MOUSE_DOWN,normal_Handler); function normal_Handler(e:MouseEvent):void { box_mc.scaleX = box_mc.scaleY = .6; box_mc.x = 180; box_mc.y = 64; box_mc.rotation=0; } cheat_but.addEventListener(MouseEvent.MOUSE_DOWN,cheat_Handler); function cheat_Handler(e:MouseEvent):void { MovieClip(ldr.content).gotoAndStop("win"); /* tilsvarende, kaldt fra den loadede swf's tidslinie, ville være: ////////// MovieClip(parent.parent).play(); ///////// */ }
Created: 15 April 2008 • by admin
Categories: as3 • eksempel • navigation • oevelse
Comments: be the first to comment
Drop_and_Catch 2
Lav først Drop_and_Catch 1
Denneher 2′ er, er en lidt varieret og videreudbygget version af Drop_and_Catch 1.
Kurven er drevet af piletasterne.
En og samme function bruges til at animere mindst 3 nedfaldende figurer.
Figurerne har individuelle speed- og point-værdier.
Parametre sendes videre gennem flere functions.
Setup
3 faldende objekter i form af movieclips og en kurv parkeres på scenen med instancenavnene:
heart1_mc, heart2_mc, poison_mc, net_mc (kurven).
Der oprettes også et dynamisk tekstfelt : score_txt.
Der må også gerne være flere sektioner på timelinen, med labels : “game”, “win”, mm.
Hver sit lag, osv. Også et lag til actions øverst.
Start variablerne i “game”
stop(); var ok:Boolean = true;
Her må indskydes at ‘ok’ er min midlertidige workaround for at slippe for uønskede fortsatte processer, efter man evt. har forladt denne frame som vinder eller taber. ok er true ved scriptens start, senere blir problematiske ENTER_FRAME events KUN affyret hvis ok er true, og til sidst sættes ok til false lige før “game” forlades. Det virker!
var score:Number = 0; var winScore:Number = 40; score_txt.text = score.toString(); /*---*/ var bottomStage:Number = stage.stageHeight; var topStage:Number = 0; var rightStage:Number = stage.stageWidth; /*---*/ var netSpeed:Number = 20; heart1_mc.myValue = 10; heart2_mc.myValue = 10; poison_mc.myValue = -10; /*---*/
Bemærk at nettet får sin egen netSpeed.
De tre figurer nedenunder får også deres personlige forskellige pointværdier lokalt placeret indeni sig, ved at anvende denne syntaks heart1_mc.myValue . På den måde kan variablerne myValue sagtens have samme navn, for de er lagt hos forskellige ejere.
net_mc flyttes med piletaster
Først et par booleans vi skal bruge til at chekke om tasterne er trykket ned. De er slukkede for til at begynde med:
var rightArrow:Boolean = false; var leftArrow:Boolean = false;
Et par overordnede KeyboardEvent’er skal registreres: KEY_DOWN, for når tastaturet er i brug med en hvilken som helst tast, og KEY_UP, for når en tast er sluppet.
Både KEY_DOWN og KEY_UP bliver sat til at chekke om der er tale om netop de to taster vi skal bruge, nemlig pil frem og pil tilbage.
Når en af dem er nede, blir dens tilsvarende boolean sat til true, og når en af dem er oppe, blir tilsvarende sat til false.
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressHANDLER); function keyPressHANDLER(e:KeyboardEvent) { if (e.keyCode == Keyboard.RIGHT) { rightArrow = true; } if (e.keyCode == Keyboard.LEFT) { leftArrow = true; } } stage.addEventListener(KeyboardEvent.KEY_UP, keyReleaseHANDLER); function keyReleaseHANDLER(e:KeyboardEvent) { if (e.keyCode == Keyboard.RIGHT) { rightArrow = false; } if (e.keyCode == Keyboard.LEFT) { leftArrow = false; } }
Således vides der præcist om piletasterne er i brug, v.h.a. rightArrow og leftArrow som er tændt eller slukket for (med true og false). rightArrow og leftArrow blir brugt om lidt til at betinge retning og bevægelse for net_mc.
Man kan godt kalde metoden lidt besværlig, men det er den bedste p.t. i AS3 for hurtig reaktion.
Nu til ENTER_FRAME igangsættelsen af net_mc, som vil registrere hvad bruger har for med de to piletaster:
net_mc.addEventListener(Event.ENTER_FRAME, netHANDLER); function netHANDLER(e:Event) { if (rightArrow) { net_mc.x += netSpeed; } if (leftArrow) { net_mc.x -= netSpeed; } }
Bemærk betingelsen: if (rightArrow) som er nøjagtigt det samme som at skrive: if (rightArrow==true). Ligesom if (!rightArrow) vil være det samme som: if (rightArrow==false).
Test filmen og se selv!
Ting falder ned
De 3 objekter blir hver især bedt om at gøre sig klar og placere sig. De får tildelt x og y værdier, random speed – og blir så sendt videre til ned-dropning.
Det gør de gennem en og samme function: POSITION(hvad hedder du?) – Den har et parameter, dvs. den vil kræve en værdi for det der står i parentheserne, ved indgangen, nemlig objektets identitet, så pågældende mc kan få den rigtige behandling.
Derfor sendes de afsted, en efter en, med navnet i parenthes:
POSITION(heart1_mc); POSITION(heart2_mc); POSITION(poison_mc);
Selve POSITION(clip) kommer her:
function POSITION(clip) { clip.y = topStage - (clip.height/2); clip.x = (Math.random()*(rightStage-clip.width))+clip.width; clip.mySpeed = (Math.random()*15) + 5;//max 20 min 5 if (clip.name == "poison_mc") { clip.mySpeed += 5; } if (ok) { clip.addEventListener(Event.ENTER_FRAME, dropHANDLER); } }
Op under toppen af scenen, en tilfældig placering på række, individuel speedværdi, lidt ekstra hvis kunden hedder poison_mc.
Hvis det er ok – dvs. hvis bruger ikke er gået, for så er ok sat til false – bliver hvert clip sat igang med dropHANDLER på hver deres ENTER_FRAME event.
function dropHANDLER(e:Event):void { var clip = e.target; clip.y += clip.mySpeed; if (clip.hitTestObject(net_mc)) { EVALUATE(clip.myValue); POSITION(clip); } else if (clip.y > bottomStage) { POSITION(clip); } }
dropHANDLER ved godt hvilket mc, som har sat den igang, og gemmer den i en variabel der kunne hedde hvadsomhelst, men nu clip igen.
Endnu 2 functions bliver kaldt under forskellige omstændigheder undervejs:
POSITION(clip) funktionen fra tidligere, med medsendt eller rettere videresendt identitetsbevis, fordi clip har ramt en bundlinie eller et net_mc og skal forberedes til en ny tur.
Den anden funktion er EVALUATE(clip.myValue); med selvangivet pointværdi, videre til regnskabsafdelingen:
function EVALUATE(receivedValue) { score += receivedValue; score_txt.text = score.toString(); if (score >= winScore) { RESUME(); gotoAndPlay("win"); } }
Points tælles op og score_txt opdateres. Der chekkes om man har vundet, men inden man går, rydder man op med : RESUME(), og her er der ikke tale om parametre:
function RESUME() { ok = false; // ha! net_mc.removeEventListener(Event.ENTER_FRAME, netHANDLER); heart1_mc.removeEventListener(Event.ENTER_FRAME, dropHANDLER); heart2_mc.removeEventListener(Event.ENTER_FRAME, dropHANDLER); poison_mc.removeEventListener(Event.ENTER_FRAME, dropHANDLER); }
Videreudbygning
Se fx. joecartoon.com/games/9
Created: 8 April 2008 • by admin
Categories: as3 • oevelse
Comments: be the first to comment
Drop_and_Catch 1
2 movieClips oprettes, frugt_mc og kurv_mc.
Ind på scenen med dem på et lag kaldet graphics.
På actionScript lages indledes på sædvanlig vis med variabler og startværdier:
stop(); Mouse.hide(); var winScore:Number = 3; var score:Number = 0; var speed:Number = 10; var stageH:Number = stage.stageHeight; var stageW:Number = stage.stageWidth; score_txt.text = "Get: " + winScore + " fruits";
score_txt er et tekstfeldt du tegner med tekstværktøjet på et tekst-lag. I property-panelet kan du indstille det til at være dynamisk, give det dets nævnte instancenavn, og formatere det på noget prøvetekst, som du så sletter igen bagefter. Teksten blir alligevel straks erstattet af værdien ovenfor.
Så til den konstante bevægelse:
addEventListener(Event.ENTER_FRAME, MOVE); function MOVE(e:Event):void { kurv_mc.x = mouseX; frugt_mc.y += speed; if (frugt_mc.y > stageH) { frugt_mc.y = 0; frugt_mc.x = Math.random()*stageW; speed++; } }
Følgende foregår konstant, på den valgte frame-rate:
kurv_mc følger musens x-værdi.
frugt_mc bevæger sig nedaf positivt på y-aksen, og hvis den rammer bunden, lægges den straks op igen på en tilfældig x-værdi, og farten øges en smule til næste himmelfald.
Bemærk Math.random(), som udgør en random værdi mellem 0 og 1 , og derfor skal ganges med max-værdien stageW, for at udgøre en random værdi mellem 0 og hele scenebredden.
Hvis man fanger den med kurv_mc (skrives indenfor MOVE, før dens afsluttende '}'):
if (kurv_mc.hitTestObject ( frugt_mc)) { score++; score_txt.text = "your score is: " + score + " fruits"; frugt_mc.y = 0; frugt_mc.x = Math.random () * stageW; speed++; if (score >= winScore) { RESUME("win"); } }
Hvis man rammer, er der pointstigning, og det vises i tekstboksen. Så blir frugt_mc’s y-værdi nulstillet påny et tilfældigt sted på indenfor bredden og farten øges til kommende tur ned.
Og derefter blir der vurderet om man er nået til vinder-stadiet og functionen RESUME(med vedhæftet parameter “win”) blir kaldt.
Se bort fra denne forklaring lige efter du har læst og forstået den, se på koden og lev dig ind i den – og skriv så en /*kommentar*/ med helt egne ord og din egen forklaring udfra helt egen forståelse.
Nedenunder MOVE defineres RESUME (som ber om et vedhæftet parameter, som den jo også får, og som den skal bruge til videre behandling):
function RESUME(where:String):void { Mouse.show(); removeEventListener(Event.ENTER_FRAME, MOVE); gotoAndStop(where); }
Et parameter er en variabel, der videresendes fra funktion til funktion, fordi dens værdi kendes i den ene, og bruges i den anden. RESUME definerer en variabel i sin parenthes, og MOVE gir den en værdi i sin parenthes. Der kan være mange parametre i en enkelt function og de adskilles med komma.
Forslag til udbygning:
//random speed
//mere frugt fra himlen, individuel point-værdi, individuel speed
//POSITION, EVALUATE functions
//sidelæns spil
//undgå i stedet for at fange
//splash, og lose + grafik
//animationer på mc’erne
//lyd
se evt. Drop_and_Catch 2
Created: 6 April 2008 • by admin
Categories: as3 • oevelse
Comments: be the first to comment
Bat_Ball
Læs det hele før du går i gang.
Du lærer mest ved at stave dig igennem koden og teste filmen ofte. Gem også ofte. Gem flere versioner, så du eksperimenterer frit med koden i en teste-fil.
Hvis du alligevel kopierer kodebidder herfra, så pas meget på anførelsestegnene – de “driller”.
Tegn og bevæg
Lav en movieclip til bat, og en movieclip til ball.
Træk den ind på scenen i hvert sit navngivet lag og kald dem:
bat_mc
ball_mc
I et nyt AS lag skrives scriptet:
stop(); Mouse.hide(); stage.addEventListener(Event.ENTER_FRAME, stuff_mover); function stuff_mover(e:Event) :void { bat_mc.x = mouseX; }
Gem og test
Bat følger musen. (markøren er skjult)
Selve filmens framerate kan du sætte op til 32 fp, så glider det bedre.
Bemærk Event.ENTER_FRAME, som ikke er en MouseEvent, og som sørger for konstant genudførelse af scriptet, i den framerate der er sat.
I stuff_mover funktionen (dvs. før dens afsluttende }) tilføjes:
ball_mc.x += xBallSpeed;
Men xBallSpeed skal lige defineres for at kunne bruges her.
Tilføj over stop(); dvs. i den øverste afdeling af scriptet som er til start variabler:
var xBallSpeed:Number = 10;
Test filmen. Nu bevæger bolden sig på x-linien med værdien 10px for hver frame i den rate du har sat den til.
ball_mc skal standses af kanten og kastes tilbage. Derfor vender vi fortegnene på den xBallSpeed værdi, som bevæger ball_mc frem når den er positiv, og tilbage når den er negativ! Dette gøres HVIS der rammes en bestemt kant.
Skriv indenfor stuff_mover:
if (ball_mc.x >= stage.stageWidth) { xBallSpeed = -xBallSpeed; } if (ball_mc.x <= 0) { xBallSpeed = -xBallSpeed; }
stage.stageWidth er flash scenens egene tal for x-værdien af scenens højre kant. Venstre kant er jo bare 0.
Den kritiske iagttager vil bemærke at bolden først ‘rammer’ kanterne når den er lidt forbi. Det skyldes dens præcise x-punkt, der formodentlig ligger i dens centrum.
Hvis effekten er uønsket, må man have dens halve bredde med i beregningerne:
if (ball_mc.x >= stage.stageWidth - (ball_mc.width / 2)) { xBallSpeed = -xBallSpeed; } if (ball_mc.x <= 0 + (ball_mc.width / 2) ) { xBallSpeed = -xBallSpeed; }
Fleksibilitet
Spillet bliver mere fleksibelt af at lægge forekommende værdier og udregninger ind i variabler, og tilbagevendende handlinger i funktioner. Dels fordi koden evt. kan genbruges, eller/og spare flere linier kode, Væedierne kan også nemmere ændres eller varieres, samt give større overblik, med de navne man selv giver funktioner og variabler.
Filmens grænser ville være oplagte at lægge i variabler – det kunne jo tænkes man ville variere med en mindre bane. Fx. ‘leftLimit’ og ‘rightLimit’.
Den tilbagevendende omvendelse af xBallSpeed-værdien kunne passende være en funktion kaldt: ‘X_BOUNCE()’.
Altså 2 nye var-deklarationer henimod toppen af scriptet:
var leftLimit:Number = 0; var rightLimit:Number = stage.stageWidth;
(stage.stageWidth kan være lidt ‘buggy’ og må erstattes med et tal, hvis du får problemer med den under upload.)
Variablerne of funktionen kan nu erstatte koden i forrige betingelser i stuff_mover og omskrive dem til:
if (ball_mc.x >= rightLimit - (ball_mc.width / 2)) { X_BOUNCE(); } if (ball_mc.x <= leftLimit + (ball_mc.width / 2)) { X_BOUNCE(); }
X_BOUNCE() er den nye function vi laver nu.
Nederst, efter stuff_mover defineres den:
function X_BOUNCE() :void { xBallSpeed *= -1; }
Plus blir hermed vendt til minus og minus til plus! og bolden bevæger sig med den samme fartværdi, bare den modsatte vej.
Den lodrette
Prøv at lave den lodrette bevægelse selv!
(fart- og kant-Variabler øverst, bevægelse og kant-betingelser i stuff_mover, ny bounce function – eller kan man genbruge den samme?..
Ram bolden med Battet
Igen en vigtig betingelse – øverst i betingelsesrækken i stuff_mover:
if (ball_mc.hitTestObject(bat_mc)) { Y_BOUNCE(); }
Lose scenariet
Nu er det tid til at udbygge scenen lidt – så den kommer til at se nogenlunde sådan ud – bortset fra, at ‘lose’ er stavet forkert.

Start med at lave en stop(); på første lose frame, og derefter: Mouse.show();, så vi kan se hvor vi er, når vi tester.
Vi kan godt tilføje med det samme at man skal tabe i en bestemt situation, fx. når bolden rammer bundlinien.
Så skal det skrives ind i ball-rammer-bundkant-betingelsen i stuff_mover (i stedet for Y_BOUNCE();)
gotoAndStop("lose");
I lose scenariet skal der laves lidt interface og placeres en knap, der kan sende een tilbage til spillet.
Test filmen nu!
Der opstår en fæl fejl, der bruger hele Output vinduet, og blir ved som var den en virus. Det er den igangværende ENTER_FRAME funktion, som “lever videre” og som man bør slukke efter sig før man går.
Altså: Før bruger forlader denne frame for at gå til ‘lose’ indsættes følgende:
e.target.removeEventListener(Event.ENTER_FRAME, stuff_mover);
Hvis du så oven i købet arrangerer dine kant-betingelser således. at de står nederst i stuff_mover, og at bund-kant-betingelsen er den nederste, så får du ikke flere fejl.
Forslag til at komme videre
Lyd på. Importer mindre lyde til library, og læg forskellige lyde på game og lose (lydlaget). I property panelet indstilles de først og fremmest til ‘event’. Du kan redigere dem sporadisk gennem edit. Du kan også lægge smålyde indeni knappen på “lose”.
Du kan øge farten på ball_mc – så det bliver sværere at ramme.
Der er i forvejen betingelser og situationer du kan bruge til acceleration og hvor du kan øge speed-vardierne med et tal:
fx. Når man rammer med battet, hvergang bolden rammer kanterne, eller bare ved hver frame..
Bolden kunne også ramme skævere ved at øge værdierne forskelligt.
Bolden kunne blive mindre.. eller battet-
Bolden kan få en unge! I så fald må det nuværende niveau have den extra bold parkeret udenfor scenen og benytte en form for tæller, før den skal komme frem. (Google eller swat)
At bolden rammer en kant og at den rammer battet kunne udløse en animation for både bat og bold. En sektioneret tidslinie på fx. en bold kan jo også indeholde forskellige lyde.
Created: 1 April 2008 • by admin
Categories: as3 • oevelse
Comments: be the first to comment
