Wie der Titel schon sagt, simulieren wir ein Atom mit Elektronenschalen, die einen Kern umkreisen, mit Papervision 3D. Lasst uns anfangen…
Dieses Projekt wurde ausschließlich mit ActionScript 3.0 mit FlashDevelop erstellt. Wenn Sie es auf die gleiche Weise tun möchten, können Sie FlashDevelop hier herunterladen. (Befolgen Sie die Konfigurationsanweisungen hier.) Andernfalls können Sie Flash CS3 oder höher verwenden.
Werfen wir einen Blick auf das Endergebnis, auf das wir hinarbeiten:
Bewegen Sie die Maus, und die Kamera kann den Atom frei umkreisen. Bringen Sie das Atom in eine Position, die Sie mögen, und klicken Sie mit der Maus auf die Bühne. Dadurch wird das Atom auf eine feste z-Position gesetzt, sodass Sie die Kamera um ihre X- und Y-Achsen drehen können. Klicken Sie erneut auf die Bühne, um den z-Orbit der Kamera freizugeben.
Öffnen Sie FlashDevelop und klicken Sie auf Projekt> Neues Projekt
Wählen Sie ActionScript 3> AS3Project. Für den Namen des Projekts geben Sie "Atoms" ein. Klicken Sie für den Speicherort auf und navigieren Sie zu dem Ordner, in dem Sie ihn speichern möchten. Lassen Sie das Kontrollkästchen "Verzeichnis für Projekt erstellen" aktiviert und klicken Sie auf "OK".
Wenn Sie Flash CS3 / CS4 verwenden möchten, erstellen Sie eine neue Flash-Datei und legen Sie die Breite und Höhe auf 600x500 fest. Setzen Sie die Hintergrundfarbe auf Schwarz. Nennen Sie es "Atoms.fla" und speichern Sie es an einem beliebigen Ort.
Kopieren Sie für Flash die Ordner "org" und "nochump" aus dem Quelldownload in den Ordner, in dem Sie die Atome.fla-Datei gespeichert haben.
Fahren Sie für FlashDevelop fort und kopieren oder ziehen Sie die Datei Papervision3D_2.1.932.swc aus den Quelldateien (oben herunterladbar) in den Ordner lib für dieses Projekt. Weitere Informationen zu PV3D finden Sie hier.
Klicken Sie in FlashDevelop auf Ansicht> Projektmanager. Klicken Sie auf das Pluszeichen links neben dem lib-Ordner, um ihn zu erweitern. Klicken Sie nun mit der rechten Maustaste auf "Papervision3D_2.1.932.swc" und wählen Sie "Zur Bibliothek hinzufügen".
Öffnen Sie für FlashDevelop den Projektmanager erneut (siehe Schritt 4), erweitern Sie den Ordner src, und doppelklicken Sie auf Main.as
Fügen Sie unterhalb der Importe und oberhalb der Klassendefinition das folgende Metadaten-Tag hinzu, um die Stage-Eigenschaften einzurichten.
[SWF (Breite = 600, Höhe = 500, FrameRate = 30, Hintergrundfarbe = 0)]
Fügen Sie in der Methode init () nach dem Kommentar "Einstiegspunkt" die folgenden Codezeilen hinzu.
stage.addEventListener (Event.RESIZE, createBackground); _backGround = neues Sprite; addChild (_backGround); createBackground (); var helium3: Helium3Atom = neues Helium3Atom; addChild (Helium3);
Als Nächstes erstellen wir einen einfachen Hintergrund mit Farbverlauf. Fügen Sie nach der Methode init () die folgenden Codezeilen hinzu:
private Funktion createBackground (e: Event = null): void var g: Graphics = _backGround.graphics; g.clear (); var fillType: String = GradientType.RADIAL; Var-Farben: Array = [0x0000FF, 0x000000]; var alphas: Array = [1, 1]; var Verhältnisse: Array = [0x00, 0xFF]; var matr: Matrix = neue Matrix (); matr.createGradientBox (stage.stageWidth, stage.stageHeight, 0, 0, 0); var spreadMethod: String = SpreadMethod.PAD; g.beginGradientFill (fillType, Farben, Alphas, Verhältnisse, Matr, SpreadMethod); g.drawRect (0, 0, stage.stageWidth, stage.stageHeight);
Das ist alles für die Hauptdokumentklasse, wenn Sie FlashDevelop verwenden.
Erstellen Sie für Flash eine neue Main.as-Klasse in demselben Ordner wie Ihr Projekt. Stellen Sie sicher, dass sich die Klasse "Main.as" im selben Ordner befindet wie die Ordner "Atoms.fla", "org" & "nochump".
Fügen Sie die folgenden Zeilen hinzu:
package import flash.display.GradientType; import flash.display.Graphics; import flash.display.SpreadMethod; import flash.display.Sprite; import flash.events.Event; import flash.geom.Matrix; public class Main erweitert Sprite private var _backGround: Sprite; öffentliche Funktion Main (): void if (stage) init (); else addEventListener (Event.ADDED_TO_STAGE, init); private Funktion init (e: Event = null): void removeEventListener (Event.ADDED_TO_STAGE, init); stage.addEventListener (Event.RESIZE, createBackground); _backGround = neues Sprite; addChild (_backGround); createBackground (); var helium3: Helium3Atom = neues Helium3Atom; addChild (Helium3); private Funktion createBackground (e: Event = null): void var g: Graphics = _backGround.graphics; g.clear (); var fillType: String = GradientType.RADIAL; Var-Farben: Array = [0x0000FF, 0x000000]; var alphas: Array = [1, 1]; var Verhältnisse: Array = [0x00, 0xFF]; var matr: Matrix = neue Matrix (); matr.createGradientBox (stage.stageWidth, stage.stageHeight, 0, 0, 0); var spreadMethod: String = SpreadMethod.PAD; g.beginGradientFill (fillType, Farben, Alphas, Verhältnisse, Matr, SpreadMethod); g.drawRect (0, 0, stage.stageWidth, stage.stageHeight);
Öffnen Sie Flash und weisen Sie "Main" als Dokumentklasse zu. (Schauen Sie sich diese kurze Einführung in Dokumentenklassen an, wenn Sie nicht sicher sind, was wir tun.)
Wenn Sie versuchen, dies jetzt auszuführen, wird eine Fehlermeldung angezeigt, da wir die Helium3Atom-Klasse noch nicht erstellt haben. Stellen Sie also sicher, dass Sie die Datei speichern und für den Moment belassen.
Klicken Sie in FlashDevelop auf Ansicht> Projektmanager, klicken Sie mit der rechten Maustaste auf den Ordner src, und wählen Sie Hinzufügen> Neue Klasse.
Benennen Sie die Klasse Helium3Atom, klicken Sie auf die Durchsuchen-Schaltfläche für die Basisklasse und geben Sie "org.papervision3d.view.BasicView" ein. Klicken Sie auf OK, um den Vorgang abzuschließen.
(Noch in FlashDevelop) Fügen Sie alle erforderlichen Importe in den Paketklammern rechts über "import org.papervision3d.view.BasicView;" und speichern Sie die Datei.
import flash.events.Event; import flash.events.MouseEvent; import org.papervision3d.lights.PointLight3D; import org.papervision3d.materials.ColorMaterial; import org.papervision3d.materials.shadematerials.GouraudMaterial; import org.papervision3d.materials.WireframeMaterial; import org.papervision3d.objects.DisplayObject3D; import org.papervision3d.objects.primitives.Cylinder; import org.papervision3d.objects.primitives.Sphere;
Erstellen Sie für Flash eine neue ActionScript-Datei, nennen Sie sie Helium3Atom und speichern Sie sie in demselben Verzeichnis, in dem Sie sich bereits befunden haben. Es sollte sich direkt neben der Datei Atoms.fla, den Ordnern "org" und "nochump" und der Klasse Main.as befinden. Fügen Sie den folgenden Code hinzu:
package import flash.events.Event; import flash.events.MouseEvent; import org.papervision3d.lights.PointLight3D; import org.papervision3d.materials.ColorMaterial; import org.papervision3d.materials.shadematerials.GouraudMaterial; import org.papervision3d.materials.WireframeMaterial; import org.papervision3d.objects.DisplayObject3D; import org.papervision3d.objects.primitives.Cylinder; import org.papervision3d.objects.primitives.Sphere; import org.papervision3d.view.BasicView; public class Helium3Atom erweitert BasicView public function Helium3Atom ()
Fügen Sie in der Klassenklammer direkt vor der Konstruktormethode die folgenden Codezeilen hinzu:
private var _do3DArray: Array; // enthält alle Referenzen zu allen Elekronen und ihren Ringen private var _easeOut: Number = .3; // Abschwächung beim Verschieben der Kamera private var _reachX: Number = .1; // der untere Dies ist gesetzt, je weiter die Reichweite in Richtung ihrer x-Achse private var _reachY: Number = .1; // die gleiche wie reachX ist, gilt jedoch für die y-Achse private var _reachZ: Number = .5; // wird in Verbindung mit dem - verwendet. mouseY: Je näher sich die MouseY an der Bühnenmitte befindet, desto mehr bewegt sich die Kamera auf das Atom zu. private var _rotX: Number = 0.5; // der für die Kamerarotation auf der x-Achse verwendete Wert private var_rotY: Number = 0.5; // wie _rotX, gilt jedoch für die y-Achse der Kamera. private var _camPitch: Number = 0; // Umlaufbahn auf der x-Achse berechnet innerhalb der onRenderTick () - Methode private var _camYaw: Number = 0; // Umlaufbahn auf der y-Achse innerhalb der onRenderTick () - Methode private var _zDist: Number = 4; // steuert die Stärke des Ein- und Auszoomens der Kamera private var _colorArray: Array = [0xCC490B, 0x26D965, 0xCC490B]; // Farben für die Neutronen und Protonen im Inneren des Nukleus private var _freeOrbit: Boolean = true; // schaltet den Orbit um Modus der Kamera
Fügen Sie die folgenden Zeilen in die Konstruktionsmethode ein.
wenn (Stufe) init (); else addEventListener (Event.ADDED_TO_STAGE, init); startRendering ();
Die ersten beiden Zeilen rufen die Methode init () auf. (Wenn die Bühne noch nicht verfügbar ist, fügt sie einen Listener hinzu, wenn die Instanz zur Bühne hinzugefügt wird, und ruft dann die Methode init () auf.)
Anschließend wird die startRendering () -Methode aufgerufen. Diese Methode stammt aus der Superklasse von BasicView, der "AbstractView". Diese Methode fügt einen ENTER_FRAME-Listener hinzu, der die onRenderTick () -Methode auslöst. Wir müssen diese geschützte Methode später überschreiben, um das Atom zu animieren und die Kamera zu bewegen.
Innerhalb der vom Konstruktor aufgerufenen Methode init () entfernen wir zuerst den Ereignis-Listener, um die Instanz der Bühne hinzuzufügen, und rufen dann die Methode createAtom () auf
Fügen Sie die folgenden Codezeilen unter der constructor () -Methode hinzu:
private Funktion init (e: Event = null): void removeEventListener (Event.ADDED_TO_STAGE, init); createAtom ();
Gehen wir einfach durch, was in der createAtom () -Methode passiert. Das _do3DArray wird instanziiert, wir müssen Referenzen von allen DisplayObject3D-Elementen einfügen, die die Ringe und Elektronen in diesem Array enthalten, damit wir später für die Animation darauf zugreifen können.
Einer lokalen Variablen mit dem Namen "light" wird eine PointLight3D-Objektinstanz zugewiesen und sie befindet sich oben rechts in der Szene.
Eine weitere lokale Variable mit dem Namen "Atom" wird einer DisplayObject3D-Instanz zugewiesen und der Szene hinzugefügt. Dies ist das übergeordnete DisplayObject3D für alle anderen Elemente.
Der "Nukleus", auch ein DisplayObject3D, wird dann instanziiert. Es wird auf der x-Achse um 90 Grad gedreht, damit es der Kamera zugewandt ist, und wird dann der DisplayObject3D-Instanz "atom" hinzugefügt.
Der "Sphäre" -Variable, auch eine lokale Variable, wird dann ein Sphere-Objekt zugewiesen. Eine Kugel ist ein in PV3D eingebautes Grundelement. Bei dieser speziellen Instanz weisen wir für den Materialparameter "Null" zu, für den Radiusparameter "25" und für die Parameter "segmentW" und "segmentH" "1".
Fügen Sie nach ihrer init () - Methode die folgenden Codezeilen hinzu:
private Funktion createAtom (): void _do3DArray = []; var light: PointLight3D = neues PointLight3D; Licht x = 300; light.y = 700; Licht.z = 0; scene.addChild (light) var atom: DisplayObject3D = neues DisplayObject3D; scene.addChild (atom); var nucleus: DisplayObject3D = neues DisplayObject3D; Nucleus.rotationX = 90; atom.addChild (Kern); var Kugel: Kugel = neue Kugel (Null, 25, 1, 1); scene.addChild (Kugel);
Fahren Sie fort und drücken Sie auf Ihrer Tastatur STRG + Eingabetaste. Die Kugel sieht eher aus wie ein Polygon mit 5 Ecken. Dies liegt daran, dass wir für beide Segmente W und Segmente 1 eine 1 zugewiesen haben. Es hat insgesamt 5 Scheitelpunkte.
Entfernen Sie nach dem Testen die addChild-Methode. Die "Kugel" wird nicht zur Szene hinzugefügt, sondern dient als Orientierungshilfe für die Positionierung der Neutronen und Protonen, wie Sie als nächstes sehen werden. Fügen Sie den folgenden Code innerhalb der createAtom () - Methode nach der "sphere" -Deklaration hinzu, in der Sie die addChild-Methode entfernt haben.
für (var i: uint = 1; i < sphere.geometry.vertices.length-1; i++) var np:Sphere = new Sphere (new GouraudMaterial (light, _colorArray[i - 1], 0, 0), 23, 12, 9); np.x = sphere.geometry.vertices[i].x; np.y = sphere.geometry.vertices[i].y; np.z = sphere.geometry.vertices[i].z; nucleus.addChild (np);
Diese Schleife wiederholt sich von 1 bis 4 und überspringt 0 und 5. Eine lokale Variable, die zweckmäßigerweise "np" (Neutronen und Protonen) genannt wird, wird während jeder Schleife erstellt und mit einem Sphere-Primitiv versehen. Jeder "np" -Kugel wird ein GouraudMaterial mit dem zuvor erstellten PointLight3D-Objekt für light und colorArray [i-1] für den Parameter lightColor zugewiesen. Dem zweiten Parameter der Sphäre "np" ist ein Radius von "23" zugewiesen, und die letzten beiden Parameter sind für die Segmente W & SegmentH, denen jeweils "12" und "9" zugewiesen sind. Wir können uns höhere Mengen an Segmenten leisten, da sich im Kern nur 3 Kugeln befinden. Das Ergebnis ist eine rundere Sphäre…
Jede "np" -Kugel wird dann innerhalb des Kerns mit den Koordinaten hinzugefügt, die auf dem Scheitelpunkt der aktuellen Iteration in der "Kugel" -Kugel basieren.
Von hier aus iterieren wir zweimal, um die Elektronen und ihre entsprechenden Ringe zu erzeugen.
Zuerst wird ein DisplayObject3D instanziiert und "do3d" zugewiesen. Dieses DisplayObject3D enthält sowohl das Elektron als auch seinen Ring.
Ein Sphere-Primitiv wird erstellt und "Elektron" zugewiesen. Dies führt dazu, dass die weiß gefärbten Elektronen den Kern umkreisen. Die Parameter, die wir zur Erzeugung jedes Elektrons zugewiesen haben, lauten wie folgt: Ein ColorMaterial mit einem Wert von 0xEFECCA mit voller Opazität, der Radius der Kugel mit einem Wert von 7. Die letzten beiden optionalen Parameter, die wir ausgelassen haben, haben die Werte 8 und 6.
Ein Zylinder-Grundelement wird dann erstellt, um die Ringe herzustellen. Hier verwenden wir einfach ein WireframeMaterial in Weiß, ein Alpha von 0,05, eine Dicke von 2, einen Radius von 300, eine Höhe von 1 und Segmente W von 48, um es wirklich rund zu machen, und Segmente H von 1, da die Höhe ebenfalls 1 beträgt Der topRadius-Wert wird mit -1 als Standardwert belassen. Wir setzen sowohl topFace als auch bottomFace auf "false", da wir sie hier nicht benötigen.
Das Elektron wird dann auf 303 positioniert, sodass sich der Ring genau in der Mitte des Elektrons befindet.
Dann setzen wir die Eigenschaft doubleSided des Materials des Rings auf "true", damit der Ring sowohl die Innen- als auch die Außenhülle zeigt.
Danach wird die localRotationZ des do3d berechnet, indem 360 durch die doppelte Anzahl von Ringen dividiert, mit i multipliziert und das Ergebnis um 45 Grad addiert wird. Wenn der Ring zum ersten Mal erstellt wird, liegt er flach wie der Boden einer Tasse. Wir multiplizieren die Anzahl der Ringe mit 2, um ihre "z" -Achse von 0 bis 90 zu drehen, und addieren Sie 45 Grad, um eine schöne "X" -Formation für die 2 Ringe zu erhalten. Dann setzen wir die "y" -Drehung des do3d auf eine zufällige Position eines vollen Kreises, so dass die Elektronen alle eine andere Position haben, wenn sie den Kern umkreisen.
Die Ringe und Elektronen werden dann in do3d hinzugefügt. Anschließend wird eine Referenz in das _do3dArray eingefügt.
Schließlich wird das do3d innerhalb des Atoms DisplayObject3D hinzugefügt.
Fügen Sie die folgenden Codezeilen direkt unter der schließenden Klammer der ersten Schleife ein:
für (i = 0; i < 2; i++) var do3d:DisplayObject3D = new DisplayObject3D; var ring:Cylinder; var electron:Sphere; electron = new Sphere (new ColorMaterial (0xEFECCA, 1), 7); ring = new Cylinder (new WireframeMaterial (0xFFFFFF, .05, 2), 300, 1, 48, 1, -1, false, false); electron.x = 303;//add half size of electron ring.material.doubleSided = true; do3d.localRotationZ = 360 / 4 * i + 45; do3d.localRotationY = 360 * Math.random (); do3d.addChild (ring); do3d.addChild (electron); _do3DArray.push (do3d); atom.addChild (do3d);
Lassen Sie uns es testen und sehen, ob es funktioniert hat. Wenn alles gut lief, sollten Sie ein Bild wie folgt haben:
Wir sind fast fertig, wir müssen jetzt nur noch eine Animation hinzufügen.
Fügen Sie in der Methode init () (siehe Schritt 12) vor dem Aufruf der Methode "createAtom ()" die folgende Codezeile hinzu:
stage.addEventListener (MouseEvent.CLICK, onStageClick);
Dies löst die Änderung des Orbitmodus der Kamera aus. Fügen Sie den folgenden Code unter der schließenden Klammer der Methode init () hinzu:
private Funktion onStageClick (e: MouseEvent): void _freeOrbit =! _freeOrbit;
Alles, was Sie tun, ist _freeOrbit zwischen wahr oder falsch umzuschalten.
Die onRenderTick () -Methode wird über eine Event.ENTER_FRAME der BasicView-Superklasse - AbstractView - ausgelöst.
Innerhalb dieses, super.onRenderTick (Ereignis) wird aufgerufen, um die Szene zu rendern.
Das DisplayObject3D, in dem sich die Ringe und Elektronen in _do3dArray befinden, wird dann mit einem Gierwinkel von 10 angewendet. Das Anwenden von Yaw auf ein DisplayObject3D ist das gleiche wie bei do3d.localRotationY + = 10 ;. Dies ist, was die Ringe und Elektronen den Kern umkreisen lässt.
XDist und yDist berechnen einfach, wie weit sich mouseX & mouseY vom Bühnenmittelpunkt entfernt befinden.
Dann haben wir die Bedingung, die den aktuellen Status von _freeOrbit überprüft. Wenn _freeOrbit wahr ist, bewegt sich die Kamera frei in ihren 3 Achsen. Wenn Sie die Maus nach links bewegen, verringert sich die Kamera nach links, während Sie die Maus nach rechts bewegen, um das Gegenteil zu tun. Gleiches gilt für die y-Achse der Kamera (auf und ab). Wenn sich die Kamera der Mitte am nächsten befindet, wird ein Zoomeffekt angewendet.
Wenn dagegen _freeOrbit falsch ist, kann die Kamera nur frei um ihre x- und y-Achsen kreisen und hat eine feste z-Position. Dies hat den Effekt, dass sich die Kamera um das Atom herum bewegt. Die Gleichung ist leichter zu verstehen, wenn Sie mit den Werten der Eigenschaften spielen. Auf _camPitch wird ein Winkel von 90 Grad angewendet, so dass das Atom vollständig in die Mitte der Bühne zeigt, wenn sich die Maus in der Mitte der Bühne befindet. Andernfalls befindet sich das Atom auf der linken Seite, wenn sich die Maus auf der Bühne befindet.
Dies ist der gleiche Grund, warum 270 Grad auf _camYaw angewendet wird. Wenn nicht hinzugefügt, befindet sich das Atom auf seiner Oberseite, wenn sich die Maus in der Mitte der Bühne befindet. Außerdem begrenzen wir den Orbit der Kamera, wenn Sie die Maus auf der Bühne auf und ab bewegen. Wenn Sie die Grenzen von _camPitch entfernen, gibt es einen Punkt, an dem die Kamera auf den Kopf gestellt wird und sich selbst korrigiert. Dies hat einen unerwünschten Effekt. Wenn die Klasse im nächsten Schritt abgeschlossen ist, entfernen Sie die Grenzwerte, um zu sehen, was passiert.
Fügen Sie nach der createAtom () -Methode die folgenden Codezeilen hinzu.
Geschützte Funktion onRenderTick überschreiben (event: Event = null): void super.onRenderTick (event); für (var i: uint = 0; i < _do3DArray.length; i++) _do3DArray[i].yaw (10); var xDist:Number = mouseX - stage.stageWidth * .5; var yDist:Number = mouseY - stage.stageHeight * .5; if (_freeOrbit) camera.x += (xDist - camera.x * _reachX) * _easeOut; camera.y += (yDist - camera.y * _reachY) * _easeOut; camera.z += (-mouseY * _zDist - camera.z) * _reachZ; else _camPitch += ((-yDist * _rotX) - _camPitch + 90) * _easeOut; _camYaw += ((xDist * _rotY) - _camYaw + 270) * _easeOut; if(_camPitch < 5) _camPitch = 5; if(_camPitch > 175) _camPitch = 175; camera.orbit (_camPitch, _camYaw);
Das sollte alles für die Helium3Atom-Klasse sein. Ihre Klasse sollte genau wie folgt aussehen:
package import flash.events.Event; import flash.events.MouseEvent; import org.papervision3d.lights.PointLight3D; import org.papervision3d.materials.ColorMaterial; import org.papervision3d.materials.shadematerials.GouraudMaterial; import org.papervision3d.materials.WireframeMaterial; import org.papervision3d.objects.DisplayObject3D; import org.papervision3d.objects.primitives.Cylinder; import org.papervision3d.objects.primitives.Sphere; import org.papervision3d.view.BasicView; public class Helium3Atom erweitert BasicView private var _do3DArray: Array; private var _easeOut: Number = .3; private var _reachX: Number = .1; private var _reachY: Number = .1; private var _reachZ: Number = .5; private var _rotX: Number = 0,5; private var _rotY: Anzahl = 0,5; private var _camPitch: Number = 0; private var _camYaw: Anzahl = 0; private var _zDist: Number = 4; private var _colorArray: Array = [0xCC490B, 0x26D965, 0xCC490B]; private var _freeOrbit: Boolean = true; öffentliche Funktion Helium3Atom () if (stage) init (); else addEventListener (Event.ADDED_TO_STAGE, init); startRendering (); private Funktion init (e: Event = null): void removeEventListener (Event.ADDED_TO_STAGE, init); stage.addEventListener (MouseEvent.CLICK, onStageClick); createAtom (); private Funktion onStageClick (e: MouseEvent): void _freeOrbit =! _freeOrbit; private Funktion createAtom (): void _do3DArray = []; var light: PointLight3D = neues PointLight3D; Licht x = 300; light.y = 700; Licht.z = 0; scene.addChild (light) var atom: DisplayObject3D = neues DisplayObject3D; scene.addChild (atom); var nucleus: DisplayObject3D = neues DisplayObject3D; Nucleus.rotationX = 90; atom.addChild (Kern); var Kugel: Kugel = neue Kugel (null, 25, 1, 1); // unsichtbare Führung für (var i: uint = 1; i < sphere.geometry.vertices.length-1; i++) var np:Sphere = new Sphere (new GouraudMaterial (light, _colorArray[i - 1], 0, 0), 23, 12, 9); np.x = sphere.geometry.vertices[i].x; np.y = sphere.geometry.vertices[i].y; np.z = sphere.geometry.vertices[i].z; nucleus.addChild (np); for (i = 0; i < 2; i++) var do3d:DisplayObject3D = new DisplayObject3D; var ring:Cylinder; var electron:Sphere; electron = new Sphere (new ColorMaterial (0xEFECCA, 1), 7); ring = new Cylinder (new WireframeMaterial (0xFFFFFF, .05, 2), 300, 1, 48, 1, -1, false, false); electron.x = 303;//add half size of electron ring.material.doubleSided = true; do3d.localRotationZ = 360 / 4 * i + 45; do3d.localRotationY = 360 * Math.random (); do3d.addChild (ring); do3d.addChild (electron); _do3DArray.push (do3d); atom.addChild (do3d); override protected function onRenderTick (event:Event = null):void super.onRenderTick (event); for (var i:uint = 0; i < _do3DArray.length; i++) _do3DArray[i].yaw (10); var xDist:Number = mouseX - stage.stageWidth * .5; var yDist:Number = mouseY - stage.stageHeight * .5; if (_freeOrbit) camera.x += (xDist - camera.x * _reachX) * _easeOut; camera.y += (yDist - camera.y * _reachY) * _easeOut; camera.z += (-mouseY * _zDist - camera.z) * _reachZ; else _camPitch += ((-yDist * _rotX) - _camPitch + 90) * _easeOut; _camYaw += ((xDist * _rotY) - _camYaw + 270) * _easeOut; if(_camPitch < 5) _camPitch = 5; if(_camPitch > 175) _camPitch = 175; camera.orbit (_camPitch, _camYaw);
Drücken Sie STRG + EINGABETASTE und Sie sollten so etwas wie Sie unten sehen:
Ok, lassen Sie uns jetzt ein etwas komplexeres Atom erstellen. Erstellen Sie eine neue Klasse (wenn Sie FlashDevelop verwenden, lesen Sie die Schritte 7 und 8). Der einzige Unterschied sollte der Name sein, es sollte "CarbonAtom" sein. Es hat fast den gleichen Code, mit ein paar Änderungen, also kopieren Sie den gesamten Inhalt des Helium3Atom, wählen Sie den gesamten Inhalt des CarbonAtom aus und ersetzen Sie ihn durch den von Helium3Atom kopierten Code.
Beginnen wir mit dem Modifizieren von oben. Entfernen Sie innerhalb der Klassendeklaration, in der _colorsArray vorhanden ist, das zugewiesene Array, das die 3 Farben enthält.
Als nächstes gehen Sie zur init () - Methode. Fügen Sie den folgenden Code vor dem Aufruf der createAtom () -Methode hinzu:
randomizeColorArray ();
Gehen Sie unter die onStageClick () -Methode und fügen Sie diese neue Methode hinzu:
private Funktion randomizeColorArray (): void _colorArray = []; var tempArray: Array = []; für (var i: uint = 0; i < 12; i++) if (i < 6) var color:uint = 0x004080; //shade of blue else color = 0xA40000; //shade of red tempArray.push (color); while (tempArray.length > 6) _colorArray.push (tempArray.splice (uint (Math.random () * tempArray.length), 1)); _colorArray = _colorArray.concat (tempArray);
Diese Methode randomisiert die Position von 2 Farben, die in _colorArray gespeichert sind. Dadurch werden 6 gleiche Teile von Rot und Blau zufällig in _colorArray positioniert.
Fahren Sie als Nächstes mit der createAtom () -Methode fort, wo "Nucleus" instanziiert wird, und entfernen Sie die Zuweisung "nucleus.rotationX = 90".
Gehen Sie 2 Zeilen nach unten und ändern Sie die Parameter der Kugel-Instantiierung in "var sphere: Sphere = new Sphere (null, 60, 4, 4);". Wir brauchen eine größere Kugel mit mehr Ecken, um alle 12 Protonen und Neutronen aufnehmen zu können.
Gehen Sie nun in die erste Schleife, in der die "np" -Sphäre instanziiert wird, und entfernen Sie die letzten 2 Parameter von 12 und 9. Dadurch werden die Segmente W und SegmentH auf ihre Standardwerte 8 bzw. 6 gesetzt und die Leistung wird beeinträchtigt.
Als nächstes ändern Sie in der zweiten Schleife die Anzahl der Schleifen von 2 auf 6. Gehen Sie rechts unterhalb der Elektroneninstanziierung vor und ersetzen Sie den folgenden Code:
ring = new Cylinder (neues WireframeMaterial (0xFFFFFF, .05, 2), 300, 1, 48, 1, -1, false, false); Elektron.x = 303;
mit:
if (i == 1 || i == 5) ring = new Cylinder (neues Drahtmodellmaterial (0xFFFFFF, .05, 2), 450, 1, 48, 1, -1, falsch, falsch); Elektron.x = 453; else ring = new Cylinder (neues WireframeMaterial (0xFFFFFF, .05, 2), 610, 1, 48, 1, -1, falsch, falsch); Elektron.x = 613;
Hier werden die beiden Schalen (Ringe) für den CarbonAtom erstellt.
Gehen Sie nun weiter unten, wo Sie die Zuordnung "ring.material.doubleSided = true" sehen, und ersetzen Sie den Code:
do3d.localRotationZ = 360/4 * i + 45;
mit:
do3d.localRotationZ = 360/12 * i + 180;
Dies gibt den 6 Elektronen die richtige Platzierung, um den Kern vollständig zu bedecken. Das ist es. Speichern Sie die Datei vor dem Testen.
Die CarbonAtom-Klasse sollte genau so aussehen:
package import flash.display.StageQuality; import flash.events.Event; import flash.events.MouseEvent; import org.papervision3d.lights.PointLight3D; import org.papervision3d.materials.ColorMaterial; import org.papervision3d.materials.shadematerials.GouraudMaterial; import org.papervision3d.materials.WireframeMaterial; import org.papervision3d.objects.DisplayObject3D; import org.papervision3d.objects.primitives.Cylinder; import org.papervision3d.objects.primitives.Sphere; import org.papervision3d.view.BasicView; public class CarbonAtom erweitert BasicView private var _do3DArray: Array; private var _easeOut: Number = .3; private var _reachX: Number = .1; private var _reachY: Number = .1; private var _reachZ: Number = .5; private var _rotX: Number = 0,5; private var _rotY: Anzahl = 0,5; private var _camPitch: Number = 0; private var _camYaw: Anzahl = 0; private var _zDist: Number = 4; private var _colorArray: Array; private var _freeOrbit: Boolean = true; öffentliche Funktion CarbonAtom () if (stage) init (); else addEventListener (Event.ADDED_TO_STAGE, init); startRendering (); private Funktion init (e: Event = null): void removeEventListener (Event.ADDED_TO_STAGE, init); stage.addEventListener (MouseEvent.CLICK, onStageClick); randomizeColorArray (); createAtom (); private Funktion onStageClick (e: MouseEvent): void _freeOrbit =! _freeOrbit; private Funktion randomizeColorArray (): void _colorArray = []; var tempArray: Array = []; für (var i: uint = 0; i < 12; i++) if (i < 6) var color:uint = 0x004080; else color = 0xA40000; tempArray.push (color); while (tempArray.length > 6) _colorArray.push (tempArray.splice (uint (Math.random () * tempArray.length), 1)); _colorArray = _colorArray.concat (tempArray); private Funktion createAtom (): void _do3DArray = []; var light: PointLight3D = neues PointLight3D; Licht x = 300; light.y = 700; Licht.z = 0; scene.addChild (light) var atom: DisplayObject3D = neues DisplayObject3D; scene.addChild (atom); var nucleus: DisplayObject3D = neues DisplayObject3D; atom.addChild (Kern); var Kugel: Kugel = neue Kugel (Null, 60, 4, 4); für (var i: uint = 1; i < sphere.geometry.vertices.length-1; i++) var np:Sphere = new Sphere (new GouraudMaterial (light, _colorArray[i - 1], 0, 0), 23); np.x = sphere.geometry.vertices[i].x; np.y = sphere.geometry.vertices[i].y; np.z = sphere.geometry.vertices[i].z; nucleus.addChild (np); for (i = 0; i < 6; i++) var do3d:DisplayObject3D = new DisplayObject3D; var ring:Cylinder; var electron:Sphere; electron = new Sphere (new ColorMaterial (0xEFECCA, 1), 7); if (i == 1 || i == 5) ring = new Cylinder (new WireframeMaterial (0xFFFFFF, .05, 2), 450, 1, 48, 1, -1, false, false); electron.x = 453; else ring = new Cylinder (new WireframeMaterial (0xFFFFFF, .05, 2), 610, 1, 48, 1, -1, false, false); electron.x = 613; ring.material.doubleSided = true; do3d.localRotationZ = 360 / 12 * i + 180; do3d.localRotationY = 360 * Math.random (); do3d.addChild (ring); do3d.addChild (electron); _do3DArray.push (do3d); atom.addChild (do3d); override protected function onRenderTick (event:Event = null):void super.onRenderTick (event); for (var i:uint = 0; i < _do3DArray.length; i++) _do3DArray[i].yaw (10); var xDist:Number = mouseX - stage.stageWidth * .5; var yDist:Number = mouseY - stage.stageHeight * .5; if (_freeOrbit) camera.x += (xDist - camera.x * _reachX) * _easeOut; camera.y += (yDist - camera.y * _reachY) * _easeOut; camera.z += (-mouseY * _zDist - camera.z) * _reachZ; else _camPitch += ((-yDist * _rotX) - _camPitch + 90) * _easeOut; _camYaw += ((xDist * _rotY) - _camYaw + 270) * _easeOut; if(_camPitch < 5) _camPitch = 5; if(_camPitch > 175) _camPitch = 175; camera.orbit (_camPitch, _camYaw);
Öffnen Sie die Hauptdokumentklasse und ersetzen Sie den Code:
var helium3: Helium3Atom = neues Helium3Atom; addChild (Helium3);
mit:
var carbon: CarbonAtom = neuer CarbonAtom; addChild (neues CarbonAtom);
Beim Testen des Films sollten Sie etwa die Vorschau sehen.
Papervision ist ein sehr einfaches und leistungsfähiges Werkzeug. Experimentieren Sie da