Bygg en effektiv Flash DecalSheet System

Build en effektiv Flash DecalSheet System
Del
Del
Del
Del

Dette Cyber ​​mandag Envato Tuts + Kursene vil bli redusert til bare $ 3. Ikke gå glipp av

. Jeg kom opp med ideen om å lage det jeg kaller Flash DecalSheets fra klistremerkene som følger med modellfly og har brukt "dekor" å flå mine egne Flash-applikasjoner siden den gang. En DecalSheet er i utgangspunktet ett stort bilde (JPG, PNG eller GIF) som blir kuttet opp i mindre bilder som kalles 'dekor', som er punktgrafikk og kan brukes hvor som helst DisplayObjects vanligvis ville bli brukt.

Denne teknikken er en av de mest effektive måter å bringe massevis av eiendeler i en Flash-applikasjonen uten å stole på biblioteket (hvis du bruker Flash IDE) eller Embed koden (hvis du bruker Flex Compiler). La oss ta en titt på hvordan å gjøre en enkel DecalSheet system.


Med DecalSheets, kan du redusere programmets minne fotavtrykk ved å konsolidere mindre bilder i større bilder. Enhver grafikken du vil bygge inn i en klasse eller sted i en FLA bibliotek kan lagres i en enkelt DecalSheet eller de kan være spredt over flere DecalSheets, avhengig av dine behov. Siden DecalSheets kan settes opp til å bare belastning når bedt om, kan du laste inn program grafikk akkurat når du trenger dem, kutte ned på første oppstart og lastetid. Til slutt kan du Reskin hele din søknad ved å endre BitmapData av dine DecalSheets under kjøring.

Dette diagrammet illustrerer hvordan vi ta et enkelt DecalSheet bilde og bruk koordinerer å kutte ut en ny Skjorte barn.
< p> I denne opplæringen skal vi lage 2 klasser: den DecalSheet og Skjorte barn. Du definerer X, Y, Bredde og Høyde-koordinater for å kutte ut grafikk fra DecalSheet og det vil returnere dekor. Dekaler er punktgrafikk og kan brukes hvor som helst DisplayObjects vil normalt bli brukt. Hva gjør dekor spesielle er at de beholder en henvisning til DecalSheet de blir kuttet ut fra. Når du oppdaterer BitmapData av DecalSheet, alle de dekor kuttet ut fra at arket vil også oppdatere. Dette gjør at du kan re-skin at hele programmet under kjøring ved ganske enkelt å laste inn nye kildebildene.

Følgende eksempel viser vår kilde DecalSheet til venstre, og en Simple på høyre med klistremerker for hver knapp stat . Når du klikker på knappen, er et nytt bilde som er lagt i og dens Bitmap data erstatter den opprinnelige huden i DecalSheet. Alle dekor i enkel knapp vil også oppdatere. Den re-skinning er nesten momentant

På slutten av opplæringen vil du ha følgende SWF:

decalpapiret Kilde Images

Før vi kommer i gang, må sikker på at du har følgende to bildene. Disse vil være våre DecalSheet kilder som vi vil bruke til å kutte ut knappe stater fra
button_skin_a.png
button_skin_b.png
Trinn 1:. Sette opp Doc Class

første vi skal gjøre er å lage vår hoved Doc klasse. Jeg har allerede satt opp en enkel klasse som vil laste inn et bilde og legge det til listen skjerm
pakke {import flash.display.Bitmap;. Import flash.display.Loader, import flash.display.Sprite; import flash .display.StageAlign, import flash.display.StageScaleMode, import flash.events.Event, import flash.net.URLRequest; public class DeaclSheetTutorial strekker Sprite {private Var loader: Loader; offentlig funksjon DeaclSheetTutorial () {configureStage (); loadDecalSheetSource ("images /button_skin_a.png"); } Private funksjon configureStage (): void {stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; } Offentlig funksjon loadDecalSheetSource (url: String): void {loader = new Loader (); loader.contentLoaderInfo.addEventListener (Event.COMPLETE, onImageLoad); loader.load (ny URLRequest (url)); } Private funksjon onImageLoad (hendelse: Hendelse): void {loader.removeEventListener (Event.COMPLETE, onImageLoad); Var bitmap: Bitmap = Bitmap (loader.content); addChild (bitmap); }}}

Når du kjører denne klassen bør du se vår button_skin_a.png som vises på scenen. Nå er vi klare til å begynne å lage vår DecalSheet

Trinn 2:. Opprette DecalSheet Class

DecalSheet forlenger Bitmap Class. Jeg har satt opp mine klasser i "com.flashartofwar" pakker, men du står fritt til å sette dem opp slik du vil. Opprett en ny klasse kalt DecalSheet og lim inn følgende kode:
pakke com.flashartofwar {import flash.display.BitmapData; import flash.display.Bitmap; public class DecalSheet strekker Bitmap {offentlig funksjon DecalSheet (bitmapData: BitmapData = null, pixelSnapping: String = "auto", glatting: Boolean = false) {super (bitmapData, pixelSnapping, glatting); }}}
Trinn 3: Testing av DecalSheet

Nå som vi har laget vår DecalSheet, la oss sørge for at den kan vise bilder. Vi kommer til å gjøre dette ved å sende i BitmapData av .png vi lastet tidligere. Gå tilbake til Doc klasse og erstatte linje 40, der vi kaller addChild, med følgende:
decalSheet = new DecalSheet (bitmap.bitmapData); addChild (decalSheet);

Vi er også nødt til å importere DecalSheet klasse på linje 3:
import com.flashartofwar.DecalSheet;

I tillegg til å sette opp en variabel for å redde vår DecalSheet på linje 16:
private Var decalSheet: DecalSheet;

Nå, når du kompilere, skal du se det samme bildet, men nå er det på innsiden av DecalSheet. La oss snakke om hvordan vi kan kutte disse grafikk ut

Trinn 4:. Lagring dekor i DecalSheet

På dette punktet har vi en enkel DecalSheet klasse som utvider Bitmap Class. Vårt mål er å være i stand til å definere områder av DecalSheet som kan klippes ut og omgjort til dekor. . Før vi kan registrere dekaler vi kommer til å trenge et sted å lagre dem

Legg følgende eiendom på linje 8:
beskyttet Var decalRectangles: ordbok = new ordbok (true);

Og import den dictonary klasse på linje 5:
import flash.utils.Dictionary;

Som du kan se denne dictonary kommer til å være stedet ble vi kan knytte en Decal største navnene med sine koordinater

Step. 5: Registrere dekor

I kjernen, en Skjorte barn er egentlig bare et navn og sin x, y, bredde og høyde verdier som vi bruker til å kutte ut BitmapData fra DecalSheet. Vi kommer denne informasjonen med følgende funksjon på linje 16.
offentlig funksjon registerDecal å registrere (navn: String, rektangel: rektangel): void {decalRectangles [navn] = rektangel;}

Nå kan du knytte en Overføringsbilde s cutout koordinater til et navn og et rektangel

Du må også importere rektangel klasse på linje 5:
import flash.geom.Rectangle;
Trinn 6:. DecalSheet prøve metoden Anmeldelser

Vi kommer til å legge den viktigste funksjonen til DeaclSheet, prøven () -metoden. Denne funksjonen er hva vi vil bruke til å kutte ut BitmapData fra DecalSheet for å skape våre dekaler. La oss sette følgende funksjon på linje 22 i DecalSheet Class
offentlig funksjon prøve (navn: String): BitmapData {var rect: rektangulært = decalRectangles [name];. //Gjelder riktig offset når prøvetaking data Var m: Matrix = new Matrix (); m.translate (-rect.x, -rect.y); //Oppretter ny BitmapData Var BMD: BitmapData = new BitmapData (rect.width, rect.height, sant, 0xFFFFFF); bmd.draw (bitmapData, m); returnere BMD;}

Også må du importere Matrix klasse på linje 5:
import flash.geom.Matrix;

Det er mye som skjer i denne funksjonen så la oss gå linje for linje gjennom . prosess
Var rect: rektangel = decalRectangles [name];

Her bruker vi passerte i Overføringsbilde navn for å slå opp den registrerte rektangel fra decalRectangles dictonary

Det neste vi skal lage. en matrise for å oppveie hvor vi smake på BitmapData fra
Var m: Matrix = new Matrix ();. m.translate (-rect.x, -rect.y);

Her bruker vi rektangel er X og Y posisjon til å skape den riktige prøven offset

Nå må vi lage en ny BitmapData å lagre. . vår cut-out
Var BMD: BitmapData = new BitmapData (rect.width, rect.height, sant, 0xFFFFFF);

Som du ser bruker vi rektangel bredde og høyde som de nye dimensjonene, sett gjennomsiktig parameter til sann, og gi den nye BitmapData en bakgrunnsfarge på 0xFFFFFF. Ved å sette gjennomsiktig å true og leverer en bakgrunnsfarge vil vi være i stand til riktig smake gjennomsiktige PNG-bilder som "button_skin" eksempler vi legger i.

Til slutt må vi trekke DecalSheets BitmapData inn i de nye BitmapData klasse eksempel, og bruke Matrix
bmd.draw (bitmapData, m);

Nå har vi vår komposittert bitmapData og vi bare returnere den nye BitmapData eksempel

Trinn 7:.. Testing av prøven metode

Før vi går videre vi kommer til å ønske å gjøre noen enkle ting for å teste vår nye DecalSheet prøve metoden. La oss gå tilbake til vår Doc klasse og legge til følgende funksjon på linje 49 etter onImageLoad metode:
offentlig funksjon registerDecals (): void {decalSheet.registerDecal ("opp", ny rektangel (0,0,99,31) ); decalSheet.registerDecal ("ned", ny rektangel (0,32,99,31)); decalSheet.registerDecal ("over", ny rektangel (99,0,99,31));}

Her kan du se vi registrere hver av knappe landene vi kommer til å trenge senere når vi skaper vår Simple. Du må importere rektangel klasse på linje 11:
importere flash.geom.Rectangle;

... samt legge samtalen for registerDecals på linje 46, innsiden av onImageLoad funksjon etter at vi legger DecalSheet . til scenen
registerDecals ();

Nå har vi tenkt å lage en siste funksjon nederst i klassen vår, rundt linje 54:
offentlig funksjon decalSheetDemo (): void {var sampleBitmap: Bitmap = ny Bitmap (decalSheet.sample ("opp")); sampleBitmap.x = 230; addChild (sampleBitmap);}

Denne funksjonen vil være vår viktigste klargjøringsområdet for resten av demoen. Akkurat nå skaper vi en ny Bitmap fra DecalSheet er "opp" registeredDecal koordinater, offseting sin x posisjon og legge det til scenen.

Vi vil kalle denne funksjonen etter registerDecals kaller vi lagt til onImageLoad rundt linjen 46:
decalSheetDemo ();

Nå hvis vi gjør en kompilering, bør vi se vår DecalSheet bildet til venstre, og vår samplet Bitmap fra DecalSheet til høyre. Du kan teste ut alle de dekor ved å endre "opp" for "ned" eller "over". Nå har vi nok til å starte vår Overføringsbilde klasse

Trinn 8:. Opprette Overføringsbilde Class

Akkurat som DecalSheet vil Skjorte barn også forlenge Bitmap Class. Den Skjorte barn men vil ha en svært spesialisert formål og vil stole på DecalSheet å levere det BitmapData i stedet for at det føres inn i konstruktøren. Opprett en ny klasse kalt dekor med lim i følgende kode:
pakke com.flashartofwar {import flash.display.Bitmap; public class Skjorte barn strekker Bitmap {beskyttet Var decalSheetSrc: DecalSheet; offentlig funksjon Skjorte barn (navn: String, src: DecalSheet, pixelSnapping: String = "auto", glatting: Boolean = false) {super (null, pixelSnapping, glatting); //Lagre decalpapiret kilde. decalSheetSrc = src; //Lagre navn merket slik at vi kan prøve den fra DecalSheet. this.name = navn; //Få bitmap data fra DecalSheet src. forfriske(); } Offentlig funksjon refresh (): void {bitmapData = decalSheetSrc.sample (navn); }}}

Så hva er det som skjer? Som du kan se vi endrer konstruktør argumenter fra den opprinnelige BitmapClass tallet. Vår Skjorte barn kommer til å trenge å vite navnet sitt (vi bruker dette til å be BitmapData fra DecalSheet gjennom prøven metode), og vi trenger å vite src DecalSheet den Skjorte barn ble kuttet ut fra.

Går gjennom bygging prosessen, passerer vi i null til super s BitmapData eiendommen sammen med noen passerte i verdier for pixelMapping og glatting. Neste vi sparer en referanse av DecalSheet src i deaclSheetSrc eiendom. Vi deretter lagre vedtatt i navnet verdi i arvet navnet eiendommen fra BitmapData. Vi bruker "dette" å skille forskjellen mellom vedtatt i parameter og navnet parameter i Class eksempel. Endelig kaller vi refresh metoden.

Overføringsbilde oppdateringsmetode utfører en enkel oppgave. Det ber om nye BitmapData fra moder DecalSheet og setter det. Dette skaper visningen av Overføringsbilde. Bremsing ut logikken å be BitmapData fra den overordnede DecalSheet vil spille en viktig rolle senere når vi begynner å endre BitampData av DecalSheet

Trinn 9:. Retur dekor fra DecalSheet

Før vi kan teste at dekor fungerer, vil vi ønsker å legge til muligheten til å be om overføringsbilder etter navn fra DecalSheet og få den tilbake en Overføringsbilde eksempel. Vi kan gjøre dette ved å legge følgende funksjon i DecalSheet etter registerDecal metoden rundt linje 21:
offentlig funksjon getDecal (navn: String): Overføringsbilde {return decalRectangles [navn]? ny Overføringsbilde (navn, dette): null;}

Nå kan vi be dekor fra DecalSheet ved ganske enkelt å føre inn navnet på eventuelle registrerte dekor. Du vil merke dette short-hand betinget. I utgangspunktet er det første elementet hva vi skal teste. I dette tilfellet ønsker vi å vite om den medfølgende navnet er registrert med decalRectangles dictonary. De ? betegner hva som skjer hvis den finnes. Her skaper vi en ny Skjorte barn, gi den samme navn som ble ført inn i getDecal funksjon og levere en referanse til DecalSheet forekomst (denne) til Skjorte barn. The: betegner hva som skjer hvis den medfølgende navn ikke ble funnet på deacalRectangles dictonary. Vi bare returnere null. La oss teste dette for å kontrollere at alt fungerer

Trinn 10:. Testing av DecalSheet og Overføringsbilde

Vi er nå klar til å teste vår Skjorte barn. For å gjøre dette vil vi flytte tilbake over til Doc klasse og erstatte decalSheetDemo metode med følgende kode:
offentlig funksjon decalSheetDemo (): void {var upDecal: Skjorte barn = decalSheet.getDecal ("opp"); upDecal.x = 230; addChild (upDecal);}

Vi må også importere merket klasse på linje 3:
import com.flashartofwar.Decal;

Hvis du kompilere klassen skal du se Skjorte barn på høyre side av den DecalSheet eksempel den ble kuttet ut fra. Så, hva er så farlig? Vi hadde det samme 4 trinn siden med mindre kode. Vel, la meg forklare hvorfor dette er en effektiv måte å bringe eiendeler inn i Flash app.

Tenk deg at du har et fotogalleri. Hva om du hadde mange områder alle bruker samme bildegalleriet, men du trenger å merke hver bildegalleri basert på det enkelte området det var å være vert på. Avhengig av hvordan du lager din bildegalleri kan du velge å opprette en SWF med hver knapp som et element i biblioteket med en kobling ID. Eller du kan laste hvert enkelt bilde en av gangen under kjøring. I lang tid jeg brukte begge veier, men alltid funnet det begrensende å vente for en stor SWF å laste opp eller mange mindre bilder å laste inn før jeg kom opp med DecalSheet system.

Nå vil jeg bare gjøre en DeaclSheet bilde, definere koordinatene for hver knapp og jeg bare nødt til å administrere ett bilde og noen kuttet ut data. Jeg pleier å sette kuttet ut koordinatene i en XML-fil, og nå kan jeg levere bildet til en designer som kan vite noe om Flash, men kan lage et nytt tema lett fra en PSD mal. Jeg vet dette høres ut som en one-off eksempel, men jeg bruker dette systemet i alle Flash nettstedet jeg bygge. Vi har ikke engang rørt på den kuleste funksjonen enda!

Hva skjer hvis du må re-skin et program på fly? Du må laste alle bildene og skape nye klasse forekomster eller bygge logikk inn dine komponenter for å være i stand til å få nye midler til å gjenoppbygge seg selv. Re-skinning en Flash app bygget med dekor er så enkelt som å endre BitmapData av DeaclSheet. La meg vise deg hvordan

Trinn 11:. Endre DecalSheet BitmapData

Vi kommer til å trenge en måte å fortelle alle de dekor kuttet ut fra et DecalSheet at BitmapData har blitt endret, og de må re-samplet. Vi kan gjøre dette enkelt ved å overstyre sett bitmapData metoden i DecalSheet. Legg til følgende metode under DecalSheet konstruktør on line 17:
styre offentlig funksjon satt bitmapData (verdi: BitmapData): void {super.bitmapData = verdi; dispatchEvent (ny hendelse (Event.CHANGE));}

... sammen med en import statement for Event på linje 5:
import flash.events.Event;

Nå som en ny hendelse blir sendt når den BitmapData av DecalSheet endres, vi må lytte til dette i Overføringsbilde Class

Trinn 12:. Lytte etter DecalSheet Hendelser

Nå som DecalSheet Dispatches en endring hendelse når sin BitmapData er oppdatert, kan vi ha Overføringsbilde lytte etter disse hendelsene og resample sin egen BitmapData fra DecalSheet. La oss legge til følgende 3 metoder i Overføringsbilde klassen under oppdateringsfunksjonen på linje 27:
beskyttet funksjons addListeners (mål: IEventDispatcher): void {target.addEventListener (Event.CHANGE, onChange, falsk, 0, true);} beskyttede funksjons removeListeners (mål: IEventDispatcher): void {target.removeEventListener (Event.CHANGE, onChange);} beskyttet funksjon onChange (hendelse: Hendelse): void {refresh ();}

Vi har også importere IEventDispatcher og Arrangement klasser på linje 4:
import flash.events.Event, import flash.events.IEventDispatcher;

Til slutt vil vi må søke lytteren til Overføringsbilde moder DecalSheet ved å legge til følgende kode på slutten av konstruktøren på linje 23 av konstruktøren:
addListeners (SRC);

Før vi går videre, vil jeg gjerne forklare hvorfor jeg bryte opp med å legge til og fjerne hendelsen lyttere i separate funksjoner. Når jeg opprette klasser jeg prøver å tenke på hvordan jeg vil forlenge ut av dem, og også hvordan jeg kan bryte opp logikken i de minste mulige stykker. Disse 3 funksjoner representerer en kjerne funksjon i dekor er trolig de viktigste vi noensinne vil endre når utvide denne klassen. Jeg prøver også å bruke grensesnitt når det er mulig. Jeg forklarer dette i mer detalj senere. Som du ser vi enkelt kan legge til og fjerne Endre hendelsen lyttere og vi kaller oppdatere når Overføringsbilde eksempel hører den aktuelle hendelsen. I neste trinn vil vi bygge vårt Simple og utforske denne nye funksjonaliteten

Trinn 13:. Opprette en Simple

La oss gå tilbake til Doc klasse og lage en Simple ved hjelp av alle de dekor vi registrert i DecalSheet. Nok en gang vi kommer til å erstatte decalSheetDemo funksjon med følgende kode:
offentlig funksjon decalSheetDemo (): void {var opp: Skjorte barn = decalSheet.getDecal ("opp"); Var igjen: Skjorte barn = decalSheet.getDecal ("over"); Var ned: Skjorte barn = decalSheet.getDecal ("ned"); Var MyButton: Simple = new Simple (opp, over, ned); myButton.useHandCursor = true; myButton.hitTestState = opp; myButton.x = 230; this.addChild (MyButton);}

Vi trenger også å importere Simple på linje 8:
import flash.display.SimpleButton;

Så nå setter vi opp hver av de dekor, skape en ny Simple tilfeller , og passerer i dekor til konstruktøren. Siden SimpeButton bruker DisplayObjects for hver stat, og våre dekor forlenger Bitmap Class, kan vi erstatte våre dekor overalt DisplayObjects brukes. Kompilere Doc klasse og sjekk ut knappen. Du vil se at opp, over og ned dekor vises når knappen endrer tilstand

Trinn 14:. Oppdatere DecalSheet sin BitmapData

Nå skal vi legge inn våre andre knappen hud " button_skin_b.png "og erstatte DecalSheet sin BitmapData. Siden dekaler lytter for Change hendelse fra DecalSheet, vil vi være i stand til å Reskin den Simple uten å endre en enkelt eiendom på den.

Dette diagrammet viser hvordan ved å endre BitmapData av DecalSheet kan vi kringkaste en hendelsen til alle barn dekor å resample

La oss komme i gang ved å legge inn følgende hendelse lytteren til knappen på linje 72 av Doc klasse etter at vi legger på knappen til listevisning.
myButton.addEventListener (MouseEvent.CLICK, onClick);

Når det er på plass la oss legge til følgende tre metodene nedenfor decalSheetDemo funksjon:
privat funksjon onClick (event: MouseEvent): void {loadBlueSkin ("images /button_skin_b.png") } private funksjon loadBlueSkin (url: String): void {loader = new Loader (); loader.contentLoaderInfo.addEventListener (Event.COMPLETE, onBlueSkinLoaded); loader.load (ny URLRequest (url));} private funksjon onBlueSkinLoaded (hendelse: Hendelse): void {loader.removeEventListener (Event.COMPLETE, onImageLoad); Var bitmap: Bitmap = Bitmap (loader.content); decalSheet.bitmapData = bitmap.bitmapData;}

Til slutt vil vi trenger å importere MouseEvent on line 13:
import flash.events.MouseEvent;

Hva vi har gjort her er lagt til en Klikk hendelse lytteren til Simple. Når vi hører klikket begynner vi å laste inn den nye huden. Når huden er lastet, vi skriver loader innhold som Bitmap og passere sine BitmapData inn i DecalSheet sin bitmapData setter. Når du kjører dette nå og klikk på knappen vil du umiddelbart se Simple hud og DecalSheet bli oppdatert til det nye bildet. Endringen-over er momentant!

Nå har du sett hvordan vi skaper en DecalSheet, registrer dekor, får dekor og huden en Simple. Vi går også til Reskin knappen ved kjøring ved ganske enkelt å laste inn en ny grafisk. Som dekker om kraften i å bruke dekor til huden din Flash app. Følgende trinn rett og slett rydde opp i koden vi har skrevet og legge til litt ekstra funksjonalitet for å hjelpe kjøtt-ut DecalSheet system

Trinn 15:. Slett Overføringsbilde

Vi kan ikke bare la vår DecalSheet uten evne til å slette dekaler vi har registrert, så la oss legge i en deleteDecal metode etter registerDecal metode:
offentlig funksjon deleteDecal (navn: String): Boolean {return slette decalRectangles [name];}
Trinn 16: Få Registrerte Decal Names

Det ville trolig være nyttig å få en liste over alle de registrerte Decal navn fra en DecalSheet så la oss legge i Array å lagre bare de Decal navn. Vi må legge til følgende eiendommen etter decalRectangles rundt linje 13:
offentlige Var decalNames: Array = new Array ();

Og erstatte registerDecal og deleteDecal metoder med følgende funksjoner:
offentlig funksjon registerDecal ( navn: String, rektangel: rektangel): void {decalRectangles [navn] = rektangel; decalNames.push (navn);} offentlig funksjon deleteDecal (navn: String): Boolean {var index: Number = decalNames.indexOf (navn); if (! index = -1) decalNames.splice (indeks, 1); returnere slette decalRectangles [name];}

Vi kan teste dette ved å kjøre følgende i Doc Klasse:
spore ("klistremerker", decalSheet.decalNames); decalSheet.deleteDecal ("ned"); trace (" Gjenværende dekor ", decalSheet.decalNames);
Trinn 17: Ta en Skjorte barn fra DecalSheet

Forbindelsen mellom dekor med moder DecalSheet er utrolig kraftig, men noen ganger vi ønsker dekor å være litt mer selvstendig . Det er derfor vi kommer til å legge en løsne metode til Overføringsbilde klasse etter onChange metode:
offentlig funksjon løsne (): void {removeListeners (decalSheetSrc); decalSheetSrc = null;}

Når løsne metoden kalles, fjerner vi hendelses lyttere samt null ut referansen til DecalSheet src. Dette kobler helt noe forhold til den overordnede DecalSheet

Trinn 18:. Opprette en DecalSheet Interface

En av de grunnleggende begreper i bygningen OO (objektorientert) kode og design mønstre er å "Program for å en Interface, ikke en implementering ". Dessverre, for å fullt ut forklare dette konseptet er ute av omfanget av denne opplæringen, men som likevel betyr ikke at vi ikke kan prøve å innpode noen beste praksis. Hvis du aldri har brukt grensesnitt før de er svært enkle. Alt et grensesnitt gjør er å definere et sett av offentlige funksjoner en klasse må inneholde. Så, i vår DecalSheet system har vi tenkt å lage en IDecalSheet grensesnitt og skriver vår dekor som det. Dette vil holde våre dekaler løst koplet til DecalSheet og sikrer at mest mulig av fleksibilitet når utvide vårt system.

For å komme i gang trenger vi å opprette en ny Interface i samme pakke som våre DecalSheet og Decal Classes. Her er strukturen i Interface:
pakke com.flashartofwar {import flash.display.BitmapData; import flash.display.IBitmapDrawable; import flash.events.IEventDispatcher; import flash.geom.Rectangle; felles grensesnitt IDecalSheet strekker IBitmapDrawable, IEventDispatcher {funksjon registerDecal (navn: String, rektangel: rektangel): void; fungere deleteDecal (navn: String): Boolean; fungere getDecal (navn: String): Overføringsbilde; funksjonsprøve (navn: String): BitmapData; }}

Så i vårt grensesnitt er vi definere de mest brukte offentlige funksjoner som utgjør vår DecalSheet. Også ta oppmerksom på at selv vår Interface kan forlenge andre grensesnitt. Vi kommer til å utvide IBitmapDrawable og IEventDispatcher. Dette vil tillate vår DecalSheet å gjøre de samme oppgavene som Bitmap klasse, og vi vil være i stand til å sende og lytte til hendelser fra den.

Nå må vi fortelle DecalSheet å implementere dette grensesnittet. Gå inn i DecalSheet klasse og erstatte klassedefinisjonen rundt linje 10 med følgende:
public class DecalSheet strekker Bitmap implementerer IDecalSheet

Hvis Interface er i samme pakke som DecalSheet du trenger ikke å bekymre deg for å importere den IDecalSheet grensesnitt.

Neste vi må implementere grensesnittet i vår Overføringsbilde Class. Hvor vi bruker den type DecalSheet, vil vi ønsker å erstatte den med IDecalSheet:

Rundt linje 9:
beskyttet Var decalSheetSrc: IDecalSheet;

Rundt linje 11:
offentlig funksjon Overføringsbilde (navn : String, src: IDecalSheet, pixelSnapping: String = "auto", glatting: Boolean = false)

Rundt linje 32:
beskyttet funksjons addListeners (mål: IDecalSheet): void

Rundt linje 37:
beskyttede funksjons removeListeners (mål: IDecalSheet): void

Nå er vår Skjorte barn er helt tastet til DecalSheet grensesnitt i stedet for selve Class. Vi har også håndhevet at enhver klasse som ønsker å bruke Overføringsbilde klasse må implementere alle de samme offentlige funksjoner som DeccalSheet

Trinn 19:. Clear dekor fra DecalSheet

Den siste funksjonen vi vil legge til er muligheten til å tømme en DecalSheet av dekor og koble noen instansiert Skjorte barn som er knyttet til DecalSheet. For å komme i gang la oss legge til følgende metode til DecalSheet:
offentlig funksjon klart (): void {dispatchEvent (ny hendelse (Event.DEACTIVATE, true, true)); decalRectangles = new ordbok (true); decalNames = new Array ();}

Nå når vi kaller den klare metoden på DecalSheet vi sende en Deaktiver Event og fjerne dictonary og Array. Nå må vi legge til en hendelse lytteren til Skjorte barn. I Decal Class erstatte addListeners og removeListeners funksjon med følgende:
beskyttet funksjons addListeners (mål: IDecalSheet): void {target.addEventListener (Event.CHANGE, onChange, falsk, 0, true); target.addEventListener (Event.DEACTIVATE, onDeactivate);} beskyttet funksjons removeListeners (mål: IDecalSheet): void {target.removeEventListener (Event.CHANGE, onChange); target.removeEventListener (Event.DEACTIVATE, onDeactivate);}

Vi må også legge til følgende metode etter onChange funksjon:
beskyttet funksjon onDeactivate (hendelse: Hendelse): void {event.stopPropagation (); løsne ();}

Vi kan teste at alle dekor har blitt frakoblet ved å ringe klart metoden på DecalSheet og deretter prøver å endre DecalSheet sin BitmapData. Du vil se at dekor ikke lenger oppdatere seg

Trinn 20:. Utvide DecalSheet System

Det er mange muligheter for å utvide DecalSheet system. En interessant spinoff er å gjøre Textfield DecalSheet. Du kan enkelt lage en DecalSheet klasse som implementerer IDecalSheet Interface men i stedet for å bruke BitmapData vil i stedet ta en Textfield og bryte det ned i dekor. Ved å bruke TextLineMetrics kan dekor lages ved å gå linje for linje ned en Textfield eller tegn for tegn. Dette er en flott måte å flytte teksten rundt på skjermen og unngå forvrengning deg en gang finne når du flytter animere Dynamic textfields.

PaperVision er også en annen utmerket sted å bruke DecalSheets. Tenk å kunne oppdatere en 3D-modell på fly! Ved å sette klistremerker som teksturer kan du oppdatere DecalSheet sin BitmapData å endre bildet av 3D-modeller.

The End!

Dette var en forenklet versjon av DecalSheet systemet som finnes i Flash camoflauge, en grafikk rammeverk som jeg skrev. Jeg har brukt denne teknikken i mine egne prosjekter i over et år nå, og tror ikke jeg kan leve uten. Jeg håper du liker den så mye som jeg gjør!

Last ned tutorial Actionscript-fil