Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Games

Einführung in Box2D für Flash und AS3

Read Time:30 minsLanguages:

German (Deutsch) translation by Valentina (you can also view the original English article)

Box2D ist eine beliebte Physik-Engine mit einem soliden Flash-Port, mit der das exzellente Spiel Fantastic Contraption erstellt wurde. In diesem Tutorial, dem ersten einer Reihe, lernen Sie die Grundlagen von Box2D 2.1a für Flash und AS3 kennen.


Schritt 1: Das langweilige Setup

Ich gehe davon aus, dass Sie bereits wissen, wie Sie ein grundlegendes Flash-Projekt mit Ihrem Editor und einem Workflow Ihrer Wahl einrichten. Dies bedeutet, dass Sie eine FLA mit einer Dokumentklasse, ein reines AS3-Projekt in einem anderen Editor oder was auch immer erstellen. Ich verwende FlashDevelop, aber Sie sollten alles verwenden, mit dem Sie sich wohl fühlen.

Erstellen Sie Ihr Projekt und benennen Sie die Hauptklasse Main.as. Geben Sie ihm einen Code für das Boilerplate. meins sieht so aus:

Machen Sie sich keine Sorgen um das Metatag [Frame] - so erstellt FlashDevelop einen Preloader. Sie müssen lediglich wissen, dass getStarted() ausgeführt wird, wenn die SWF-Datei vollständig geladen ist. Erstellen Sie eine gleichnamige Funktion, die ausgeführt wird, wenn Ihre Hauptklasse geladen wurde.

Ich gehe auch davon aus, dass Sie mit der Verwendung einer separaten Bibliothek oder API in Ihrem Projekt vertraut sind. Laden Sie Box2DFlash 2.1a von dieser Seite herunter (ich verwende die Flash 9-Version) und extrahieren Sie die Zip-Datei an die Stelle, an der Sie normalerweise Ihre APIs ablegen. Fügen Sie als Nächstes einen Klassenpfad hinzu, der aus der Zip-Datei auf den Ordner \Source\ verweist. Alternativ können Sie den Inhalt des Ordners \Source\ einfach in dasselbe Verzeichnis wie Ihre Hauptklasse extrahieren.

Großartig! Das war einfach. Beginnen wir mit Box2D.


Schritt 2: Eine ganz neue b2World

"Wenn Sie einen Apfelkuchen von Grund auf neu herstellen möchten, müssen Sie zuerst das Universum erschaffen", schrieb Carl Sagan. Wenn wir ein paar physikalische Objekte herstellen wollen, müssen wir nur eine Welt erschaffen.

In Box2D ist eine Welt kein Planet oder Ökosystem. Es ist nur der Name des Objekts, das die gesamte Physiksimulation verwaltet. Es legt auch die Stärke der Schwerkraft fest - nicht nur, wie schnell Objekte beschleunigen, sondern auch in welche Richtung sie fallen.

Wir werden einen Vektor erstellen, um die Schwerkraft einzustellen, bevor wir die Welt selbst erstellen:

Ein b2Vec2 ist ein euklidischer Box2D-Vektor (die zweite 2 steht wieder für 2D, da es möglich ist, einen euklidischen 3D-Vektor zu haben). Daniel Sidhion hat ein hervorragendes Tutorial geschrieben, in dem erklärt wird, was euklidische Vektoren sind (sie haben nichts mit der Vektorklasse in AS3 zu tun). Schauen Sie sich das an, wenn Sie sich nicht sicher sind. Stellen Sie sich einen euklidischen Vektor kurz als Pfeil vor:

Dieser Pfeil zeigt b2Vec2(4, 9); es zeigt nach unten und rechts. Unser Schwerkraftvektor zeigt dann gerade nach unten. Je länger der Pfeil ist, desto stärker ist die Schwerkraft. Später im Lernprogramm können Sie versuchen, den Schwerkraftvektor in b2Vec(0, 2) zu ändern, um eine viel schwächere Schwerkraft zu simulieren, ähnlich wie auf dem Mond.

Jetzt erschaffen wir die Welt selbst:

Der zweite Parameter, den wir an b2World() übergeben, gibt an, dass die Simulation von Objekten gestoppt werden kann, die nicht mehr simuliert werden müssen. Dies beschleunigt die Simulation, ist jedoch für uns derzeit völlig irrelevant.

Führen Sie die SWF aus, um zu überprüfen, ob keine Fehler vorliegen. Sie werden jedoch noch nichts sehen können. Die Welt ist derzeit völlig leer!


Schritt 3: Das Rad neu erfinden

Lassen Sie uns ein einfaches kreisförmiges Objekt erstellen. Dies könnte einen Stein, einen Basketball oder eine Kartoffel darstellen, aber ich werde es als Rad sehen.

Ich würde gerne sagen, dass dies so einfach ist wie:

... aber das wäre eine große fette Lüge. Die Sache mit Box2D ist, dass anscheinend einfache Dinge ziemlich viel Code erfordern können, um sortiert zu werden. Diese zusätzliche Komplexität ist sehr nützlich für fortgeschrittene Arbeiten, steht jedoch einfachen Dingen wie dem, was wir gerade versuchen, im Weg. Ich werde schnell darüber nachdenken, was wir tun müssen, um dieses Rad herzustellen. Wir können es in späteren Tutorials genauer untersuchen.

Um ein einzelnes "Physikobjekt" zu erstellen, d.h. ein Objekt mit einer Form und einer Masse, die Box2D innerhalb einer Welt simulieren kann, müssen wir es mit fünf verschiedenen Klassen konstruieren:

  • Eine Körperdefinition, die wie eine Vorlage zum Erstellen von ...
  • Ein Körper, der eine Masse und eine Position hat, aber keine ...
  • Eine Form, die so einfach wie ein Kreis sein kann und mit einem Körper verbunden werden muss, indem ...
  • Eine Fixture, das mit ...
  • Eine Fixture-Definition, die eine andere Vorlage ist, wie die Body-Definition.

Puh. So sieht das alles im Code aus:

Das Argument, das wir an b2CircleShape() übergeben, gibt den Radius des Kreises an. Alles andere sollte auf der Grundlage der obigen Liste sinnvoll sein, auch wenn die Argumentation hinter dieser Struktur keinen Sinn ergibt.

Beachten Sie, dass wir niemals new b2Body() oder new b2Fixture() schreiben. Die Welt wird verwendet, um den Körper aus der Körperdefinition zu erstellen, und der Körper wird verwendet, um das Fixture aus der Fixture-Definition zu erstellen. Dies bedeutet, dass die Welt über alle Körper Bescheid weiß, die in ihr geschaffen werden, und dass der Körper über alle Vorrichtungen Bescheid weiß, die geschaffen werden, um Formen mit ihr zu verbinden.

Das eigentliche Physikobjekt, das wir erstellt haben, ist der wheelBody. Alles andere ist nur ein Teil eines Rezepts, um dieses eine Objekt zu bilden. Um zu überprüfen, ob wir erfolgreich waren, wollen wir sehen, ob der wheelBody vorhanden ist:

Ergebnis:

Gut.


Schritt 4: Bewegen Sie Ihren Körper

Wissen Sie was ich meine, wenn ich über die "Spielschleife" und ein "Häkchen" spreche? Wenn nicht, lesen Sie jetzt meinen kurzen Artikel "Understanding the Game Loop", denn es ist wirklich wichtig für das, was wir tun.

Das Box2D-Weltobjekt verfügt über die Methode Step(), die die Simulation steuert. Sie geben einen winzigen Zeitraum (einen Bruchteil einer Sekunde) an, und Step() simuliert die Bewegung und Kollisionen jedes Objekts auf der Welt. Sobald die Funktion ausgeführt wurde, wurden alle Körperobjekte mit ihren neuen Positionen aktualisiert.

Lassen Sie uns dies in Aktion sehen. Anstatt wheelBody selbst zu verfolgen, verfolgen wir seine Position. Dann führen wir b2World.Step() aus und verfolgen die Position des Rads erneut:

(Die GetPosition()-Methode eines Körpers gibt ein b2Vec2 zurück, daher müssen wir die einzelnen x- und y-Eigenschaften verfolgen, anstatt nur trace(wheelBody.GetPosition() aufzurufen.)

Der erste Parameter, den wir an Step() übergeben, ist die Anzahl der Sekunden, um das Übergeben in der Box2D-Welt zu simulieren. Die beiden anderen Parameter geben an, wie viel Genauigkeit Box2D bei allen mathematischen Berechnungen verwenden soll, die zur Simulation des Zeitablaufs verwendet werden. Machen Sie sich jetzt keine Sorgen. Wissen Sie nur, dass größere Zahlen dazu führen können, dass Box2D mehr Zeit benötigt, um die Welt zu simulieren. Wenn Sie diese zu hoch einstellen, kann es sogar länger als 0,025 Sekunden dauern, bis Step() ausgeführt wird, sodass wir nicht mehr mit der Realität synchron sind Welt!

Testen Sie die SWF und sehen Sie sich Ihr Ausgabefenster an:

Das ist ein bisschen deprimierend. Das Rad hat sich überhaupt nicht bewegt - und doch hat die Welt die Schwerkraft, also würde man denken, dass es ein bisschen gefallen wäre. Was ist los?


Schritt 5: Dynamisch sein

Standardmäßig sind alle Box2D-Körper statisch, was bedeutet, dass sie sich nicht bewegen. Denken Sie an die tatsächlichen Plattformen in einem Plattformspiel. Sie sind feste Objekte, werden jedoch nicht von der Schwerkraft beeinflusst und können nicht herumgeschoben werden.

Unser Rad muss dynamisch sein, damit es sich bewegen kann. Ratet mal, wie wir diese Eigenschaft des Körpers definieren? Natürlich mit der Körper-Definition!

Probieren Sie jetzt die SWF aus und sehen Sie, was Sie bekommen:

Es ist bewegt! Wie aufregend!


Schritt 6: Bewegen Sie sich weiter

Wir können dies jedoch noch nicht als Spielschleife bezeichnen, da sie nur einmal ausgeführt wird; wir brauchen es, um immer und immer wieder zu rennen. Wir können dies mit einem Timer und einem Ereignis-Listener erreichen:

(Beachten Sie, dass ich dem Timer auch einen Zeitraum von 0,025 Sekunden gegeben habe, damit er mit den Schritten der Welt synchron bleibt. Sie müssen dies nicht tun - tatsächlich, wenn Sie die beiden Zeiträume unterschiedlich machen, Sie kann einige wirklich coole zeitbezogene Effekte wie Zeitlupe bekommen.)

Aber hoppla, dieser Code wird nicht funktionieren. Wir brauchen wheelBody, um in der Funktion onTick() erreichbar zu sein. Wenn wir schon dabei sind, können wir den Timer auch überall zugänglich machen:

Beachten Sie, dass sich die obigen Zeilen 14 und 20 geändert haben, nachdem der Radkörper und der Timer an anderer Stelle definiert wurden.

Versuchen Sie es jetzt:

Hurra, es fällt für immer! Okay, das reicht aus, um die Zahlen zu analysieren. Lassen Sie uns etwas visuell machen.


Schritt 7: Zeichnen!

Wir haben all diese Koordinaten. Warum also nicht die Punkte verbinden?

Ersetzen Sie die Spuren durch den Code, um eine Linie von der alten Position des Rads zur neuen zu ziehen:

Um die Linie zu sehen, müssen wir ihren lineStyle setzen:

Führen Sie nun die SWF aus. Sie sehen eine rote Linie am linken Rand. Ich habe meinem SWF einige Tricks hinzugefügt, die bedeuten, dass es nichts tut, bis Sie darauf klicken. Sie können es also unten überprüfen:

Großartig! Das Rad fällt also frei und wird aufgrund der Schwerkraft schneller, wie es sein sollte. Wir sollten die vertikale Geschwindigkeit in Ruhe lassen, damit die Schwerkraft ihre Arbeit erledigen kann, aber wir können die anfängliche horizontale Geschwindigkeit manuell ändern, um die Form der Linie etwas interessanter zu gestalten:

Denken Sie daran, dass ein b2Vec2 wie ein Pfeil aussieht. In diesem Fall sieht die Startgeschwindigkeit also wie ein Pfeil aus, der direkt nach rechts zeigt, als hätten wir ihn gerade aus einer Kanone von der Spitze einer Klippe geschossen. Unsere Welt hat keinen Luftwiderstand (weil es keine Luft gibt!), Also gibt es absolut nichts, was sie verlangsamen könnte - obwohl sie dank der Schwerkraft vertikal schneller wird.

Klingt verwirrend, sollte aber nach dem Ausführen des SWF klar sein:

Wir haben gerade versehentlich eine Parabel gezeichnet. Also ... das ist ordentlich, denke ich?


Schritt 9: Die Illusion der Bewegung

Okay, okay, vielleicht bist du nicht so begeistert, eine gekrümmte rote Linie zu sehen wie ich. Wenn wir eine Welt simulieren wollen, sollten wir die Objekte wie Objekte aussehen lassen, oder? Anstatt eine Linie zu sehen, die die Position des Rades durch den Raum verfolgt, sollten wir es so aussehen lassen, als ob sich das Rad tatsächlich durch den Raum bewegt.

Wir können dies tun, indem wir wiederholt einen Kreis zeichnen und löschen, der auf der Position des Rads zentriert ist:

Wir müssen den Linienstil jetzt in onTick() angeben, da graphics.clear() ihn zurücksetzt und alle Grafiken vom Bildschirm löscht. Beachten Sie, dass ich den Radius des Kreises auf 5 gesetzt habe, was dem Radius der zuvor erstellten circleShape entspricht.

Versuchen Sie diese SWF:

Ich denke, es ist ziemlich offensichtlich, was der nächste Schritt sein sollte ...


Schritt 10: Geerdet

Diese unendliche Welt des Nichts eignet sich nicht für viele aufregende Situationen. Sicher, wir könnten neue Räder hinzufügen, aber ohne Boden oder Wände würden sie niemals etwas Interessantes tun.

Wir werden einige feste Objekte erstellen, mit denen das Rad kollidieren kann, beginnend mit einem großen flachen Stück Boden. Dafür verwenden wir ein Rechteck.

Erinnern Sie sich an die Objekte, die wir brauchen, um einen Körper zu erschaffen?

  • Eine Körperdefinition, die wie eine Vorlage zum Erstellen von ...
  • Ein Körper, der eine Masse und eine Position hat, aber keine ...
  • Eine Form, die so einfach wie ein Kreis sein kann und mit einem Körper verbunden werden muss, indem ...
  • Ein Fixture, das mit ...
  • Eine Fixture-Definition, die eine andere Vorlage ist, wie die Body-Definition.

Sie wissen, wie man das für einen kreisförmigen Körper macht; Jetzt müssen wir ein rechteckiges machen:

Es ist größtenteils dasselbe, außer dass wir beim Erstellen eines kreisförmigen Körpers den gewünschten Radius an den Konstruktor b2CircleShape() übergeben haben. Hier müssen wir die gewünschte Breite und Höhe des Rechtecks an die Funktion b2PolygonShape.SetAsBox() übergeben. (Tatsächlich übergeben wir die gewünschte halbe Breite und halbe Höhe, sodass die Box doppelt so breit wie die Bühne und zwei Pixel hoch ist, aber das ist in Ordnung.) Denken Sie daran, dass alle Körper standardmäßig statisch sind, also nicht Ich muss mir Sorgen machen, dass der Boden abfällt. Sie müssen import Box2D.Collision.Shapes.b2PolygonShape, damit dies funktioniert.

Standardmäßig wird jede neue Form bei (0, 0) erstellt, daher müssen wir angeben, dass der Boden am unteren Rand der Bühne erstellt werden soll. Wir könnten die Position des Bodenkörpers manuell ändern, sobald er erstellt wurde, genauso wie wir die Geschwindigkeit des Radkörpers manuell geändert haben, aber es ist ordentlicher, wenn wir die Position als Teil der Bodenkörperdefinition festlegen:

Stellen Sie sicher, dass Sie dies festlegen, bevor Sie die Body-Definition an world.CreateBody() übergeben. Andernfalls werden die Änderungen ignoriert.

Testen Sie nun die SWF:

Wir können den Boden nicht sehen, weil wir ihn nicht gezeichnet haben, aber Box2D simuliert ihn immer noch, sodass wir seine Wirkung sehen: Das Rad kollidiert damit und rollt zur Seite.


Schritt 11: Legen Sie einige Grenzen fest

Wir werden im nächsten Schritt weitere Räder hinzufügen, aber zuerst machen wir dies zu einem vollständig geschlossenen Raum mit einem Boden, einer Decke und zwei Wänden.

Ich möchte, dass Sie es selbst versuchen. Erstellen Sie drei weitere rechteckige Körper mit der richtigen Größe und an den richtigen Positionen. Es ist am einfachsten, mit dem rechts zu beginnen, da das Rad damit kollidieren wird. Um die anderen zu testen, spielen Sie mit der Anfangsgeschwindigkeit.

Sie müssen die Ausgangsposition des Rads ändern, da es sonst die linke Wand und die Decke überlappt, wenn sie erstellt werden. Sie können dies auf die gleiche Weise tun, wie Sie die Position der rechteckigen Objekte über die Methode position.Set() der Körperdefinition festlegen.

Viel Glück! Wenn Sie nicht weiterkommen, lesen Sie meinen Code unten:

Und das Ergebnis:

Gute Arbeit.


Schritt 12: Erstellen Sie ein Array

Jetzt sind wir bereit, weitere Körper hinzuzufügen, sie zusammenzuschlagen und zu sehen, was passiert.

Wir könnten sie alle einzeln erstellen, wie ich es mit den Rechtecken getan habe, aber es wäre ordentlicher, ein Array zu verwenden, um sie alle zu halten, und eine einzige Funktion, um sie zu erstellen.

Lassen Sie uns zunächst dieses Array mit einem einzigen Element erstellen: dem vorhandenen Rad.

Wenn dies funktioniert, verhält sich Ihr SWF genauso wie zuvor.


Schritt 13: Fügen Sie ein weiteres Rad hinzu

Um dies richtig zu testen, können wir ein zusätzliches Rad hinzufügen - vorerst nur eines! Kopieren Sie den Code zum Erstellen des Rads und fügen Sie ihn ein, und ändern Sie Teile davon, damit die Räder nicht genau gleich sind:

Sie erhalten eine Reihe von Warnungen zu doppelten Variablendefinitionen, die jedoch abhängig von Ihren Einstellungen kompiliert werden sollten:

Das erste Rad fällt ohne anfängliche Seitengeschwindigkeit gerade nach unten. Dies ist absolut sinnvoll, wenn Sie sich den Code ansehen. Wir rufen wheelBody.SetLinearVelocity() an der falschen Stelle auf. Bewegen Sie sie nach oben:

Okay! Das funktioniert gut. Wir können jetzt den gesamten Rad-Erstellungscode in einer Funktion zusammenfassen.


Schritt 14: Radgenerator

Um diese Radgenerierungsfunktion zu erstellen, können Sie grundsätzlich den gesamten von uns verwendeten Code kopieren und einfügen. Hier ist meins:

Ich habe einige Parameter hinzugefügt, damit wir die anpassbaren Eigenschaften der Räder angeben können. Während wir gerade dabei sind, schlage ich vor, dass wir den gesamten Code zur Erstellung von Grenzen in eine separate Funktion verschieben, um die Dinge in Ordnung zu halten:

Jetzt können wir die gesamte Funktion getStarted() folgendermaßen umschreiben:

Versuchen Sie sie! Auch hier sollte der SWF genauso handeln wie zuvor.


Schritt 15: Automatische Räder

Nachdem wir die Radgenerierung vereinfacht haben, können wir viele davon ohne große Schwierigkeiten oder Unordnung herstellen:

Dadurch entstehen zwanzig Räder mit einem Radius zwischen 0 und 10, einer Position zwischen (10, 10) und (StageWidth-10, StageHeight-10) und einer horizontalen Geschwindigkeit zwischen -50 und +50. Versuch es!

Es funktioniert fast, aber etwas stimmt nicht. Lassen Sie uns herausfinden, was los ist.


Schritt 16: Spoiler - Es ist der Radius

Schauen Sie sich dieses Bild an, als ich die SWF ausgeführt habe:

Einige der Räder sind im Boden oder in der Wand versenkt, andere überlappen sich. Es ist wirklich komisch. Haben wir die Radien der Räder nicht auf einen Wert zwischen 0 und 10 eingestellt? Warum sind sie alle gleich?

Wie Sie wahrscheinlich herausgefunden haben, sind sie gleich, da wir den Radius des Kreises fest codiert haben, um ihn in der Ereignishandlerfunktion onTick() zu zeichnen. Hoppla.

Leider können wir nicht einfach wheelBody.radius verwenden, um den Radius des Rads zu ermitteln. Denken Sie daran, dass der Körper keine Form hat, sondern über eine Vorrichtung mit einer Form verbunden ist. Um den Radius zu finden, müssen wir so etwas tun:

Glücklicherweise können wir dies vereinfachen, um (wheelBody.GetFixtureList().GetShape() as b2CircleShape).GetRadius(); verwenden wir dies in onTick():

Wie ist das?

Ah, viel besser!


Schritt 17: Viel Spaß

Die Simulation ist im Moment etwas langweilig; Die Räder rollen nur ein wenig und halten dann an. Langweilig. Lassen Sie uns die Dinge ein wenig beleben, indem wir sie von Metallrädern auf luftgefüllte Gummireifen umstellen.

Dazu können wir eine Eigenschaft verwenden, die als Restitutionskoeffizient bezeichnet wird. Dies ist ein Physikgespräch für "Hüpfburg"; Der Restitutionskoeffizient eines Objekts gibt an, wie stark es nach einer Kollision mit einem anderen Objekt zurückprallt. Normalerweise nimmt dies einen Wert zwischen 0 und 1 an, wobei 0 bedeutet, dass es stoppt, sobald es ein anderes Objekt berührt, und 1 bedeutet, dass es zurückprallt, ohne Energie zu verlieren.

Standardmäßig haben alle Box2D-Körper einen Restitutionskoeffizienten von 0; Lassen Sie uns die Dinge beleben, indem wir sie etwas höher einstellen:

Dadurch wird der Restitutionskoeffizient jedes Rads auf einen zufälligen Wert zwischen 0,5 und 1 eingestellt. Beachten Sie, dass dies eher eine Eigenschaft der Vorrichtungsdefinition als der Form oder der Körperdefinition ist.

Schauen wir mal, was passiert: 

Das ist eher so! Was können wir noch einstellen?


Schritt 18: Andere Eigenschaften

Wir können auch die Reibung (wie rau oder glatt die Außenfläche ist; ein poliertes Stahlrad hat weniger Reibung als ein raues Steinrad) und die Dichte (wie schwer der Körper im Vergleich zu einem anderen mit der gleichen Größe und Form wäre; Stein ist dichter als Holz).

Der Reibungskoeffizient sollte zwischen 0 und 1 liegen, wobei 0 extrem glatt und 1 extrem rau bedeutet und standardmäßig 0,2 beträgt. Die Dichte kann ein beliebiger Wert sein und ist standardmäßig 1. (Nun, für statische Körper ist es 0, aber es ist ihnen eigentlich egal, da sie sich sowieso nicht bewegen.)

Lassen Sie uns mit diesen Werten herumspielen und sehen, was passiert:

Das Ergebnis:

Alles gut. Wenn Sie etwas mehr Kontrolle wünschen, können Sie der Funktion createWheel() Parameter für Restitution, Reibung und Dichte hinzufügen.

Es gibt jedoch etwas, das mich nervt ...


Schritt 19: Schwer, Mann

... Warum fühlt sich alles so schwebend an?

Im Ernst, es ist, als würde sich die ganze Welt durch Melassesirup bewegen. Aber es gibt keinen Luftwiderstand, geschweige denn Melassewiderstand; die Schwerkraft ist auf einem vernünftigen Niveau; und der Zeitschritt wird an die Tick-Dauer des Timers angepasst - was ist das Problem?

Wenn Sie Wissenschaftler sind, haben Sie wahrscheinlich bemerkt, dass ich im gesamten Tutorial keine Einheiten erwähnt habe. Der Radius des ersten Rades betrug nur "5" - nicht "5 Zoll" oder was auch immer. Wir haben gerade in Pixel gearbeitet. Box2D ist jedoch eine Physik-Engine und verwendet daher tatsächliche physikalische Einheiten. Dieses Rad hatte einen Radius von fünf Metern, nicht fünf Pixel; Das sind ungefähr sechzehn Fuß, nicht weit von der Höhe eines durchschnittlichen Hauses entfernt. Die meisten Räder sind nicht so hoch, obwohl es Ausnahmen gibt, wie dieses Flickr-Foto von Monochrome zeigt:

Selbst dann haben die Reifen auf diesem Foto einen Radius von etwa 2,5 Metern; normalerweise würden wir erwarten, dass der Radius eines Rades zwischen einigen Zentimetern und einem halben Meter liegt. Dies bedeutet, dass jedes von uns erstellte Box2D-Objekt viel größer ist, als es auf dem Bildschirm angezeigt wird, und - wie jeder weiß, der Honey I Shrunk The Kids gesehen hat - größere Objekte in Zeitlupe bewegen.

Wir können also eine viel weniger schwebende Simulation erzielen, indem wir den Radius der von uns erstellten Räder ändern:

Das resultierende SWF fühlt sich viel realistischer an, aber gleichzeitig sind die Räder alle so klein gezeichnet, dass es sich anfühlt, als würden wir aus einer halben Meile Entfernung zuschauen:

Es gibt einen allgemeinen Trick, den Box2D-Entwickler hier verwenden ...


Schritt 20: Stellen Sie den Skalierungsfaktor ein

Um es noch einmal zusammenzufassen: Box2D verwendet Messgeräte, Flash jedoch Pixel. Daher wird ein Rad mit einem Radius von 0,5 Metern als winziger Kreis mit einer Breite von etwas mehr als einem Pixel gezeichnet.

Wenn Sie es so lesen, scheint die Lösung vielleicht offensichtlich: Wir müssen die Konvertierung zwischen Metern und Pixeln skalieren, damit ein Meter als beispielsweise 20 Pixel gezeichnet wird.

Ändern Sie den Aufruf von graphics.drawCircle() in onTick(), um diesen neuen Skalierungsfaktor widerzuspiegeln:

Funktioniert das?

Ähm, nein. Wir sind wieder schwebend und die Räder kollidieren nicht mehr miteinander.

Ah, aber das ist irreführend. Die grafischen Darstellungen der Räder scheinen sich zu überlappen, sind es aber nicht. Sehen Sie, wir können diesen Skalierungsfaktor nicht einfach für die Radien der Räder verwenden und dabei belassen. wir müssen es für alle längen und abstände verwenden - und dazu gehören auch die x- und y-positionen der räder. Versuchen Sie Folgendes:

Moment mal - verwenden wir eine öffentliche Variable, anstatt die Nummer 20 fest zu codieren:

Probieren Sie jetzt die SWF aus und ... hmm. Nur eine leere weiße Leinwand. Schauen wir mal, was unter der Haube los ist: 

Ergebnis:

Whoa! Diese Zahlen sind viel zu groß. Aber das macht Sinn - sie sind 20 Mal größer als früher.

Denken Sie darüber nach, wann wir die Räder erstellen - und insbesondere, wann wir ihre Ausgangspositionen festlegen:

Meine Bühne ist 500x400px. Wenn ich keinen Skalierungsfaktor verwendet habe, kann die x-Position eines neuen Rads zwischen 10 und 490 Pixel links von der Bühne liegen. Dies war das Gleiche wie zwischen 10 und 490 Metern links von der Bühne, da jeder Meter als ein einzelnes Pixel lang dargestellt wurde. Jetzt wird jeder Meter durch zwanzig Pixel dargestellt - die x-Position eines neuen Rads kann also zwischen 200 und 9800 Pixel links von der Bühne liegen! Kein Wunder, dass wir keinen von ihnen sehen.

Um dies zu beheben, verwenden wir den Skalierungsfaktor im Code, der ein neues Rad erstellt:

Ist es für Sie sinnvoll, dass wir es teilen, anstatt es zu multiplizieren? Denken Sie daran, Box2D verwendet Messgeräte, Flash verwendet Pixel und unser Skalierungsfaktor ist in Pixel / Meter.

Probieren Sie jetzt die SWF aus:

Viel besser - aber die rechte Wand und der rechte Boden scheinen verschwunden zu sein.

... Haben Sie schon erraten, was passiert?

Dies liegt daran, dass die Entfernungen wiederum in Metern angegeben werden und wir den Skalierungsfaktor nicht angewendet haben. Anstatt dass die rechte Wand 500 Pixel vom linken Rand entfernt ist, sind es 500 Meter oder 10.000 Pixel. Auch hier müssen wir unsere Entfernungen durch den Skalierungsfaktor dividieren, um dies zu berücksichtigen.

Wenn Sie diesen Code selbst geschrieben haben, können Sie sicher selbst herausfinden, wie Sie ihn ändern können :) Ansonsten ist hier meins:

Versuchen Sie es jetzt:

Ausgezeichnet! Und da der Skalierungsfaktor weich codiert ist, können Sie versuchen, ihn zu erhöhen:


Abschluss

Herzliche Glückwünsche! Wenn Sie so weit gegangen sind, verstehen Sie die sehr wichtigen Grundkonzepte von Box2D. (Wenn Sie nicht so weit gefolgt sind, schreiben Sie einen Kommentar, in dem Sie erklären, wo Sie stecken geblieben sind, und ich werde Ihnen helfen.) Okay, die endgültige SWF sieht vielleicht nicht nach viel aus, aber lassen Sie sich nicht täuschen. Sie haben sich einen hervorragenden Rahmen für das gegeben, was Sie als nächstes lernen werden.

Apropos was kommt als nächstes ... was möchten Sie lernen? Ich habe viele Ideen und bin froh, diese Serie in jede Richtung fortzusetzen, die ich erkunden möchte, aber es wäre cool zu wissen, was Sie denken. Möchten Sie ein Physik-Rätsel machen? Ein Plattformer? Ein Side-Scrolling-Rennspiel? Gibt es Kernkonzepte, auf die Sie sich konzentrieren möchten, z. B. das Erstellen von Gelenken?

Das nächste Tutorial in dieser Reihe befasst sich höchstwahrscheinlich mit dem Rendern von Objekten mit anderen Methoden als den integrierten Zeichenmethoden. Insbesondere werden wir uns mit DisplayObjects befassen, die entweder über Flash gezeichnet oder als Bitmaps importiert werden. Wir werden auch einige aktuelle Boxen erstellen, da es ziemlich seltsam ist, ein komplettes Box2D-Tutorial ohne solche zu erstellen.


Sie können über Tutorial-Ideen über unsere Google Moderator-Seite unter http://bit.ly/Box2DFlashTutorialIdeas abstimmen oder eine brandneue einreichen, wenn noch niemand daran gedacht hat. Ich freue mich darauf zu sehen, was Sie vorschlagen!

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.