En av de enklaste spelmekanikerna är att låta spelaren hitta ett doldt objekt. Spel baserade på detta tar många former: Var är Waldo, Peek-A-Boo, Spot the Difference, Hide and Seek, och naturligtvis Hidden Object. I denna Premium-handledning visar jag dig två metoder för att dölja en scen så att spelaren kan upptäcka den senare.
I den första SWF-klicket, klicka så galen att popa alla ballongerna. Okej, det är inte mycket utmaning, men tänk dig att göra det mot klockan, eller med fler ballonger som visas hela tiden.
I den andra SWF, torka bort smutsen genom att svepa musen över bilden. Denna mekaniker användes i Window Washy, en av de första spelen för PS2 EyeToy - för att inte tala om i otaliga skraplotter!
Vi måste skapa ballonger innan vi kan spränga dem. Jag använder Flash Pro CS3 för att göra det här; Om du inte har Flash Pro kan du antingen rita din egen med vilken metod du brukar använda, eller använd SWC från hämtningspaketet och skumma alla steg i den här handledningen förklarar hur man ritar. Jag kommer att inkludera instruktioner för användare av andra redaktörer där det är relevant.
Öppna Flash Pro och skapa en ny Flash-fil (ActionScript 3.0). Jag ska basera utformningen av mina ballonger på denna Illustrator-handledning från Vectortuts + - men med hjälp av Flash-verktyg, självklart.
Välj penncirkelverktyget och sätt det i jämna läge, med en svart puls på 1 px. Jag har använt standardutjämningsvärdet på 50.
Dra nu en grov ballongform. Oroa dig inte för att få det perfekt; Vi justerar det om en sekund. Här är min:
Hmm. Se de vassa hörnen? Smid dem ut. Använd markeringsverktyget för att välja den delen av raden och klicka sedan på Smooth-knappen några gånger.
Jag är säker på att det finns ett bättre sätt som de professionella använder, men det brukar göra tricket för mig. Tweak ballongens form men du vill - kom ihåg, du kan klicka och dra någon punkt på linjen för att sträcka ut den.
Så här har jag slutat med:
Lägg nu till knuten. Som Jesse säger i ovannämnda Vectortuts + handledning, "det är bara en enkel cirkel med en rund, triangelformad form nedan."
Okej, fyll nu ballongen med en trevlig pastellfärg (jag har valt # dae8b3, vilket är igen från Vectortuts + handledning) och radera alla rader.
Inte dåligt! Om du vill lägga till en glans, använd linjverktyget med en tjockare streckbredd (jag har använt 3px) och en vit färg för att rita en rak linje över ett "hörn" och använd sedan markeringsverktyget för att kurva det.
Välj denna glanslinje och klicka sedan på Ändra | Form | Konvertera linjer till fyllningar -- På det här sättet, om du ändrar storleken på ballongen, kommer glansen att hålla samma storlek som resten av ballongen.
För att kunna interagera med en ballong med ActionScript måste vi konvertera den till en symbol. Välj din konst och klicka sedan på Ändra | Konvertera till symbol. Gör det till en filmklippsymbol som heter Ballong
, och exportera den till ActionScript med samma klassnamn.
Ignorera varningen om att det inte finns en klass med samma namn, om det kommer upp när du klickar på OK.
Du kan hitta en FLA och SWC av de tillgångar som hittills använts i BalloonsStep2-mappen i källnedladdningen.
Välj en bakgrund för att du ska flyta framför. Jag har valt den här tapeten (kredit LGLab och envato) och beskärde den något:
Om du använder Flash Professional lägger du till ett nytt lager i scenen och importerar bilden. Annars bädda in grafiken och lägg till den längst ner i bildlistan med vilken metod som helst du föredrar. Du kanske vill ändra storlek på ditt skede för att passa bilden, som jag har gjort.
Nästa kommer vi att göra denna lone ballong försvinna när den klickas.
Tid för någon kod!
Skapa en klass, som heter Main.as, i samma katalog som din FLA, och länka den till FLA som dokumentklassen - se här för detaljer. (Om du inte använder Flash Pro, antar du att du vet hur du gör motsvarande i din redaktör, du måste redan ha skapat en huvudklass för att få bakgrunden på scenen.)
paket import flash.display.MovieClip; public class Main utökar MovieClip public function Main ()
Vi behöver komma åt ballongen från dokumentklassen, och så måste det ge ett klassnamn.
Om du använder Flash Professional väljer du ballongen på scenen och skriver theBalloon
in i rutan i fönstret Egenskaper. Klicka sedan Fil | Publicera inställningar, öppna Blixt fliken, klicka inställningar? bredvid rullgardinsmenyn för ActionScript-versionen och avmarkera rutan "Automatiskt deklarera instans". (Detta är inte absolut nödvändigt, men låter koden vara densamma oavsett om du använder Flash Pro eller någon annan redaktör.)
Ändra sedan din dokumentklass så här:
paket import flash.display.MovieClip; public class Main utökar MovieClip public var theBalloon: Balloon; allmän funktion Main ()
Om du använder en annan redaktör lägger du till en förekomst av ballongklassen i visningslistan vid alla koordinater du gillar (så länge det ligger framför bakgrunden), vilket ger det ett förekomstnamn på theBalloon
.
Vi använder en MouseEvent-lyssnare för att upptäcka när ballongen är klickad och en hanterarfunktion för att ta bort den:
paket import flash.display.MovieClip; importera flash.events.MouseEvent; public class Main utökar MovieClip public var theBalloon: Balloon; allmän funktion Main () theBalloon.addEventListener (MouseEvent.CLICK, onClickBalloon); privat funktion onClickBalloon (a_event: MouseEvent): void this.removeChild (theBalloon); theBalloon.removeEventListener (MouseEvent.CLICK, onClickBalloon);
Enkla saker. Testa det:
Inget tänker, men åtminstone fungerar det.
Inte mycket utmaning i det här är det? Dra några fler ballonger till scenen, på samma lager som originalet:
Hur ska vi komma åt dessa i kod? Jag antar att vi skulle kunna ge dem alla exempel namn som greenBalloon1
, greenBalloon2
, och så vidare, och lägg till en MouseEvent-lyssnare till var och en? usch. Vi kodar, vi kan automatisera detta.
Dokumentklassen är a Filmklipp
, vilket betyder att det är a Display
(hoj för arv), vilket betyder att den har en getChildAt () -funktion och en numChildren-egenskap, vilket innebär att vi kan använda en för
loop för att iterera genom alla föremål på scenen. Jag ska bevisa det. Ändra din Main () contsructor funktion som så:
allmän funktion Main () for (var i: int = 0; i < this.numChildren; i++) trace(getChildAt(i)); theBalloon.addEventListener(MouseEvent.CLICK, onClickBalloon);
(Du kan lämna koden för att ta bort den ursprungliga ballongen.) Kör SWF och kolla din Output-panel:
[objektform] [objektballong] [objektballong] [objektballong] [objektballong] [objektballong] [objektballong] [objektballong] [objektballong] [objektballong] [objektballong]
Koden returnerar typen av varje barn i Main - det vill säga varje objekt i displaylistan, från botten (getChildAt (0)
) till toppen (getChildAt (10)
). Eftersom jag inte exporterade bakgrundsbilden för ActionScript, vet allt Flash att det är en slags Form
.
Vi måste lägga till onClickBalloon ()
lyssnare till var och en av ballongerna, men inte till bakgrunden. Lyckligtvis finns ett nyckelord som låter oss kolla objektets klass: är
. Vi kan använda det som så:
allmän funktion Main () for (var i: int = 0; i < this.numChildren; i++) if (getChildAt(i) is Balloon) getChildAt(i).addEventListener(MouseEvent.CLICK, onClickBalloon);
(Observera att jag har tagit bort raden som specifikt lägger händelselistan till theBalloon
exempel.)
Testa SWF:
Hmm. Inte riktigt rätt, är det?
Oavsett vilken ballong du klickar, tas den ursprungliga ballongen bort. Orsaken till detta är lätt att upptäcka:
allmän funktion Main () for (var i: int = 0; i < this.numChildren; i++) if (getChildAt(i) is Balloon) getChildAt(i).addEventListener(MouseEvent.CLICK, onClickBalloon); private function onClickBalloon(a_event:MouseEvent):void this.removeChild(theBalloon); theBalloon.removeEventListener(MouseEvent.CLICK, onClickBalloon);
I rad 16 lägger vi händelselyssnaren till varje ballong. I linjerna 23 och 24 tar vi emellertid specifikt bort theBalloon
exempel. I händelsehanteringsfunktionen måste vi ta bort vilken ballong som helst klickades på istället. Detta kallas evenemangsmål, och kan nås via a_event.target
fast egendom. Så du förväntar dig att detta ska fungera:
privat funktion onClickBalloon (a_event: MouseEvent): void this.removeChild (a_event.target); a_event.target.removeEventListener (MouseEvent.CLICK, onClickBalloon);
? men det gör det inte; vi får ett fel:
1118: Implicit tvång av ett värde med statisk typ Objekt till en eventuellt orelaterad typ flash.display: DisplayObject.
Se, Flash vet inte vilken klass av objekt händelsemålet är, så det vet inte säkert att det kan vara removeChild ()
-ed eller att det kan ha några händelseläsare bifogade. Vi måste berätta för Flash att behandla händelsemålet som en förekomst av ballongklassen, som så:
privat funktion onClickBalloon (a_event: MouseEvent): void this.removeChild ((a_event.target as Balloon)); (a_event.target som ballong) .removeEventListener (MouseEvent.CLICK, onClickBalloon);
Prova det nu:
Bra! Det är en anständig milstolpe; Du kan hitta alla filer som hittills skapats i BalloonsStep8 mapp i källnedladdning.
Utmaning: Prova att räkna hur många ballonger det är när SWF först laddar, räkna hur många avlägsnas som de klickas och visa någon gratulationstext eller spela segerljud när alla ballonger är borta.
Låt oss sedan göra ballongerna pop med lite animering när de klickas.
Jag var inte säker på hur man animerade detta, så jag tittade på en slow-mo-video av en riktig ballong som brister:
Tyvärr ser det här bara på mig (jag vet), så jag försökte något annat.
Redigera din ballong och lägg till en ny ram till tidslinjen. Rita i den här ramen en stor spikig röra med pennaverktyget:
Ta bort glanslinjen (fyll den med ballongfärgen) och dra några rader från den spika rumpan ut till ballongens kant:
Klicka på varje sektion, vrid den till en grupp (CTRL-G), skilja den från de andra och ta bort raderna:
Skapa en ny keyframe och tweak de separata bitarna med hjälp av Free Transform Tool och genom att sträcka några av kanterna på fyllningarna. Jag har aktiverat Onion Skinning här så att du kan se hur mina avsnitt jämför med sina positioner i ramen innan:
Jag har funnit det hjälper till att hålla ballongens bitar inom samma område som ballongen ockuperade tidigare, men du kan experimentera med det här. Skapa sedan en ny keyframe och gör alla segmenten ännu mindre:
Jag har gjort segmenten släppa lite här, som om på grund av gravitation. Lägg nu till en ny keyframe, helt tom. Testa din animering (du kanske vill justera bildhastigheten för din film, jag gick för 24 bilder / s).
Grymt bra. Självklart, om du kör din SWF nu, kommer alla ballonger att hålla popping om och om igen:
? öppna så åtkomstpanelen i den första ramen på ballongens tidslinje och lägg till den här koden:
sluta();
Ballongens animering ingår i SWC och FLA i katalogen BalloonsStep9 i källnedladdningen.
För att bara göra en ballongpop när den klickas, måste vi bara göra animationen spela()
:
privat funktion onClickBalloon (a_event: MouseEvent): void (a_event.target as Balloon) .play (); this.removeChild ((a_event.target as Balloon)); (a_event.target som ballong) .removeEventListener (MouseEvent.CLICK, onClickBalloon);
? det, förutom att det inte kommer att fungera, för att ballongen omedelbart kommer att tas bort från visningslistan, eller hur? Bara kommentera removeChild ()
linje för nu och se till att SWF fungerar:
Åh, vi måste sluta()
animationen när den är klar. Öppna den tomma nyckelramen i ballongens tidslinje och lägg till följande:
sluta();
Egentligen, medan vi är här, kunde vi lösa vårt removeChild ()
problem. Om vi gör ballongen att skicka a KOMPLETT
händelse när dess sprängande animering är klar kunde vi lyssna på denna händelse i Main.as
, och ta bort ballongen från visningslistan när vi hör det. Lägg till den här raden i de tomma nyckelrammens åtgärder:
sluta(); dispatchEvent (ny händelse (Event.COMPLETE));
(Det här är allt i BalloonsStep10 SWC och FLA, oroa dig inte.) Nu, i Main.as
, ändra din onClickBalloon ()
hanteringsfunktion:
privat funktion onClickBalloon (a_event: MouseEvent): void (a_event.target as Balloon) .play (); //this.removeChild((a_event.target som ballong)); (a_event.target som ballong) .removeEventListener (MouseEvent.CLICK, onClickBalloon); (a_event.target as Balloon) .addEventListener (Event.COMPLETE, onBalloonBurst);
? skapa en onBalloonBurst ()
handler-funktionen, som kommer att köras när animeringen är klar:
privat funktion onBalloonBurst (a_event: Event): void this.removeChild (a_event.target as Balloon);
? och importera händelseklassen:
paket import flash.display.MovieClip; importera flash.events.Event; importera flash.events.MouseEvent;
Testa det:
Ser bra ut hittills.
Utmaning: Vad sägs om att animera ballongerna så att de boblar lite innan du klickar på dem?
Jag hittade en perfekt ljudeffekt för detta på AudioJungle: Balloon Pop. Jag kan inte inkludera den i källnedladdningen, men du kan köpa den för bara en dollar.
Om du vill kan du köpa den här effekten, eller hitta en annan online, och få den att spela när en ballong är poppad. För att göra detta, lägg till det först i ditt bibliotek och exportera det till ActionScript (eller bädda in det i ditt projekt, för icke-Flash Pro-användare) med ett klassnamn på PopSWF.
Sedan i Main.as
, skapa en privat instans av ljudet:
public class Main utökar MovieClip public var theBalloon: Balloon; privat var popSfx: PopSFX = ny PopSFX ();
? och spela det när det behövs:
privat funktion onClickBalloon (a_event: MouseEvent): void popSfx.play (); (a_event.target som ballong) .play (); //this.removeChild((a_event.target som ballong)); (a_event.target som ballong) .removeEventListener (MouseEvent.CLICK, onClickBalloon); (a_event.target as Balloon) .addEventListener (Event.COMPLETE, onBalloonBurst);
Testa:
Låt oss fylla på skärmen med flera färger av ballonger. Duplicera ballonsymbolen i biblioteket och ring det BlueBalloon, med en Klass av BlueBalloon
. Håll den identisk med den ursprungliga ballongen, men med en blå fyllning (jag har använt # c1e6ee, igen från den Vectortuts + handledningen).
Dra några exempel på scenen. Kom ihåg att du kan ta bort några av de gröna ballongerna, och du kan ändra storlek på någon av ballongerna om du gillar:
Om du testar SWF, gör de blå ballongerna inte något än:
De blå ballongerna gör ingenting eftersom alla våra kod är skrivna för att hantera Ballong
klass, och inte den BlueBalloon
klass. Vi kan dubbla hela vår kod för att hantera olika ballongfärger, men det är rörigt och det skulle vara en smärta att ändra senare om vi ville.
Låt oss istället göra den blå ballongen och den gröna ballongen använda samma klass, med hjälp av arvskraften. Välj din ursprungliga ballongsymbol i biblioteket och byt namn på den till GreenBalloon; ändra klassen till GreenBalloon
också.
Vårt mål är att ge båda ballongerna en basklass av Ballong
; Detta innebär att varje grön ballong ses som en förekomst av Ballong
såväl som av GreenBalloon
, och varje blå ballong ses som en förekomst av Ballong
såväl som BlueBalloon
-- vår kod, som skrivs med ballongklassen i åtanke, kommer alla att fungera bra.
Tyvärr, även om vi kan ställa in klassen av en symbol till namnet på en klass som inte existerar, kan vi inte göra detsamma med basklassen. Vi måste skapa en klassfil som de två ballongerna kan ärva.
Skapa en ny klassfil, Balloon.as
, i samma katalog som din FLA, och skriv in den här koden:
paket import flash.display.MovieClip; public class Balloon utökar MovieClip public function Balloon ()
Det är allt du behöver. Det måste förlängas Filmklipp
eftersom båda ballongerna använder animationer; om vi förlängde, säg, Sprite
i stället kunde de två ballong symbolerna inte använda en tidslinje, och skulle vara statiska bilder.
Ställ in basklassen för var och en av ballonsymbolerna i biblioteket till Ballong
, och kör SWF:
Bra! Det är nu lätt att lägga till någon annan ballongfärg. Bara för att bevisa det, låt oss lägga till röda och gula.
Detta är ett enkelt steg. Duplicera den gröna ballonsymbolen två gånger mer och lita på en pastellröd (# f2daea) med ett namn och en klass av RedBalloon, och den andra pastellgula (# f6f5b4), med ett namn och en klass av YellowBalloon. Ange i varje fall basklassen till Ballong
. Lägg till massor av var och en till scenen.
Kör SWF; De nya ballongerna ska fungera utan problem.
Om någon färg vägrar pop, kontrollera att symbolens basklass är inställd på Ballong
.
Vi är konditionerade för att tro att Flash-objekt endast är klickbara om muspekaren blir en hand när vi svävar över dem. För att denna hand ska dyka upp måste vi bara ställa in ballongen button
egendom till Sann
.
Det enklaste stället att göra detta är i för
slinga där vi lägger till KLICK
händelse lyssnare till varje ballong. Men alla Flash vet om ballongerna i detta skede är att de är förekomster av Display
, sedan det är vad getChildAt ()
returnerar - men button
är en egenskap av Sprite-klassen. Det betyder att vi måste använda som
sökord igen. Vi kunde skriva:
allmän funktion Main () for (var i: int = 0; i < this.numChildren; i++) if (getChildAt(i) is Balloon) getChildAt(i).addEventListener(MouseEvent.CLICK, onClickBalloon); (getChildAt(i) as Sprite).buttonMode = true;
? och sedan importera flash.display.Sprite
klass, men för enkelhetens skull kommer jag att använda Ballong
klass istället:
allmän funktion Main () for (var i: int = 0; i < this.numChildren; i++) if (getChildAt(i) is Balloon) getChildAt(i).addEventListener(MouseEvent.CLICK, onClickBalloon); (getChildAt(i) as Balloon).buttonMode = true;
Kör SWF:
Utmaning: För att hålla med temat poppande ballonger kan du ändra muspekaren till en nål eller en pinne. För hjälp, ta en titt på denna Snabba Tips genom att göra ett filmklipp följ musen eller den här om du vill ändra operativsystemets inbyggda markör.
Grattis, du har avslutat det här avsnittet i handledningen! Om du har följt alla utmaningar hittills borde du vara bra på väg till en snygg liten minigame.
Låt oss skynda igenom det här. Om du använder Flash Pro:
Om du använder en annan editor, skapar du bara ett nytt AS3-projekt med vilken metod du normalt brukar. Ring projektet WindowCleaning och huvudklassen Main.as, för att göra denna handledning lättare att följa.
I båda fallen ska din huvudklass se ut så här:
paket import flash.display.MovieClip; public class Main utökar MovieClip public function Main ()
Vissa versioner av Flash och vissa redaktörer kan generera lite lite annorlunda kod för den här klassen. Det är bra, gå bara med standardinställningarna. Om din redaktör inte genererar någon kod automatiskt kopierar du gruvan ovanifrån.
Till att börja med ska vi skapa en solid rektangel av färg och städa upp det; vi kommer vidare till mer komplicerade bilder senare.
Skapa en ny Sprite i din huvudklass för att innehålla den här "smutsiga" rektangeln:
paket import flash.display.MovieClip; importera flash.display.Sprite; public class Main utökar MovieClip public var smuts: Sprite = new Sprite (); allmän funktion Main ()
Använd sedan Sprite grafisk
egenskap för att skapa en rektangel av färg storleken på scenen. Du kan hårdkoda värdena i, om du vill (min FLA är 500x400px), eller ställ in värdena dynamiskt som jag har gjort här:
paket import flash.display.MovieClip; importera flash.display.Sprite; public class Main utökar MovieClip public var smuts: Sprite = new Sprite (); allmän funktion Main () dirt.graphics.drawRect (0, 0, stage.stageWidth, stage.stageHeight);
Detta kommer inte att synas om vi inte väljer en fyllningsfärg. Jag har valt # 440000, en djupröd.
allmän funktion Main () dirt.graphics.beginFill (0x440000); dirt.graphics.drawRect (0, 0, stage.stageWidth, stage.stageHeight);
Åh, vi måste lägga till smuts
Sprite till visningslistan:
allmän funktion Main () dirt.graphics.beginFill (0x440000); dirt.graphics.drawRect (0, 0, stage.stageWidth, stage.stageHeight); this.addChild (smuts);
Kör din SWF. Om du inte ser en solid färg, kanske är din FLA inte ansluten till din dokumentklass korrekt.
I Carlos Yanezs handledning, Skapa ett grundläggande ritningsapplikation med Flash, visade han oss hur man skapar utseendet som färger på en duk hade raderats av muspekaren, helt enkelt genom att dra en tjock vit linje som följer musen. Vi använder samma trick här.
Först måste vi skapa en MouseEvent-lyssnare för att spåra musen när den rör sig, och en handlarfunktion för när den gör det:
paket import flash.display.MovieClip; importera flash.display.Sprite; importera flash.events.MouseEvent; public class Main utökar MovieClip public var smuts: Sprite = new Sprite (); allmän funktion Main () dirt.graphics.beginFill (0x440000); dirt.graphics.drawRect (0, 0, stage.stageWidth, stage.stageHeight); this.addChild (smuts); dirt.addEventListener (MouseEvent.MOUSE_MOVE, onMouseMoveOverDirt); privat funktion onMouseMoveOverDirt (a_event: MouseEvent): void
Därefter måste vi rita en rad från musens tidigare position till dess nuvarande position:
privat funktion onMouseMoveOverDirt (a_event: MouseEvent): void dirt.graphics.lineStyle (10, 0xffffff); dirt.graphics.lineTo (mouseX, mouseY);
Glöm inte linestyle ()
ring upp; Den första raden är linjens tjocklek (i pixlar); den andra definierar sin färg (#ffffff är vit).
Testa:
Wow, det är det? en intressant effekt, men inte vad vi skulle för! Problemet här är det lineTo ()
ritar en rad från smuts
grafiskt objekt nuvarande ritningsläge till vilken punkt du anger (musens koordinater, i det här fallet). Vi flyttar emellertid inte nuvarande ritposition, så den stannar vid (0, 0)
, scenens övre vänstra hörn. Vi behöver ritningspositionen för att följa med musen också; vi kan göra detta med flytta till()
metod:
privat funktion onMouseMoveOverDirt (a_event: MouseEvent): void dirt.graphics.lineStyle (10, 0xffffff); dirt.graphics.lineTo (mouseX, mouseY); smuts.graphics.moveTo (mouseX, mouseY);
Prova SWF nu:
Ganska bra, förutom att den ursprungliga punkten är inställd på (0, 0)
, vilket betyder att den första raden som dragits alltid kommer att hoppa från övre vänstra hörnet. Dessutom, om du flyttar musen från SWF på en plats och in i SWF på en annan, hoppar linjen igen.
För att lösa båda problemen bör vi
Här är koden för det. Om du inte helt följer logiken, försök att kommentera vissa rader eller lägga till din egen för att se hur det ändrar den slutliga effekten.
paket import flash.display.MovieClip; importera flash.display.Sprite; importera flash.events.MouseEvent; public class Main utökar MovieClip public var smuts: Sprite = new Sprite (); allmän funktion Main () dirt.graphics.beginFill (0x440000); dirt.graphics.drawRect (0, 0, stage.stageWidth, stage.stageHeight); smuts.graphics.moveTo (mouseX, mouseY); this.addChild (smuts); dirt.addEventListener (MouseEvent.MOUSE_OUT, onMouseLeaveDirt); dirt.addEventListener (MouseEvent.MOUSE_OVER, onMouseReturnToDirt); privat funktion onMouseLeaveDirt (a_event: MouseEvent): void dirt.removeEventListener (MouseEvent.MOUSE_MOVE, onMouseMoveOverDirt); privat funktion onMouseReturnToDirt (a_event: MouseEvent): void dirt.addEventListener (MouseEvent.MOUSE_MOVE, onMouseMoveOverDirt); smuts.graphics.moveTo (mouseX, mouseY); privat funktion onMouseMoveOverDirt (a_event: MouseEvent): void dirt.graphics.lineStyle (10, 0xffffff); dirt.graphics.lineTo (mouseX, mouseY); smuts.graphics.moveTo (mouseX, mouseY);
Kör din SWF:
Ganska bra! Det är inte perfekt, men det visar vad vi vill göra tillräckligt bra.
Vårt slutliga mål är att radera en förgrund för att avslöja en bakgrund. I ögonblicket verkar vi radera en röd förgrund för att avslöja en vit bakgrund; Låt oss nu lägga till en mer intressant backgound.
Jag har valt den här bilden av Envato kontors dörr från Flickr (kredit till Envato
), trimmad för att passa min FLA:
Om du använder Flash Pro, skapa en ny filmklippssymbol, dra din valda bild till den (eller skapa din egen med hjälp av ritverktygen) och exportera symbolen för ActionScript med ett klassnamn på Bakgrund
. Om du använder en annan editor, lägger du in den i ditt projekt (även med namnet Bakgrund
) med din vanliga metod. Jag har inkluderat den här bilden i WindowWashing.swc
inuti källans nedladdning.
Istället för att dra det på scenen, använd kod för att lägga till den i visningslistan under smutsen:
paket import flash.display.MovieClip; importera flash.display.Sprite; importera flash.events.MouseEvent; public class Main utökar MovieClip public var smuts: Sprite = new Sprite (); public var background: Background = new Background (); allmän funktion Main () this.addChild (bakgrund); dirt.graphics.beginFill (0x440000); dirt.graphics.drawRect (0, 0, stage.stageWidth, stage.stageHeight); smuts.graphics.moveTo (mouseX, mouseY); this.addChild (smuts); dirt.addEventListener (MouseEvent.MOUSE_OUT, onMouseLeaveDirt); dirt.addEventListener (MouseEvent.MOUSE_OVER, onMouseReturnToDirt);
Så nu ligger bakgrunden under smutsen, men kan vi se den?
Er, nej.
Det enklaste sättet att kontrollera att bakgrunden faktiskt finns, är att minska alfabetet av förgrunden så att det är halvtransparent:
allmän funktion Main () this.addChild (bakgrund); dirt.graphics.beginFill (0x440000); dirt.graphics.drawRect (0, 0, stage.stageWidth, stage.stageHeight); smuts.graphics.moveTo (mouseX, mouseY); this.addChild (smuts); dirt.alpha = 0.5; dirt.addEventListener (MouseEvent.MOUSE_OUT, onMouseLeaveDirt); dirt.addEventListener (MouseEvent.MOUSE_OVER, onMouseReturnToDirt);
Som du kan se från SWF nedan finns bakgrunden där:
Denna SWF gör det också uppenbart varför vi inte ser bakgrunden skina genom (om du inte redan har utarbetat det): Vi ritar vita linjer ovanpå rötten och tar inte bort de röda linjerna helt och hållet. Helst skulle vi göra de mörkare delarna av smuts ogenomskinliga, medan de vita områdena var transparenta. Detta är möjligt med hjälp av blandningslägen.
Om du inte har använt blandningslägen före, kolla in den här introduktionen av Trent Sterling. Kortfattat definierar ett blandningsläge hur två bilder samlas ihop när man läggs ovanpå varandra.
det blandningsläge vi ska ansöka kallas MÖRKNA
. Tänk på det på så vis: för varje pixel jämför Flash den här pixelens färg från de två bilderna och visar vilken som är den mörkaste (dvs. den som ligger längst bort från ren vit). Så här ser det ut om vi lägger den röda smutsen ovanpå Envato-tecknet och tillämpar blandningsläget:
Jämför det med den ursprungliga skyltbilden:
De mörka blues och greenerna i tecknet räknas som mörkare än smutsens djupa röda, och så visas genom. Kornets kornighet leder till den spännande effekten på den blandade bilden.
Hur skriver vi koden för detta? Det är enkelt, faktiskt:
paket im