For å knytte seg sammen med Papervision3D Essentials giveaway, har dagens opplæring også et PV3D-tema.
Denne todelte opplæringen vil vise deg hvordan du kommer i gang med Papervision3D-motoren, og deretter hvordan du får din tilrettelegging å hoppe ut av skjermen ved hjelp av en anaglyph-effekt i kombinasjon med 3D-briller.
Fikk et par 3D-briller liggende? Her i Storbritannia driver Channel 4 en spesiell 3D-uke - syv dager med TV-programmer som sendes i 3D - så mange mennesker gjør det her. La oss sette dem til bruk.
Denne todelte opplæringen vil vise deg hvordan du kommer i gang med Papervision3D-motoren, og hvordan kan du gjøre at etableringen hopper ut av skjermen.
I denne første delen lærer du grunnleggende om PV3D, og slutter med noe slikt:
... og i den andre delen lærer du om anaglyph-effekten for 3D-briller, og bruker den til det du har laget slik:
Hvis du bruker Flash, oppretter du en ny FlashScript-fil for ActionScript 3.0. Still størrelsen på scenen for å være hva du vil - Jeg holder fast med standard 550 ved 400 piksler.
Mens du er i det, opprett en ny ActionScript-fil, og lagre den som Main.as i samme mappe som din FLA. Vi skal bruke denne AS-filen som FLA dokument klasse, så klikk et tomt mellomrom i FLA-filen din, og skriv inn Hoved i boksen "Dokumentklasse" på Egenskaper-panelet.
(Hvis du ikke bruker Flash IDE, må du bare opprette et nytt AS3-prosjekt.)
Gå over til Papervision Download Page. Det er mange forskjellige versjoner og noen forskjellige typer filer (zip, swc, mxp). Bare ta tak i den nyeste .zip-filen (den burde si Utvalgt ved siden av det). Den jeg bruker er kalt Papervision3D 2.1.920.zip (for bruk med "Papervision3D Essentials" bok).
Trekk ut zip-filen du nettopp lastet ned til hvor som helst på harddisken din. Jeg liker å beholde alle de forskjellige motoren jeg bruker i samme mappe, men det er opp til deg.
Flash trenger å vite hvor du hentet Papervision før den kan bruke den. Vi bruker en CLASSPATH for dette: klikk Rediger> Innstillinger, å velge Action, klikk deretter ActionScript 3.0-innstillinger ... .
I boksen som vises, klikker du på det lille "krysshår" -ikonet, og deretter finner du mappen der du unzipped Papervision og klikker OK. Klikk OK til de andre boksene til du kommer tilbake til FLA.
Hvis du ikke bruker Flash IDE, må du sette dette på en annen måte. For eksempel, i FlashDevelop, bør du klikke Verktøy> Global Classpaths.
I Papervision må alle 3D-objektene plasseres inne i a scene. Det er litt som scenen i vanlig ActionScript. Så, før vi gjør noe vi trenger for å lage en Scene3D objekt som vil inneholde alt annet.
Bytt til Main.as-filen din. La oss raskt legge til basekoden som trengs for en hvilken som helst dokumentklasse:
pakke import flash.display.MovieClip; offentlig klasse Main utvider MovieClip offentlig funksjon Main ()
Scene3D-objektet er i org.papervision3d.scenes.Scene3D, så vi må importere det, og opprett en ny offentlig var å holde scenen, og til slutt lage den aktuelle sceneobjektet: (linjer 4, 8 og 12)
pakke import flash.display.MovieClip; importer org.papervision3d.scenes.Scene3D; offentlig klasse Main utvider MovieClip offentlig var scene: Scene3D; offentlig funksjon Main () scene = new Scene3D ();
Til å begynne med, la oss bare lage en stor ren kube sitte i vår scene.
Vi følger de samme trinnene som ovenfor for å lage den, og legg den til vår scene: (linjer 5, 10, 15, 16)
pakke import flash.display.MovieClip; importer org.papervision3d.scenes.Scene3D; importer org.papervision3d.objects.primitives.Cube; offentlig klasse Main utvider MovieClip offentlig var scene: Scene3D; offentlig var kube: Cube; offentlig funksjon Main () scene = new Scene3D (); kube = ny kube (); scene.addChild (kube);
Legg merke til at vi bruker "addChild ()" for å legge terningen til scenen, akkurat som vi gjør når du legger til en MovieClip på scenen.
Ovennevnte kode vil gi deg en feil hvis du prøver å kjøre den. Det er fordi vi ikke har fortalt kuben hvordan ansiktsflatene skal se ut.
Papervision bruker materialer å beskrive hvordan en overflate ser ut. Vi kan lage et veldig enkelt, enkeltfarget materiale ved hjelp av a ColorMaterial:
var grayMaterial: ColorMaterial = new ColorMaterial (0xCCCCCC);
"0xCCCCCC" representerer fargen grå; bare ta fargekoden av hvilken som helst farge og erstatt den # med 0x:
Fordi en terning har seks ansikter, må vi gi det seks materialer. For å gjøre dette legger vi alle seks på en liste:
var materialsList: MaterialsList = new MaterialsList (); materialsList.addMaterial (grayMaterial, "front"); materialsList.addMaterial (grayMaterial, "back"); materialsList.addMaterial (grayMaterial, "left"); materialsList.addMaterial (grayMaterial, "right"); materialsList.addMaterial (grayMaterial, "top"); materialsList.addMaterial (grayMaterial, "bottom");
... og så send den listen til kuben når vi lager den:
kube = ny kube (materialsList);
Så hele koden din burde ende opp med å se slik ut: (ikke glem det importere uttalelser!)
pakke import flash.display.MovieClip; importer org.papervision3d.scenes.Scene3D; importer org.papervision3d.objects.primitives.Cube; importere org.papervision3d.materials.ColorMaterial; importer org.papervision3d.materials.utils.MaterialsList; offentlig klasse Main utvider MovieClip offentlig var scene: Scene3D; offentlig var kube: Cube; offentlig funksjon Main () var grayMaterial: ColorMaterial = new ColorMaterial (0xCCCCCC); var materialsList: MaterialsList = new MaterialsList (); materialsList.addMaterial (grayMaterial, "front"); materialsList.addMaterial (grayMaterial, "back"); materialsList.addMaterial (grayMaterial, "left"); materialsList.addMaterial (grayMaterial, "right"); materialsList.addMaterial (grayMaterial, "top"); materialsList.addMaterial (grayMaterial, "bottom"); scene = ny Scene3D (); kube = ny kube (materialsList); scene.addChild (kube);
Så vi har ingen feil, men for å se noe, må vi legge til en kamera til scenen. Vi ser alt gjennom kameraets "objektiv".
Å legge til et kamera er like enkelt som å legge til en terning - enklere, faktisk, da vi ikke trenger å leggeChild () til scenen:
importer org.papervision3d.cameras.Camera3D;
offentlig var kamera: Camera3D;
scene = ny Scene3D (); kube = ny kube (materialsList); scene.addChild (kube); kamera = nytt kamera3D (); // dette er den nye linjen i Main ()
Nå er et kamera på scenen, men det er ikke koblet til noe utgang, så vi kan fortsatt ikke se terningen!
Som standard er kuben plassert rett i midten av scenen (ved x = 0, y = 0, z = 0), og kameraet er plassert 1000 enheter tilbake fra det (ved x = 0, y = 0, z = -1.000).
Hvordan kan vi få bildet som kameraet ser i Flash Player-vinduet?
Svaret er at vi bruker en view. Dette er en type DisplayObject, som en MovieClip, slik at vi kan leggeChild () til scenen. Men vi kan også lage Papervision gjengi (dvs. tegne) kameraets utsikt til denne visningsporten - det er litt som å ha en kunstner tegne det han kan se gjennom en kameralins, deretter ta tegningen og stikke den til et TV-apparat. Unntatt raskere.
Så vi trenger å lage en visningsport og en renderer:
importer org.papervision3d.view.Viewport3D; importer org.papervision3d.render.BasicRenderEngine;
offentlig var viewport: Viewport3D; offentlig var renderer: BasicRenderEngine;
// sett dette på slutten av Main () viewport = new Viewport3D (); viewport.autoScaleToStage = true; // dette vil gjøre visningsporten så stor som scenen addChild (viewport); renderer = ny BasicRenderEngine ();
Nå er alt vi trenger å gjøre, gjør gjengivelsen til den faktiske gjengivelsen. For dette må den kjenne scenen, kameraet og visningsporten:
renderer.renderScene (scene, kamera, visningsport);
Endelig! Vi kan endelig teste ut SWF. Trommelrulle, vær så snill ...
Utrolig! Forbløffende! OK bra, det er faktisk ganske halt. Hvordan kan vi til og med si at det er en terning? Det ser ut som et torg.
Hvis vi roterer terningen, kan vi fortelle om det faktisk er en terning eller ikke.
Siden kuben er i tre dimensjoner, er ordet "rotere" litt forvirrende - hvilken retning mener vi? Vi må spesifisere om vi roterer rundt x-aksen, y-aksen eller z-aksen.
De Cube objektet har tre egenskaper vi kan bruke til å definere dette, kalt (overraskende) rotationX, rotationY og rotationZ. La oss endre et par av dem:
scene = ny Scene3D (); kube = ny kube (materialsList); cube.rotationX = 25; // endre rotasjon cube.rotationY = 40; // endre rotasjon scene.addChild (kube); kamera = nytt kamera3D ();
Det er bedre, men siden alle ansikter er akkurat i samme farge, går de bare sammen i hverandre. La oss fikse det.
I stedet for grå, skal jeg male sidene med ActiveTuts + -logoen.
Hvis du bruker Flash IDE, lager du et nytt filmklipp og tegner eller limer inn bildet du vil bruke. Jeg har tatt med logoen i min FLAs bibliotek inne i glidelåsen.
Høyreklikk filmklippet ditt og velg Egenskaper. Sjekk "eksport for ActionScript" og gi den et Klassenavn. Dette vil gi deg tilgang til det ved hjelp av kode. (Hvis du ikke bruker Flash IDE, inneholder zip også en SWC med en MovieClip kalt ActiveTutsLogo som du kan bruke. Eller du kan opprette en ny MovieClip-kode og legge bildet til det. Jeg skal ikke gå inn i detaljene om det her, skjønt.)
I stedet for a ColorMaterial vi skal bruke en MovieMaterial, og i stedet for å spesifisere en farge, vil vi spesifisere et filmklipp. Så erstatt dette:
var grayMaterial: ColorMaterial = new ColorMaterial (0xCCCCCC); var materialsList: MaterialsList = new MaterialsList (); materialsList.addMaterial (grayMaterial, "front"); materialsList.addMaterial (grayMaterial, "back"); materialsList.addMaterial (grayMaterial, "left"); materialsList.addMaterial (grayMaterial, "right"); materialsList.addMaterial (grayMaterial, "top"); materialsList.addMaterial (grayMaterial, "bottom");
… med dette:
var logoMaterial: MovieMaterial = ny MovieMaterial (ny ActiveTutsLogo ()); // erstatte "ActiveTutsLogo" ovenfor med klassenavnet til filmklippet ditt materialsList: MaterialsList = new MaterialsList (); materialsList.addMaterial (logoMaterial, "front"); materialsList.addMaterial (logoMaterial, "back"); materialsList.addMaterial (logoMaterial, "left"); materialsList.addMaterial (logoMaterial, "right"); materialsList.addMaterial (logoMaterial, "top"); materialsList.addMaterial (logoMaterial, "bottom");
Du må også importere MovieMaterial:
importere org.papervision3d.materials.MovieMaterial;
Test det igjen:
Vel, det virker, men det ser litt ut.
Den "pussete" utseendet er fordi Papervision er satt som standard for å trekke ting raskt i stedet for nøyaktig. Jeg vil sørge for at denne opplæringen kjører på tregere datamaskiner, så jeg skal forlate det, men her kan du forbedre det:
Når du lager kuben, kan du sende det til parametere for å definere hvor mange segmenter hvert ansikt er delt opp i. Jo flere segmenter du velger, jo mer nøyaktig ser kuben ut - men jo tregere blir det gjengitt.
Jeg har funnet ut at 10 er et godt antall segmenter å bruke i hver retning. Slik ser koden for det ut:
kube = ny kube (materialsList, 500, 500, 500, 10, 10, 10);
Den femte, sjette og syvende parametere definerer antall segmenter som brukes i hver retning. For å sette dem, må vi imidlertid angi alle parametrene før den femte også.
Vi angir allerede den første parameteren - det er materiallisten. Den andre, tredje og fjerde parameteren definerer bredden, dybden og høyden på terningen. Disse er satt til 500 som standard, så jeg har holdt dem de samme her.
Hvis du bruker koden ovenfor, vil kuben se slik ut:
Mye penere!
Vi kan gjøre en vanlig MovieClip spinn rundt ved å øke dens rotasjon eiendom hver ramme - og selvfølgelig kan vi gjøre det samme med terningen og dets rotasjonX / Y / Z-verdier.
Opprett en ENTER_FRAME hendelseslytter, som kjører hver ramme:
importere flash.events.Event;
// nederst på Main () addEventListener (Event.ENTER_FRAME, onEnterFrame);
// som en ny funksjon // inne i hovedklassen men utenfor hovedfunksjonen () funksjonen offentlig funksjon onEnterFrame (evt: Event): void cube.rotationX = cube.rotationX + 5; cube.rotationY = cube.rotationY + 5;
Dette vil gjøre kuben svinge litt mer hver ramme. Så hvis du tester SWF ut nå ... blir kuben helt stille. Hu h?
Tenk tilbake til maleren. Vi ser fortsatt på sitt gamle bilde - vi trenger ham til å tegne oss en ny hver ramme, eller vi vil ikke se noen endringer!
Så, endre onEnterFrame () -funksjonen:
offentlig funksjon onEnterFrame (evt: Event): void cube.rotationX = cube.rotationX + 5; cube.rotationY = cube.rotationY + 5; renderer.renderScene (scene, kamera, visningsport);
Sjekk det nå:
En kube er flott, men som Roman allerede viste deg hvordan du gjør det med Away3D, la oss ta ting litt lenger.
La oss legge til noen flere, for å danne en horisontal linje med terninger. Vi kan bruke en enkel til sløyfe for å gjøre det; bare erstatt denne koden:
kube = ny kube (materialsList); cube.rotationX = 25; // endre rotasjon cube.rotationY = 40; // endre rotasjon scene.addChild (kube);
… med dette:
for (var jeg: int = -1; jeg <= 1; i++ ) cube = new Cube( materialsList ); cube.x = i * 350; cube.rotationX = 25; cube.rotationY = 40; scene.addChild( cube );
Merk at jeg lager x-posisjonen til hver kube avhengig av hvor langt vi er gjennom løkken. Hvis du kjører dette, får du følgende:
Whoops, kubene er for tett sammen. Vi kan krympe dem for å komme seg rundt dette; bare endre skala Egenskapen til hver terning:
for (var jeg: int = -1; jeg <= 1; i++ ) cube = new Cube( materialsList ); cube.x = i * 350; cube.scale = 0.40; //make the cubes 40% of original size cube.rotationX = 25; cube.rotationY = 40; scene.addChild( cube );
Så det løser skjæringsproblemet, men bare en av våre terninger snurrer. Hvorfor det?
Det er fordi cube variabel refererer alltid bare til siste kube opprettet - og vår onEnterFrame () -funksjon endrer bare rotasjonene til den ene kuben.
Så for å fikse dette, trenger vi en Array. Akkurat som vår materialliste lagret flere materialer, vil vår Array lagre flere kuber.
offentlig var cubeArray: Array;
cubeArray = new Array (); // Opprett den nye Array for (var i: int = -1; jeg <= 1; i++ ) cube = new Cube( materialsList ); cube.x = i * 350; cube.scale = 0.40; cube.rotationX = 25; cube.rotationY = 40; scene.addChild( cube ); cubeArray.push( cube ); //add the new cube to the array
("Push" betyr bare "legg til slutten av listen".)
Nå som hver kube er i Array, kan vi løse gjennom Array hver ramme og rotere hver av dem:
offentlig funksjon onEnterFrame (evt: Event): void for hver (kube i cubeArray) cube.rotationX = cube.rotationX + 5; cube.rotationY = cube.rotationY + 5; renderer.renderScene (scene, kamera, visningsport);
"For hver" sløyfe gjør cube variabel refererer til hver kube i sin tur, en om gangen, i stedet for bare til den siste kuben som ble opprettet som den gjorde før. Her er resultatet:
Suksess!
Vi har laget en linje med kuber, så et torg kommer ikke til å være vanskelig. I stedet for å bare lage tre kubber, lager vi tre linjer av tre kuber.
For å gjøre dette kan vi bruke en loop-within-a-loop, slik som:
for (var jeg: int = -1; jeg <= 1; i++ ) for ( var j:int = -1; j <= 1; j++ ) //loop inside a loop cube = new Cube( materialsList ); cube.x = i * 350; cube.y = j * 350; //don't forget to change j! cube.scale = 0.40; cube.rotationX = 25; cube.rotationY = 40; scene.addChild( cube ); cubeArray.push( cube ); //don't forget this closing bracket either
Test det ut:
Hyggelig. Og merk at vi ikke måtte endre koden inni onEnterFrame () i det hele tatt; sløyfen som kjører hver ramme roterer bare hver kube inne i Array - og vi skyver fortsatt hver eneste kube på Array.
Vel, det ville være skuffende å stoppe på et torg, ville det ikke? Tross alt er dette en 3D opplæring.
Jeg forventer at du kan finne ut hvordan du gjør dette trinnet på egen hånd. Men hvis du vil sammenligne:
for (var jeg: int = -1; jeg <= 1; i++ ) for ( var j:int = -1; j <= 1; j++ ) for ( var k:int = 0; k <= 2; k++ ) cube = new Cube( materialsList ); cube.x = i * 350; cube.y = j * 350; cube.z = k * 350; cube.scale = 0.40; cube.rotationX = 25; cube.rotationY = 40; scene.addChild( cube ); cubeArray.push( cube );
Jeg har vært litt sneaky her. Jeg har startet k på 0 i stedet for på -1, fordi ellers ville det fremste laget av kuber være for nær kameraet. Selvfølgelig kan du bruke hvilket nummer du liker.
Hei, la du merke til at "dented" -effekten i utgangspunktet forsvunnet nå, da vi bruker mindre kuber?
Rått!
Dette skraper bare overflaten av det du kan gjøre med Papervision3D. Før vi går videre til 3D-briller, er det noen ting du kan eksperimentere med:
I den andre delen lærer du hvordan du får scenen til å fungere med 3D-briller. Så hvis du har et par, ikke kast dem bort!
I mellomtiden, takk for at du har lest den første delen. Jeg håper du fant det nyttig. Hvis du har noen spørsmål, eller hvis noe var forvirrende, vennligst legg inn en kommentar nedenfor.