För att koppla ihop med våra Papervision3D Essentials giveaway, har dagens handledning också ett PV3D-tema.
Den här tvådelade handledningen visar hur du kommer igång med Papervision3D-motorn, hur du gör din skapning hoppa ur skärmen med en anaglyph-effekt i kombination med 3D-glasögon.
Fick ett par 3D-glasögon liggande? Här i Storbritannien kör Channel 4 en speciell 3D-vecka - sju dagar av TV-program sänds i 3D - så mycket folk gör här. Låt oss sätta dem att använda.
Den här tvådelade handledningen visar hur du kommer igång med Papervision3D-motorn, och sedan hur du gör din skapning hoppa ur skärmen.
I den här första delen lär du dig grunderna för PV3D och slutar med något som detta:
... och i den andra delen lär du dig information om anaglyph-effekten för 3D-glasögon och tillämpa den på vad du har gjort så här:
Om du använder Flash skapar du en ny Flash-fil för ActionScript 3.0. Ställ in scenens storlek för att vara vad du vill - Jag håller med standard 550 med 400 pixlar.
Medan du är på den, skapa en ny ActionScript-fil och spara den som Main.as i samma mapp som din FLA. Vi ska använda denna AS-fil som FLA: n dokument klass, klicka så på ett tomt utrymme i din FLA-fil och skriv in Huvudsaklig i rutan "Dokumentklass" på Egenskaper-panelen.
(Om du inte använder Flash IDE, skapa bara ett nytt AS3-projekt.)
Gå över till Papervisions nedladdningssida. Det finns många olika versioner och några olika typer av filer (zip, swc, mxp). Ta bara den senaste .zip-filen (det borde säga Dagens bredvid den). Den jag använder heter Papervision3D 2.1.920.zip (för användning med "Papervision3D Essentials" bok).
Ta ut zip-filen du bara laddade ner till var som helst på hårddisken. Jag gillar att behålla alla de olika motorerna jag använder i samma mapp, men det är upp till dig.
Flash behöver veta var du extraherade Papervision innan den kan använda den. Vi använder en classpath för detta: klicka Redigera> Inställningar, Välj Action, Klicka sedan ActionScript 3.0-inställningar ... .
I rutan som visas klickar du på den lilla "crosshair" -ikonen och hittar sedan mappen där du plockade ut Papervision och klickar på OK. Klicka på OK i de andra rutorna tills du kommer tillbaka till FLA.
Om du inte använder Flash IDE måste du ange det på ett annat sätt. I FlashDevelop bör du till exempel klicka på Verktyg> Global Classpaths.
I Papervision måste alla dina 3D-objekt placeras inuti a scen. Det är typiskt som scenen i vanliga ActionScript. Så innan vi gör någonting behöver vi skapa en Scene3D objekt som innehåller allt annat.
Byt till din Main.as-fil. Låt oss snabbt lägga till baskoden som behövs för någon dokumentklass:
paket import flash.display.MovieClip; public class Main utökar MovieClip public function Main ()
Scene3D-objektet är i org.papervision3d.scenes.Scene3D, så måste vi göra det importera så skapar du en ny offentlig var att hålla scenen och slutligen skapa det aktuella scenobjektet: (linjerna 4, 8 och 12)
paket import flash.display.MovieClip; importera org.papervision3d.scenes.Scene3D; public class Main utökar MovieClip public var scene: Scene3D; allmän funktion Main () scene = new Scene3D ();
Till att börja med, låt oss bara skapa en stor vanlig kubssitta i vår scen.
Vi följer samma slags steg som ovan för att skapa det och lägg sedan till det i vår scen: (linjerna 5, 10, 15, 16)
paket import flash.display.MovieClip; importera org.papervision3d.scenes.Scene3D; importera org.papervision3d.objects.primitives.Cube; public class Main utökar MovieClip public var scene: Scene3D; offentlig var kub: kub; allmän funktion Main () scene = new Scene3D (); kub = ny kub (); scene.addChild (kub);
Observera att vi använder "addChild ()" för att lägga till kuben på scenen, precis som vi gör när vi lägger till en MovieClip på scenen.
Ovanstående kod kommer att ge dig ett fel om du försöker köra den. Det beror på att vi inte har sagt kuben hur ansiktsytorna ska se ut.
Papervision använder material för att beskriva hur en yta ser ut. Vi kan göra ett mycket enkelt, enkelfärgat material med hjälp av a ColorMaterial:
var grå Material: ColorMaterial = nytt ColorMaterial (0xCCCCCC);
"0xCCCCCC" representerar färgen grå; Ta bara färgkoden av vilken som helst färg och ersätt den # med 0x:
Eftersom en kub har sex ansikten behöver vi ge det sex material. För att göra detta sätter vi alla sex i en lista:
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");
... och skicka sedan den listan till kuben när vi skapar den:
kub = ny kub (materiallista);
Så hela din kod ska äntligen se ut så här: (glöm inte importera uttalanden!)
paket import flash.display.MovieClip; importera org.papervision3d.scenes.Scene3D; importera org.papervision3d.objects.primitives.Cube; importera org.papervision3d.materials.ColorMaterial; importera org.papervision3d.materials.utils.MaterialsList; public class Main utökar MovieClip public var scene: Scene3D; offentlig var kub: kub; allmän funktion 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"); scen = ny Scene3D (); kub = ny kub (materiallista); scene.addChild (kub);
Så vi har inga fel, men för att se någonting behöver vi lägga till en kamera till scenen. Vi ser allt genom kamerans "objektiv".
Att lägga till en kamera är lika enkelt som att lägga till en kub - enklare, eftersom vi inte behöver lägga tillChild () till scenen:
importera org.papervision3d.cameras.Camera3D;
public var kamera: Camera3D;
scen = ny Scene3D (); kub = ny kub (materiallista); scene.addChild (kub); kamera = ny Camera3D (); // Detta är den nya raden i Main ()
Nu är en kamera på scenen, men den är inte ansluten till någon utgång, så vi kan fortfarande inte se kuben!
Som standard placeras kuben högerklump i mitten av scenen (vid x = 0, y = 0, z = 0) och kameran är placerad 1000 enheter tillbaka från den (vid x = 0, y = 0, z = -1000).
Hur kan vi få den bild som kameran ser i Flash Player-fönstret?
Svaret är, vi använder en visningsområde. Det här är en typ av DisplayObject, som en MovieClip, så vi kan läggaChild () till scenen. Men vi kan också göra Papervision göra (dvs teckna) kamerans syn på den här utsikten - det är lite som att en konstnär ritar vad han kan se genom en kameralins, sedan tar sin ritning och klibbar den till en TV-apparat. Utom snabbare.
Så vi behöver skapa en visningsport och en renderer:
importera org.papervision3d.view.Viewport3D; importera org.papervision3d.render.BasicRenderEngine;
public var viewport: Viewport3D; public var renderer: BasicRenderEngine;
// sätt detta i slutet av Main () viewport = nytt Viewport3D (); viewport.autoScaleToStage = true; // detta kommer att göra visningsporten så stor som scenen addChild (viewport); renderer = ny BasicRenderEngine ();
Nu är allt vi behöver göra för att göra renderaren göra den verkliga rendering. För detta behöver den känna till scenen, kameran och visningsporten:
renderer.renderScene (scen, kamera, visningsport);
Äntligen! Vi kan äntligen testa SWF. Trumvirvel, tack…
Otrolig! Förvånande! OK bra, det är faktiskt ganska lamt. Hur kan vi till och med säga att det är en kub? Det ser ut som en fyrkant.
Om vi roterar kuben kan vi berätta om det verkligen är en kub eller inte.
Eftersom kuben är i tre dimensioner är ordet "rotera" lite förvirrande - vilken riktning menar vi? Vi måste ange huruvida vi roterar runt x-axeln, y-axeln eller z-axeln.
De Kub objektet har tre egenskaper som vi kan använda för att definiera detta, kallat (överraskande) rotationX, rotationY och rotationZ. Låt oss ändra ett par av dem:
scen = ny Scene3D (); kub = ny kub (materiallista); kub.rotationX = 25; // ändra rotation cube.rotationY = 40; // ändra rotation scen.addChild (kub); kamera = ny Camera3D ();
Det är bättre, men eftersom alla ansikten är exakt samma färg, går de bara in i varandra. Låt oss fixa det.
Istället för grått ska jag måla sidorna med ActiveTuts + -logotypen.
Om du använder Flash IDE, skapa ett nytt filmklipp och dra eller klistra in den bild du vill använda. Jag har tagit med logotypen i mitt FLA-bibliotek inom zip.
Högerklicka på ditt filmklipp och välj Egenskaper. Markera "exportera till ActionScript" och ge det ett klassnamn. Detta låter dig komma åt det med hjälp av kod. (Om du inte använder Flash IDE, innehåller zip också en SWC med en MovieClip som heter ActiveTutsLogo som du kan använda. Eller du kan skapa en ny MovieClip-kod och lägga till din bild till den. Jag ska inte gå in i detaljerna om det här, men.)
I stället för a ColorMaterial vi ska använda en MovieMaterial, och istället för att ange en färg ska vi ange ett filmklipp. Så ersätt det här:
var grå Material: ColorMaterial = nytt 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 detta:
var logoMaterial: MovieMaterial = nytt MovieMaterial (nytt ActiveTutsLogo ()); // ersätt "ActiveTutsLogo" ovan med klassnamnet på ditt filmklipp var 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åste också importera MovieMaterial:
importera org.papervision3d.materials.MovieMaterial;
Testa det igen:
Tja, det fungerar, men det ser lite ut.
Den "dämpade" utseendet är att Papervision är som standard för att rita saker snabbt snarare än exakt. Jag vill se till att denna handledning kommer att springa på långsammare datorer, så jag ska lämna den där, men här är hur du kan förbättra det:
När du skapar kuben kan du skicka det parametrar för att definiera hur många segment Varje ansikte delas upp i. Ju fler segment du väljer, desto mer exakt ser kuben ut - men desto långsammare blir den gjord.
Jag har funnit att 10 är ett bra antal segment att använda i varje riktning. Så här ser koden ut:
kub = ny kub (materiallista, 500, 500, 500, 10, 10, 10);
Den femte, sjätte och sjunde parametern definierar antalet segment som används i varje riktning. För att ställa in dem måste vi dock ange alla parametrar innan den femte också.
Vi anger redan den första parametern - det är materiallistan. Den andra, tredje och fjärde parametern definierar kubens bredd, djup och höjd. Dessa är inställda till 500 som standard, så jag har hållit dem samma här.
Om du använder ovanstående kodregel kommer din kub att se ut så här:
Mycket snyggare!
Vi kan göra en vanlig MovieClip spinn runt genom att öka dess rotation egendom varje ram - och vi kan naturligtvis göra samma sak med kuben och dess rotationX / Y / Z-värden.
Skapa en ENTER_FRAME händelse lyssnare, som kommer att köra varje ram:
importera flash.events.Event;
// längst ner i Main () addEventListener (Event.ENTER_FRAME, onEnterFrame);
// som en ny funktion // i huvudklassen men utanför huvudfunktionen () funktionen public function onEnterFrame (evt: Event): void cube.rotationX = cube.rotationX + 5; cube.rotationY = cube.rotationY + 5;
Detta gör att kuben vänder lite mer varje ram. Så om du testar SWF ut nu ... kommer kuben vara helt stilla. Huh?
Tänk tillbaka till målaren. Vi tittar fortfarande på hans gamla bild - vi behöver honom att dra oss en ny varje ram, eller vi kommer inte se några förändringar!
Så, ändra funktionen onEnterFrame ():
offentlig funktion onEnterFrame (evt: Event): void cube.rotationX = cube.rotationX + 5; cube.rotationY = cube.rotationY + 5; renderer.renderScene (scen, kamera, visningsport);
Kolla in det nu:
En kub är stor, men som Roman redan visat dig hur man gör det med Away3D, låt oss ta saker lite längre.
Låt oss lägga till några fler, för att bilda en horisontell linje av kuber. Vi kan använda en enkel för loop för att göra det; ersätt bara den här koden:
kub = ny kub (materiallista); kub.rotationX = 25; // ändra rotation cube.rotationY = 40; // ändra rotation scen.addChild (kub);
… med detta:
för (var i: int = -1; i <= 1; i++ ) cube = new Cube( materialsList ); cube.x = i * 350; cube.rotationX = 25; cube.rotationY = 40; scene.addChild( cube );
Observera att jag gör x-positionen för varje kub beror på hur långt vi är genom slingan. Om du kör detta får du följande:
Whoops, kuberna är för nära varandra. Vi kan krympa dem för att komma runt detta; ändra bara skala egenskapen hos varje kub:
för (var i: int = -1; i <= 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å fixar skärningsproblemet, men bara en av våra kuber spinner. Hurså?
Det beror på att kub variabel hänvisar alltid endast till sista kub skapad - och vår funktion onEnterFrame () ändrar bara rotationerna i den där kuben.
Så för att fixa detta behöver vi en Array. Precis som vår materiallista har lagrat flera material, kommer vår Array att lagra flera kuber.
public var cubeArray: Array;
cubeArray = new Array (); // skapa den nya Array för (var i: int = -1; i <= 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" betyder bara "lägg till i slutet av listan".)
Nu när varje kub är i Array kan vi loopa genom Array varje ram och rotera var och en av dem:
offentlig funktion onEnterFrame (evt: Event): void för varje (kub i cubeArray) cube.rotationX = cube.rotationX + 5; cube.rotationY = cube.rotationY + 5; renderer.renderScene (scen, kamera, visningsport);
"För varje" slinga gör kub variabel hänvisar till varje kub i sin tur, en i taget, snarare än bara till den sista kuben som skapades som den gjorde tidigare. Här är resultatet:
Framgång!
Vi har gjort en rad kuber, så en kvadrat kommer inte bli svårt. I stället för att bara göra tre kuber ska vi göra tre rader av tre kuber.
För att göra detta kan vi använda en loop-within-a-loop, så här:
för (var i: int = -1; i <= 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
Testa det:
Trevlig. Och notera att vi inte behövde ändra koden inuti onEnterFrame () alls; slingan som löper varje ram roterar bara varje kub inuti arrayen - och vi pressar fortfarande varje enskild kub på arrayen.
Tja, det skulle vara en besvikelse att sluta på en torg, eller hur? Det här är trots allt en 3D-handledning.
Jag förväntar mig att du kan räkna ut hur man gör det här steget på egen hand. Men om du vill jämföra:
för (var i: int = -1; i <= 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 );
Jag har varit lite snuskig här. Jag har startat k vid 0 istället för vid -1, för annars skulle det främsta lagret av kuber vara för nära kameran. Naturligtvis kan du använda vilket nummer du vill ha.
Hej, märkte du att "dämpad" effekten i grunden har försvunnit nu att vi använder mindre kuber?
Grymt bra!
Detta skrapar bara ytan på vad du kan göra med Papervision3D. Innan vi går vidare till 3D-glasögon, är det några saker du kan experimentera med:
I den andra delen lär du dig hur du gör din scen med 3D-glasögon. Så om du har ett par, släng dem inte bort!
Under tiden tack för att du läste den första delen. Jag hoppas att du fann det användbart. Om du har några frågor, eller om något var förvirrande, vänligen skriv en kommentar nedan.