(category) LIST of posts

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

Drag’n drop

Setup

2 movieclips, drag_mc og target_mc, placeret på scenen et stykke fra hinanden.

Grundkode:

drag_mc.addEventListener(MouseEvent.MOUSE_DOWN, dragHANDLER);
function dragHANDLER(e:MouseEvent):void {
	drag_mc.startDrag();
}
drag_mc.addEventListener(MouseEvent.MOUSE_UP, dropHANDLER);
function dropHANDLER(e:MouseEvent):void {
	drag_mc.stopDrag();
}

Med HitTestPoint():

var sourceX:int=drag_mc.x;
var sourceY:int=drag_mc.y;
 
drag_mc.buttonMode=true;
drag_mc.addEventListener(MouseEvent.MOUSE_DOWN, dragHANDLER);
function dragHANDLER(e:MouseEvent):void {
	drag_mc.startDrag();
	//////////////////////////////////
	e.target.parent.addChild(e.target);//lægger øverst
	///////////////////////////////////
}
drag_mc.addEventListener(MouseEvent.MOUSE_UP,dropHANDLER);
function dropHANDLER(e:MouseEvent):void {
	drag_mc.stopDrag();
	if (drag_mc.hitTestPoint(target_mc.x, target_mc.y, true)) {
		drag_mc.x=target_mc.x;
		drag_mc.y=target_mc.y;
	} else {
		drag_mc.x=sourceX;
		drag_mc.y=sourceY;
	}
}

Keyboard – kort men hakkende

stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
function keyPressed(e:KeyboardEvent) {
	if (e.keyCode == Keyboard.RIGHT) {
		mc.x +=5;
	}
	if (e.keyCode == Keyboard.LEFT) {
		mc.x -=5;
	}
	if (e.keyCode == Keyboard.UP) {
		mc.y -=5;
	}
	if (e.keyCode == Keyboard.DOWN) {
		mc.y +=5;
	}
}

Se også: Keyboard – lang men flydende

Keyboard – lang men flydende

Alle de keys man har brug for i form af booleans

var rightArrow:Boolean=false;
var leftArrow:Boolean=false;
var upArrow:Boolean=false;
var downArrow:Boolean=false;

KEY_DOWN listeneren sætter dem til true

stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
function keyPressed(e:KeyboardEvent) {
	if (e.keyCode == Keyboard.RIGHT) {
		rightArrow = true;
	}
	if (e.keyCode == Keyboard.LEFT) {
		leftArrow = true;
	}
	if (e.keyCode == Keyboard.UP) {
		upArrow = true;
	}
	if (e.keyCode == Keyboard.DOWN) {
		downArrow = true;
	}
}

KEY_UP listeneren sætter dem til false

stage.addEventListener(KeyboardEvent.KEY_UP, keyReleased);
function keyReleased(e:KeyboardEvent) {
	if (e.keyCode == Keyboard.RIGHT) {
		rightArrow = false;
	}
	if (e.keyCode == Keyboard.LEFT) {
		leftArrow = false;
	}
	if (e.keyCode == Keyboard.UP) {
		upArrow = false;
	}
	if (e.keyCode == Keyboard.DOWN) {
		downArrow = false;
	}
}

ENTER_FRAME listeneren reagerer på dem prompte

stage.addEventListener(Event.ENTER_FRAME, MOVE);
function MOVE(e:Event) {
	if (rightArrow) {
		mc.x += 5;
		mc.play();
	}
	if (leftArrow) {
		mc.x -= 5;
		mc.play();
	}
	if (upArrow) {
		mc.y -= 5;
		mc.play();
	}
	if (downArrow) {
		mc.y += 5;
		mc.play();
	}
	if (!rightArrow && !leftArrow && !upArrow && !downArrow) {
		mc.stop();
	}
}

Se også: Keyboard – kort men hakkende

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

mcStatus mekanik

mc er movieclippet med den sektionerede timeline og relevante labels. Dens labels har her samme navne som de mcStatus værdier den skal reagere på! De behøver ikke at være de samme, men det er smart.
mcStatus er en variabel, der får værdi af tilstande, som indgår i en logisk rækkefølge. Hvert trin betinger det næste (erstat navne med dem du arbejder med).

Start med at få overblik over de forskellige mcStatus værdier

/*mcStatus værdier: sleep, awake, dressup */

Og definer så en startværdi for mcStatus

var mcStatus:String = "sleep";

Kombinationer

Andre objekter ændrer mcStatus:

alarm_mc.buttonMode = true;
alarm_mc.addEventListener(MouseEvent.CLICK, alarm_HANDLER);
function alarm_HANDLER (e:MouseEvent):void {
	if (mcStatus == "sleep") {
		mcStatus = "awake";
	}
}
dress_mc.buttonMode = true;
dress_mc.addEventListener(MouseEvent.CLICK, dress_HANDLER);
function dress_HANDLER (e:MouseEvent):void {
	if (mcStatus == "awake") {
		mcStatus = "dressup";
	}
}

mc aktiveres ved direkte klik (hvis den ikke har været der):

mc.buttonMode = true;
mc.addEventListener(MouseEvent.CLICK, mc_HANDLER);
function mc_HANDLER (e:MouseEvent):void {
if (mc.currentLabel!= mcStatus){
	mc.gotoAndPlay(mcStatus);
	}

Andre objekter ændrer mcStatus og aktiverer mc:

dress_mc.buttonMode = true;
dress_mc.addEventListener(MouseEvent.CLICK, dress_HANDLER);
function dress_HANDLER (e:MouseEvent):void {
	if (mcStatus == "awake") {
		mcStatus = "dressup";
		mc.gotoAndPlay (mcStatus);
	}
}