Werken op Pixel-niveau met BitmapData en Away3D

Welkom bij deze introductie voor het werken op pixelniveau met het BitmapData-object van ActionScript 3. We nemen een aantal 2D-afbeeldingen, splitsen deze in hun componentpixels en assembleeren ze vervolgens als 3D-afbeeldingen die we kunnen verplaatsen en roteren.


Eindresultaat voorbeeld

Laten we eens kijken naar het eindresultaat waar we naartoe zullen werken:


Stap 1: instellen

Vlak voordat je gaat springen, nemen we even de tijd om te kijken hoe het voorbeeldproject is ingedeeld. Als u de bronrits voor deze zelfstudie opent, krijgt u bronnen voor elke belangrijke stap, kunt u meteen verdergaan en een kopie maken van de beginnen map omdat dit als ons startpunt zal dienen.

In deze map vindt u twee andere mappen; src en bak. De src map is waar we al onze code en FLA-bestanden zullen opslaan en de bak map is waar de Flash de SWF-bestanden opslaat. Binnen in de src map daar is de Main.FLA en de Main.AS documentklasse.

Als u om welke reden dan ook een fout in uw code aantreft, probeer het dan te repareren (altijd goed om te leren van fouten) maar als u zich dan geen zorgen kunt maken! U kunt meteen weer naar binnen springen en een van de stappenmappen in de bron-zip gebruiken die het dichtst bij de stap ligt waarop u zich bevond.


Stap 2: Download Away3D

Als je al een kijkje hebt genomen in de Main.as bestand zul je al een paar verwijzingen naar Away3D opmerken, een 3D-raamwerk voor Flash. We moeten dit downloaden en toevoegen aan ons project om door te gaan.

Je kunt hun nieuwste versie van de Away3D-site halen.

Nadat deze download is voltooid, opent u het zipbestand en in de away3d_3_6_0 \ src map vindt u drie mappen, Away3D, nochump en wumedia. Kopieer deze, zoals hieronder getoond, naar uw src map.


Stap 3: Het Flash-bestand

Als je dat nog niet hebt gedaan, open dan Main.fla en Main.as. Als u in de Flash-bibliotheek kijkt, ziet u een afbeelding met de naam 1.png en a Filmclip met een instantienaam van img1, die als basiscontainer voor de png zal dienen.

We gaan een snelle compilatie uitvoeren om er zeker van te zijn dat we Away3D correct hebben toegevoegd. Als alles goed gaat, zouden we een lege Flash-film met een donkergrijze achtergrond en geen foutmeldingen van Flash moeten zien.


Stap 4: Het Main.as-bestand

Het onderzoeken van de Main.as bestand kunnen we een paar variabelen zien die worden gebruikt in Away3D, er is al een heleboel tutorials op Away3D, maar we zullen hier snel een samenvatting van maken:

 // standaard Away3D-eigenschappen beschermd var-scène: Scene3D; beschermde var camera: TargetCamera3D; beschermde var-weergave: View3D;
  • Scene3D is een ruimte die we kunnen gebruiken om 3D-objecten zoals kubussen en bollen toe te voegen.
  • TargetCamera3D is een van de vele soorten camera's die beschikbaar zijn in Away3D, het is wat we gebruiken om naar de Scene3D te kijken.
  • View3D is een viewport, vaak beschreven als het "venster" waarin we onze scène zien.

Zonder in te gaan op specifieke informatie, kunt u ook een basisscène zien die klaar is voor gebruik met de initAway3d () methode. Let op het voegt een toe ENTER_FRAME EventListener, dit vertelt simpelweg Away3D aan render () (of teken) objecten toegevoegd aan de Scene3D elk frame.

 / ** * Away3D basisscène-instelling * / persoonlijke functie initAway3d (): void scene = new Scene3D (); camera = nieuwe TargetCamera3D (z: -200); view = new View3D (scène: scène, camera: camera); addChild (view); addEventListener (Event.ENTER_FRAME, renderLoop);  / ** * de render-loop * / private function renderLoop (event: Event): void view.render (); 

Dat is zo ongeveer de introductie tot de Main.as klas, we zullen de rest verder bouwen als we gaan.


Stap 5: Bitmaps en BitmapData

We gaan meteen naar binnen en introduceren deze twee klassen, omdat we deze tijdens de tutorial zullen gebruiken. Als je nieuw bent Bitmap en BitmapData je kunt ze beschouwen als een schildersdoek en een verzameling verfklodders. Het zijn geheel verschillende objecten maar beide verbonden, de BitmapData bevat alle pixelinformatie of penseelstreken en zou niets zijn zonder op een schildersdoek te worden geschilderd of in dit geval de Bitmap!

Laten we dit uittesten door een exemplaar toe te voegen van de img1 MovieClip naar de stadium en er een kopie van maken met Bitmap / BitmapData.

Wijzig de Main.as als volgt:

 / ** * constructor * / public function Main () initAway3d (); drawExample ();  / ** * een snel voorbeeld van het gebruik van BitmapData en Bitmap * / private function drawExample (): void // maak een instantie van het img1-object op het werkgebied om te kopiëren var img: MovieClip = new img1 (); addChild (img); // maak een object BitmapData met de volgende parameters: width, height, transparent, color var bmpData: BitmapData = new BitmapData (img.width, img.height, true, 0x000000); // tekent een kopie van de img MovieClip in de BitmapData bmpData.draw (img); // voegt een bitmap toe aan de fase met de BitmapData (kopie van de img1) informatie om var bmp weer te geven: Bitmap = nieuwe bitmap (bmpData); bmp.y = img.hoogte; addChild (BMP); 

Kijken naar de drawExample () code, de eerste twee regels voegen gewoon de img1 bezwaar tegen de stadium, dit is de afbeelding die we van kopie maken.

Vervolgens maken we een BitmapData object met de volgende parameters:

  • breedte, de breedte om het te maken BitmapData
  • hoogte, de hoogte om de te maken BitmapData
  • transparant, of het BitmapData zou transparante pixels moeten bevatten
  • kleur, de achtergrondkleur

Zoals we de breedte en hoogte kennen van img1 we hebben ze direct ingesteld, omdat we transparantie nodig hebben, stellen we de volgende parameter in op true en als laatste specificeren we die 0x000000 of zwart als achtergrondkleur omdat het transparant zal lijken totdat we het vullen.


Stap 6: Bitmaps en BitmapData Vervolg

Verdergaand, nu hebben we de BitmapData het instellen van objecten hebben we verschillende opties die beschikbaar zijn, we kunnen bijvoorbeeld pixel per pixel doorlopen en de afbeelding kopiëren (we zullen zoiets later in de tutorial gebruiken), of we zouden de trek() methode.

De trek() methode kost een Filmclip of sprite als een parameter en kopieert alle pixelinformatie van het object naar de BitmapData.

 / ** * een snel voorbeeld van het gebruik van BitmapData en Bitmap * / private function drawExample (): void // maak een instantie van het img1-object op het werkgebied om te kopiëren var img: MovieClip = new img1 (); addChild (img); // maak een object BitmapData met de volgende parameters: width, height, transparent, color var bmpData: BitmapData = new BitmapData (img.width, img.height, true, 0x000000); // tekent een kopie van de img MovieClip in de BitmapData bmpData.draw (img); // voegt een bitmap toe aan de fase met de BitmapData (kopie van de img1) informatie om var bmp weer te geven: Bitmap = nieuwe bitmap (bmpData); bmp.y = img.hoogte; addChild (BMP); 

Hierna maken de volgende paar regels een Bitmap object met de BitmapData pixelinformatie als een parameter, die vervolgens onder het origineel wordt verplaatst img MovieClip en toegevoegd aan de stadium.

 / ** * een snel voorbeeld van het gebruik van BitmapData en Bitmap * / private function drawExample (): void // maak een instantie van het img1-object op het werkgebied om te kopiëren var img: MovieClip = new img1 (); addChild (img); // maak een object BitmapData met de volgende parameters: width, height, transparent, color var bmpData: BitmapData = new BitmapData (img.width, img.height, true, 0x000000); // tekent een kopie van de img MovieClip in de BitmapData bmpData.draw (img); // voegt een bitmap toe aan de fase met de BitmapData (kopie van de img1) informatie om var bmp weer te geven: Bitmap = nieuwe bitmap (bmpData); bmp.y = img.hoogte; addChild (BMP); 

Er is niet veel setup betrokken bij het instellen van de Bitmap als het gewoon een BitmapData toont, is alle magie bij de BitmapData. Bij het testen moeten we nu het volgende krijgen:


Stap 7: Pixelinformatie lezen

Nu hebben we inhoud binnen de BitmapData objecten beginnen interessant te worden, omdat we beelden kunnen gebruiken met behulp van getPixel32 () en setPixel32 ().

Beginnend met getPixel32 () de drawExample () code van bovenaf naar het volgende:

 / ** * een snel voorbeeld van het gebruik van BitmapData en Bitmap * / private function drawExample (): void // maak een instantie van het img1-object op het werkgebied om te kopiëren var img: MovieClip = new img1 (); addChild (img); // maak een object BitmapData met de volgende parameters: width, height, transparent, color var bmpData: BitmapData = new BitmapData (img.width, img.height, true, 0x000000); // tekent een kopie van de img MovieClip in de BitmapData bmpData.draw (img); // voegt een bitmap toe aan de fase met de BitmapData (kopie van de img1) informatie om var bmp weer te geven: Bitmap = nieuwe bitmap (bmpData); bmp.y = img.hoogte; addChild (BMP); // lees pixelinformatie van de BitmapData var pixelInformation: uint = bmpData.getPixel32 (5, 0); trace (pixelInformation, pixelInformation.toString (16)); 

Bij het onderzoeken van de code hebben we een reguliere uint variabele gemaakt en deze toegewezen aan de waarde van de pixel in de bmpData op 5 pixels horizontaal en 0 pixels verticaal. Onthoud dat de waarden als volgt beginnen bij 0:

Wetende dat we ervoor kozen om de pixelinformatie voor 5,0 te krijgen, zou dat het een zwarte pixel op de bovenste rij maken en zeker genoeg Flash-outputs: 4278190080 ff000000

Dat lijkt in eerste instantie misschien niet goed, maar setPixel32 leest de alpha-waarde van de pixel (waar as setPixel leest gewoon de kleur). We zijn over het algemeen gewend om te werken met hex-waarden voor kleuren zoals FFFFFF of 000000 zodat we Flash aan kunnen vertellen toString (16) om de hexadecimale waarde te krijgen:


Stap 8: Pixels tekenen

Nu weten we hoe we pixelinformatie moeten lezen, pixels tekenen naar de BitmapData is erg vergelijkbaar, alleen deze keer gebruiken we setPixel32 () om pixels naar de BitmapData te tekenen en we gooien er ook een in voor loop om enkele pixels te tekenen.

Wijzig eerst de code als volgt:

 / ** * een snel voorbeeld van het gebruik van BitmapData en Bitmap * / private function drawExample (): void // maak een instantie van het img1-object op het werkgebied om te kopiëren var img: MovieClip = new img1 (); addChild (img); // maak een object BitmapData met de volgende parameters: width, height, transparent, color var bmpData: BitmapData = new BitmapData (img.width, img.height, true, 0x000000); // tekent een kopie van de img MovieClip in de BitmapData bmpData.draw (img); // voegt een bitmap toe aan de fase met de BitmapData (kopie van de img1) informatie om var bmp weer te geven: Bitmap = nieuwe bitmap (bmpData); bmp.y = img.hoogte; addChild (BMP); // lees pixelinformatie van de BitmapData var pixelInformation: uint = bmpData.getPixel32 (5, 0); trace (pixelInformation, pixelInformation.toString (16)); // schrijf pixelinformatie naar de BitmapData var kleur: uint = 0xffff0000; // ff0000 - volledige rode var-rij: uint = 0; var kolom: uint = 0; voor (rij; rij < bmpData.height; row++)  bmpData.setPixel32(column, row, color); column++; if(column > bmpData.width) column = 0; 

De nieuwe code begint met het maken van een standaard uint variabele genoemd kleur die we opslaan 0xffff0000 dat is: ff volledig transparant, ff volledig rood, 00 geen groen, 00 geen blauw.

Dan zijn er twee tellers gemaakt voor rijen en kolommen (rijen zijn een rij horizontale pixels, kolommen zijn een rij verticale pixels). Deze tellers worden vervolgens in een a geplaatst voor lus die de rij en de tellerwaarde telkens verhoogt, dus in combinatie met de setPixel32 () methode zal het een diagonale lijn tekenen:


Stap 9: De klasse PixelObject3D

In deze stap introduceren we de PixelObject3D.as klasse. Om een ​​beetje tijd te besparen, neemt u een kopie van de klas uit de Stap 8 map in de bron-zip en zet deze in uw src map naast de Main.fla en Main.as.

Zodra je dit hebt gedaan, laten we het snel bekijken voordat we beginnen met het toevoegen van de code om 3D-objecten van pixels te maken.

 // eigenschappen beschermd var _bitmapData: BitmapData = null; public var _scaleFactor: Number = 1; protected var _width: Number = 0; beschermd var _height: Number = 0;

We hebben enkele beschermde variabelen aan de bovenkant van de klas, een voor een BitmapData en drie Numbers voor de breedte, hoogte en een schaal van het object.

 / ** * constructor * / openbare functie PixelObject3D ()  / ** * begint het maakproces * / public function createFromMovieClip (mc: MovieClip): void 

Ze volgen is een lege klassenbouwer en de methode waarmee we zullen werken, createFromMovieClip (). Je zult merken dat deze methode een parameter van neemt Filmclip type, dus zoals je al kunt raden, geven we het a Filmclip en het geeft ons een 3D-weergave ervan terug. Als het klaar is, is dat zo!


Stap 10: Een exemplaar van de PixelObject3D-klasse

Terwijl de PixelObject3D.as klasse doet eigenlijk helemaal niets maar laten we er een instantie van toevoegen aan de Main.as klasse, zodat we de wijzigingen op het scherm daadwerkelijk kunnen bekijken.

Beginnend met het toevoegen van een privévariabele:

 // standaard Away3D-eigenschappen beschermd var-scène: Scene3D; beschermde var camera: TargetCamera3D; beschermde var-weergave: View3D; // de door Pixel3DObject beschermde var po3d: PixelObject3D;

Hierna voegt u aan de constructor een oproep toe aan createPixelObect3D ().

 / ** * constructor * / public function Main () initAway3d (); drawExample (); createPixelObect3D (); 

Voeg ten slotte de volgende functie toe aan de Main.as het dossier. Hiermee maakt u een exemplaar van de PixelObject3D klasse, roep het createFromMovieClip () methode en geef het een nieuw Filmclip, de img1 we hebben eerder gebruikt.

Een laatste regel om op te wijzen is dat we de PixelObject3D klasse als kind van de scène omdat het een 3D-object is, niet het Stadium.

 / ** * maakt een PixelObject3D * / private function createPixelObect3D (): void po3d = new PixelObject3D (); po3d.createFromMovieClip (nieuwe img1 ()); scene.addChild (po3d); 

Stap 11: createFromMovieClip (mc: MovieClip)

Wetende dat we de Filmclip we willen van deze methode recreëren, het eerste wat op onze agenda staat is om een ​​kopie ervan te maken met BitmapData precies zoals we eerder deden. We kunnen dan de pixelgegevens gebruiken om te beginnen met het maken van 3D-objecten.

Net zoals eerder gaan we een maken BitmapData object en teken de mc MovieClip voorwerp:

 / ** * begint het aanmaakproces * / public function createFromMovieClip (mc: MovieClip): void // winkelverwijzingen en maak de bitmapdata _bitmapData = nieuwe BitmapData (mc.width, mc.height, true, 0x000000); _bitmapData.draw (mc); // set width / height _width = mc.width * (2 * _scaleFactor); _height = mc.height * (2 * _scaleFactor); 

We hebben ook de _breedte en _hoogte variabelen volgens de mc breedte en hoogte en vermenigvuldig dit met de _schaal factor variabele, dit stelt ons in staat om de grootte van de 3D-pixels naar wens op te schalen. Hierover later meer.


Stap 12: createFromMovieClip (mc: MovieClip)

Onthoud dat de BitmapData alleen de pixelinformatie is en zonder de BitmapData toe te voegen aan een Bitmap zullen we het niet kunnen zien, maar we kunnen het nog steeds lezen en ernaar schrijven. Dit is perfect voor ons, want we gaan deze stap gebruiken om de pixels van de BitmapData door te lussen en de rode, groene, blauwe en alpha-waarden te scheiden.

Wijzig uw createFromMovieClip () methode om dit te evenaren:

 / ** * begint het aanmaakproces * / public function createFromMovieClip (mc: MovieClip): void // winkelverwijzingen en maak de bitmapdata _bitmapData = nieuwe BitmapData (mc.width, mc.height, true, 0x000000); _bitmapData.draw (mc); // set width / height _width = mc.width * (2 * _scaleFactor); _height = mc.height * (2 * _scaleFactor); // pixelinformatie var pixelValue: uint = 0; var rood: uint = 0; var groen: uint = 0; var blue: uint = 0; var alpha: uint = 0; // doorloop elke pixel horizontaal voor (var i: int = 0; i < mc.width; i++)  pixelValue = _bitmapData.getPixel32(i, 0); alpha = pixelValue >> 24 & 0xFF; rood = pixelWaarde >> 16 & 0xFF; groen = pixelValue >> 8 & 0xFF; blauw = pixelValue & 0xFF; trace ("alpha:" + alpha + "red:" + red + "green:" + green + "blue:" + blue); 

Hier hebben we een paar variabelen ingesteld voor de kleur- en alpha-waarden die vervolgens zijn gestart a voor loop op basis van de mc's breedte.

Deze voor loop stelt de pixelValue variabele naar de waarde van de huidige pixel met behulp van de getPixel32 () methode die we eerder hebben gebruikt, maar deze tijdnotitie die we hebben gebruikt 0 voor de tweede parameter die is Y, dus we gaan alleen de eerste horizontale lijn met pixels verwerken.

Hierna is er een behoorlijk ingewikkelde wiskunde bekend als bit maskeren en verschuiven, om een ​​beetje tijd te besparen kun je aannemen dat elk van de kleuren wordt geëxtraheerd uit de pixelValue verander en uitvoer voor ons om te gebruiken spoor(). Als je meer wilt weten over bitwise operatoren, bit shifting en masking dan kun je een geweldige post vinden op de Polygonal Labs website.

Wat je zou moeten zien is de output van een hele reeks 0 waarden, maar let op de twee alpha: 255 lijnen, dit zijn de twee zwarte pixels aan de bovenkant van de hand.


Stap 13: 3D-objecten maken van de pixelwaarden

Pff was er nogal wat logica in die laatste paar stappen! Nu hebben we de basisbeginselen in handen, laten we de pixelinformatie gebruiken die we eerder hebben verkregen om een ​​3D-meesterwerk te maken? bijna.

Als u Away3D of Papervision 3D hebt gebruikt voordat u bekend bent met deze stap, gaan we 3D-kubussen maken en materialen toepassen. Voor elke pixel met alpha 255 (ondoorzichtig) pakken we de kleur en maken we een materiaal op basis van de kleur die op een 3D-kubus moet worden toegepast. Hieronder vindt u de code om dit te starten:

 / ** * begint het aanmaakproces * / public function createFromMovieClip (mc: MovieClip): void // winkelverwijzingen en maak de bitmapdata _bitmapData = nieuwe BitmapData (mc.width, mc.height, true, 0x000000); _bitmapData.draw (mc); // set width / height _width = mc.width * (2 * _scaleFactor); _height = mc.height * (2 * _scaleFactor); // pixelinformatie var pixelValue: uint = 0; var rood: uint = 0; var groen: uint = 0; var blue: uint = 0; var alpha: uint = 0; // doorloop elke pixel horizontaal voor (var i: int = 0; i < mc.width; i++)  pixelValue = _bitmapData.getPixel32(i, 0); alpha = pixelValue >> 24 & 0xFF; rood = pixelWaarde >> 16 & 0xFF; groen = pixelValue >> 8 & 0xFF; blauw = pixelValue & 0xFF; // als pixel ondoorzichtig is als (alpha == 255) // een normale hex-kleurenserie maakt, bijv. FFFFFF of 000000 var kleur: String = rood.toString (16) + green.toString (16) + blue.toString (16 ); if (color == "000") color = "000000"; trace ("#" + kleur); // maak een materiaal uit de kleur en pas het toe op een 3D-kubus var-materiaal: Materiaal = nieuw ColorMaterial (kleur); var cube: Cube = nieuwe Cube (material: material, width: 2 * _scaleFactor, height: 2 * _scaleFactor, depth: 2 * _scaleFactor); // plaats de kubus van een - waarde, zodat het registratie / transformatiepunt altijd de middelste cube.x = 0 - (_width / 2) + cube.width * i; this.addChild (kubus); 

In de bovenstaande code hebben we de rood, groen en blauw variabelen en creëerde een normale hex-kleur, die u kunt zien als output van de spoor().

Dan de hexuitdraaikleur kleur variabele wordt gebruikt om een ​​te maken ColorMaterial met Away3D, wat slechts een normaal materiaal is, gebaseerd op een kleur die op 3D-objecten kan worden toegepast.

Vervolgens maken we een Kubus object en specificeer de materiaal om de ... te zijn materiaal object hebben we de regel ervoor gemaakt. Ook vermeldenswaard is dat we de breedte, hoogte en diepte (onthoud dat we nu in drie dimensies werken!) tot een waarde van tweemaal de waarde van de _scaleValue variabel, dit stelt ons in staat om de kubussen groter of kleiner te maken door te veranderen _scaleValue.

Ten slotte plaatsen we de Kubus tot nul minus de helft van de breedte van de mc vermenigvuldigd met de voor loops teller ik, dit maakt het registratie- of transformatiepunt van het voltooide 3D-object in het midden. Het wordt dan toegevoegd als een kind en als je het test, zie je twee kleine zwarte 3D Kubus voorwerpen.


Stap 14: rijen en kolommen

Nu zijn twee 3D-kubussen geweldig en alles behalve we willen de hele handvorm naar 3D-kubussen. We gebruiken al een voor lus om door alle pixels in de eerste rij te lopen, maar hoe krijgen we deze door de resterende rijen pixels?

Je raadt het al, een andere voor lus!

 / ** * begint het aanmaakproces * / public function createFromMovieClip (mc: MovieClip): void // winkelverwijzingen en maak de bitmapdata _bitmapData = nieuwe BitmapData (mc.width, mc.height, true, 0x000000); _bitmapData.draw (mc); // set width / height _width = mc.width * (2 * _scaleFactor); _height = mc.height * (2 * _scaleFactor); // pixelinformatie var pixelValue: uint = 0; var rood: uint = 0; var groen: uint = 0; var blue: uint = 0; var alpha: uint = 0; // doorloop elke rij met pixels voor (var j: int = 0; j < mc.height; j++)  // loop through each pixel horizontally for (var i:int = 0; i < mc.width; i++)  pixelValue = _bitmapData.getPixel32(i, j); alpha = pixelValue >> 24 & 0xFF; rood = pixelWaarde >> 16 & 0xFF; groen = pixelValue >> 8 & 0xFF; blauw = pixelValue & 0xFF; // als pixel ondoorzichtig is als (alpha == 255) // een normale hex-kleurenserie maakt, bijv. FFFFFF of 000000 var kleur: String = rood.toString (16) + green.toString (16) + blue.toString (16 ); if (color == "000") color = "000000"; trace ("#" + kleur); // maak een materiaal uit de kleur en pas het toe op een 3D-kubus var-materiaal: Materiaal = nieuw ColorMaterial (kleur); var cube: Cube = nieuwe Cube (material: material, width: 2 * _scaleFactor, height: 2 * _scaleFactor, depth: 2 * _scaleFactor); // plaats de kubus van een - waarde, zodat het registratie / transformatiepunt altijd de middelste cube.x = 0 - (_width / 2) + cube.width * i; cube.y = (_height / 2) + -cube.height * j; this.addChild (kubus); 

Deze keer hebben we slechts drie dingen echt veranderd, een nieuwe voor loop die deze tijd heeft j voor zijn aanrecht. De getPixel32 () heeft nu de j variabele toegevoegd als de Y parameter en tenslotte de Kubus wordt verticaal gepositioneerd met behulp van de j teller.

Dit voltooit vrijwel de hoofdlogica, nu zal het horizontaal doorlopen, de pixelwaarden lezen, een a creëren ColorMaterial en een Kubus en plaats ze dienovereenkomstig. Zodra het het einde van de horizontale lijn bereikt, vanwege de nieuwe voor Loop het zal naar de volgende pixel naar beneden gaan en horizontaal opnieuw lus doorlopen totdat de afbeelding voltooid is. Kijk zelf maar eens door de film te testen:


Stap 15: In de 3e dimensie

We hebben nu al deze 3D-objecten, maar ze zien er erg 2D uit, dus we gaan wat beweging toevoegen en het hele object laten draaien.

Om dit te doen, moeten we teruggaan naar de Main.as bestand en zoek de renderLoop () methode. Vergeet niet dat Away3D het 3D-beeld in elk frame moet renderen (of verven), zodat we enkele eenvoudige rotaties aan ons kunnen toevoegen PixelObject3D om al het kind te zien Cubes draaien:

 / ** * de render-loop * / private function renderLoop (event: Event): void pObject3D.rotationZ ++; view.render (); 

Voel je vrij om mee te experimenteren rotationX, rotationY en rotationZ hier onthoud gewoon om het terug te zetten naar de bovenstaande code alvorens verder te gaan. U kunt ook toevoegen aan de create3DObject () om het centrum beter te centreren en uit te lijnen Cubes naar de camera.

 / ** * maakt een 3D-pixelobject van een MovieClip * / public function create3DObject (): void pObject3D = new PixelObject3D (); pObject3D.createFromMovieClip (nieuwe img1 ()); pObject3D.x = 80; pObject3D.y = -55; pObject3D.rotationX = -5; scene.addChild (pObject3D); 

Stap 16: Exploderen van PixelObject3D

Dit lijkt er nu meer op, we kunnen eindelijk het 3D-pixelobject zien roteren. We kunnen dit gaan tweaken en een exploded view toevoegen door simpelweg de z waarde van de Cubes wanneer we ze maken.

Spring terug naar de PixelObject3d.as klasse en zoek de lijnen waar we het plaatsen Kubus's X en Y en voeg het volgende toe:

 // als pixel ondoorzichtig is als (alpha == 255) // een normale hex-kleurenserie maakt, bijv. FFFFFF of 000000 var kleur: String = rood.toString (16) + green.toString (16) + blue.toString (16 ); if (color == "000") color = "000000"; trace ("#" + kleur); // maak een materiaal uit de kleur en pas het toe op een 3D-kubus var-materiaal: Materiaal = nieuw ColorMaterial (kleur); var cube: Cube = nieuwe Cube (material: material, width: 2 * _scaleFactor, height: 2 * _scaleFactor, depth: 2 * _scaleFactor); // plaats de kubus van een - waarde, zodat het registratie / transformatiepunt altijd de middelste cube.x = 0 - (_width / 2) + cube.width * i; cube.y = (_height / 2) + -cube.height * j; cube.z = -25 + (Math.random () * 50); this.addChild (kubus); 

Dit zal elk bewegen Kubus tot een willekeurige diepte van -25 tot positief 25 en creëer een leuk geëxplodeerd effect:


Stap 17: Schalen

Als de PixelObject3D is een beetje klein op het scherm, we gaan de schaal iets aanpassen. We kunnen dit snel doen door de _scaleValue variabele in de PixelObject3D.as klasse en verhoog het naar 1.5.

 / ** * maakt een 3D-object van een MovieClip * * @author Anton Mills * / public class PixelObject3D breidt ObjectContainer3D uit // eigenschappen beschermd var _bitmapData: BitmapData = null; public var _scaleFactor: Number = 1.5; protected var _width: Number = 0; beschermd var _height: Number = 0;

Stap 18: Verschillende afbeeldingen

De ... gebruiken PixelObject3D klasse om andere afbeeldingen te maken is eenvoudig, importeer eenvoudig de afbeelding die u wilt verwerken naar Flash. Converteer het vervolgens zoals gebruikelijk naar een MovieClip, maar geef dit een keer Naam van de klasse van img2 zoals dit:

Nu kun je veranderen Main.as om het nieuwe te gebruiken img2 object met een kleine wijziging:

 / ** * maakt een 3D-pixelobject van een MovieClip * / public function create3DObject (): void pObject3D = new PixelObject3D (); pObject3D.createFromMovieClip (nieuwe img2 ()); pObject3D.x = 80; pObject3D.y = -55; pObject3D.rotationX = -5; scene.addChild (pObject3D); 

Stap 19: Meerdere objecten

Je kunt zoveel van deze gebruiken als je wilt, zorg er gewoon voor dat je ze toevoegt aan de Away3D-scène en je kunt er meerdere hebben. In dit voorbeeld heb ik de z eigenschap die we in stap 16 hebben gebruikt voor het explosie-effect.

Main.as met iemand anders PixelObject3D toegevoegd:

 / ** * Een zelfstudie gericht op het introduceren van BitmapData * in ActionScript 3 en het gebruik van de BitmapData-informatie om een ​​3D * pixelvorm te maken met Away3D. * * @author Anton Mills * / public class Main breidt MovieClip uit // basic Away3D properties protected var scene: Scene3D; beschermde var camera: TargetCamera3D; beschermde var-weergave: View3D; beschermd var pObject3D: PixelObject3D; beschermd var pObject3D2: PixelObject3D;

Maak vervolgens een andere instantie:

 / ** * maakt een 3D-pixelobject van een MovieClip * / public function create3DObject (): void pObject3D = new PixelObject3D (); pObject3D.createFromMovieClip (nieuwe img2 ()); pObject3D.x = 40; pObject3D.y = -55; pObject3D.rotationX = -5; scene.addChild (pObject3D); pObject3D2 = nieuwe PixelObject3D (); pObject3D2.createFromMovieClip (nieuwe img1 ()); pObject3D2.x = 115; pObject3D2.y = -55; pObject3D2.rotationX = -5; scene.addChild (pObject3D2); 

En ten slotte draai je het in de Away3D render-loop:

 / ** * de render-loop * / private function renderLoop (event: Event): void pObject3D.rotationY ++; pObject3D2.rotationY--; pObject3D2.rotationZ--; pObject3D2.rotationX ++; view.render (); 

Stap 20: Fin.

Het enige dat overblijft, is dat u uw film test en geniet van de schoonheid van 2D-pixels die zijn getransformeerd in 3D-objecten. Wat kun je nu doen? BitmapData in je volgende applicatie of spel?


Conclusie

In deze zelfstudie hebben we gekeken naar een combinatie van items, maar daar hebben we ons vooral op gericht BitmapData gebruik zoals tekenen MovieClips in naar BitmapData, gebruik makend van setPixel32 () om afzonderlijke pixels te tekenen, de BitmapData door a te gebruiken Bitmap en het lezen van pixelwaarden met behulp van getPixel32 ().

We hebben ook enkele kleurberekeningen behandeld, waarbij hex-kleuren en zelfs individuel