Carve opp en video i sanntid med AS3
Del
Del
4
Del
Denne Cyber Monday Envato Tuts + kurs vil bli redusert til bare $ 3. Ikke gå glipp av.
Hei, kode freaks! Denne veiledningen vil vise deg hvordan du kan dele en video som spilles inn i blokker som om det har eksplodert. Og alt dette med bare Actionscript. For denne opplæringen vil vi bruke kameraet som videokilde, slik at du kan se endringene bor.
Endelig resultat Forhåndsvisning
La oss ta en titt på det endelige resultatet vil vi jobbe mot:
Klikk og dra en blokk for å flytte det rundt på skjermen! (Kamera-tilgang kreves.)
Trinn 1: Setup - IDE
For denne opplæringen vi skal bruke FlashDevelop IDE (selv om du kan bruke en hvilken som helst AS3 editor). I tilfelle du ikke har det, og ønsker å prøve, kan du ta det herfra. En grunnleggende opplæringen på å sette opp FlashDevelop på deg maskinen finner du her.
Også hvis du har Flash Professional installert på din side, vil det fungere også. Alt du trenger å gjøre er å opprette en ekstern klasse fil som nevnt nedenfor, og koble den til Flash prosjektet som et dokument klasse.
Det setter opp vårt arbeidsmiljø.
Trinn 2 .: Setup - Nytt prosjekt
Opprett en ny AS3 prosjekt i FlashDevelop
Når det er gjort, vil du ha en hovedklasse opprettet i src mappen som sett i det høyre panelet:
Trinn 3: Oppsett -Den største klassen
Neste vi trenger å gjøre Main.as registrere en litt renere ved å eliminere noen kode. Utgangspunktet når du åpner Main.as filen, ville det ha kode noe sånt som dette:
pakke {import flash.display.Sprite; import flash.events.Event; public class Hoved strekker Sprite {offentlig funksjon main (): void {if (scene) init (); annet addEventListener (Event.ADDED_TO_STAGE, init); } Private funksjon init (e: Hendelses = null): void {removeEventListener (Event.ADDED_TO_STAGE, init); //Inngangspunkt}}}
Vi vil slette en del av koden slik at den ser renere. Så du bør ha denne:
pakke {import flash.display.Sprite; import flash.events.Event; public class Hoved strekker Sprite {offentlig funksjon main (): void {}}}
Nå er hele oppsettet gjort, og det er på tide å dykke inn noen kode
Trinn 4:. forkynner video og kamera variabler
Vårt første mål er å trekke videoen på scenen ved hjelp av kamera; Til dette trenger vi å erklære noen variabler. Sett disse erklæringene like over hoved klassen konstruktør
//video variablesprivate Var camW: int = 300; privat Var CAMH: int = 300; privat Var video: Video;
camW - Bredden på kamera /video. .
CAMH - Høyden på kamera /video. .
video - Vår Video klassen forekomst
Trinn 5: Forbered Device Camera
Som nevnt før, vil vi bruke kameraet utgang i videoen. Så først må vi gjøre enheten kameraet klart. Følgende kode bør gå inn i klassen konstruktør
Var kamera. Kamera = Camera.getCamera ();
Her instantiate vi et kamera forekomst og få den tilgjengelig enhet kameraet ved hjelp av statiske metoden getCamera () på kameraet . klasse
camera.setMode (camW, CAMH, 30);
Vi gir noen kamerainnstillinger: bredde, høyde og fps
Merk at vi ikke gjør kameraet variabel global fordi vi aner. t trenger tilgang til den hvor som helst utenfor denne funksjonen, så vil du se neste. I neste trinn initial vi videoen variable
Trinn 6:.! Egentlig Opprett Video
video = new Video (camW, CAMH); video.attachCamera (kamera);
Vi har nå startes videoen variable og brukt attachCamera () metode for å feste kameraet til det. Dette betyr at nå videoen bruker kameraet utgang som sin kilde.
Alle gjort med video og kamera stuff. Husk, du må importere aktuelle klassene i koden. Din komplette klassekoden skal se slik ut i øyeblikket:
pakke {import flash.display.Sprite; import flash.events.Event; import flash.media.Camera; import flash.media.Video; public class Hoved strekker Sprite {//video variabler privat Var camW: int = 300; private Var CAMH: int = 300; private Var video: Video; offentlig funksjon main (): void {var kamera: Camera = Camera.getCamera (); camera.setMode (camW, CAMH, 30); video = new Video (camW, CAMH); video.attachCamera (kamera); }}}
Hvis du kjører (F5 eller CTRL + Enter) prosjektet akkurat nå, ville det være tomt scenen, men du vil sannsynligvis få et kamera tilgangsforespørsel som programmet prøver å få tilgang til enheten kameraet. Tillater det.
Grunnen til at du ikke ser noe er fordi vi ikke ønsker å vise video og så vi havn't lagt det til scenen (display liste). Det vil bli bare brukes som en kilde til våre separate blokker. Hvis du ønsker å teste at alt fungerer fint, bare legge til følgende linje på slutten i hoved konstruktør:
addChild (video); //Gjør fjerne denne linjen etter å ha testet
Trinn 7: Erklærte Blokker Variabler
Nå skaper vi blokkene - de separate peices av videoen. Og det første trinnet er å erklære noen variabler som kreves for det. Så gå videre og legge opp følgende variabeldeklarasjoner rett under video variabler:
//blokk variablesprivate Var rekker: int = 3; private Var Cols: int = 3; privat Var blockW: int = camW /Cols; privat Div blockH: int = CAMH /rader, privat Var PointCollection: Object = new Object ();
pinner - Antall rader for å dele videoen i
cols - Ja.. Du fikk det. Antall kolonner for å dele videoen i
blockW -. Hver blokk bredde. Dette er en avledet variabler som det er bare beregnet ved å dele den totale bredden (camW) etter antall søyler (kolonner)
blockH -.. Hver blokk høyde dvs. CAMH dividert med rader
PointCollection - Slutt men viktigste variabelen. Det er en assosiativ array som vi skal bruke til å lagre tilsvarende punkt for hver blokk. For eksempel, hvis en blokk har navn block12, så ville vi lagre den tilsvarende punkt p12 som dette:
PointCollection ["block12"] = p12; //Poeng er Point klasse tilfeller her
Trinn 8: begynne å tjene blokkene
Nå som vi har de nødvendige variablene definert, vi faktisk begynne å lage blokkene. Vi kommer til å holde alle blokk skapelsen kode i en funksjon kalt initBlocks (). Denne funksjonen skal kalles fra hoved konstruktør etter innstilling av video
Så, la oss først erklære en funksjon som heter initBlocks () rett etter hoved konstruktør
privat funksjons initBlocks ():.. Void {for ( var r: int = 0; r < p; r ++) {for (VAR c: int = 0; c < kolonner; c ++) {//kode for å lage hver blokk}}}
Legg merke til de to for sløyfer vi har plassert på innsiden, noe som vil hjelpe oss å lage blokkene i et 2D grid, rad-klok. Og deretter legge et kall til denne funksjonen på slutten av main ():
offentlig funksjon main (): void {var kamera: Camera = Camera.getCamera (); camera.setMode (camW, CAMH, 30); video = new Video (camW, CAMH); video.attachCamera (kamera); initBlocks ();}
Trinn 9: Komponenter i en blokk
Før du oppretter blokkene, la oss forstå hva en enkelt blokk består av. Hver blokk er faktisk:
En Sprite
med en Bitmap inni den
som igjen trenger en BitmapData
Tenk på sprite som det ytterste container. Helt blank.
Hvis du vil tegne blokken, trenger vi en Bitmap som vil vise den tilsvarende videoutgangen.
Og til slutt, må hver Bitmap noen data å trekke inni den. Som er gitt i form av BitmapData
Trinn 10: Lag Block Base - Sprite
Den første komponenten i en blokk, som vi snakket om, er en Sprite.. Så kan opprette en. All kode som vi skriver for å skape blokken skal skrives inne i for løkker
Var newBlock: Sprite = new Sprite ();
Vi skaper en ny forekomst av Sprite klasse
newBlock... name = "blokk" + r + c;
Så vi nevne sprite slik at vi kan referere til den senere i koden. Navnekonvensjonen er enkel: en blokk rad r og kolonne c på er oppkalt blokk + r + c (+ betyr sammensetning). Så en blokk på rad 2 og kolonne 1 er oppkalt block21
Trinn 11:. Plassere det
Etter å ha skapt det, må vi plassere den på scenen etter sin rad og kolonne. Så kan du legge til følgende kode
Var p: Point = new Point (c * blockW, r * blockH);
Vi bruker en Point klasse objekt til å lagre noen punkt er koordinater her.. Og så skaper vi en ny forekomst av Point og passere c * blockW som x-verdi og r * blockH som y-verdi. Nå kan nås av koordinatene bare som px og py og brukes senere til å hente hver blokk er clippped region fra et komplett videoramme. Husk hver blokk poeng er faktisk koordinatene for øverste venstre punkt i nettet.
Hvis du har en tvil om hvordan stillingen er beregnet her, vil figuren gjøre det klart. Anmeldelser newBlock.x = c * (blockW + 1) + 20; newBlock.y = r * (blockH + 1) + 20;
Neste, vi plassere sprite. De cordinates er mer eller mindre det samme forventer nå vi legge til 20 for å gi en offset. Også vi legger en til blockW og blockH å skille blokkene ved en piksel, som er synlig i demoen ovenfor
PointCollection [newBlock.name] = p;.
Til slutt, sparer vi det punktet vi tidligere beregnet i den PointCollection
Trinn 12:. Legge til Bitmap til Block
Nå, kommer til andre og tredje del av blokk
Var bmpd:. BitmapData = nye BitmapData (blockW, blockH);
Først lager vi en BitmapData forekomst og passerer den nødvendige blokken bredde og høyde som vi hadde lagret før. Som omtalt tidligere, er en BitmapData eksempel kreves for å skape et Bitmap forekomst som er vedtatt i konstruktøren
Var bmp. Bitmap = new Bitmap (bmpd); bmp.name = "myBmp";
Nå skaper vi en Bitmap forekomst og passere tidligere opprettet bmpd i konstruktøren. Også vi kalle bitmap myBmp slik at vi kan referere til den senere
newBlock.addChild (bmp),. AddChild (newBlock);
Til slutt legger vi bitmap bmp som et barn av newBlock og newBlock seg som den . barn av scenen
Bare for å være sikker på at du er på rett spor, din Main.as koden skal se omtrent slik ut:
pakke {import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Sprite; import flash.geom.Point; import flash.media.Camera; import flash.media.Video; public class Hoved strekker Sprite {//video variabler privat Var camW: int = 300; private Var CAMH: int = 300; private Var video: Video; //Blokk variabler private Var rader: int = 3; private Var kolonner: int = 3; private Var blockW: int = camW /kolonner; private Var blockH: int = CAMH /rader; private Var PointCollection: Array = new Array (); offentlig funksjon main (): void {var kamera: Camera = Camera.getCamera (); camera.setMode (camW, CAMH, 30); video = new Video (camW, CAMH); video.attachCamera (kamera); initBlocks (); } Private funksjon initBlocks (): void {for (var r: int = 0; r < p; r ++) {for (VAR c: int = 0; c < kolonner; c ++) {var newBlock: Sprite = new Sprite (); newBlock.name = "blokk" + r + c; Var p: Point = new Point (c * blockW, r * blockH); newBlock.x = c * (blockW + 1) + 20; newBlock.y = r * (blockH + 1) + 20; PointCollection [newBlock.name] = p; Var bmpd: BitmapData = new BitmapData (blockW, blockH); Var bmp: Bitmap = new Bitmap (bmpd); bmp.name = "myBmp"; newBlock.addChild (bmp); addChild (newBlock); }}}}}
Trinn 13: Oppdatere Blocks - Concept
Selv om vi har de blokker plassert i de riktige posisjonene, vi fortsatt ikke ser noe på å drive prosjektet. Det er fordi vi fortsatt havn't trukket noe inne i blokken bitmaps
Vårt neste skritt er å kjøre en konstant-kjører løkke som utfører følgende operasjoner:.
- Et rektangulært objekt som angir øvre venstre punkt, bredde og kolonne i regionen i kilden som skal kopieres.
Poenget i destnation der klippet delen er å bli kopiert. (0,0) i dette tilfellet. Så vi bare passere en ny Point objekt.
Alle Ferdig! Nå er det på tide å kjøre prosjektet og se den utrolige effekten
Trinn 18:. Legge Dra-og-slipp-funksjonalitet
For å legge til dra-og-slipp-funksjonen som sett i demoen, vi trenger bare å feste to muse lyttere til hver blokk - en for MOUSE_DOWN hendelse og en annen for MOUSE_UP hendelsen. Så gå videre og definere to muse handler funksjoner på slutten av klassen:
privat funksjon onMouseDown (e: MouseEvent): void {Sprite (e.currentTarget) .startDrag ();} private funksjon onMouseUp (e: MouseEvent) : void {Sprite (e.currentTarget) .stopDrag ();}Alt vi gjør innenfor disse lytter funksjoner er å få henvisning til event-utsending blokk med currentTarget eiendom hendelsesobjektet, typecast den til en Sprite ( som det er hva våre blokker er) og kaller startdrag () og stopdrag () for å håndtere dra-og-slipp.
Det er litt av alt ennå ikke. Vi trenger fortsatt å feste disse lytterne til deres tilsvarende hendelser. Så legge disse to linjene til de initBlocks ()
funksjon private funksjons initBlocks (): void {for. (Var r: int = 0; r < p; r ++) {for (var c: int = 0; c < kolonner; c ++) {var newBlock: Sprite = new Sprite (); newBlock.name = "blokk" + r + c; Var p: Point = new Point (c * blockW, r * blockH); newBlock.x = c * (blockW + 1) + 20; newBlock.y = r * (blockH + 1) + 20; PointCollection [newBlock.name] = p; Var bmpd: BitmapData = new BitmapData (blockW, blockH); Var bmp: Bitmap = new Bitmap (bmpd); bmp.name = "myBmp"; newBlock.addChild (bmp); addChild (newBlock); newBlock.addEventListener (MouseEvent.MOUSE_DOWN, onMouseDown); newBlock.addEventListener (MouseEvent.MOUSE_UP, onMouseUp); }}}
Trinn 19: Final Touch
En siste ting bare for å gjøre det ser mer interaktiv. Du har kanskje lagt merke til hvordan blokkene tones inn og ut når trykket og utgitt. Det er en alpha manipulasjon vi gjøre inne lytterne. Endre lytterne til noe sånt som:
privat funksjon onMouseDown (e: MouseEvent): void {Sprite (e.currentTarget) a = 0,4; Sprite (e.currentTarget) .startDrag ();} private funksjon onMouseUp (e: MouseEvent): void {Sprite (e.currentTarget) a = 1; Sprite (e.currentTarget) .stopDrag ();}Og det du har alfa overgangseffekt
Konklusjon
Den effekten har et stort potensial til å bli brukt i ulike applikasjoner. . Jeg har vært å utvikle et puslespill nylig å bruke det.
Bortsett fra det, kan det brukes til å lage overgangseffekter for video-spillere, eller i conjuction med 3D å tekstur en overflate med en video.
< p> Jeg håper å se noen kule ting folk kommer opp med å bruke denne effekten! Anmeldelser
Få dagens video rammen.
Loop gjennom alle blokkene.
Hent hver blokk synspunkt og bitmap barn.
Tegn den tilsvarende delen av videobildet på blokken sin bitmap. Anmeldelser
Så ... la oss gjøre det!
Før implementering løkken kode, det vi trenger er en LOOP FUNKSJON (type som et spill loop). Legg til følgende funksjon erklæring under initBlocks () -funksjonen:
private funksjons updateBlocks (e: Hendelses): void {}
Som er synlig fra funksjonen parameter, virker det som en hendelse lytteren og ja det er. Dette er en lytter funksjon som vi vil legge til ENTER_FRAME ved scenen. For å feste lytteren Legg til denne linjen på slutten av Main () konstruktør
offentlig funksjon main (): void {var kamera: Camera = Camera.getCamera ();. camera.setMode (camW, CAMH, 30); video = new Video (camW, CAMH); video.attachCamera (kamera); initBlocks (); addEventListener (Event.ENTER_FRAME, updateBlocks);}
Trinn 14: Capture Frame
Dette er den første operasjonen som vi utfører i loop - de updateBlocks () funksjon som kalles på hver ramme. Sett inn følgende kode inne updateBlocks () -funksjonen
Var srcBmpd. BitmapData = new BitmapData (camW, CAMH);
Hver bitmap data i Actionscript 3.0 trenger å ligge i en BitmapData forekomst og så skaper vi en. Vi vil fylle dette tilfellet med dagens video rammedata neste
srcBmpd.draw (video);.
Her har vi brukt uavgjort () funksjon av BitmapData klassen. Det krever et formål med enhver klasse som implementerer IBitmapDrawable grensesnitt. For eg. Sprite, MovieClip, BitmapData etc. Hva den gjør er rett og slett ta den visuelle data av objektet gått og lagrer den i BitmapData eksempel.
Så nå har vi dagens videobilde (eller, kan du si, en skjermbilde) i variabelen srcBmpd
Trinn 15:. La oss Loop
Som vi trenger å oppdatere hver blokk, skaper vi en dobbel for-løkke, lik den vi skrev for å lage blokkene . Så gå videre og legge det
Funksjonen bør ligne på dette akkurat nå:
private funksjons updateBlocks (e: Hendelses): void {var srcBmpd. BitmapData = new BitmapData (camW, CAMH); srcBmpd.draw (video); for (var r: int = 0; r < p; r ++) {for (VAR c: int = 0; c < kolonner; c ++) {//oppdatering kode her}}}
Trinn 16: Hent den Block er Bitmap og Point
Husk at vi har navngitt blokkene på en bestemt måte mens du oppretter dem slik at vi kunne referere noen blokk med sin rad og kolonnenummer. Det er det vi skal bruke nå for å få hver blokk referanse
Var b_mc: Sprite = this.getChildByName ("block" + r + c) som Sprite;
Vi bruker getChildByName funksjon av scenen (dette. ) som returnerer en referanse til et objekt hvis navn matcher strengen passert. Også vi typecast det til Sprite klassen bare for å være sikker på at det returnerte objektet er en Sprite. Nå blokken referanse er i variabelen b_mc
Var bmp: Bitmap = b_mc.getChildByName ("myBmp") som Bitmap;
På samme måte, hente vi referansen til bitmap som ble lagt til som en. barn av blokken sprite
Var p: Point = PointCollection [b_mc.name];
Til slutt får vi den aktuelle blokken er (b_mc) koordinater fra tabellen der vi lagret den tidligere bruker blokken navn. .
Trinn 17: Tegn Det
Nå som vi har all nødvendig informasjon om hva du skal tegne hvor vi faktisk kan tegne det. Vårt motiv er å få den rektangulære område av videobildet (dvs. srcBmpd) med øverste venstre punkt som hentes punktet p, bredde som blockW og høyde som blockH.
For dette formålet bruker vi copyPixels () metoden i BitmapData klassen. . Den faktisk kopier regionens av en annen kilde BitmapData spesifisert ved å sende en rektangel objekt
bmp.bitmapData.copyPixels (srcBmpd, nytt rektangel (px, py, blockW, blockH), nytt punkt ());
Trekningen () funksjonen kalles på bmp sin bitmapData eiendom. Parametere som sendes inn i den er:
Kilden BitmapData obeject. Skjermbildet av video i dette tilfellet (srcBmpd).