publicclassDominosDemoBasicextendsScene{/** * Der Boden, auf dem die Dominosteine stehen. */privateRectangleground;/** * Der Ball, der die Dominosteine umwerfen soll. */privateCircleball;publicDominosDemoBasic(){setupBasicObjects();makeDominoes();}privatevoidsetupBasicObjects(){ground=newRectangle(200,2);ground.center(0,-5);ground.color("blue");ground.friction(1);add(ground);ball=newCircle(0.5);ball.color("red");ball.anchor(-17,-2);add(ball);}privatevoidmakeDominoes(){for(inti=0;i<20;i++){Rectangledomino=newRectangle(0.2,3);domino.anchor(-10+i*1.3,-4);domino.color("white");add(domino);}}publicstaticvoidmain(String[]args){Controller.instantMode(false);Controller.start(newDominosDemoBasic(),1200,300);}}
Dieser Code baut ein einfaches Spielfeld auf: Ein roter Ball, ein paar
Dominosteine, und ein blauer Boden.
Das Spielbrett ist aufgebaut, allerdings passiert noch nichts interessantes. Zeit für Physik!
Wir erwarten verschiedenes Verhalten von den physikalischen Objekten. Dies
drückt sich in verschiedenen BodyTypes aus:
Der Ball und die Dominos sollen sich verhalten wie normale physische Objekte:
Der Ball prallt an den Dominos ab und die Steine fallen um. Diese Actors haben
einen dynamischen Körper.
Aber der Boden soll nicht wie die Dominos umfallen.
Dieser Actor hat einen statischen Körper.
Mit der Methode Actor.setBodyType(BodyType) wird das grundlegende
Verhalten eines Actors bestimmt. Zusätzlich wird mit
Scene.setGracity(Vector) eine Schwerkraft gesetzt, die auf den Ball und die
Dominos wirkt. Jetzt wirkt Schwerkraft auf die dynamischen Objekte und der
statische Boden hält den Fall
In einer setupPhysics()-Methode werden die Body Types für die Actors
gesetzt und die Schwerkraft (standardmäßige 9,81 m/s^2, gerade nach unten)
aktiviert:
Zusätzlich werden die Dominos in makeDominoes() mit domino.makeDynamic();
eingerichtet.
Jetzt wirkt Schwerkraft auf die dynamischen Objekte und der statische Boden hält den Fall
Dynamische und statische Körper sind die essentiellsten Body Types in der
Engine, allerdings nicht die einzigen. Du findest einen Umriss aller Body Types
in der Dokumentation von BodyType und eine
vergleichende Übersicht in der dedizierten Wikiseite Den Ball Werfen Mit einem
Methodenaufruf fliegt der Ball
Zeit, die Dominos umzuschmeißen! Die Methode
applyImpulse(Vector) erlaubt, den Ball physikalisch korrekt zu
'werfen'.
Mit der Zeile ball.applyImpulse(new Vector(15, 12)); kannst der erste
Ballwurf getestet werden.
Mit einem Methodenaufruf fliegt der Ball
Um hieraus eine Spielmechanik zu bauen, soll der Spieler Richtung und Stärke des
Wurfes mit der Maus kontrollieren können: Per Mausklick wird der Ball in
Richtung des Mauscursors katapultiert. Das Angle-Objekt hilft dem Spieler
Hierzu wird ein weiteres Rechteck angle eingeführt, das die Richtung des
Impulses markiert:
Wir wollen, dass eine Linie stets Ball und Maus verbindet. Die einfachste
Methode hierzu ist, in jedem Einzelbild die Linie erneut an die Maus anzupassen.
Dafür implementiert die Dominoes-Klasse das Interface FrameListener und berechnet
frameweise anhand der aktuellen Mausposition die korrekte Länge und den
korrekten Winkel, um die visuelle Hilfe richtig zu positionieren:
/* * Source: https://github.com/engine-alpha/tutorials/blob/master/src/eatutorials/physics/Dominoes.java * * Engine Alpha ist eine anfängerorientierte 2D-Gaming Engine. * * Copyright (c) 2011 - 2024 Michael Andonie and contributors. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */packagedemos.docs.physics.impulse;importpi.Controller;importpi.Scene;importpi.actor.Circle;importpi.actor.Line;importpi.actor.Rectangle;importpi.event.FrameListener;importpi.event.MouseButton;importpi.event.MouseClickListener;importpi.graphics.geom.Vector;// Go to file:///data/school/repos/inf/java/engine-pi/docs/manual/physics/impulse.md// Go to file:///data/school/repos/inf/java/engine-pi/subprojects/jbox2d/testbed/src/main/java/org/jbox2d/testbed/tests/DominoTest.java// Go to file:///data/school/repos/inf/java/engine-pi/subprojects/jbox2d/testbed/src/main/java/org/jbox2d/testbed/tests/DominoTower.java// https://de.wikipedia.org/wiki/Domino: Professionelle Spielsteine// haben im Allgemeinen eine Größe von ca. 56 × 28 × 13 mm./** * Das fertig Dominos-Demo. */publicclassDominosDemoFinalextendsSceneimplementsFrameListener,MouseClickListener{/** * Der Boden, auf dem die Dominosteine stehen. */privateRectangleground;/** * Der Ball, der die Dominosteine umwerfen soll. */privateCircleball;/** * Zeigt den Impuls an, mit dem der Ball gegen die Dominosteine katapultiert * wird. */privateLineline;publicDominosDemoFinal(){setupBasicObjects();makeDominoes();setupPhysics();setupLine();}privatevoidsetupBasicObjects(){ground=newRectangle(20,0.2);ground.center(0,-0.5);ground.color("blue");ground.friction(1);add(ground);ball=newCircle(0.15);ball.color("red");ball.anchor(-3,-0.2);add(ball);}privatevoidmakeDominoes(){for(inti=0;i<10;i++){Rectangledomino=newRectangle(0.13,0.56);domino.anchor(-1+i*0.5,-0.4);domino.color("white");domino.makeDynamic();domino.friction(1);domino.density(5);add(domino);}}// >>privatevoidsetupPhysics(){ground.makeStatic();ball.makeDynamic();gravityOfEarth();}// <<// >>privatevoidsetupLine(){line=newLine();line.end2.arrow(true).arrowSideLength(0.1);line.strokeWidth(0.01);line.dashed();line.dashPattern(0.03);line.color("gray");line.makeSensor();line.gravityScale(0);add(line);}// <<// >>@OverridepublicvoidonFrame(doublepastTime){line.end1(ball.center());line.end2(mousePosition());}// <<// >>@OverridepublicvoidonMouseDown(Vectorposition,MouseButtonbutton){Vectorimpulse=ball.center().distance(position);ball.applyImpulse(impulse);}// <<publicstaticvoidmain(String[]args){Controller.instantMode(false);Controller.config.graphics.pixelPerMeter(128);Controller.start(newDominosDemoFinal(),1200,300);}}