├── .classpath
├── .gitignore
├── .project
├── .settings
├── org.eclipse.core.resources.prefs
├── org.eclipse.jdt.core.prefs
└── org.eclipse.m2e.core.prefs
├── LICENSE.md
├── README.md
├── captures
├── BasketBall.gif
├── Billiards.gif
├── Platformer.gif
├── Ragdoll.gif
├── Tank.gif
├── Thrust.gif
└── Truck.gif
├── pom.xml
└── src
└── main
└── java
└── org
└── dyn4j
└── samples
├── BasketBall.java
├── Billiards.java
├── Bowling.java
├── Bridge.java
├── Bucket.java
├── Concave.java
├── Crank.java
├── Decomposition.java
├── Destructible.java
├── Images.java
├── LinkTerrain.java
├── Maze.java
├── Organize.java
├── Platformer.java
├── Pyramid.java
├── Ragdoll.java
├── Stacking.java
├── Tank.java
├── Thrust.java
├── Tracking.java
├── Truck.java
├── UsingGraphics2D.java
├── UsingJogl.java
├── framework
├── Camera.java
├── Graphics2DRenderer.java
├── SimulationBody.java
├── SimulationFrame.java
└── input
│ ├── AbstractInputHandler.java
│ ├── AbstractKeyboardInputHandler.java
│ ├── AbstractMouseInputHandler.java
│ ├── BooleanStateKeyboardInputHandler.java
│ ├── BooleanStateMouseInputHandler.java
│ ├── CodeExporter.java
│ ├── ExportCodeKeyboardInputHandler.java
│ ├── InputHandler.java
│ ├── Key.java
│ ├── MousePanningInputHandler.java
│ ├── MousePickingInputHandler.java
│ ├── MouseZoomInputHandler.java
│ └── ToggleStateKeyboardInputHandler.java
├── package-info.java
└── resources
├── Basketball.png
└── Crate.png
/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | dyn4j-samples
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 | org.eclipse.m2e.core.maven2Builder
15 |
16 |
17 |
18 |
19 |
20 | org.eclipse.jdt.core.javanature
21 | org.eclipse.m2e.core.maven2Nature
22 |
23 |
24 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.core.resources.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | encoding/=UTF-8
3 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.jdt.core.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
4 | org.eclipse.jdt.core.compiler.compliance=1.6
5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
6 | org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
7 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
8 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
9 | org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
10 | org.eclipse.jdt.core.compiler.release=disabled
11 | org.eclipse.jdt.core.compiler.source=1.6
12 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.m2e.core.prefs:
--------------------------------------------------------------------------------
1 | activeProfiles=
2 | eclipse.preferences.version=1
3 | resolveWorkspaceProjects=true
4 | version=1
5 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright (c) 2010-2021, William Bittle
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 |
7 | * Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | * Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation
12 | and/or other materials provided with the distribution.
13 |
14 | * Neither the name of the copyright holder nor the names of its
15 | contributors may be used to endorse or promote products derived from
16 | this software without specific prior written permission.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # dyn4j-samples
2 | A collection of samples that use the dyn4j library in a variety of ways.
3 |
4 | The intent of these samples is to provide a simple framework for building applications with the dyn4j library. The samples show how to use features like joints, static collision detection, raycasting, CCD, and so on. They also provide some creative ways to solve common problems like one-way platforms, jumping, destruction, player control, and so on. That said, none of these are intended to be complete solutions or even the correct solution for your use-case.
5 |
6 | * All samples support zoom and pan using the mouse and mouse wheel
7 | * All samples support object manipulation with the mouse
8 | * All samples have features like reset, reset camera, toggle rendering, etc.
9 | * Each sample may have it's own controls - see the console output when running for the full list of controls
10 |
11 | | Sample | Description | Concepts |
12 | | --- | --- | --- |
13 | | [BasketBall](https://github.com/dyn4j/dyn4j-samples/tree/master/src/main/java/org/dyn4j/samples/BasketBall.java) | A side view basketball game | Player Input, DistanceJoint, RevoluteJoint, Image Mapping/Texturing, Filtering, Bounds Listening |
14 | | [Billiards](https://github.com/dyn4j/dyn4j-samples/tree/master/src/main/java/org/dyn4j/samples/Billiards.java) | A top down billiards simulation | Density, Friction, Damping, Player Input |
15 | | [Bowling](https://github.com/dyn4j/dyn4j-samples/tree/master/src/main/java/org/dyn4j/samples/Bowling.java) | A side view of a bowling ball hitting pins | Density, Friction, Restitution, CategoryFilter |
16 | | [Bridge](https://github.com/dyn4j/dyn4j-samples/tree/master/src/main/java/org/dyn4j/samples/Bridge.java) | A side view of a bridge made from joined bodies | RevoluteJoint |
17 | | [Bucket](https://github.com/dyn4j/dyn4j-samples/tree/master/src/main/java/org/dyn4j/samples/Bucket.java) | A side view of a bucket with 200 random objects | Larger world |
18 | | [Concave](https://github.com/dyn4j/dyn4j-samples/tree/master/src/main/java/org/dyn4j/samples/Concave.java) | A side view of a concave object | Concave vs. Convex, Convex Composition |
19 | | [Crank](https://github.com/dyn4j/dyn4j-samples/tree/master/src/main/java/org/dyn4j/samples/Crank.java) | A side view of a piston | RevoluteJoint, PrismaticJoint |
20 | | [Decomposition](https://github.com/dyn4j/dyn4j-samples/tree/master/src/main/java/org/dyn4j/samples/Decomposition.java) | A side view of a few simple polygons decomposed | Convex Decomposition |
21 | | [Destructible](https://github.com/dyn4j/dyn4j-samples/tree/master/src/main/java/org/dyn4j/samples/Destructible.java) | A side view of destruction of a body and joint | Remove/Add Buffering |
22 | | [Images](https://github.com/dyn4j/dyn4j-samples/tree/master/src/main/java/org/dyn4j/samples/Images.java) | A side view of a scene where images are mapped to bodies | Image Mapping/Texturing |
23 | | [LinkTerrain](https://github.com/dyn4j/dyn4j-samples/tree/master/src/main/java/org/dyn4j/samples/LinkTerrain.java) | A side view of a link-based floor | Smooth Sliding, Link |
24 | | [Maze](https://github.com/dyn4j/dyn4j-samples/tree/master/src/main/java/org/dyn4j/samples/Maze.java) | A top down view of a maze with a player controled body | MotorJoint, Player Control |
25 | | [Organize](https://github.com/dyn4j/dyn4j-samples/tree/master/src/main/java/org/dyn4j/samples/Organize.java) | A side view of a scene where bodies are randomly joined and self organize | DistanceJoint |
26 | | [Platformer](https://github.com/dyn4j/dyn4j-samples/tree/master/src/main/java/org/dyn4j/samples/Platformer.java) | A side view of a platformer simulation | OnGround, Player Control, One-way Platform, Jumping |
27 | | [Pyramid](https://github.com/dyn4j/dyn4j-samples/tree/master/src/main/java/org/dyn4j/samples/Pyramid.java) | A side view of a Pyramid of stacked boxes | Stacking |
28 | | [Ragdoll](https://github.com/dyn4j/dyn4j-samples/tree/master/src/main/java/org/dyn4j/samples/Ragdoll.java) | A side view of a ragdoll made from joints | RevoluteJoint |
29 | | [Stacking](https://github.com/dyn4j/dyn4j-samples/tree/master/src/main/java/org/dyn4j/samples/Stacking.java) | A side view of a scene where the player can add boxes dynamically | Stacking, Add Bodies |
30 | | [Tank](https://github.com/dyn4j/dyn4j-samples/tree/master/src/main/java/org/dyn4j/samples/Tank.java) | A top down tank simulation | Raycasting, Player Control, FrictionJoint, RevoluteJoint |
31 | | [Thrust](https://github.com/dyn4j/dyn4j-samples/tree/master/src/main/java/org/dyn4j/samples/Thrust.java) | A side view of a scene with a rocket | Applying Forces |
32 | | [Tracking](https://github.com/dyn4j/dyn4j-samples/tree/master/src/main/java/org/dyn4j/samples/Tracking.java) | A scene where contact tracking is printed to the console | Contact Tracking |
33 | | [Truck](https://github.com/dyn4j/dyn4j-samples/tree/master/src/main/java/org/dyn4j/samples/Truck.java) | A scene where a truck filled with boxes moves through a world | WheelJoint, Fixture Composition |
34 | | [UsingGraphics2D](https://github.com/dyn4j/dyn4j-samples/tree/master/src/main/java/org/dyn4j/samples/UsingGraphics2D.java) | A scene with just a bunch of shapes rendered via Java 2D | Java 2D |
35 | | [UsingJogl](https://github.com/dyn4j/dyn4j-samples/tree/master/src/main/java/org/dyn4j/samples/UsingJogl.java) | A scene with a few shapes rendered via OpenGL via JOGL | JOGL |
36 |
37 | ### BasketBall
38 | Use angle, power, and position to attempt to make baskets. The sample only scores goals, so don't miss! If you are close you get 2 points, far away you get 3. Only if you get it in when you launch it is counted.
39 |
40 | 
41 |
42 | ### Billiards
43 | Use the cue stick to hit the cue ball to hit the other balls. You must wait until the balls settle before your next hit.
44 |
45 | 
46 |
47 | ### Platformer
48 | Use the ball to "run" around the level and jump. You can jump onto platforms above you no matter where you are, but if you land on them, they are solid. You can drop down from the top level as well. Green means you are touching the ground and can jump. Purple means you are not touching the ground.
49 |
50 | 
51 |
52 | ### Ragdoll
53 | Use your mouse to drag around and contort the ragdoll
54 |
55 | 
56 |
57 | ### Tank
58 | Drive a tank! Independently operating the tracks and barrel. The barrel will be pushed aside by obstacles. The barrel is "shooting" a ray to see what it would hit. You can press a key to destroy the closest object you are aiming at.
59 |
60 | 
61 |
62 | ### Thrust
63 | How hard can it be to fly a rocket? Using only front, back and side thrusters (applied force) fly a rocket around an enclosed area. Challenge yourself to land without tipping over or flying in a smooth trajectory.
64 |
65 | 
66 |
67 | ### Truck
68 | Drive a truck with cargo! Accelerate and decelerate using the keyboard or stop immediately. Watch the contents slide around as you drive. Use the mouse to manipulate the truck frame to see the suspension compress.
69 |
70 | 
71 |
72 |
--------------------------------------------------------------------------------
/captures/BasketBall.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dyn4j/dyn4j-samples/747a479d3a0059f73a4de62d33b6003d387d933e/captures/BasketBall.gif
--------------------------------------------------------------------------------
/captures/Billiards.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dyn4j/dyn4j-samples/747a479d3a0059f73a4de62d33b6003d387d933e/captures/Billiards.gif
--------------------------------------------------------------------------------
/captures/Platformer.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dyn4j/dyn4j-samples/747a479d3a0059f73a4de62d33b6003d387d933e/captures/Platformer.gif
--------------------------------------------------------------------------------
/captures/Ragdoll.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dyn4j/dyn4j-samples/747a479d3a0059f73a4de62d33b6003d387d933e/captures/Ragdoll.gif
--------------------------------------------------------------------------------
/captures/Tank.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dyn4j/dyn4j-samples/747a479d3a0059f73a4de62d33b6003d387d933e/captures/Tank.gif
--------------------------------------------------------------------------------
/captures/Thrust.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dyn4j/dyn4j-samples/747a479d3a0059f73a4de62d33b6003d387d933e/captures/Thrust.gif
--------------------------------------------------------------------------------
/captures/Truck.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dyn4j/dyn4j-samples/747a479d3a0059f73a4de62d33b6003d387d933e/captures/Truck.gif
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 | org.dyn4j
4 | dyn4j-samples
5 | 1.0.0
6 | dyn4j-samples
7 | http://www.dyn4j.org
8 | A collection of samples that use the dyn4j library in a variety of ways
9 | 2010
10 |
11 | dyn4j
12 | http://www.dyn4j.org
13 |
14 |
15 | https://github.com/dyn4j/dyn4j-samples
16 |
17 |
18 | GitHub Issues
19 | https://github.com/dyn4j/dyn4j-samples/issues
20 |
21 |
22 | 6
23 |
24 |
25 |
26 | org.jogamp.jogl
27 | jogl-all-main
28 | 2.3.2
29 |
30 |
31 | org.jogamp.gluegen
32 | gluegen-rt-main
33 | 2.3.2
34 |
35 |
36 | org.dyn4j
37 | dyn4j
38 | 5.0.2
39 |
40 |
41 |
42 |
43 |
44 |
45 | maven-compiler-plugin
46 | 3.8.0
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/Billiards.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2023 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples;
26 |
27 | import java.awt.Color;
28 | import java.awt.Graphics2D;
29 | import java.awt.event.KeyEvent;
30 |
31 | import org.dyn4j.collision.Filter;
32 | import org.dyn4j.dynamics.BodyFixture;
33 | import org.dyn4j.geometry.Geometry;
34 | import org.dyn4j.geometry.MassType;
35 | import org.dyn4j.geometry.Polygon;
36 | import org.dyn4j.geometry.Transform;
37 | import org.dyn4j.geometry.Vector2;
38 | import org.dyn4j.samples.framework.Camera;
39 | import org.dyn4j.samples.framework.SimulationBody;
40 | import org.dyn4j.samples.framework.SimulationFrame;
41 | import org.dyn4j.samples.framework.input.BooleanStateKeyboardInputHandler;
42 | import org.dyn4j.samples.framework.input.Key;
43 | import org.dyn4j.world.World;
44 |
45 | /**
46 | * A simple scene of two billiard balls colliding with one another
47 | * and a wall.
48 | *
49 | * Primarily used to illustrate the computation of the mass and size
50 | * of the balls. See the {@link Billiards#initializeWorld()} method.
51 | * @author William Bittle
52 | * @version 5.0.2
53 | * @since 3.2.0
54 | */
55 | public final class Billiards extends SimulationFrame {
56 | /** The serial version id */
57 | private static final long serialVersionUID = -8518496343422955267L;
58 |
59 | private static final Object BALL_IDENTIFIER = new Object();
60 | private SimulationBody cueBall;
61 | private SimulationBody cueStick;
62 | private Vector2 stickLocation = new Vector2();
63 |
64 | private double angle;
65 | private double power;
66 |
67 | private final BooleanStateKeyboardInputHandler left;
68 | private final BooleanStateKeyboardInputHandler right;
69 |
70 | private final BooleanStateKeyboardInputHandler plus;
71 | private final BooleanStateKeyboardInputHandler minus;
72 |
73 | private final BooleanStateKeyboardInputHandler shoot;
74 |
75 | /**
76 | * Default constructor.
77 | */
78 | public Billiards() {
79 | super("Billiards");
80 |
81 | this.left = new BooleanStateKeyboardInputHandler(this.canvas, KeyEvent.VK_LEFT);
82 | this.right = new BooleanStateKeyboardInputHandler(this.canvas, KeyEvent.VK_RIGHT);
83 | this.plus = new BooleanStateKeyboardInputHandler(this.canvas, new Key(KeyEvent.VK_PLUS), new Key(KeyEvent.VK_ADD), new Key(KeyEvent.VK_EQUALS, KeyEvent.SHIFT_DOWN_MASK));
84 | this.minus = new BooleanStateKeyboardInputHandler(this.canvas, KeyEvent.VK_MINUS, KeyEvent.VK_SUBTRACT);
85 | this.shoot = new BooleanStateKeyboardInputHandler(this.canvas, KeyEvent.VK_S);
86 |
87 | this.left.install();
88 | this.right.install();
89 | this.plus.install();
90 | this.minus.install();
91 | this.shoot.install();
92 | }
93 |
94 | /* (non-Javadoc)
95 | * @see org.dyn4j.samples.SimulationFrame#initializeWorld()
96 | */
97 | @Override
98 | protected void initializeWorld() {
99 | // no gravity on a top-down view of a billiards game
100 | this.world.setGravity(World.ZERO_GRAVITY);
101 |
102 | final double edgeDepth = 0.29 / 2.0;
103 | final double tableWidth = 1.83;
104 | final double tableHeight = 1.12;
105 |
106 | final double halfTableWidth = tableWidth / 2.0;
107 | final double halfTableHeight = tableHeight / 2.0;
108 | final double halfEdgeDepth = edgeDepth / 2.0;
109 |
110 | // 2.25 in diameter = 0.028575 m radius
111 | final double ballRadius = 0.028575;
112 |
113 | // 0.126 oz/in^3 = 217.97925 kg/m^3
114 | final double ballDensity = 217.97925;
115 |
116 | final double ballFriction = 0.08;
117 | final double ballRestitution = 0.9;
118 |
119 | // I wouldn't do this in practice - I'm being lazy and using a body
120 | // to render a green bottom to the billiards table. Instead, you should
121 | // just render the green bottom and not use a body.
122 | SimulationBody bottom = new SimulationBody(new Color(60, 164, 114));
123 | BodyFixture bf = bottom.addFixture(Geometry.createRectangle(tableWidth, tableHeight), 1.0, 0.0, 0.0);
124 | bf.setFilter(new Filter() {
125 | @Override
126 | public boolean isAllowed(Filter filter) {
127 | return false;
128 | }
129 | });
130 | bottom.setMass(MassType.INFINITE);
131 | world.addBody(bottom);
132 |
133 | SimulationBody wallRight = new SimulationBody(new Color(150, 75, 0));
134 | BodyFixture fixture = wallRight.addFixture(Geometry.createRectangle(edgeDepth, tableHeight), 1.0, 0.4, 0.3);
135 | fixture.setRestitutionVelocity(0.0);
136 | wallRight.translate(halfTableWidth - halfEdgeDepth, 0);
137 | wallRight.setMass(MassType.INFINITE);
138 | wallRight.setAtRestDetectionEnabled(false);
139 | world.addBody(wallRight);
140 |
141 | SimulationBody wallLeft = new SimulationBody(new Color(150, 75, 0));
142 | fixture = wallLeft.addFixture(Geometry.createRectangle(edgeDepth, tableHeight), 1.0, 0.4, 0.3);
143 | fixture.setRestitutionVelocity(0.0);
144 | wallLeft.translate(-halfTableWidth + halfEdgeDepth, 0);
145 | wallLeft.setMass(MassType.INFINITE);
146 | wallLeft.setAtRestDetectionEnabled(false);
147 | world.addBody(wallLeft);
148 |
149 | SimulationBody wallTop = new SimulationBody(new Color(150, 75, 0));
150 | fixture = wallTop.addFixture(Geometry.createRectangle(tableWidth, edgeDepth), 1.0, 0.4, 0.3);
151 | fixture.setRestitutionVelocity(0.0);
152 | wallTop.translate(0, halfTableHeight - halfEdgeDepth);
153 | wallTop.setMass(MassType.INFINITE);
154 | wallTop.setAtRestDetectionEnabled(false);
155 | world.addBody(wallTop);
156 |
157 | SimulationBody wallBottom = new SimulationBody(new Color(150, 75, 0));
158 | fixture = wallBottom.addFixture(Geometry.createRectangle(tableWidth, edgeDepth), 1.0, 0.4, 0.3);
159 | fixture.setRestitutionVelocity(0.0);
160 | wallBottom.translate(0, -halfTableHeight + halfEdgeDepth);
161 | wallBottom.setMass(MassType.INFINITE);
162 | wallBottom.setAtRestDetectionEnabled(false);
163 | world.addBody(wallBottom);
164 |
165 | cueBall = new SimulationBody(new Color(255, 255, 255));
166 | fixture = cueBall.addFixture(Geometry.createCircle(ballRadius), ballDensity, ballFriction, ballRestitution);
167 | fixture.setRestitutionVelocity(0.001);
168 | cueBall.setUserData(BALL_IDENTIFIER);
169 | cueBall.translate(-0.25, 0.0);
170 | cueBall.setLinearDamping(0.8);
171 | cueBall.setAngularDamping(0.8);
172 | cueBall.setMass(MassType.NORMAL);
173 | cueBall.setBullet(true);
174 | this.world.addBody(cueBall);
175 |
176 | cueStick = new SimulationBody(new Color(180, 140, 50));
177 | cueStick.addFixture(new Polygon(
178 | new Vector2(0.0, 0.008),
179 | new Vector2(-1.0, 0.015),
180 | new Vector2(-1.0, -0.015),
181 | new Vector2(0.0, -0.008)));
182 | cueStick.setMass(MassType.NORMAL);
183 | stickLocation = new Vector2(-0.25, 0.0);
184 |
185 | // billiard colors
186 | Color[] colors = new Color[] {
187 | // solid
188 | new Color(255, 215, 0),
189 | new Color(0, 0, 255),
190 | new Color(255, 0, 0),
191 | new Color(75, 0, 130),
192 | new Color(255, 69, 0),
193 | new Color(34, 139, 34),
194 | new Color(128, 0, 0),
195 | new Color(0, 0, 0),
196 |
197 | // striped (just do a lighter color)
198 | new Color(255, 215, 0).darker(),
199 | new Color(0, 0, 255).darker(),
200 | new Color(255, 0, 0).darker(),
201 | new Color(75, 0, 130).brighter(),
202 | new Color(255, 69, 0).darker(),
203 | new Color(34, 139, 34).brighter(),
204 | new Color(128, 0, 0).brighter(),
205 | new Color(0, 0, 0).brighter()
206 | };
207 |
208 | final int rackSize = 5;
209 | final double sx = 0.45;
210 | final double sy = -ballRadius;
211 |
212 | // 5 columns
213 | int n = 0;
214 | for (int i = 0; i < rackSize; i++) {
215 | double x = sx - (ballRadius * 2.0 * (double)i);
216 | double columnHeight = ballRadius * 2.0 * (rackSize - i);
217 | double csy = columnHeight / 2.0;
218 | // 5 - i rows
219 | for (int j = 0; j < rackSize - i; j++) {
220 | double y = sy + csy - (ballRadius * 2.0 * j);
221 |
222 | SimulationBody ball = new SimulationBody(colors[n]);
223 | fixture = ball.addFixture(Geometry.createCircle(ballRadius), ballDensity, ballFriction, ballRestitution);
224 | fixture.setRestitutionVelocity(0.005);
225 | ball.setUserData(BALL_IDENTIFIER);
226 | ball.translate(x, y);
227 | ball.setLinearDamping(0.8);
228 | ball.setAngularDamping(0.8);
229 | ball.setMass(MassType.NORMAL);
230 | ball.setBullet(true);
231 | this.world.addBody(ball);
232 |
233 | n++;
234 | }
235 | }
236 | }
237 |
238 | /* (non-Javadoc)
239 | * @see org.dyn4j.samples.framework.SimulationFrame#initializeCamera(org.dyn4j.samples.framework.Camera)
240 | */
241 | @Override
242 | protected void initializeCamera(Camera camera) {
243 | super.initializeCamera(camera);
244 | camera.scale = 250.0;
245 | }
246 |
247 | /* (non-Javadoc)
248 | * @see org.dyn4j.samples.framework.SimulationFrame#printControls()
249 | */
250 | @Override
251 | protected void printControls() {
252 | super.printControls();
253 |
254 | printControl("Rotate Left", "Left", "Use the left key to rotate counter-clockwise");
255 | printControl("Rotate Right", "Right", "Use the right key to rotate clockwise");
256 | printControl("Increase Power", "+", "Use the + key to increase the shoot power");
257 | printControl("Decrease Power", "-", "Use the - key to decrease the shoot power");
258 | printControl("Shoot", "s", "Use the s key to hit the cue ball");
259 | }
260 |
261 | /* (non-Javadoc)
262 | * @see org.dyn4j.samples.framework.SimulationFrame#render(java.awt.Graphics2D, double)
263 | */
264 | @Override
265 | protected void render(Graphics2D g, double elapsedTime) {
266 | super.render(g, elapsedTime);
267 |
268 | // check if all balls are at rest, if so, then reset the cue stick position
269 | if (allBallsAtRest()) {
270 | this.stickLocation = this.cueBall.getWorldCenter();
271 | }
272 |
273 | Transform tx = new Transform();
274 | tx.setTranslation(stickLocation.sum(-this.power - 0.05, 0.0));
275 | tx.rotate(this.angle, stickLocation);
276 |
277 | this.cueStick.setTransform(tx);
278 | this.render(g, elapsedTime, cueStick);
279 | }
280 |
281 | private final boolean allBallsAtRest() {
282 | final int n = this.world.getBodyCount();
283 | for (int i = 0; i < n; i++) {
284 | SimulationBody b = this.world.getBody(i);
285 | if (b.getUserData() == BALL_IDENTIFIER) {
286 | if (!b.isAtRest()) {
287 | return false;
288 | }
289 | }
290 | }
291 |
292 | return true;
293 | }
294 |
295 | /* (non-Javadoc)
296 | * @see org.dyn4j.samples.framework.SimulationFrame#reset()
297 | */
298 | @Override
299 | public void reset() {
300 | super.reset();
301 |
302 | this.angle = 0.0;
303 | this.power = 0.0;
304 | this.stickLocation.zero();
305 | }
306 |
307 | /* (non-Javadoc)
308 | * @see org.dyn4j.samples.framework.SimulationFrame#handleEvents()
309 | */
310 | @Override
311 | protected void handleEvents() {
312 | super.handleEvents();
313 |
314 | if (allBallsAtRest()) {
315 | if (this.left.isActive()) {
316 | this.angle += 0.005;
317 | }
318 |
319 | if (this.right.isActive()) {
320 | this.angle -= 0.005;
321 | }
322 |
323 | if (this.plus.isActive()) {
324 | this.power += 0.005;
325 | }
326 |
327 | if (this.minus.isActive()) {
328 | this.power -= 0.005;
329 | if (this.power <= 0.0) {
330 | this.power = 0.0;
331 | }
332 | }
333 |
334 | if (this.shoot.isActiveButNotHandled()) {
335 | this.shoot.setHasBeenHandled(true);
336 |
337 | if (this.power > 0.0) {
338 | Vector2 v = new Vector2(this.cueStick.getTransform().getRotationAngle());
339 | v.multiply(this.power * 10.0);
340 | this.cueBall.setAtRest(false);
341 | this.cueBall.setLinearVelocity(v);
342 | this.power = 0.0;
343 | }
344 | }
345 | }
346 | }
347 |
348 | /**
349 | * Entry point for the example application.
350 | * @param args command line arguments
351 | */
352 | public static void main(String[] args) {
353 | Billiards simulation = new Billiards();
354 | simulation.run();
355 | }
356 | }
357 |
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/Bowling.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2022 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples;
26 |
27 | import java.util.List;
28 |
29 | import org.dyn4j.collision.CategoryFilter;
30 | import org.dyn4j.dynamics.BodyFixture;
31 | import org.dyn4j.geometry.Geometry;
32 | import org.dyn4j.geometry.Link;
33 | import org.dyn4j.geometry.MassType;
34 | import org.dyn4j.geometry.Vector2;
35 | import org.dyn4j.samples.framework.Camera;
36 | import org.dyn4j.samples.framework.SimulationBody;
37 | import org.dyn4j.samples.framework.SimulationFrame;
38 |
39 | /**
40 | * A scene where a bowling ball hits a set of pins.
41 | *
42 | * The pins can interact with anything in the ALL and BALL groups, but not with themselves.
43 | * @author William Bittle
44 | * @version 5.0.0
45 | * @since 3.2.1
46 | */
47 | public class Bowling extends SimulationFrame {
48 | /** The serial version id */
49 | private static final long serialVersionUID = 6102930425312889302L;
50 |
51 | private static final CategoryFilter ALL = new CategoryFilter(1, Long.MAX_VALUE);
52 | private static final CategoryFilter BALL = new CategoryFilter(2, Long.MAX_VALUE);
53 | private static final CategoryFilter PIN = new CategoryFilter(4, 1 | 2 | 8);
54 | private static final CategoryFilter NOT_BALL = new CategoryFilter(8, 1 | 4);
55 |
56 | /**
57 | * Default constructor.
58 | */
59 | public Bowling() {
60 | super("Bowling");
61 | }
62 |
63 | /**
64 | * Creates game objects and adds them to the world.
65 | */
66 | protected void initializeWorld() {
67 | SimulationBody floor = new SimulationBody();
68 | BodyFixture fixture = floor.addFixture(Geometry.createRectangle(15.0, 0.2), 0.9);
69 | fixture.setFilter(ALL);
70 | floor.setMass(MassType.INFINITE);
71 | this.world.addBody(floor);
72 |
73 | SimulationBody wall = new SimulationBody();
74 | fixture = wall.addFixture(Geometry.createRectangle(0.2, 3.0));
75 | fixture.setFilter(NOT_BALL);
76 | wall.setMass(MassType.INFINITE);
77 | wall.translate(7.0, 1.5);
78 | this.world.addBody(wall);
79 |
80 | SimulationBody top = new SimulationBody();
81 | fixture = top.addFixture(Geometry.createRectangle(2.0, 0.2));
82 | fixture.setFilter(ALL);
83 | fixture = top.addFixture(Geometry.createRectangle(1.0, 0.2));
84 | fixture.setFilter(ALL);
85 | fixture.getShape().rotate(Math.toDegrees(60));
86 | fixture.getShape().translate(-1.25, -0.25);
87 | top.setMass(MassType.INFINITE);
88 | top.translate(6.0, 2.0);
89 | this.world.addBody(top);
90 |
91 | SimulationBody channel = new SimulationBody();
92 | Vector2[] verts = new Vector2[] {
93 | new Vector2(7.0, 0.5),
94 | new Vector2(8.0, 0.5),
95 | new Vector2(8.5, 0.25),
96 | new Vector2(9.0, 0.0),
97 | new Vector2(8.5, -0.25),
98 | new Vector2(8.0, -0.5),
99 | new Vector2(-8.0, -1.0),
100 | new Vector2(-9.0, -0.5),
101 | new Vector2(-10.0, 0.0),
102 | new Vector2(-9.0, 0.5),
103 | new Vector2(-8.0, 1.0)
104 | };
105 | List links = Geometry.createLinks(verts, false);
106 | for (Link link : links) {
107 | channel.addFixture(link);
108 | }
109 | channel.setMass(MassType.INFINITE);
110 | this.world.addBody(channel);
111 |
112 | SimulationBody bowlingBall = new SimulationBody();
113 | fixture = new BodyFixture(Geometry.createCircle(0.109));
114 | fixture.setDensity(194.82);
115 | fixture.setRestitution(0.5);
116 | fixture.setFilter(BALL);
117 | bowlingBall.addFixture(fixture);
118 | bowlingBall.setMass(MassType.NORMAL);
119 | bowlingBall.setLinearVelocity(new Vector2(10.0, 0.0));
120 | bowlingBall.setAngularDamping(0.5);
121 | bowlingBall.translate(-3.0, 0.1);
122 | this.world.addBody(bowlingBall);
123 |
124 | // create some pins
125 | double x = 6;
126 | for (int i = 0; i < 10; i++) {
127 | SimulationBody pin = new SimulationBody();
128 | BodyFixture bf = pin.addFixture(Geometry.createRectangle(0.1, 0.5), 2.0, 0.5, 0.6);
129 | bf.setFilter(PIN);
130 | pin.setMass(MassType.NORMAL);
131 | pin.translate(x, 0.1 + 0.25);
132 | this.world.addBody(pin);
133 | x += 0.06;
134 | }
135 | }
136 |
137 | @Override
138 | protected void initializeCamera(Camera camera) {
139 | super.initializeCamera(camera);
140 | camera.scale = 64.0;
141 | camera.offsetX = -150.0;
142 | camera.offsetY = -100.0;
143 | }
144 |
145 | /**
146 | * Entry point for the example application.
147 | * @param args command line arguments
148 | */
149 | public static void main(String[] args) {
150 | Bowling simulation = new Bowling();
151 | simulation.run();
152 | }
153 | }
154 |
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/Bridge.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2022 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples;
26 |
27 | import org.dyn4j.dynamics.BodyFixture;
28 | import org.dyn4j.dynamics.joint.RevoluteJoint;
29 | import org.dyn4j.geometry.Convex;
30 | import org.dyn4j.geometry.Geometry;
31 | import org.dyn4j.geometry.MassType;
32 | import org.dyn4j.geometry.Vector2;
33 | import org.dyn4j.samples.framework.Camera;
34 | import org.dyn4j.samples.framework.SimulationBody;
35 | import org.dyn4j.samples.framework.SimulationFrame;
36 |
37 | /**
38 | * A scene where we create a suspension bridge via RevoluteJoints.
39 | * @author William Bittle
40 | * @version 5.0.0
41 | * @since 4.1.1
42 | */
43 | public class Bridge extends SimulationFrame {
44 | /** The serial version id */
45 | private static final long serialVersionUID = -2350301592218819726L;
46 |
47 | /**
48 | * Default constructor.
49 | */
50 | public Bridge() {
51 | super("Bridge");
52 | }
53 |
54 | /**
55 | * Creates game objects and adds them to the world.
56 | */
57 | protected void initializeWorld() {
58 | // Ground
59 | SimulationBody ground = new SimulationBody();
60 | ground.addFixture(Geometry.createRectangle(50.0, 1.0));
61 | ground.translate(new Vector2(0.6875, -8.75));
62 | ground.setMass(MassType.INFINITE);
63 | world.addBody(ground);
64 |
65 | final double y = 2.0;
66 | final int n = 20;
67 | final double hn = n / 2.0;
68 | final double w = 1.0;
69 | final double hw = w / 2.0;
70 | final double h = 0.25;
71 |
72 | SimulationBody prev = ground;
73 | for (int i = 0; i < n; i++) {
74 | SimulationBody section = new SimulationBody();
75 | {// Fixture1
76 | Convex c = Geometry.createRectangle(w, h);
77 | BodyFixture bf = new BodyFixture(c);
78 | section.addFixture(bf);
79 | }
80 | section.translate(new Vector2(i - hn, y));
81 | section.setMass(MassType.NORMAL);
82 | world.addBody(section);
83 |
84 | // connect the previous body with this body
85 | RevoluteJoint rj = new RevoluteJoint(prev, section, new Vector2(i - hn - hw, y));
86 | world.addJoint(rj);
87 |
88 | prev = section;
89 | }
90 |
91 | // connect the last body with the ground
92 | RevoluteJoint rj = new RevoluteJoint(prev, ground, new Vector2(hn + hw, y));
93 | world.addJoint(rj);
94 | }
95 |
96 | /* (non-Javadoc)
97 | * @see org.dyn4j.samples.framework.SimulationFrame#initializeCamera(org.dyn4j.samples.framework.Camera)
98 | */
99 | @Override
100 | protected void initializeCamera(Camera camera) {
101 | super.initializeCamera(camera);
102 | camera.scale = 32.0;
103 | }
104 |
105 | /**
106 | * Entry point for the example application.
107 | * @param args command line arguments
108 | */
109 | public static void main(String[] args) {
110 | Bridge simulation = new Bridge();
111 | simulation.run();
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/Bucket.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2022 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples;
26 |
27 | import java.util.Random;
28 |
29 | import org.dyn4j.geometry.Convex;
30 | import org.dyn4j.geometry.Geometry;
31 | import org.dyn4j.geometry.MassType;
32 | import org.dyn4j.geometry.Vector2;
33 | import org.dyn4j.samples.framework.Camera;
34 | import org.dyn4j.samples.framework.SimulationBody;
35 | import org.dyn4j.samples.framework.SimulationFrame;
36 |
37 | /**
38 | * A scene where we fill a "bucket" with shapes.
39 | * @author William Bittle
40 | * @since 5.0.0
41 | * @version 4.1.1
42 | */
43 | public class Bucket extends SimulationFrame {
44 | /** The serial version id */
45 | private static final long serialVersionUID = -3837218136220591307L;
46 |
47 | /**
48 | * Default constructor.
49 | */
50 | public Bucket() {
51 | super("Bucket");
52 | }
53 |
54 | /**
55 | * Creates game objects and adds them to the world.
56 | */
57 | protected void initializeWorld() {
58 | // world.getSettings().setStepFrequency(1.0/30.0);
59 | // world.getSettings().setPositionConstraintSolverIterations(10);
60 | // world.getSettings().setVelocityConstraintSolverIterations(10);
61 |
62 | // Bottom
63 | SimulationBody bucketBottom = new SimulationBody();
64 | bucketBottom.addFixture(Geometry.createRectangle(15.0, 1.0));
65 | bucketBottom.setMass(MassType.INFINITE);
66 | world.addBody(bucketBottom);
67 |
68 | // Left-Side
69 | SimulationBody bucketLeft = new SimulationBody();
70 | bucketLeft.addFixture(Geometry.createRectangle(1.0, 15.0));
71 | bucketLeft.translate(new Vector2(-7.5, 7.0));
72 | bucketLeft.setMass(MassType.INFINITE);
73 | world.addBody(bucketLeft);
74 |
75 | // Right-Side
76 | SimulationBody bucketRight = new SimulationBody();
77 | bucketRight.addFixture(Geometry.createRectangle(1.0, 15.0));
78 | bucketRight.translate(new Vector2(7.5, 7.0));
79 | bucketRight.setMass(MassType.INFINITE);
80 | world.addBody(bucketRight);
81 |
82 | Random r = new Random(23);
83 | double xmin = -7.0;
84 | double xmax = 7.0;
85 | double ymin = 0.5;
86 | double ymax = 20.0;
87 | double maxSize = 0.6;
88 | double minSize = 0.2;
89 |
90 | for (int i = 0; i < 1000; i++) {
91 | double size = r.nextDouble() * maxSize + minSize;
92 |
93 | Convex c = null;
94 |
95 | int type = r.nextInt(2);
96 | switch (type) {
97 | case 0:
98 | c = Geometry.createRectangle(size, size);
99 | break;
100 | case 1:
101 | default:
102 | c = Geometry.createCircle(size * 0.5);
103 | break;
104 | }
105 |
106 | double x = r.nextDouble() * xmax * 2 + xmin;
107 | double y = r.nextDouble() * ymax + ymin;
108 |
109 | SimulationBody b = new SimulationBody();
110 | b.addFixture(c);
111 | b.translate(new Vector2(x, y));
112 | b.setMass(MassType.NORMAL);
113 | world.addBody(b);
114 | }
115 | }
116 |
117 | /* (non-Javadoc)
118 | * @see org.dyn4j.samples.framework.SimulationFrame#initializeCamera(org.dyn4j.samples.framework.Camera)
119 | */
120 | @Override
121 | protected void initializeCamera(Camera camera) {
122 | super.initializeCamera(camera);
123 | camera.scale = 32.0;
124 | camera.offsetY = -200;
125 | }
126 |
127 | /**
128 | * Entry point for the example application.
129 | * @param args command line arguments
130 | */
131 | public static void main(String[] args) {
132 | Bucket simulation = new Bucket();
133 | simulation.run();
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/Concave.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2022 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples;
26 |
27 | import org.dyn4j.geometry.Convex;
28 | import org.dyn4j.geometry.Geometry;
29 | import org.dyn4j.geometry.MassType;
30 | import org.dyn4j.geometry.Vector2;
31 | import org.dyn4j.samples.framework.Camera;
32 | import org.dyn4j.samples.framework.SimulationBody;
33 | import org.dyn4j.samples.framework.SimulationFrame;
34 |
35 | /**
36 | * An example of using a "Concave" body.
37 | * @author William Bittle
38 | * @since 5.0.0
39 | * @version 4.1.1
40 | */
41 | public class Concave extends SimulationFrame {
42 | /** The serial version id */
43 | private static final long serialVersionUID = 8797361529527319100L;
44 |
45 | /**
46 | * Default constructor.
47 | */
48 | public Concave() {
49 | super("Concave");
50 | }
51 |
52 | /* (non-Javadoc)
53 | * @see org.dyn4j.samples.framework.SimulationFrame#initializeWorld()
54 | */
55 | protected void initializeWorld() {
56 | // Ground
57 | SimulationBody ground = new SimulationBody();
58 | ground.addFixture(Geometry.createRectangle(15.0, 1.0));
59 | ground.setMass(MassType.INFINITE);
60 | world.addBody(ground);
61 |
62 | // Concave
63 | SimulationBody table = new SimulationBody();
64 | {
65 | Convex c = Geometry.createRectangle(3.0, 1.0);
66 | c.translate(new Vector2(0.0, 0.5));
67 | table.addFixture(c);
68 | }
69 | {
70 | Convex c = Geometry.createRectangle(1.0, 1.0);
71 | c.translate(new Vector2(-1.0, -0.5));
72 | table.addFixture(c);
73 | }
74 | {
75 | Convex c = Geometry.createRectangle(1.0, 1.0);
76 | c.translate(new Vector2(1.0, -0.5));
77 | table.addFixture(c);
78 | }
79 | table.translate(new Vector2(0.0, 4.0));
80 | table.setMass(MassType.NORMAL);
81 | world.addBody(table);
82 |
83 | // Body3
84 | SimulationBody box = new SimulationBody();
85 | box.addFixture(Geometry.createSquare(0.5));
86 | box.translate(new Vector2(0.0, 1.0));
87 | box.setMass(MassType.NORMAL);
88 | world.addBody(box);
89 | }
90 |
91 | @Override
92 | protected void initializeCamera(Camera camera) {
93 | super.initializeCamera(camera);
94 | camera.scale = 64.0;
95 | camera.offsetY = -200.0;
96 | }
97 |
98 | /**
99 | * Entry point for the example application.
100 | * @param args command line arguments
101 | */
102 | public static void main(String[] args) {
103 | Concave simulation = new Concave();
104 | simulation.run();
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/Crank.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2022 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples;
26 |
27 | import org.dyn4j.dynamics.joint.PrismaticJoint;
28 | import org.dyn4j.dynamics.joint.RevoluteJoint;
29 | import org.dyn4j.geometry.Geometry;
30 | import org.dyn4j.geometry.MassType;
31 | import org.dyn4j.geometry.Vector2;
32 | import org.dyn4j.samples.framework.Camera;
33 | import org.dyn4j.samples.framework.SimulationBody;
34 | import org.dyn4j.samples.framework.SimulationFrame;
35 |
36 | /**
37 | * A scene that replicates a piston in an ICE.
38 | * @author William Bittle
39 | * @since 5.0.0
40 | * @version 4.1.1
41 | */
42 | public class Crank extends SimulationFrame {
43 | /** The serial version id */
44 | private static final long serialVersionUID = -602182516495632849L;
45 |
46 | /**
47 | * Default constructor.
48 | */
49 | public Crank() {
50 | super("Crank");
51 | }
52 |
53 | /* (non-Javadoc)
54 | * @see org.dyn4j.samples.framework.SimulationFrame#initializeWorld()
55 | */
56 | protected void initializeWorld() {
57 | SimulationBody ground = new SimulationBody();
58 | ground.addFixture(Geometry.createRectangle(10.0, 0.5));
59 | ground.setMass(MassType.INFINITE);
60 | world.addBody(ground);
61 |
62 | // piston+crank
63 |
64 | SimulationBody crank = new SimulationBody();
65 | crank.addFixture(Geometry.createRectangle(0.5, 2.0), 2.0, 0.0, 0.0);
66 | crank.translate(new Vector2(0.0, 5.0));
67 | crank.setMass(MassType.NORMAL);
68 | world.addBody(crank);
69 |
70 | SimulationBody rod = new SimulationBody();
71 | rod.addFixture(Geometry.createRectangle(0.5, 4.0), 2.0, 0.0, 0.0);
72 | rod.translate(new Vector2(0.0, 7.5));
73 | rod.setMass(MassType.NORMAL);
74 | world.addBody(rod);
75 |
76 | SimulationBody piston = new SimulationBody();
77 | piston.addFixture(Geometry.createRectangle(1.5, 1.5), 2.0, 0.0, 0.0);
78 | piston.translate(new Vector2(0.0, 9.75));
79 | piston.setMass(MassType.FIXED_ANGULAR_VELOCITY);
80 | world.addBody(piston);
81 |
82 | // provides the motion
83 | RevoluteJoint crankShaftJoint = new RevoluteJoint(ground, crank, new Vector2(0.0, 4.25));
84 | crankShaftJoint.setMotorEnabled(true);
85 | crankShaftJoint.setMotorSpeed(Math.toRadians(180.0));
86 | crankShaftJoint.setMaximumMotorTorque(10000.0);
87 | world.addJoint(crankShaftJoint);
88 |
89 | // links the crank to the rod
90 | RevoluteJoint crankToRodJoint = new RevoluteJoint(crank, rod, new Vector2(0.0, 5.75));
91 | world.addJoint(crankToRodJoint);
92 |
93 | // links the rod to the piston
94 | RevoluteJoint rodToPistonJoint = new RevoluteJoint(rod, piston, new Vector2(0.0, 9.25));
95 | world.addJoint(rodToPistonJoint);
96 |
97 | // keeps the piston moving along the y-axis
98 | PrismaticJoint pistonPathJoint = new PrismaticJoint(ground, piston, new Vector2(0.0, 9.75), new Vector2(0.0, 1.0));
99 | world.addJoint(pistonPathJoint);
100 | }
101 |
102 | /* (non-Javadoc)
103 | * @see org.dyn4j.samples.framework.SimulationFrame#initializeCamera(org.dyn4j.samples.framework.Camera)
104 | */
105 | @Override
106 | protected void initializeCamera(Camera camera) {
107 | super.initializeCamera(camera);
108 | camera.scale = 32.0;
109 | camera.offsetY = -200.0;
110 | }
111 |
112 | /**
113 | * Entry point for the example application.
114 | * @param args command line arguments
115 | */
116 | public static void main(String[] args) {
117 | Crank simulation = new Crank();
118 | simulation.run();
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/Decomposition.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2022 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples;
26 |
27 | import java.util.List;
28 |
29 | import org.dyn4j.geometry.Convex;
30 | import org.dyn4j.geometry.Geometry;
31 | import org.dyn4j.geometry.MassType;
32 | import org.dyn4j.geometry.Vector2;
33 | import org.dyn4j.geometry.decompose.Bayazit;
34 | import org.dyn4j.geometry.decompose.Decomposer;
35 | import org.dyn4j.geometry.decompose.EarClipping;
36 | import org.dyn4j.geometry.decompose.SweepLine;
37 | import org.dyn4j.samples.framework.Camera;
38 | import org.dyn4j.samples.framework.SimulationBody;
39 | import org.dyn4j.samples.framework.SimulationFrame;
40 |
41 | /**
42 | * An example of using the convex decomposition classes to
43 | * build a set of convex objects from a simple polygon.
44 | *
45 | * NOTE: Please review the definition of Simple Polygon.
46 | * @author William Bittle
47 | * @since 5.0.0
48 | * @version 4.1.1
49 | */
50 | public class Decomposition extends SimulationFrame {
51 | /** The serial version id */
52 | private static final long serialVersionUID = 805187905337457811L;
53 |
54 | /**
55 | * Default constructor.
56 | */
57 | public Decomposition() {
58 | super("Decomposition");
59 | }
60 |
61 | /* (non-Javadoc)
62 | * @see org.dyn4j.samples.framework.SimulationFrame#initializeWorld()
63 | */
64 | protected void initializeWorld() {
65 |
66 | // Ground
67 | SimulationBody ground = new SimulationBody();
68 | ground.addFixture(Geometry.createRectangle(15.0, 1.0));
69 | ground.setMass(MassType.INFINITE);
70 | world.addBody(ground);
71 |
72 | // a (lowercase) "d" shape
73 | Vector2[] dVerticies = new Vector2[] {
74 | new Vector2(-0.703125, 0.859375),
75 | new Vector2(-0.828125, 0.625),
76 | new Vector2(-0.875, 0.25),
77 | new Vector2(-0.625, 0.0625),
78 | new Vector2(-0.359375, 0.046875),
79 | new Vector2(-0.1875, 0.1875),
80 | new Vector2(-0.21875, 0.0),
81 | new Vector2(0.0, -0.0),
82 | new Vector2(-0.015625, 1.625),
83 | new Vector2(-0.171875, 1.640625),
84 | new Vector2(-0.171875, 0.671875),
85 | new Vector2(-0.375, 0.84375)
86 | };
87 |
88 | Decomposer bayazit = new Bayazit();
89 | List parts = bayazit.decompose(dVerticies);
90 | SimulationBody d = new SimulationBody();
91 | for (Convex c : parts) {
92 | d.addFixture(c);
93 | }
94 | d.rotate(Math.toRadians(-0.17453292519943292));
95 | d.translate(new Vector2(-1.950745294864571, 0.4726801090249715));
96 | d.setMass(MassType.NORMAL);
97 | world.addBody(d);
98 |
99 | // a (lowercase) "y" shape
100 | Vector2[] yVerticies = new Vector2[] {
101 | new Vector2(0.53125, -1.390625),
102 | new Vector2(1.1171875, -0.546875),
103 | new Vector2(1.703125, 0.296875),
104 | new Vector2(1.421875, 0.3125),
105 | new Vector2(1.015625, -0.34375),
106 | new Vector2(0.703125, 0.28125),
107 | new Vector2(0.4375, 0.265625),
108 | new Vector2(0.8125, -0.484375),
109 | new Vector2(0.25, -1.1875)
110 | };
111 |
112 | Decomposer sweep = new SweepLine();
113 | parts = sweep.decompose(yVerticies);
114 | SimulationBody y = new SimulationBody();
115 | for (Convex c : parts) {
116 | y.addFixture(c);
117 | }
118 | y.getFixture(2).setSensor(true);
119 | y.translate(new Vector2(-2.1822787101720906, 1.4407710711648776));
120 | y.setMass(MassType.NORMAL);
121 | world.addBody(y);
122 |
123 | // a (lowercase) "n" shape
124 | Vector2[] nVerticies = new Vector2[] {
125 | new Vector2(-0.03125, 0.984375),
126 | new Vector2(-0.015625, -0.015625),
127 | new Vector2(0.140625, -0.015625),
128 | new Vector2(0.15625, 0.375),
129 | new Vector2(0.34375, 0.578125),
130 | new Vector2(0.5, 0.71875),
131 | new Vector2(0.6875, 0.671875),
132 | new Vector2(0.765625, 0.5625),
133 | new Vector2(0.734375, -0.0),
134 | new Vector2(1.015625, -0.015625),
135 | new Vector2(1.046875, 0.640625),
136 | new Vector2(0.953125, 0.84375),
137 | new Vector2(0.78125, 0.96875),
138 | new Vector2(0.5, 0.96875),
139 | new Vector2(0.296875, 0.84375),
140 | new Vector2(0.1875, 0.734375),
141 | new Vector2(0.1875, 0.984375),
142 | };
143 |
144 | Decomposer ear = new EarClipping();
145 | parts = ear.decompose(nVerticies);
146 | SimulationBody n = new SimulationBody();
147 | for (Convex c : parts) {
148 | n.addFixture(c);
149 | }
150 | n.translate(new Vector2(-0.5112465256848169, 0.6500452079566003));
151 | n.setMass(MassType.NORMAL);
152 | world.addBody(n);
153 |
154 | // a "4" shape
155 | Vector2[] fourVerticies = new Vector2[] {
156 | new Vector2(0.8125, 0.8125),
157 | new Vector2(0.828125, 0.046875),
158 | new Vector2(1.125, 0.046875),
159 | new Vector2(1.125, 1.828125),
160 | new Vector2(0.859375, 1.828125),
161 | new Vector2(-0.21875, 0.8125)
162 | };
163 |
164 | parts = bayazit.decompose(fourVerticies);
165 | SimulationBody four = new SimulationBody();
166 | for (Convex c : parts) {
167 | four.addFixture(c);
168 | }
169 | four.translate(new Vector2(0.26865946239058014, 0.9649433050584864));
170 | four.setMass(MassType.NORMAL);
171 | world.addBody(four);
172 |
173 | // a (lowercase) "j" shape
174 | Vector2[] jVerticies = new Vector2[] {
175 | new Vector2(0.90625, 0.203125),
176 | new Vector2(0.96875, 0.34375),
177 | new Vector2(1.0, 1.21875),
178 | new Vector2(0.78125, 1.265625),
179 | new Vector2(0.734375, 0.34375),
180 | new Vector2(0.5625, 0.296875),
181 | new Vector2(0.34375, 0.296875),
182 | new Vector2(0.234375, 0.4375),
183 | new Vector2(0.234375, 0.65625),
184 | new Vector2(0.046875, 0.65625),
185 | new Vector2(0.046875, 0.5),
186 | new Vector2(0.078125, 0.28125),
187 | new Vector2(0.203125, 0.109375),
188 | new Vector2(0.46875, 0.046875),
189 | new Vector2(0.734375, 0.109375),
190 |
191 | };
192 |
193 | parts = bayazit.decompose(jVerticies);
194 | SimulationBody j = new SimulationBody();
195 | for (Convex c : parts) {
196 | j.addFixture(c);
197 | }
198 | j.translate(new Vector2(0.8752422480620154, 0.4841370269037847));
199 | j.setMass(MassType.NORMAL);
200 | world.addBody(j);
201 | }
202 |
203 | /* (non-Javadoc)
204 | * @see org.dyn4j.samples.framework.SimulationFrame#initializeCamera(org.dyn4j.samples.framework.Camera)
205 | */
206 | @Override
207 | protected void initializeCamera(Camera camera) {
208 | super.initializeCamera(camera);
209 | camera.scale = 64.0;
210 | camera.offsetY = -200.0;
211 | }
212 |
213 | /**
214 | * Entry point for the example application.
215 | * @param args command line arguments
216 | */
217 | public static void main(String[] args) {
218 | Decomposition simulation = new Decomposition();
219 | simulation.run();
220 | }
221 | }
222 |
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/Destructible.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2022 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples;
26 |
27 | import java.util.ArrayList;
28 | import java.util.List;
29 |
30 | import org.dyn4j.dynamics.Body;
31 | import org.dyn4j.dynamics.contact.Contact;
32 | import org.dyn4j.dynamics.joint.Joint;
33 | import org.dyn4j.dynamics.joint.WeldJoint;
34 | import org.dyn4j.geometry.Convex;
35 | import org.dyn4j.geometry.Geometry;
36 | import org.dyn4j.geometry.MassType;
37 | import org.dyn4j.geometry.Transform;
38 | import org.dyn4j.geometry.Vector2;
39 | import org.dyn4j.geometry.Wound;
40 | import org.dyn4j.samples.framework.Camera;
41 | import org.dyn4j.samples.framework.SimulationBody;
42 | import org.dyn4j.samples.framework.SimulationFrame;
43 | import org.dyn4j.world.ContactCollisionData;
44 | import org.dyn4j.world.listener.ContactListener;
45 | import org.dyn4j.world.listener.ContactListenerAdapter;
46 |
47 | /**
48 | * An example of destruction of bodies and joints
49 | * @author William Bittle
50 | * @since 5.0.0
51 | * @version 4.1.1
52 | */
53 | public class Destructible extends SimulationFrame {
54 | private static final long serialVersionUID = -3302959427805814281L;
55 |
56 | public Destructible() {
57 | super("Destructible");
58 | }
59 |
60 | /**
61 | * Extends the contact counter to implement the destruction
62 | * of a joint when a contact is encountered. Normally you would just
63 | * extend the {@link ContactListener} interface.
64 | * @author William Bittle
65 | */
66 | public class Destructor extends ContactListenerAdapter {
67 | /** Used to flag that the joint has been removed */
68 | private boolean removed = false;
69 |
70 | /** Used to flag that the test body has been destroyed */
71 | private boolean broken = false;
72 |
73 | @Override
74 | public void begin(ContactCollisionData collision, Contact contact) {
75 | super.begin(collision, contact);
76 |
77 | // when a contact is added
78 | if (!this.removed) {
79 | Body jb1 = joint.getBody1();
80 | Body jb2 = joint.getBody2();
81 | Body b1 = collision.getBody1();
82 | Body b2 = collision.getBody2();
83 |
84 | // check the bodies involved
85 | if (b2 == jb1 || b2 == jb2 || b1 == jb1 || b1 == jb2) {
86 | // remove the joint
87 | toDeleteJoints.add(joint);
88 | this.removed = true;
89 | }
90 | }
91 |
92 | if (!this.broken) {
93 | Body b1 = collision.getBody1();
94 | Body b2 = collision.getBody2();
95 |
96 | // check the bodies involved
97 | if (b2 == icosigon || b1 == icosigon) {
98 | // remove the body from the world
99 | toDeleteBodies.add(icosigon);
100 |
101 | // make the test body into triangles
102 |
103 | // get the velocity
104 | Vector2 v = icosigon.getLinearVelocity().copy();
105 | // half the velocity to give the effect of a broken body
106 | v.multiply(0.5);
107 |
108 | Convex convex = icosigon.getFixture(0).getShape();
109 | Transform tx = icosigon.getTransform();
110 | Vector2 center = convex.getCenter();
111 | // we assume its a unit circle polygon to make
112 | // tessellation easy
113 | Vector2[] vertices = ((Wound) convex).getVertices();
114 | int size = vertices.length;
115 | for (int i = 0; i < size; i++) {
116 | // get the first and second vertices
117 | Vector2 p1 = vertices[i];
118 | Vector2 p2 = vertices[i + 1 == size ? 0 : i + 1];
119 | // create a body for the triangle
120 | SimulationBody b = new SimulationBody(icosigon.getColor());
121 | b.addFixture(Geometry.createTriangle(p1, p2, center), 1.0, 0.3, 0.0);
122 | b.setMass(MassType.NORMAL);
123 | // copy over the transform
124 | b.setTransform(tx.copy());
125 | // copy over the velocity
126 | b.setLinearVelocity(v.copy());
127 | b.setUserData("Piece" + (i + 1));
128 | // add the new body to the world
129 | toAddBodies.add(b);
130 | }
131 |
132 | this.broken = true;
133 |
134 | // set the requires setMass flag
135 | world.setUpdateRequired(true);
136 |
137 | // don't allow the contact
138 | collision.getContactConstraint().setEnabled(false);
139 | }
140 | }
141 | }
142 | }
143 |
144 | /** The floor body */
145 | private SimulationBody floor;
146 |
147 | /** The 20 sided body */
148 | private SimulationBody icosigon;
149 |
150 | /** The weld joint */
151 | private WeldJoint joint;
152 |
153 | /** The destrution class */
154 | private Destructor destructor;
155 |
156 | // buffer the deletes/adds
157 |
158 | private List> toDeleteJoints = new ArrayList>();
159 | private List toDeleteBodies = new ArrayList();
160 | private List toAddBodies = new ArrayList();
161 |
162 | /* (non-Javadoc)
163 | * @see org.dyn4j.samples.framework.SimulationFrame#initializeWorld()
164 | */
165 | @Override
166 | public void initializeWorld() {
167 |
168 | // create the floor
169 | this.floor = new SimulationBody();
170 | this.floor.addFixture(Geometry.createRectangle(15.0, 1.0));
171 | this.floor.setMass(MassType.INFINITE);
172 | this.floor.setUserData("Floor");
173 |
174 | // create the weld joint bodies
175 | SimulationBody top = new SimulationBody();
176 | top.addFixture(Geometry.createRectangle(0.5, 1.0));
177 | top.setMass(MassType.NORMAL);
178 | top.translate(0.0, 3.0);
179 | top.getLinearVelocity().set(2.0, 0.0);
180 | top.setUserData("Top");
181 |
182 | SimulationBody bot = new SimulationBody();
183 | bot.addFixture(Geometry.createRectangle(0.5, 1.0));
184 | bot.setMass(MassType.NORMAL);
185 | bot.translate(0.0, 2.0);
186 | bot.setUserData("Bottom");
187 |
188 | this.joint = new WeldJoint(top, bot, new Vector2(0.0, 2.5));
189 | this.joint.setUserData("WeldJoint1");
190 |
191 | this.icosigon = new SimulationBody();
192 | this.icosigon.addFixture(Geometry.createUnitCirclePolygon(20, 1.0));
193 | this.icosigon.setMass(MassType.NORMAL);
194 | this.icosigon.translate(-2.5, 2.0);
195 | this.icosigon.setUserData("Icosigon");
196 |
197 | this.destructor = new Destructor();
198 |
199 | this.world.addBody(this.floor);
200 | this.world.addBody(this.icosigon);
201 | this.world.addBody(top);
202 | this.world.addBody(bot);
203 | this.world.addJoint(this.joint);
204 | this.world.addContactListener(this.destructor);
205 | }
206 |
207 | /* (non-Javadoc)
208 | * @see org.dyn4j.samples.framework.SimulationFrame#initializeCamera(org.dyn4j.samples.framework.Camera)
209 | */
210 | @Override
211 | protected void initializeCamera(Camera camera) {
212 | super.initializeCamera(camera);
213 | camera.scale = 64.0;
214 | }
215 |
216 | /* (non-Javadoc)
217 | * @see org.dyn4j.samples.framework.SimulationFrame#handleEvents()
218 | */
219 | @Override
220 | protected void handleEvents() {
221 | super.handleEvents();
222 |
223 | for (Joint joint : this.toDeleteJoints) {
224 | this.world.removeJoint(joint);
225 | }
226 | this.toDeleteJoints.clear();
227 |
228 | for (SimulationBody body : this.toDeleteBodies) {
229 | this.world.removeBody(body);
230 | }
231 | this.toDeleteBodies.clear();
232 |
233 | for (SimulationBody body : this.toAddBodies) {
234 | this.world.addBody(body);
235 | }
236 | this.toAddBodies.clear();
237 | }
238 |
239 | /**
240 | * Entry point for the example application.
241 | * @param args command line arguments
242 | */
243 | public static void main(String[] args) {
244 | Destructible simulation = new Destructible();
245 | simulation.run();
246 | }
247 | }
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/Images.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2022 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples;
26 |
27 | import java.awt.Color;
28 | import java.awt.Graphics2D;
29 | import java.awt.image.BufferedImage;
30 | import java.io.IOException;
31 |
32 | import javax.imageio.ImageIO;
33 |
34 | import org.dyn4j.dynamics.BodyFixture;
35 | import org.dyn4j.geometry.Circle;
36 | import org.dyn4j.geometry.Convex;
37 | import org.dyn4j.geometry.Geometry;
38 | import org.dyn4j.geometry.MassType;
39 | import org.dyn4j.geometry.Rectangle;
40 | import org.dyn4j.geometry.Vector2;
41 | import org.dyn4j.samples.framework.Camera;
42 | import org.dyn4j.samples.framework.SimulationBody;
43 | import org.dyn4j.samples.framework.SimulationFrame;
44 |
45 | /**
46 | * A simple scene illustrating the mapping of images to bodies.
47 | * @author William Bittle
48 | * @version 5.0.0
49 | * @since 3.2.0
50 | */
51 | public class Images extends SimulationFrame {
52 | /** Generated serial version id */
53 | private static final long serialVersionUID = -4165832122583574360L;
54 |
55 | // images
56 |
57 | /** The basketball image */
58 | private static final BufferedImage BASKETBALL = getImageSuppressExceptions("/org/dyn4j/samples/resources/Basketball.png");
59 |
60 | /** The create image */
61 | private static final BufferedImage CRATE = getImageSuppressExceptions("/org/dyn4j/samples/resources/Crate.png");
62 |
63 | /** Helper function to read the images from the class path */
64 | private static final BufferedImage getImageSuppressExceptions(String pathOnClasspath) {
65 | try {
66 | return ImageIO.read(Images.class.getResource(pathOnClasspath));
67 | } catch (IOException e) {
68 | return null;
69 | }
70 | }
71 |
72 | /**
73 | * A custom body that uses an image instead.
74 | * @author William Bittle
75 | * @version 3.2.1
76 | * @since 3.2.0
77 | */
78 | private final class ImageBody extends SimulationBody {
79 | /** The image to use, if required */
80 | public BufferedImage image;
81 |
82 | /* (non-Javadoc)
83 | * @see org.dyn4j.samples.SimulationBody#renderFixture(java.awt.Graphics2D, double, org.dyn4j.dynamics.BodyFixture, java.awt.Color)
84 | */
85 | @Override
86 | protected void renderFixture(Graphics2D g, double scale, BodyFixture fixture, Color color) {
87 | // do we need to render an image?
88 | if (this.image != null) {
89 | // get the shape on the fixture
90 | Convex convex = fixture.getShape();
91 | // check the shape type
92 | if (convex instanceof Rectangle) {
93 | Rectangle r = (Rectangle)convex;
94 | Vector2 c = r.getCenter();
95 | double w = r.getWidth();
96 | double h = r.getHeight();
97 | g.drawImage(CRATE,
98 | (int)Math.ceil((c.x - w / 2.0) * scale),
99 | (int)Math.ceil((c.y - h / 2.0) * scale),
100 | (int)Math.ceil(w * scale),
101 | (int)Math.ceil(h * scale),
102 | null);
103 | } else if (convex instanceof Circle) {
104 | // cast the shape to get the radius
105 | Circle c = (Circle) convex;
106 | double r = c.getRadius();
107 | Vector2 cc = c.getCenter();
108 | int x = (int)Math.ceil((cc.x - r) * scale);
109 | int y = (int)Math.ceil((cc.y - r) * scale);
110 | int w = (int)Math.ceil(r * 2 * scale);
111 | // lets us an image instead
112 | g.drawImage(BASKETBALL, x, y, w, w, null);
113 | }
114 | } else {
115 | // default rendering
116 | super.renderFixture(g, scale, fixture, color);
117 | }
118 | }
119 | }
120 |
121 | /**
122 | * Default constructor.
123 | */
124 | public Images() {
125 | super("Images");
126 | }
127 |
128 | /**
129 | * Creates game objects and adds them to the world.
130 | */
131 | protected void initializeWorld() {
132 | // create all your bodies/joints
133 |
134 | // create the floor
135 | SimulationBody floor = new SimulationBody();
136 | floor.addFixture(Geometry.createRectangle(15, 1));
137 | floor.setMass(MassType.INFINITE);
138 | // move the floor down a bit
139 | floor.translate(0.0, -4.0);
140 | this.world.addBody(floor);
141 |
142 | // create a circle
143 | ImageBody circle = new ImageBody();
144 | circle.image = BASKETBALL;
145 | circle.addFixture(Geometry.createCircle(0.5), 1, 0.2, 0.5);
146 | circle.setMass(MassType.NORMAL);
147 | circle.translate(2.0, 2.0);
148 | // test adding some force
149 | circle.applyForce(new Vector2(-100.0, 0.0));
150 | // set some linear damping to simulate rolling friction
151 | circle.setLinearDamping(0.05);
152 | this.world.addBody(circle);
153 |
154 | // try a rectangle
155 | ImageBody rectangle = new ImageBody();
156 | rectangle.image = CRATE;
157 | rectangle.addFixture(Geometry.createRectangle(1, 1));
158 | rectangle.setMass(MassType.NORMAL);
159 | rectangle.translate(0.0, 1.0);
160 | rectangle.getLinearVelocity().set(-2, 0);
161 | this.world.addBody(rectangle);
162 | }
163 |
164 | /* (non-Javadoc)
165 | * @see org.dyn4j.samples.framework.SimulationFrame#initializeCamera(org.dyn4j.samples.framework.Camera)
166 | */
167 | @Override
168 | protected void initializeCamera(Camera camera) {
169 | super.initializeCamera(camera);
170 | camera.scale = 45.0;
171 | }
172 |
173 | /**
174 | * Entry point for the example application.
175 | * @param args command line arguments
176 | */
177 | public static void main(String[] args) {
178 | Images simulation = new Images();
179 | simulation.run();
180 | }
181 | }
182 |
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/LinkTerrain.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2022 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples;
26 |
27 | import java.util.List;
28 |
29 | import org.dyn4j.collision.narrowphase.Sat;
30 | import org.dyn4j.geometry.Geometry;
31 | import org.dyn4j.geometry.Link;
32 | import org.dyn4j.geometry.MassType;
33 | import org.dyn4j.geometry.Vector2;
34 | import org.dyn4j.samples.framework.Camera;
35 | import org.dyn4j.samples.framework.SimulationBody;
36 | import org.dyn4j.samples.framework.SimulationFrame;
37 |
38 | /**
39 | * A simple scene of a terrain made using the {@link Link}s to avoid
40 | * the internal edge collision problem.
41 | * @author William Bittle
42 | * @version 5.0.0
43 | * @since 3.2.2
44 | */
45 | public class LinkTerrain extends SimulationFrame {
46 | /** The serial version id */
47 | private static final long serialVersionUID = -3675099977835892473L;
48 |
49 | /**
50 | * Default constructor for the window
51 | */
52 | public LinkTerrain() {
53 | super("LinkTerrain");
54 |
55 | this.pause();
56 | }
57 |
58 | /**
59 | * Creates game objects and adds them to the world.
60 | */
61 | protected void initializeWorld() {
62 | this.world.setNarrowphaseDetector(new Sat());
63 |
64 | // the terrain
65 | List links = Geometry.createLinks(
66 | new Vector2[] {
67 | new Vector2( 6.0, -0.5),
68 | new Vector2( 4.5, 0.3),
69 | new Vector2( 4.0, 0.2),
70 | new Vector2( 2.0, 0.0),
71 | new Vector2( 0.0, 0.0),
72 | new Vector2(-6.0, 0.5)
73 | }, false);
74 |
75 | SimulationBody floor = new SimulationBody();
76 | for (Link link : links) {
77 | floor.addFixture(link);
78 | }
79 | floor.setMass(MassType.INFINITE);
80 | this.world.addBody(floor);
81 |
82 | // the body
83 | SimulationBody slider = new SimulationBody();
84 | slider.addFixture(Geometry.createSquare(0.25));
85 | slider.setMass(MassType.NORMAL);
86 | slider.setLinearVelocity(6.2, 0);
87 | slider.translate(-5.5, 1.0);
88 | this.world.addBody(slider);
89 | }
90 |
91 | /* (non-Javadoc)
92 | * @see org.dyn4j.samples.framework.SimulationFrame#initializeCamera(org.dyn4j.samples.framework.Camera)
93 | */
94 | @Override
95 | protected void initializeCamera(Camera camera) {
96 | super.initializeCamera(camera);
97 | camera.scale = 64.0;
98 | }
99 |
100 | /**
101 | * Entry point for the example application.
102 | * @param args command line arguments
103 | */
104 | public static void main(String[] args) {
105 | LinkTerrain simulation = new LinkTerrain();
106 | simulation.run();
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/Maze.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2022 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples;
26 |
27 | import java.awt.Color;
28 | import java.awt.Point;
29 | import java.awt.event.MouseAdapter;
30 | import java.awt.event.MouseEvent;
31 |
32 | import org.dyn4j.dynamics.joint.MotorJoint;
33 | import org.dyn4j.geometry.Geometry;
34 | import org.dyn4j.geometry.MassType;
35 | import org.dyn4j.geometry.Transform;
36 | import org.dyn4j.geometry.Vector2;
37 | import org.dyn4j.samples.framework.Camera;
38 | import org.dyn4j.samples.framework.SimulationBody;
39 | import org.dyn4j.samples.framework.SimulationFrame;
40 | import org.dyn4j.world.World;
41 |
42 | /**
43 | * Use the mouse to move the green body to the blue body. Notice how
44 | * the green body tries to work around the obstacles, but does not go
45 | * through them.
46 | * @author William Bittle
47 | * @since 5.0.0
48 | * @version 4.1.1
49 | */
50 | public class Maze extends SimulationFrame {
51 | /** The serial version id */
52 | private static final long serialVersionUID = -4132057742762298086L;
53 |
54 | /** The controller body */
55 | private SimulationBody controller;
56 |
57 | /** The current mouse drag point */
58 | private Point point;
59 |
60 | /**
61 | * A custom mouse adapter to track mouse drag events.
62 | * @author William Bittle
63 | */
64 | private final class CustomMouseAdapter extends MouseAdapter {
65 | @Override
66 | public void mouseMoved(MouseEvent e) {
67 | // just create a new point and store it locally
68 | // later, on the next update we'll check for it
69 | point = new Point(e.getX(), e.getY());
70 | }
71 | }
72 |
73 | /**
74 | * Default constructor for the window
75 | */
76 | public Maze() {
77 | super("Maze");
78 |
79 | this.setMousePickingEnabled(false);
80 |
81 | // setup the mouse listening
82 | MouseAdapter ml = new CustomMouseAdapter();
83 | this.canvas.addMouseMotionListener(ml);
84 | this.canvas.addMouseWheelListener(ml);
85 | this.canvas.addMouseListener(ml);
86 | }
87 |
88 | /**
89 | * Creates game objects and adds them to the world.
90 | */
91 | protected void initializeWorld() {
92 | // no gravity please
93 | this.world.setGravity(World.ZERO_GRAVITY);
94 |
95 | // player control setup
96 |
97 | this.controller = new SimulationBody(Color.CYAN);
98 | this.controller.addFixture(Geometry.createCircle(0.25));
99 | this.controller.setMass(MassType.INFINITE);
100 | this.controller.setAtRestDetectionEnabled(false);
101 | this.world.addBody(this.controller);
102 |
103 | SimulationBody player = new SimulationBody(Color.GREEN);
104 | player.addFixture(Geometry.createCircle(0.25));
105 | player.setMass(MassType.NORMAL);
106 | player.setAtRestDetectionEnabled(false);
107 | this.world.addBody(player);
108 |
109 | MotorJoint control = new MotorJoint(player, this.controller);
110 | control.setCollisionAllowed(false);
111 | control.setMaximumForce(1000.0);
112 | control.setMaximumTorque(1000.0);
113 | this.world.addJoint(control);
114 |
115 | // maze
116 |
117 | double wallWidth = 0.5;
118 | double mazeSize = 30;
119 | double mazeOffset = mazeSize / 2.0 - wallWidth / 2.0;
120 | double pathWidth = 1.5;
121 |
122 | // outer walls
123 |
124 | SimulationBody wall = new SimulationBody();
125 | wall.addFixture(Geometry.createRectangle(wallWidth, mazeSize));
126 | wall.setMass(MassType.INFINITE);
127 | wall.translate(mazeOffset, 0);
128 | this.world.addBody(wall);
129 |
130 | SimulationBody wall2 = new SimulationBody();
131 | wall2.addFixture(Geometry.createRectangle(mazeSize - pathWidth, wallWidth));
132 | wall2.setMass(MassType.INFINITE);
133 | wall2.translate(pathWidth * 0.5, mazeOffset);
134 | this.world.addBody(wall2);
135 |
136 | SimulationBody wall3 = new SimulationBody();
137 | wall3.addFixture(Geometry.createRectangle(mazeSize - pathWidth, wallWidth));
138 | wall3.setMass(MassType.INFINITE);
139 | wall3.translate(-pathWidth * 0.5, -mazeOffset);
140 | this.world.addBody(wall3);
141 |
142 | SimulationBody wall4 = new SimulationBody();
143 | wall4.addFixture(Geometry.createRectangle(wallWidth, mazeSize));
144 | wall4.setMass(MassType.INFINITE);
145 | wall4.translate(-mazeOffset, 0);
146 | this.world.addBody(wall4);
147 |
148 | // inner walls
149 |
150 | for (int i = 0; i < 7; i++) {
151 | SimulationBody wall5 = new SimulationBody();
152 | wall5.addFixture(Geometry.createRectangle(wallWidth, mazeSize - pathWidth));
153 | wall5.setMass(MassType.INFINITE);
154 | wall5.translate(-mazeOffset + (i + 1) * pathWidth, (i % 2 == 0 ? 1 : -1) * pathWidth / 2.0);
155 | this.world.addBody(wall5);
156 | }
157 |
158 | for (int i = 0; i < 18; i++) {
159 | SimulationBody wall5 = new SimulationBody();
160 | wall5.addFixture(Geometry.createRectangle(mazeSize / 2 - pathWidth, wallWidth));
161 | wall5.setMass(MassType.INFINITE);
162 | wall5.translate(-mazeOffset + 12 * pathWidth + (i % 2 == 0 ? 1 : -1) * pathWidth / 2.0, -mazeOffset + (i + 1) * pathWidth);
163 | this.world.addBody(wall5);
164 | }
165 |
166 | for (int i = 0; i < 3; i++) {
167 | SimulationBody wall5 = new SimulationBody();
168 | wall5.addFixture(Geometry.createRectangle(wallWidth, mazeSize - pathWidth));
169 | wall5.setMass(MassType.INFINITE);
170 | wall5.translate(0 + (i + 7) * pathWidth, (i % 2 == 0 ? -1 : 1) * pathWidth / 2.0);
171 | this.world.addBody(wall5);
172 | }
173 | }
174 |
175 | /* (non-Javadoc)
176 | * @see org.dyn4j.samples.framework.SimulationFrame#initializeCamera(org.dyn4j.samples.framework.Camera)
177 | */
178 | @Override
179 | protected void initializeCamera(Camera camera) {
180 | super.initializeCamera(camera);
181 | camera.scale = 16.0;
182 | }
183 |
184 | /* (non-Javadoc)
185 | * @see org.dyn4j.samples.framework.SimulationFrame#handleEvents()
186 | */
187 | @Override
188 | protected void handleEvents() {
189 | super.handleEvents();
190 |
191 | // check if the mouse has moved/dragged
192 | if (this.point != null) {
193 | Vector2 v = this.toWorldCoordinates(this.point);
194 |
195 | // reset the transform of the controller body
196 | Transform tx = new Transform();
197 | tx.translate(v.x, v.y);
198 | this.controller.setTransform(tx);
199 |
200 | // clear the point
201 | this.point = null;
202 | }
203 | }
204 |
205 | /**
206 | * Entry point for the example application.
207 | * @param args command line arguments
208 | */
209 | public static void main(String[] args) {
210 | Maze simulation = new Maze();
211 | simulation.run();
212 | }
213 | }
214 |
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/Organize.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2022 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples;
26 |
27 | import java.awt.event.KeyEvent;
28 | import java.util.ArrayList;
29 | import java.util.HashMap;
30 | import java.util.List;
31 | import java.util.Map;
32 | import java.util.Random;
33 |
34 | import org.dyn4j.dynamics.joint.DistanceJoint;
35 | import org.dyn4j.geometry.Geometry;
36 | import org.dyn4j.geometry.Mass;
37 | import org.dyn4j.geometry.MassType;
38 | import org.dyn4j.geometry.Vector2;
39 | import org.dyn4j.samples.framework.Camera;
40 | import org.dyn4j.samples.framework.SimulationBody;
41 | import org.dyn4j.samples.framework.SimulationFrame;
42 | import org.dyn4j.samples.framework.input.BooleanStateKeyboardInputHandler;
43 |
44 | /**
45 | * A scene where a set of different sized bodies are strung together with
46 | * distance = 0 DistanceJoints that causes the bodies to try to self
47 | * organize.
48 | * @author William Bittle
49 | * @version 5.0.0
50 | * @since 4.1.1
51 | */
52 | public class Organize extends SimulationFrame {
53 | /** The serial version id */
54 | private static final long serialVersionUID = -2350301592218819726L;
55 |
56 | /** A list of bodies that can be joined (i.e. excludes the static bodies) */
57 | private List bodies;
58 |
59 | private final BooleanStateKeyboardInputHandler organize;
60 |
61 | /** True if the joints have been added */
62 | private boolean jointsAdded = false;
63 |
64 | /**
65 | * Default constructor.
66 | */
67 | public Organize() {
68 | super("Organize");
69 |
70 | this.organize = new BooleanStateKeyboardInputHandler(this.canvas, KeyEvent.VK_O);
71 |
72 | this.organize.install();
73 | }
74 |
75 | /* (non-Javadoc)
76 | * @see org.dyn4j.samples.framework.SimulationFrame#printControls()
77 | */
78 | @Override
79 | protected void printControls() {
80 | super.printControls();
81 |
82 | printControl("Organize", "o", "Use the o key to toggle the distance joints");
83 | }
84 |
85 | /**
86 | * Creates game objects and adds them to the world.
87 | */
88 | protected void initializeWorld() {
89 | SimulationBody bottom = new SimulationBody();
90 | bottom.addFixture(Geometry.createRectangle(15.0, 1.0));
91 | bottom.translate(new Vector2(0, -5));
92 | bottom.setMass(MassType.INFINITE);
93 | world.addBody(bottom);
94 |
95 | SimulationBody top = new SimulationBody();
96 | top.addFixture(Geometry.createRectangle(15.0, 1.0));
97 | top.translate(new Vector2(0, 5));
98 | top.setMass(MassType.INFINITE);
99 | world.addBody(top);
100 |
101 | SimulationBody left = new SimulationBody();
102 | left.addFixture(Geometry.createRectangle(1.0, 15.0));
103 | left.translate(new Vector2(-5, 0));
104 | left.setMass(MassType.INFINITE);
105 | world.addBody(left);
106 |
107 | SimulationBody right = new SimulationBody();
108 | right.addFixture(Geometry.createRectangle(1.0, 15.0));
109 | right.translate(new Vector2(5, 0));
110 | right.setMass(MassType.INFINITE);
111 | world.addBody(right);
112 |
113 | Random r = new Random(123);
114 | bodies = new ArrayList();
115 | for (int i = 0; i < 20; i++) {
116 | SimulationBody body = new SimulationBody();
117 | body.addFixture(Geometry.createCircle(r.nextDouble()));
118 | body.translate(r.nextDouble(),0);
119 | body.setMass(new Mass(new Vector2(), 1, 10));
120 | world.addBody(body);
121 |
122 | bodies.add(body);
123 | }
124 | }
125 |
126 | /* (non-Javadoc)
127 | * @see org.dyn4j.samples.framework.SimulationFrame#initializeCamera(org.dyn4j.samples.framework.Camera)
128 | */
129 | @Override
130 | protected void initializeCamera(Camera camera) {
131 | super.initializeCamera(camera);
132 | camera.scale = 48.0;
133 | }
134 |
135 | /* (non-Javadoc)
136 | * @see org.dyn4j.samples.framework.SimulationFrame#handleEvents()
137 | */
138 | @Override
139 | protected void handleEvents() {
140 | super.handleEvents();
141 |
142 | if (this.organize.isActiveButNotHandled()) {
143 | this.organize.setHasBeenHandled(true);
144 |
145 | if (!this.jointsAdded) {
146 | this.jointsAdded = true;
147 | Random r = new Random(44);
148 | Map used = new HashMap();
149 | for (int i = 0; i < 10; i++) {
150 | int n = r.nextInt(19);
151 | int m = r.nextInt(19);
152 | String name = (n < m ? n : m) + "," + (n > m ? n : m);
153 | if (n != m && !used.containsKey(name)) {
154 | used.put(name, true);
155 | SimulationBody b1 = this.bodies.get(n);
156 | SimulationBody b2 = this.bodies.get(m);
157 |
158 | DistanceJoint dj = new DistanceJoint(b1, b2, b1.getWorldCenter(), b2.getWorldCenter());
159 | dj.setCollisionAllowed(true);
160 | dj.setRestDistance(0.0);
161 | dj.setSpringEnabled(true);
162 | dj.setSpringDamperEnabled(true);
163 | dj.setSpringFrequency(2);
164 | dj.setSpringDampingRatio(1.0);
165 | this.world.addJoint(dj);
166 | }
167 | }
168 | } else {
169 | this.world.removeAllJoints();
170 | this.jointsAdded = false;
171 | }
172 | }
173 | }
174 |
175 | /* (non-Javadoc)
176 | * @see org.dyn4j.samples.framework.SimulationFrame#reset()
177 | */
178 | @Override
179 | public void reset() {
180 | super.reset();
181 | this.jointsAdded = false;
182 | }
183 |
184 | /**
185 | * Entry point for the example application.
186 | * @param args command line arguments
187 | */
188 | public static void main(String[] args) {
189 | Organize simulation = new Organize();
190 | simulation.run();
191 | }
192 | }
193 |
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/Platformer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2022 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples;
26 |
27 | import java.awt.Color;
28 | import java.awt.event.KeyEvent;
29 | import java.util.List;
30 |
31 | import org.dyn4j.dynamics.TimeStep;
32 | import org.dyn4j.dynamics.contact.ContactConstraint;
33 | import org.dyn4j.geometry.AABB;
34 | import org.dyn4j.geometry.Geometry;
35 | import org.dyn4j.geometry.MassType;
36 | import org.dyn4j.geometry.Vector2;
37 | import org.dyn4j.samples.framework.Camera;
38 | import org.dyn4j.samples.framework.SimulationBody;
39 | import org.dyn4j.samples.framework.SimulationFrame;
40 | import org.dyn4j.samples.framework.input.BooleanStateKeyboardInputHandler;
41 | import org.dyn4j.world.ContactCollisionData;
42 | import org.dyn4j.world.PhysicsWorld;
43 | import org.dyn4j.world.listener.ContactListenerAdapter;
44 | import org.dyn4j.world.listener.StepListenerAdapter;
45 |
46 | /**
47 | * A simple scene of a circle that is controlled by the left and
48 | * right arrow keys that is moved by applying torques and forces.
49 | *
50 | * Also illustrated here is how to track whether the body is in
51 | * contact with the "ground."
52 | *
53 | * Always keep in mind that this is just an example, production
54 | * code should be more robust and better organized.
55 | * @author William Bittle
56 | * @since 5.0.1
57 | * @version 3.2.0
58 | */
59 | public class Platformer extends SimulationFrame {
60 | /** The serial version id */
61 | private static final long serialVersionUID = -313391186714427055L;
62 |
63 | private static final Color WHEEL_OFF_COLOR = Color.MAGENTA;
64 | private static final Color WHEEL_ON_COLOR = Color.GREEN;
65 |
66 | private static final Object CHARACTER = new Object();
67 | private static final Object FLOOR = new Object();
68 | private static final Object ONE_WAY_PLATFORM = new Object();
69 |
70 | private final BooleanStateKeyboardInputHandler up;
71 | private final BooleanStateKeyboardInputHandler down;
72 | private final BooleanStateKeyboardInputHandler left;
73 | private final BooleanStateKeyboardInputHandler right;
74 |
75 | private SimulationBody character;
76 | private boolean onGround = false;
77 |
78 | /**
79 | * Default constructor for the window
80 | */
81 | public Platformer() {
82 | super("Platformer");
83 |
84 | this.up = new BooleanStateKeyboardInputHandler(this.canvas, KeyEvent.VK_UP);
85 | this.down = new BooleanStateKeyboardInputHandler(this.canvas, KeyEvent.VK_DOWN);
86 | this.left = new BooleanStateKeyboardInputHandler(this.canvas, KeyEvent.VK_LEFT);
87 | this.right = new BooleanStateKeyboardInputHandler(this.canvas, KeyEvent.VK_RIGHT);
88 |
89 | this.up.install();
90 | this.down.install();
91 | this.left.install();
92 | this.right.install();
93 | }
94 |
95 | /* (non-Javadoc)
96 | * @see org.dyn4j.samples.framework.SimulationFrame#initializeCamera(org.dyn4j.samples.framework.Camera)
97 | */
98 | @Override
99 | protected void initializeCamera(Camera camera) {
100 | super.initializeCamera(camera);
101 | camera.scale = 32.0;
102 | }
103 |
104 | /**
105 | * Creates game objects and adds them to the world.
106 | */
107 | protected void initializeWorld() {
108 | // the floor
109 | SimulationBody floor = new SimulationBody();
110 | floor.addFixture(Geometry.createRectangle(50.0, 0.2));
111 | floor.setMass(MassType.INFINITE);
112 | floor.translate(0, -3);
113 | floor.setUserData(FLOOR);
114 | this.world.addBody(floor);
115 |
116 | // some obstacles
117 | final int n = 5;
118 | for (int i = 0; i < n; i++) {
119 | SimulationBody sb = new SimulationBody();
120 | double w = 1.0;
121 | double h = Math.random() * 0.3 + 0.1;
122 | sb.addFixture(Geometry.createIsoscelesTriangle(w, h));
123 | sb.translate((Math.random() > 0.5 ? -1 : 1) * Math.random() * 5.0, h * 0.5 - 2.9);
124 | sb.setMass(MassType.INFINITE);
125 | sb.setUserData(FLOOR);
126 | this.world.addBody(sb);
127 | }
128 |
129 | // the platform
130 | SimulationBody platform = new SimulationBody();
131 | platform.addFixture(Geometry.createRectangle(10.0, 0.2));
132 | platform.setMass(MassType.INFINITE);
133 | platform.translate(0, 0);
134 | platform.setUserData(ONE_WAY_PLATFORM);
135 | this.world.addBody(platform);
136 |
137 | // some bounding shapes
138 | SimulationBody right = new SimulationBody();
139 | right.addFixture(Geometry.createRectangle(0.2, 20));
140 | right.setMass(MassType.INFINITE);
141 | right.translate(10, 7);
142 | this.world.addBody(right);
143 |
144 | SimulationBody left = new SimulationBody();
145 | left.addFixture(Geometry.createRectangle(0.2, 20));
146 | left.setMass(MassType.INFINITE);
147 | left.translate(-10, 7);
148 | this.world.addBody(left);
149 |
150 | // the wheel
151 | character = new SimulationBody(WHEEL_OFF_COLOR);
152 | // NOTE: lots of friction to simulate a sticky tire
153 | character.addFixture(Geometry.createCircle(0.5), 1.0, 20.0, 0.1);
154 | character.setMass(MassType.NORMAL);
155 | character.translate(0.0, -2.0);
156 | character.setUserData(CHARACTER);
157 | character.setAtRestDetectionEnabled(false);
158 | this.world.addBody(character);
159 |
160 | // Use a number of concepts here to support movement, jumping, and one-way
161 | // platforms - this is by no means THE solution to these problems, but just
162 | // and example to provide some ideas on how you might
163 |
164 | // One consideration might be to use a sensor body to get less accurate
165 | // on-ground detection so that it's not frustrating to the user. dyn4j
166 | // will detect them in collision, but small bouncing or other things could
167 | // cause it to look/feel wrong
168 |
169 | // SETP 1:
170 | // at the beginning of each world step, check if the body is in
171 | // contact with any of the floor bodies
172 | this.world.addStepListener(new StepListenerAdapter() {
173 | @Override
174 | public void begin(TimeStep step, PhysicsWorld world) {
175 | super.begin(step, world);
176 |
177 | boolean isGround = false;
178 | List> contacts = world.getContacts(character);
179 | for (ContactConstraint cc : contacts) {
180 | if (is(cc.getOtherBody(character), FLOOR, ONE_WAY_PLATFORM) && cc.isEnabled()) {
181 | isGround = true;
182 | }
183 | }
184 |
185 | // only clear it
186 | if (!isGround) {
187 | onGround = false;
188 | }
189 | }
190 | });
191 |
192 | // STEP 2:
193 | // when contacts are processed, we need to check if we're colliding with either
194 | // the one-way platform or the ground
195 | this.world.addContactListener(new ContactListenerAdapter() {
196 | @Override
197 | public void collision(ContactCollisionData collision) {
198 | ContactConstraint cc = collision.getContactConstraint();
199 |
200 | // set the other body to one-way if necessary
201 | disableContactForOneWay(cc);
202 |
203 | // track on the on-ground status
204 | trackIsOnGround(cc);
205 |
206 | super.collision(collision);
207 | }
208 | });
209 | }
210 |
211 | /**
212 | * Helper method to determine if a body is one of the given types assuming
213 | * the type is stored in the user data.
214 | * @param body the body
215 | * @param types the set of types
216 | * @return boolean
217 | */
218 | private boolean is(SimulationBody body, Object... types) {
219 | for (Object type : types) {
220 | if (body.getUserData() == type) {
221 | return true;
222 | }
223 | }
224 | return false;
225 | }
226 |
227 | /**
228 | * Returns true if the given platform should be toggled as one-way
229 | * given the position of the character body.
230 | * @param character the character body
231 | * @param platform the platform body
232 | * @return boolean
233 | */
234 | private boolean allowOneWayUp(SimulationBody character, SimulationBody platform) {
235 | AABB wAABB = character.createAABB();
236 | AABB pAABB = platform.createAABB();
237 |
238 | // NOTE: this would need to change based on the shape of the platform and it's orientation
239 | //
240 | // one thought might be to store the allowed normal of the platform on the platform body
241 | // and check that against the ContactConstraint normal to see if they are pointing in the
242 | // same direction
243 | //
244 | // another option might be to project both onto the platform normal to see where they are overlapping
245 | if (wAABB.getMinY() < pAABB.getMinY()) {
246 | return true;
247 | }
248 | return false;
249 | }
250 |
251 | /**
252 | * Disables the constraint if it's between the character and platform and it
253 | * the scenario meets the condition for one-way.
254 | * @param contactConstraint the constraint
255 | */
256 | private void disableContactForOneWay(ContactConstraint contactConstraint) {
257 | SimulationBody b1 = contactConstraint.getBody1();
258 | SimulationBody b2 = contactConstraint.getBody2();
259 |
260 | if (is(b1, CHARACTER) && is(b2, ONE_WAY_PLATFORM)) {
261 | if (allowOneWayUp(b1, b2) || down.isActiveButNotHandled()) {
262 | down.setHasBeenHandled(true);
263 | contactConstraint.setEnabled(false);
264 | }
265 | } else if (is(b1, ONE_WAY_PLATFORM) && is(b2, CHARACTER)) {
266 | if (allowOneWayUp(b2, b1) || down.isActiveButNotHandled()) {
267 | down.setHasBeenHandled(true);
268 | contactConstraint.setEnabled(false);
269 | }
270 | }
271 | }
272 |
273 | /**
274 | * Sets the isOnGround flag if the given contact constraint is between
275 | * the character body and a floor or one-way platform.
276 | * @param contactConstraint
277 | */
278 | private void trackIsOnGround(ContactConstraint contactConstraint) {
279 | SimulationBody b1 = contactConstraint.getBody1();
280 | SimulationBody b2 = contactConstraint.getBody2();
281 |
282 | if (is(b1, CHARACTER) &&
283 | is(b2, FLOOR, ONE_WAY_PLATFORM) &&
284 | contactConstraint.isEnabled()) {
285 | onGround = true;
286 | } else if (is(b1, FLOOR, ONE_WAY_PLATFORM) &&
287 | is(b2, CHARACTER) &&
288 | contactConstraint.isEnabled()) {
289 | onGround = true;
290 | }
291 | }
292 |
293 | /* (non-Javadoc)
294 | * @see org.dyn4j.samples.framework.SimulationFrame#reset()
295 | */
296 | @Override
297 | public void reset() {
298 | super.reset();
299 | this.onGround = false;
300 | }
301 |
302 | /* (non-Javadoc)
303 | * @see org.dyn4j.samples.framework.SimulationFrame#handleEvents()
304 | */
305 | @Override
306 | protected void handleEvents() {
307 | super.handleEvents();
308 |
309 | // apply a torque based on key input
310 | if (this.left.isActive()) {
311 | character.applyTorque(Math.PI / 2);
312 | }
313 | if (this.right.isActive()) {
314 | character.applyTorque(-Math.PI / 2);
315 | }
316 |
317 | // only allow jumping if the body is on the ground
318 | if (this.up.isActiveButNotHandled()) {
319 | this.up.setHasBeenHandled(true);
320 | if (this.onGround) {
321 | character.applyImpulse(new Vector2(0.0, 7));
322 | }
323 | }
324 |
325 | // color the body green if it's on the ground
326 | if (this.onGround) {
327 | character.setColor(WHEEL_ON_COLOR);
328 | } else {
329 | character.setColor(WHEEL_OFF_COLOR);
330 | }
331 | }
332 |
333 | /**
334 | * Entry point for the example application.
335 | * @param args command line arguments
336 | */
337 | public static void main(String[] args) {
338 | Platformer simulation = new Platformer();
339 | simulation.run();
340 | }
341 | }
342 |
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/Pyramid.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2022 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples;
26 |
27 | import org.dyn4j.geometry.Geometry;
28 | import org.dyn4j.geometry.MassType;
29 | import org.dyn4j.geometry.Vector2;
30 | import org.dyn4j.samples.framework.Camera;
31 | import org.dyn4j.samples.framework.SimulationBody;
32 | import org.dyn4j.samples.framework.SimulationFrame;
33 |
34 | /**
35 | * A scene where we build a Pyramid of blocks.
36 | * @author William Bittle
37 | * @since 5.0.0
38 | * @version 4.1.1
39 | */
40 | public class Pyramid extends SimulationFrame {
41 | /** The serial version id */
42 | private static final long serialVersionUID = -3837218136220591307L;
43 |
44 | /**
45 | * Default constructor.
46 | */
47 | public Pyramid() {
48 | super("Pyramid");
49 | }
50 |
51 | /* (non-Javadoc)
52 | * @see org.dyn4j.samples.framework.SimulationFrame#initializeWorld()
53 | */
54 | protected void initializeWorld() {
55 | // allow for better/more stable stacking
56 | world.getSettings().setVelocityConstraintSolverIterations(10);
57 |
58 | SimulationBody ground = new SimulationBody();
59 | ground.addFixture(Geometry.createRectangle(15.0, 1.0));
60 | ground.setMass(MassType.INFINITE);
61 | world.addBody(ground);
62 |
63 | int ph = 15;
64 | double size = 0.5;
65 | double s = size;
66 |
67 | for (int i = 0; i < ph; i++) {
68 | for (int j = 0; j < ph - i; j++) {
69 |
70 | SimulationBody b = new SimulationBody();
71 | b.addFixture(Geometry.createSquare(size), 5.0, 0.5, 0.0);
72 | b.translate(new Vector2(j * s - (ph - i) * s * 0.5, 0.5 + size / 2.0 + i * size));
73 | b.setMass(MassType.NORMAL);
74 | world.addBody(b);
75 | }
76 | }
77 | }
78 |
79 | /* (non-Javadoc)
80 | * @see org.dyn4j.samples.framework.SimulationFrame#initializeCamera(org.dyn4j.samples.framework.Camera)
81 | */
82 | @Override
83 | protected void initializeCamera(Camera camera) {
84 | super.initializeCamera(camera);
85 | camera.scale = 48.0;
86 | camera.offsetY = -200;
87 | }
88 |
89 | /**
90 | * Entry point for the example application.
91 | * @param args command line arguments
92 | */
93 | public static void main(String[] args) {
94 | Pyramid simulation = new Pyramid();
95 | simulation.run();
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/Ragdoll.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2022 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples;
26 |
27 | import org.dyn4j.dynamics.joint.RevoluteJoint;
28 | import org.dyn4j.geometry.Convex;
29 | import org.dyn4j.geometry.Geometry;
30 | import org.dyn4j.geometry.MassType;
31 | import org.dyn4j.geometry.Vector2;
32 | import org.dyn4j.samples.framework.Camera;
33 | import org.dyn4j.samples.framework.SimulationBody;
34 | import org.dyn4j.samples.framework.SimulationFrame;
35 |
36 | /**
37 | * A somewhat complex scene with a ragdoll.
38 | * @author William Bittle
39 | * @since 5.0.0
40 | * @version 3.2.0
41 | */
42 | public class Ragdoll extends SimulationFrame {
43 | /** The serial version id */
44 | private static final long serialVersionUID = -2350301592218819726L;
45 |
46 | /**
47 | * Default constructor.
48 | */
49 | public Ragdoll() {
50 | super("Ragdoll");
51 | }
52 |
53 | /**
54 | * Creates game objects and adds them to the world.
55 | */
56 | protected void initializeWorld() {
57 | // Ground
58 | SimulationBody ground = new SimulationBody();
59 | ground.addFixture(Geometry.createRectangle(100.0, 1.0));
60 | ground.translate(new Vector2(0.6875, -8.75));
61 | ground.setMass(MassType.INFINITE);
62 | world.addBody(ground);
63 |
64 | // the ragdoll
65 |
66 | // Head
67 | SimulationBody head = new SimulationBody();
68 | head.addFixture(Geometry.createCircle(0.25));
69 | head.setMass(MassType.NORMAL);
70 | world.addBody(head);
71 |
72 | // Torso
73 | SimulationBody torso = new SimulationBody();
74 | torso.addFixture(Geometry.createRectangle(0.5, 1.0));
75 | {
76 | Convex c = Geometry.createRectangle(1.0, 0.25);
77 | c.translate(new Vector2(0.00390625, 0.375));
78 | torso.addFixture(c);
79 | }
80 | torso.translate(new Vector2(0.0234375, -0.8125));
81 | torso.setMass(MassType.NORMAL);
82 | world.addBody(torso);
83 |
84 | // Right Humerus
85 | SimulationBody rightHumerus = new SimulationBody();
86 | rightHumerus.addFixture(Geometry.createRectangle(0.25, 0.5));
87 | rightHumerus.translate(new Vector2(0.4375, -0.609375));
88 | rightHumerus.setMass(MassType.NORMAL);
89 | world.addBody(rightHumerus);
90 |
91 | // Right Ulna
92 | SimulationBody rightUlna = new SimulationBody();
93 | rightUlna.addFixture(Geometry.createRectangle(0.25, 0.4));
94 | rightUlna.translate(new Vector2(0.44140625, -0.98828125));
95 | rightUlna.setMass(MassType.NORMAL);
96 | world.addBody(rightUlna);
97 |
98 | // Neck
99 | SimulationBody neck = new SimulationBody();
100 | neck.addFixture(Geometry.createRectangle(0.15, 0.2));
101 | neck.translate(new Vector2(0.015625, -0.2734375));
102 | neck.setMass(MassType.NORMAL);
103 | world.addBody(neck);
104 |
105 | // Left Humerus
106 | SimulationBody leftHumerus = new SimulationBody();
107 | leftHumerus.addFixture(Geometry.createRectangle(0.25, 0.5));
108 | leftHumerus.translate(new Vector2(-0.3828125, -0.609375));
109 | leftHumerus.setMass(MassType.NORMAL);
110 | world.addBody(leftHumerus);
111 |
112 | // Left Ulna
113 | SimulationBody leftUlna = new SimulationBody();
114 | leftUlna.addFixture(Geometry.createRectangle(0.25, 0.4));
115 | leftUlna.translate(new Vector2(-0.3828125, -0.9765625));
116 | leftUlna.setMass(MassType.NORMAL);
117 | world.addBody(leftUlna);
118 |
119 | // Right Femur
120 | SimulationBody rightFemur = new SimulationBody();
121 | rightFemur.addFixture(Geometry.createRectangle(0.25, 0.75));
122 | rightFemur.translate(new Vector2(0.1796875, -1.5703125));
123 | rightFemur.setMass(MassType.NORMAL);
124 | world.addBody(rightFemur);
125 |
126 | // Left Femur
127 | SimulationBody leftFemur = new SimulationBody();
128 | leftFemur.addFixture(Geometry.createRectangle(0.25, 0.75));
129 | leftFemur.translate(new Vector2(-0.1328125, -1.5703125));
130 | leftFemur.setMass(MassType.NORMAL);
131 | world.addBody(leftFemur);
132 |
133 | // Right Tibia
134 | SimulationBody rightTibia = new SimulationBody();
135 | rightTibia.addFixture(Geometry.createRectangle(0.25, 0.5));
136 | rightTibia.translate(new Vector2(0.18359375, -2.11328125));
137 | rightTibia.setMass(MassType.NORMAL);
138 | world.addBody(rightTibia);
139 |
140 | // Left Tibia
141 | SimulationBody leftTibia = new SimulationBody();
142 | leftTibia.addFixture(Geometry.createRectangle(0.25, 0.5));
143 | leftTibia.translate(new Vector2(-0.1328125, -2.1171875));
144 | leftTibia.setMass(MassType.NORMAL);
145 | world.addBody(leftTibia);
146 |
147 | // Head to Neck
148 | RevoluteJoint headToNeck = new RevoluteJoint(head, neck, new Vector2(0.01, -0.2));
149 | world.addJoint(headToNeck);
150 |
151 | // Neck to Torso
152 | RevoluteJoint neckToTorso = new RevoluteJoint(neck, torso, new Vector2(0.01, -0.35));
153 | world.addJoint(neckToTorso);
154 |
155 | // Torso to Left Humerus
156 | RevoluteJoint torsoToLeftHumerus = new RevoluteJoint(torso, leftHumerus, new Vector2(-0.4, -0.4));
157 | world.addJoint(torsoToLeftHumerus);
158 |
159 | // Torso to Right Humerus
160 | RevoluteJoint torsoToRightHumerus = new RevoluteJoint(torso, rightHumerus, new Vector2(0.4, -0.4));
161 | world.addJoint(torsoToRightHumerus);
162 |
163 | // Right Humerus to Right Ulna
164 | RevoluteJoint rightHumerusToRightUlna = new RevoluteJoint(rightHumerus, rightUlna, new Vector2(0.43, -0.82));
165 | world.addJoint(rightHumerusToRightUlna);
166 |
167 | // Left Humerus to Left Ulna
168 | RevoluteJoint leftHumerusToLeftUlna = new RevoluteJoint(leftHumerus, leftUlna, new Vector2(-0.4, -0.81));
169 | world.addJoint(leftHumerusToLeftUlna);
170 |
171 | // Torso to Right Femur
172 | RevoluteJoint torsoToRightFemur = new RevoluteJoint(torso, rightFemur, new Vector2(0.16, -1.25));
173 | world.addJoint(torsoToRightFemur);
174 |
175 | // Torso to Left Femur
176 | RevoluteJoint torsoToLeftFemur = new RevoluteJoint(torso, leftFemur, new Vector2(-0.13, -1.25));
177 | world.addJoint(torsoToLeftFemur);
178 |
179 | // Right Femur to Right Tibia
180 | RevoluteJoint rightFemurToRightTibia = new RevoluteJoint(rightFemur, rightTibia, new Vector2(0.17, -1.9));
181 | world.addJoint(rightFemurToRightTibia);
182 |
183 | // Left Femur to Left Tibia
184 | RevoluteJoint leftFemurToLeftTibia = new RevoluteJoint(leftFemur, leftTibia, new Vector2(-0.14, -1.9));
185 | world.addJoint(leftFemurToLeftTibia);
186 | }
187 |
188 | /* (non-Javadoc)
189 | * @see org.dyn4j.samples.framework.SimulationFrame#initializeCamera(org.dyn4j.samples.framework.Camera)
190 | */
191 | @Override
192 | protected void initializeCamera(Camera camera) {
193 | super.initializeCamera(camera);
194 | camera.scale = 64.0;
195 | camera.offsetY = 300;
196 | }
197 |
198 | /**
199 | * Entry point for the example application.
200 | * @param args command line arguments
201 | */
202 | public static void main(String[] args) {
203 | Ragdoll simulation = new Ragdoll();
204 | simulation.run();
205 | }
206 | }
207 |
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/Stacking.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2022 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples;
26 |
27 | import java.awt.event.MouseEvent;
28 |
29 | import org.dyn4j.geometry.Geometry;
30 | import org.dyn4j.geometry.MassType;
31 | import org.dyn4j.geometry.Vector2;
32 | import org.dyn4j.samples.framework.Camera;
33 | import org.dyn4j.samples.framework.SimulationBody;
34 | import org.dyn4j.samples.framework.SimulationFrame;
35 | import org.dyn4j.samples.framework.input.BooleanStateMouseInputHandler;
36 |
37 | /**
38 | * A simple scene where you use Mouse Button 3 to create boxes.
39 | * @author William Bittle
40 | * @version 5.0.1
41 | * @since 3.2.0
42 | */
43 | public class Stacking extends SimulationFrame {
44 | /** The serial version id */
45 | private static final long serialVersionUID = -1366264828445805140L;
46 |
47 | private final BooleanStateMouseInputHandler create;
48 |
49 | /**
50 | * Default constructor.
51 | */
52 | public Stacking() {
53 | super("Stacking");
54 |
55 | this.create = new BooleanStateMouseInputHandler(this.canvas, MouseEvent.BUTTON3);
56 |
57 | this.create.install();
58 | }
59 |
60 | /* (non-Javadoc)
61 | * @see org.dyn4j.samples.framework.SimulationFrame#initializeCamera(org.dyn4j.samples.framework.Camera)
62 | */
63 | @Override
64 | protected void initializeCamera(Camera camera) {
65 | super.initializeCamera(camera);
66 | camera.scale = 32.0;
67 | }
68 |
69 | /**
70 | * Creates game objects and adds them to the world.
71 | */
72 | protected void initializeWorld() {
73 | SimulationBody floor = new SimulationBody();
74 | floor.addFixture(Geometry.createRectangle(20, 1), 1.0, 0.5, 0.0);
75 | floor.setMass(MassType.INFINITE);
76 | this.world.addBody(floor);
77 | }
78 |
79 | /* (non-Javadoc)
80 | * @see org.dyn4j.samples.framework.SimulationFrame#printControls()
81 | */
82 | @Override
83 | protected void printControls() {
84 | super.printControls();
85 |
86 | this.printControl("Create", "RMB", "Click the right mouse button to create a square");
87 | }
88 |
89 | /* (non-Javadoc)
90 | * @see org.dyn4j.samples.framework.SimulationFrame#handleEvents()
91 | */
92 | @Override
93 | protected void handleEvents() {
94 | super.handleEvents();
95 |
96 | // see if the user clicked
97 | if (this.create.isActiveButNotHandled()) {
98 | this.create.setHasBeenHandled(true);
99 | // convert from screen space to world space coordinates
100 | Vector2 v = this.toWorldCoordinates(this.create.getMouseLocation());
101 |
102 | // create a new body
103 | SimulationBody no = new SimulationBody();
104 | no.addFixture(Geometry.createSquare(0.5), 1.0, 0.8, 0.0);
105 | no.translate(v.x, v.y);
106 | no.setMass(MassType.NORMAL);
107 | this.world.addBody(no);
108 | }
109 | }
110 |
111 | /**
112 | * Entry point for the example application.
113 | * @param args command line arguments
114 | */
115 | public static void main(String[] args) {
116 | Stacking simulation = new Stacking();
117 | simulation.run();
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/Thrust.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2022 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples;
26 |
27 | import java.awt.Color;
28 | import java.awt.Graphics2D;
29 | import java.awt.event.KeyEvent;
30 | import java.awt.geom.Line2D;
31 |
32 | import org.dyn4j.dynamics.BodyFixture;
33 | import org.dyn4j.geometry.Geometry;
34 | import org.dyn4j.geometry.MassType;
35 | import org.dyn4j.geometry.Vector2;
36 | import org.dyn4j.samples.framework.Camera;
37 | import org.dyn4j.samples.framework.SimulationBody;
38 | import org.dyn4j.samples.framework.SimulationFrame;
39 | import org.dyn4j.samples.framework.input.BooleanStateKeyboardInputHandler;
40 |
41 | /**
42 | * Moderately complex scene of a rocket that has propulsion at various points
43 | * to allow control. Control is given by the left, right, up, and down keys
44 | * and applies forces when pressed.
45 | * @author William Bittle
46 | * @version 5.0.1
47 | * @since 3.2.0
48 | */
49 | public class Thrust extends SimulationFrame {
50 | /** The serial version id */
51 | private static final long serialVersionUID = 3770932661470247325L;
52 |
53 | /** The controlled ship */
54 | private SimulationBody ship;
55 |
56 | // input control
57 |
58 | private final BooleanStateKeyboardInputHandler up;
59 | private final BooleanStateKeyboardInputHandler down;
60 | private final BooleanStateKeyboardInputHandler left;
61 | private final BooleanStateKeyboardInputHandler right;
62 |
63 | /**
64 | * Default constructor.
65 | */
66 | public Thrust() {
67 | super("Thrust");
68 |
69 | this.up = new BooleanStateKeyboardInputHandler(this.canvas, KeyEvent.VK_UP);
70 | this.down = new BooleanStateKeyboardInputHandler(this.canvas, KeyEvent.VK_DOWN);
71 | this.left = new BooleanStateKeyboardInputHandler(this.canvas, KeyEvent.VK_LEFT);
72 | this.right = new BooleanStateKeyboardInputHandler(this.canvas, KeyEvent.VK_RIGHT);
73 |
74 | this.up.install();
75 | this.down.install();
76 | this.left.install();
77 | this.right.install();
78 | }
79 |
80 | /* (non-Javadoc)
81 | * @see org.dyn4j.samples.framework.SimulationFrame#initializeCamera(org.dyn4j.samples.framework.Camera)
82 | */
83 | @Override
84 | protected void initializeCamera(Camera camera) {
85 | super.initializeCamera(camera);
86 | camera.scale = 64.0;
87 | }
88 |
89 | /* (non-Javadoc)
90 | * @see org.dyn4j.samples.framework.SimulationFrame#printControls()
91 | */
92 | @Override
93 | protected void printControls() {
94 | super.printControls();
95 |
96 | printControl("Thrust Up", "Up", "Use the up key to apply thrust to move up");
97 | printControl("Thrust Down", "Down", "Use the down key to apply thrust to move down");
98 | printControl("Thrust Left", "Left", "Use the left key to apply thrust to move left");
99 | printControl("Thrust Right", "Right", "Use the right key to apply thrust to move right");
100 | }
101 |
102 | /**
103 | * Creates game objects and adds them to the world.
104 | */
105 | protected void initializeWorld() {
106 | this.world.setGravity(new Vector2(0, -3));
107 |
108 | // create all your bodies/joints
109 |
110 | // the bounds so we can keep playing
111 | SimulationBody l = new SimulationBody();
112 | l.addFixture(Geometry.createRectangle(1, 15));
113 | l.translate(-5, 0);
114 | l.setMass(MassType.INFINITE);
115 | this.world.addBody(l);
116 |
117 | SimulationBody r = new SimulationBody();
118 | r.addFixture(Geometry.createRectangle(1, 15));
119 | r.translate(5, 0);
120 | r.setMass(MassType.INFINITE);
121 | this.world.addBody(r);
122 |
123 | SimulationBody t = new SimulationBody();
124 | t.addFixture(Geometry.createRectangle(15, 1));
125 | t.translate(0, 5);
126 | t.setMass(MassType.INFINITE);
127 | this.world.addBody(t);
128 |
129 | SimulationBody b = new SimulationBody();
130 | b.addFixture(Geometry.createRectangle(15, 1));
131 | b.translate(0, -5);
132 | b.setMass(MassType.INFINITE);
133 | this.world.addBody(b);
134 |
135 | // the ship
136 | ship = new SimulationBody();
137 | ship.addFixture(Geometry.createRectangle(0.5, 1.5), 1, 0.2, 0.2);
138 | BodyFixture bf2 = ship.addFixture(Geometry.createEquilateralTriangle(0.5), 1, 0.2, 0.2);
139 | bf2.getShape().translate(0, 0.9);
140 | ship.translate(0.0, 2.0);
141 | ship.setMass(MassType.NORMAL);
142 | this.world.addBody(ship);
143 | }
144 |
145 | /* (non-Javadoc)
146 | * @see org.dyn4j.samples.framework.SimulationFrame#render(java.awt.Graphics2D, double)
147 | */
148 | @Override
149 | protected void render(Graphics2D g, double elapsedTime) {
150 | super.render(g, elapsedTime);
151 |
152 | final double scale = this.getCameraScale();
153 | final double force = 1000 * elapsedTime;
154 |
155 | final Vector2 r = new Vector2(ship.getTransform().getRotationAngle() + Math.PI * 0.5);
156 | final Vector2 c = ship.getWorldCenter();
157 |
158 | // apply thrust
159 | if (this.up.isActive()) {
160 | Vector2 f = r.product(force);
161 | Vector2 p = c.sum(r.product(-0.9));
162 |
163 | ship.applyForce(f);
164 |
165 | g.setColor(Color.RED);
166 | g.draw(new Line2D.Double(p.x * scale, p.y * scale, (p.x - f.x) * scale, (p.y - f.y) * scale));
167 | }
168 | if (this.down.isActive()) {
169 | Vector2 f = r.product(-force);
170 | Vector2 p = c.sum(r.product(0.9));
171 |
172 | ship.applyForce(f);
173 |
174 | g.setColor(Color.RED);
175 | g.draw(new Line2D.Double(p.x * scale, p.y * scale, (p.x - f.x) * scale, (p.y - f.y) * scale));
176 | }
177 | if (this.left.isActive()) {
178 | Vector2 f1 = r.product(force * 0.1).right();
179 | Vector2 f2 = r.product(force * 0.1).left();
180 | Vector2 p1 = c.sum(r.product(0.9));
181 | Vector2 p2 = c.sum(r.product(-0.9));
182 |
183 | // apply a force to the top going left
184 | ship.applyForce(f1, p1);
185 | // apply a force to the bottom going right
186 | ship.applyForce(f2, p2);
187 |
188 | g.setColor(Color.RED);
189 | g.draw(new Line2D.Double(p1.x * scale, p1.y * scale, (p1.x - f1.x) * scale, (p1.y - f1.y) * scale));
190 | g.draw(new Line2D.Double(p2.x * scale, p2.y * scale, (p2.x - f2.x) * scale, (p2.y - f2.y) * scale));
191 | }
192 | if (this.right.isActive()) {
193 | Vector2 f1 = r.product(force * 0.1).left();
194 | Vector2 f2 = r.product(force * 0.1).right();
195 | Vector2 p1 = c.sum(r.product(0.9));
196 | Vector2 p2 = c.sum(r.product(-0.9));
197 |
198 | // apply a force to the top going left
199 | ship.applyForce(f1, p1);
200 | // apply a force to the bottom going right
201 | ship.applyForce(f2, p2);
202 |
203 | g.setColor(Color.RED);
204 | g.draw(new Line2D.Double(p1.x * scale, p1.y * scale, (p1.x - f1.x) * scale, (p1.y - f1.y) * scale));
205 | g.draw(new Line2D.Double(p2.x * scale, p2.y * scale, (p2.x - f2.x) * scale, (p2.y - f2.y) * scale));
206 | }
207 | }
208 |
209 | /**
210 | * Entry point for the example application.
211 | * @param args command line arguments
212 | */
213 | public static void main(String[] args) {
214 | Thrust simulation = new Thrust();
215 | simulation.run();
216 | }
217 | }
218 |
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/Tracking.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2022 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples;
26 |
27 | import java.util.HashMap;
28 | import java.util.Map;
29 |
30 | import org.dyn4j.dynamics.BodyFixture;
31 | import org.dyn4j.dynamics.contact.Contact;
32 | import org.dyn4j.geometry.Geometry;
33 | import org.dyn4j.geometry.MassType;
34 | import org.dyn4j.geometry.Vector2;
35 | import org.dyn4j.samples.framework.Camera;
36 | import org.dyn4j.samples.framework.SimulationBody;
37 | import org.dyn4j.samples.framework.SimulationFrame;
38 | import org.dyn4j.world.ContactCollisionData;
39 | import org.dyn4j.world.listener.ContactListenerAdapter;
40 |
41 | /**
42 | * A simple scene with a few shape types that tracks the creation,
43 | * persistence and removal of contacts by using their unique ids.
44 | * @author William Bittle
45 | * @version 5.0.0
46 | * @since 3.0.0
47 | */
48 | public class Tracking extends SimulationFrame {
49 | /** The serial version id */
50 | private static final long serialVersionUID = -7551190289570564575L;
51 |
52 | /**
53 | * A simple class to generate "id"s.
54 | * @author William Bittle
55 | * @version 4.1.1
56 | * @since 4.1.1
57 | */
58 | private class IdGenerator {
59 | private long lastId = -1;
60 | public final Object getId() {
61 | return Long.valueOf(++lastId);
62 | }
63 | }
64 |
65 | // contact listening
66 |
67 | /** A mapping of contact id to UUID */
68 | private final Map idTracking = new HashMap();
69 |
70 | /** The id generator */
71 | private final IdGenerator idGenerator = new IdGenerator();
72 |
73 | /**
74 | * A custom contact listener for tracking contacts.
75 | * @author William Bittle
76 | * @version 3.2.1
77 | * @since 3.2.1
78 | */
79 | private class CustomContactListener extends ContactListenerAdapter {
80 | @Override
81 | public void begin(ContactCollisionData collision, Contact contact) {
82 | Object id = idGenerator.getId();
83 | idTracking.put(contact, id);
84 | System.out.println("BEGIN: " + id);
85 | }
86 |
87 | @Override
88 | public void persist(ContactCollisionData collision, Contact oldContact, Contact newContact) {
89 | Object id = idTracking.get(oldContact);
90 | if (id == null) {
91 | System.err.println("Shouldn't happen");
92 | }
93 | // since the contact object itself changes between iterations
94 | // remove the old contact and add the new contact with the same id
95 | idTracking.remove(oldContact);
96 | idTracking.put(newContact, id);
97 | }
98 |
99 | @Override
100 | public void end(ContactCollisionData collision, Contact contact) {
101 | Object id = idTracking.get(contact);
102 | if (id == null) {
103 | System.err.println("Shouldn't happen");
104 | }
105 | System.out.println("END: " + id);
106 | idTracking.remove(contact);
107 | }
108 | }
109 |
110 | /**
111 | * Default constructor.
112 | */
113 | public Tracking() {
114 | super("Tracking");
115 | }
116 |
117 | /**
118 | * Creates game objects and adds them to the world.
119 | */
120 | protected void initializeWorld() {
121 | // create all your bodies/joints
122 |
123 | // create the floor
124 | SimulationBody floor = new SimulationBody();
125 | floor.addFixture(Geometry.createRectangle(15, 1));
126 | floor.setMass(MassType.INFINITE);
127 | // move the floor down a bit
128 | floor.translate(0.0, -4.0);
129 | this.world.addBody(floor);
130 |
131 | // create a triangle object
132 | SimulationBody triangle = new SimulationBody();
133 | triangle.addFixture(Geometry.createTriangle(
134 | new Vector2(0.0, 0.5),
135 | new Vector2(-0.5, -0.5),
136 | new Vector2(0.5, -0.5)));
137 | triangle.setMass(MassType.NORMAL);
138 | triangle.translate(-1.0, 2.0);
139 | // test having a velocity
140 | triangle.getLinearVelocity().set(5.0, 0.0);
141 | this.world.addBody(triangle);
142 |
143 | // create a circle
144 | SimulationBody circle = new SimulationBody();
145 | circle.addFixture(Geometry.createCircle(0.5));
146 | circle.setMass(MassType.NORMAL);
147 | circle.translate(2.0, 2.0);
148 | // test adding some force
149 | circle.applyForce(new Vector2(-100.0, 0.0));
150 | // set some linear damping to simulate rolling friction
151 | circle.setLinearDamping(0.05);
152 | this.world.addBody(circle);
153 |
154 | // try a rectangle
155 | SimulationBody rectangle = new SimulationBody();
156 | rectangle.addFixture(Geometry.createRectangle(1, 1));
157 | rectangle.setMass(MassType.NORMAL);
158 | rectangle.translate(0.0, 2.0);
159 | rectangle.getLinearVelocity().set(-5.0, 0.0);
160 | this.world.addBody(rectangle);
161 |
162 | // try a polygon with lots of vertices
163 | SimulationBody polygon = new SimulationBody();
164 | polygon.addFixture(Geometry.createUnitCirclePolygon(10, 1));
165 | polygon.setMass(MassType.NORMAL);
166 | polygon.translate(-2.5, 2.0);
167 | // set the angular velocity
168 | polygon.setAngularVelocity(Math.toRadians(-20.0));
169 | this.world.addBody(polygon);
170 |
171 | // try a compound object (Capsule)
172 | BodyFixture c1Fixture = new BodyFixture(Geometry.createCircle(0.5));
173 | BodyFixture c2Fixture = new BodyFixture(Geometry.createCircle(0.5));
174 | c1Fixture.setDensity(0.5);
175 | c2Fixture.setDensity(0.5);
176 | // translate the circles in local coordinates
177 | c1Fixture.getShape().translate(-1.0, 0.0);
178 | c2Fixture.getShape().translate(1.0, 0.0);
179 | SimulationBody capsule = new SimulationBody();
180 | capsule.addFixture(c1Fixture);
181 | capsule.addFixture(c2Fixture);
182 | capsule.addFixture(Geometry.createRectangle(2, 1));
183 | capsule.setMass(MassType.NORMAL);
184 | capsule.translate(0.0, 4.0);
185 | this.world.addBody(capsule);
186 |
187 | SimulationBody issTri = new SimulationBody();
188 | issTri.addFixture(Geometry.createIsoscelesTriangle(1.0, 3.0));
189 | issTri.setMass(MassType.NORMAL);
190 | issTri.translate(2.0, 3.0);
191 | this.world.addBody(issTri);
192 |
193 | SimulationBody equTri = new SimulationBody();
194 | equTri.addFixture(Geometry.createEquilateralTriangle(2.0));
195 | equTri.setMass(MassType.NORMAL);
196 | equTri.translate(3.0, 3.0);
197 | this.world.addBody(equTri);
198 |
199 | SimulationBody rightTri = new SimulationBody();
200 | rightTri.addFixture(Geometry.createRightTriangle(2.0, 1.0));
201 | rightTri.setMass(MassType.NORMAL);
202 | rightTri.translate(4.0, 3.0);
203 | this.world.addBody(rightTri);
204 |
205 | // attach the contact listener
206 | this.world.addContactListener(new CustomContactListener());
207 | }
208 |
209 | /* (non-Javadoc)
210 | * @see org.dyn4j.samples.framework.SimulationFrame#initializeCamera(org.dyn4j.samples.framework.Camera)
211 | */
212 | @Override
213 | protected void initializeCamera(Camera camera) {
214 | super.initializeCamera(camera);
215 | camera.scale = 45.0;
216 | }
217 |
218 | /**
219 | * Entry point for the example application.
220 | * @param args command line arguments
221 | */
222 | public static void main(String[] args) {
223 | Tracking simulation = new Tracking();
224 | simulation.run();
225 | }
226 | }
227 |
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/Truck.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2022 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples;
26 |
27 | import java.awt.event.KeyEvent;
28 |
29 | import org.dyn4j.dynamics.BodyFixture;
30 | import org.dyn4j.dynamics.ContinuousDetectionMode;
31 | import org.dyn4j.dynamics.joint.WheelJoint;
32 | import org.dyn4j.geometry.Convex;
33 | import org.dyn4j.geometry.Geometry;
34 | import org.dyn4j.geometry.MassType;
35 | import org.dyn4j.geometry.Vector2;
36 | import org.dyn4j.samples.framework.Camera;
37 | import org.dyn4j.samples.framework.SimulationBody;
38 | import org.dyn4j.samples.framework.SimulationFrame;
39 | import org.dyn4j.samples.framework.input.BooleanStateKeyboardInputHandler;
40 |
41 | /**
42 | * A scene where a truck is carrying other objects.
43 | * @author William Bittle
44 | * @since 5.0.1
45 | * @version 4.1.1
46 | */
47 | public class Truck extends SimulationFrame {
48 | /** The serial version id */
49 | private static final long serialVersionUID = 4610026750399376114L;
50 |
51 | private final BooleanStateKeyboardInputHandler left;
52 | private final BooleanStateKeyboardInputHandler right;
53 | private final BooleanStateKeyboardInputHandler stop;
54 |
55 | private double speed;
56 | private WheelJoint wj1;
57 | private WheelJoint wj2;
58 |
59 | /**
60 | * Default constructor.
61 | */
62 | public Truck() {
63 | super("Truck");
64 |
65 | this.left = new BooleanStateKeyboardInputHandler(this.canvas, KeyEvent.VK_LEFT);
66 | this.right = new BooleanStateKeyboardInputHandler(this.canvas, KeyEvent.VK_RIGHT);
67 | this.stop = new BooleanStateKeyboardInputHandler(this.canvas, KeyEvent.VK_S);
68 |
69 | this.left.install();
70 | this.right.install();
71 | this.stop.install();
72 | }
73 |
74 | /* (non-Javadoc)
75 | * @see org.dyn4j.samples.framework.SimulationFrame#printControls()
76 | */
77 | @Override
78 | protected void printControls() {
79 | super.printControls();
80 |
81 | printControl("Move Left", "Left", "Use the left key to accelerate left");
82 | printControl("Move Right", "Right", "Use the right key to accelerate right");
83 | printControl("Stop", "s", "Use the s key to stop");
84 | }
85 |
86 | /**
87 | * Creates game objects and adds them to the world.
88 | */
89 | protected void initializeWorld() {
90 | this.world.getSettings().setContinuousDetectionMode(ContinuousDetectionMode.NONE);
91 |
92 | // Ground
93 | SimulationBody ground = new SimulationBody();
94 | ground.addFixture(Geometry.createRectangle(50.0, 1.0), 1.0, 0.5, 0.0);
95 | ground.translate(new Vector2(-2.0, -4.0));
96 | ground.setMass(MassType.INFINITE);
97 | world.addBody(ground);
98 |
99 | // Ramp
100 | SimulationBody ramp = new SimulationBody();
101 | ramp.addFixture(Geometry.createRectangle(10.0, 0.2));
102 | ramp.rotate(Math.toRadians(10.0));
103 | ramp.translate(new Vector2(0.0, -3.0));
104 | ramp.setMass(MassType.INFINITE);
105 | world.addBody(ramp);
106 |
107 | // Frame
108 | SimulationBody truck = new SimulationBody();
109 | {// drive shaft
110 | truck.addFixture(Geometry.createRectangle(5.0, 0.25));
111 | }
112 | {// body
113 | Convex c = Geometry.createRectangle(5.2, 0.5);
114 | c.translate(new Vector2(0.0, 0.5));
115 | BodyFixture bf = new BodyFixture(c);
116 | truck.addFixture(bf);
117 | }
118 | {// tailgate
119 | Convex c = Geometry.createRectangle(0.25, 0.5);
120 | c.translate(new Vector2(-2.4, 1.0));
121 | BodyFixture bf = new BodyFixture(c);
122 | truck.addFixture(bf);
123 | }
124 | {// cab
125 | Convex c = Geometry.createRectangle(2.0, 2.0);
126 | c.translate(new Vector2(2.4, 1.0));
127 | BodyFixture bf = new BodyFixture(c);
128 | truck.addFixture(bf);
129 | }
130 | truck.translate(new Vector2(-23.0, -3.0));
131 | truck.setMass(MassType.NORMAL);
132 | world.addBody(truck);
133 |
134 | // Rear Wheel
135 | SimulationBody rearWheel = new SimulationBody();
136 | rearWheel.addFixture(Geometry.createCircle(0.5), 1.0, 0.5, 0.0);
137 | rearWheel.translate(-25.0, -3.0);
138 | rearWheel.setMass(MassType.NORMAL);
139 | world.addBody(rearWheel);
140 |
141 | // Front Wheel
142 | SimulationBody frontWheel = new SimulationBody();
143 | frontWheel.addFixture(Geometry.createCircle(0.5), 1.0, 0.5, 0.0);
144 | frontWheel.translate(-21.0, -3.0);
145 | frontWheel.setMass(MassType.NORMAL);
146 | world.addBody(frontWheel);
147 |
148 | // Rear Motor
149 | WheelJoint rearWheelJoint = new WheelJoint(truck, rearWheel, new Vector2(-25.0, -3.0), new Vector2(0.0, -1.0));
150 | rearWheelJoint.setMotorEnabled(true);
151 | rearWheelJoint.setMotorSpeed(0.0);
152 | rearWheelJoint.setMaximumMotorTorqueEnabled(true);
153 | rearWheelJoint.setMaximumMotorTorque(1000.0);
154 | world.addJoint(rearWheelJoint);
155 | this.wj1 = rearWheelJoint;
156 |
157 | // Front Motor
158 | WheelJoint frontWheelJoint = new WheelJoint(truck, frontWheel, new Vector2(-21.0, -3.0), new Vector2(0.0, -1.0));
159 | frontWheelJoint.setMotorEnabled(true);
160 | frontWheelJoint.setMotorSpeed(0.0);
161 | frontWheelJoint.setMaximumMotorTorqueEnabled(true);
162 | frontWheelJoint.setMaximumMotorTorque(1000);
163 | world.addJoint(frontWheelJoint);
164 | this.wj2 = frontWheelJoint;
165 |
166 | // put some stuff in the back of the truck
167 | double x = -24;
168 | double y = -2.0;
169 | double s = 0.25;
170 | for (int i = 0; i < 10; i++) {
171 | for (int j = 0; j < 3; j++) {
172 | SimulationBody box = new SimulationBody();
173 | box.addFixture(Geometry.createSquare(s), 1.0, 0.2, 0.0);
174 | box.translate(new Vector2(x + (i * s), y + (j * s)));
175 | box.setMass(MassType.NORMAL);
176 | world.addBody(box);
177 | }
178 | }
179 | }
180 |
181 | /* (non-Javadoc)
182 | * @see org.dyn4j.samples.framework.SimulationFrame#initializeCamera(org.dyn4j.samples.framework.Camera)
183 | */
184 | @Override
185 | protected void initializeCamera(Camera camera) {
186 | super.initializeCamera(camera);
187 | camera.scale = 16.0;
188 | }
189 |
190 | /* (non-Javadoc)
191 | * @see org.dyn4j.samples.framework.SimulationFrame#reset()
192 | */
193 | @Override
194 | public void reset() {
195 | super.reset();
196 | this.speed = 0.0;
197 | }
198 |
199 | /* (non-Javadoc)
200 | * @see org.dyn4j.samples.framework.SimulationFrame#handleEvents()
201 | */
202 | @Override
203 | protected void handleEvents() {
204 | super.handleEvents();
205 |
206 | if (this.left.isActive()) {
207 | this.speed += Math.PI / 100;
208 | }
209 | if (this.right.isActive()) {
210 | this.speed -= Math.PI / 100;
211 | }
212 | if (this.stop.isActive()) {
213 | this.speed = 0.0;
214 | }
215 |
216 | if (this.wj1 != null) {
217 | this.wj1.setMotorSpeed(this.speed);
218 | }
219 | if (this.wj2 != null) {
220 | this.wj2.setMotorSpeed(this.speed);
221 | }
222 |
223 |
224 | }
225 |
226 | /**
227 | * Entry point for the example application.
228 | * @param args command line arguments
229 | */
230 | public static void main(String[] args) {
231 | Truck simulation = new Truck();
232 | simulation.run();
233 | }
234 | }
235 |
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/UsingGraphics2D.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2022 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples;
26 |
27 | import org.dyn4j.dynamics.BodyFixture;
28 | import org.dyn4j.geometry.Capsule;
29 | import org.dyn4j.geometry.Circle;
30 | import org.dyn4j.geometry.Geometry;
31 | import org.dyn4j.geometry.MassType;
32 | import org.dyn4j.geometry.Polygon;
33 | import org.dyn4j.geometry.Rectangle;
34 | import org.dyn4j.geometry.Slice;
35 | import org.dyn4j.geometry.Triangle;
36 | import org.dyn4j.geometry.Vector2;
37 | import org.dyn4j.samples.framework.Camera;
38 | import org.dyn4j.samples.framework.SimulationBody;
39 | import org.dyn4j.samples.framework.SimulationFrame;
40 |
41 | /**
42 | * Class used to show a simple example of using the dyn4j project using
43 | * Java2D for rendering.
44 | *
45 | * This class can be used as a starting point for projects.
46 | * @author William Bittle
47 | * @version 5.0.0
48 | * @since 3.0.0
49 | */
50 | public class UsingGraphics2D extends SimulationFrame {
51 | /** The serial version id */
52 | private static final long serialVersionUID = 5663760293144882635L;
53 |
54 | /**
55 | * Default constructor for the window
56 | */
57 | public UsingGraphics2D() {
58 | super("Graphics2D Example");
59 |
60 | }
61 |
62 | /**
63 | * Creates game objects and adds them to the world.
64 | *
65 | * Basically the same shapes from the Shapes test in
66 | * the TestBed.
67 | */
68 | protected void initializeWorld() {
69 | // create all your bodies/joints
70 |
71 | // create the floor
72 | Rectangle floorRect = new Rectangle(15.0, 1.0);
73 | SimulationBody floor = new SimulationBody();
74 | floor.addFixture(new BodyFixture(floorRect));
75 | floor.setMass(MassType.INFINITE);
76 | // move the floor down a bit
77 | floor.translate(0.0, -4.0);
78 | this.world.addBody(floor);
79 |
80 | // create a triangle object
81 | Triangle triShape = new Triangle(
82 | new Vector2(0.0, 0.5),
83 | new Vector2(-0.5, -0.5),
84 | new Vector2(0.5, -0.5));
85 | SimulationBody triangle = new SimulationBody();
86 | triangle.addFixture(triShape);
87 | triangle.setMass(MassType.NORMAL);
88 | triangle.translate(-1.0, 2.0);
89 | // test having a velocity
90 | triangle.getLinearVelocity().set(5.0, 0.0);
91 | this.world.addBody(triangle);
92 |
93 | // create a circle
94 | Circle cirShape = new Circle(0.5);
95 | SimulationBody circle = new SimulationBody();
96 | circle.addFixture(cirShape);
97 | circle.setMass(MassType.NORMAL);
98 | circle.translate(2.0, 2.0);
99 | // test adding some force
100 | circle.applyForce(new Vector2(-100.0, 0.0));
101 | // set some linear damping to simulate rolling friction
102 | circle.setLinearDamping(0.05);
103 | this.world.addBody(circle);
104 |
105 | // try a rectangle
106 | Rectangle rectShape = new Rectangle(1.0, 1.0);
107 | SimulationBody rectangle = new SimulationBody();
108 | rectangle.addFixture(rectShape);
109 | rectangle.setMass(MassType.NORMAL);
110 | rectangle.translate(0.0, 2.0);
111 | rectangle.getLinearVelocity().set(-5.0, 0.0);
112 | this.world.addBody(rectangle);
113 |
114 | // try a polygon with lots of vertices
115 | Polygon polyShape = Geometry.createUnitCirclePolygon(10, 1.0);
116 | SimulationBody polygon = new SimulationBody();
117 | polygon.addFixture(polyShape);
118 | polygon.setMass(MassType.NORMAL);
119 | polygon.translate(-2.5, 2.0);
120 | // set the angular velocity
121 | polygon.setAngularVelocity(Math.toRadians(-20.0));
122 | this.world.addBody(polygon);
123 |
124 | // try a compound object
125 | Circle c1 = new Circle(0.5);
126 | BodyFixture c1Fixture = new BodyFixture(c1);
127 | c1Fixture.setDensity(0.5);
128 | Circle c2 = new Circle(0.5);
129 | BodyFixture c2Fixture = new BodyFixture(c2);
130 | c2Fixture.setDensity(0.5);
131 | Rectangle rm = new Rectangle(2.0, 1.0);
132 | // translate the circles in local coordinates
133 | c1.translate(-1.0, 0.0);
134 | c2.translate(1.0, 0.0);
135 | SimulationBody capsule = new SimulationBody();
136 | capsule.addFixture(c1Fixture);
137 | capsule.addFixture(c2Fixture);
138 | capsule.addFixture(rm);
139 | capsule.setMass(MassType.NORMAL);
140 | capsule.translate(0.0, 4.0);
141 | this.world.addBody(capsule);
142 |
143 | SimulationBody issTri = new SimulationBody();
144 | issTri.addFixture(Geometry.createIsoscelesTriangle(1.0, 3.0));
145 | issTri.setMass(MassType.NORMAL);
146 | issTri.translate(2.0, 3.0);
147 | this.world.addBody(issTri);
148 |
149 | SimulationBody equTri = new SimulationBody();
150 | equTri.addFixture(Geometry.createEquilateralTriangle(2.0));
151 | equTri.setMass(MassType.NORMAL);
152 | equTri.translate(3.0, 3.0);
153 | this.world.addBody(equTri);
154 |
155 | SimulationBody rightTri = new SimulationBody();
156 | rightTri.addFixture(Geometry.createRightTriangle(2.0, 1.0));
157 | rightTri.setMass(MassType.NORMAL);
158 | rightTri.translate(4.0, 3.0);
159 | this.world.addBody(rightTri);
160 |
161 | SimulationBody cap = new SimulationBody();
162 | cap.addFixture(new Capsule(1.0, 0.5));
163 | cap.setMass(MassType.NORMAL);
164 | cap.translate(-3.0, 3.0);
165 | this.world.addBody(cap);
166 |
167 | SimulationBody slice = new SimulationBody();
168 | slice.addFixture(new Slice(0.5, Math.toRadians(120)));
169 | slice.setMass(MassType.NORMAL);
170 | slice.translate(-3.0, 3.0);
171 | this.world.addBody(slice);
172 | }
173 |
174 | /* (non-Javadoc)
175 | * @see org.dyn4j.samples.framework.SimulationFrame#initializeCamera(org.dyn4j.samples.framework.Camera)
176 | */
177 | @Override
178 | protected void initializeCamera(Camera camera) {
179 | super.initializeCamera(camera);
180 | camera.scale = 45.0;
181 | }
182 |
183 | /**
184 | * Entry point for the example application.
185 | * @param args command line arguments
186 | */
187 | public static void main(String[] args) {
188 | UsingGraphics2D simulation = new UsingGraphics2D();
189 | simulation.run();
190 | }
191 | }
192 |
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/framework/Camera.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2021 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples.framework;
26 |
27 | import java.awt.Point;
28 |
29 | import org.dyn4j.geometry.Vector2;
30 |
31 | /**
32 | * Stores the zoom and panning state of the camera.
33 | * @author William Bittle
34 | * @version 4.1.1
35 | * @since 4.1.1
36 | */
37 | public class Camera {
38 | /** The scale (zoom) in pixels per meter */
39 | public double scale;
40 |
41 | /** The pan-x in pixels */
42 | public double offsetX;
43 |
44 | /** The pan-y in pixels */
45 | public double offsetY;
46 |
47 | /**
48 | * Returns World coordinates for the given point given the width/height of the viewport.
49 | * @param width the viewport width
50 | * @param height the viewport height
51 | * @param p the point
52 | * @return Vector2
53 | */
54 | public final Vector2 toWorldCoordinates(double width, double height, Point p) {
55 | if (p != null) {
56 | Vector2 v = new Vector2();
57 | // convert the screen space point to world space
58 | v.x = (p.getX() - width * 0.5 - this.offsetX) / this.scale;
59 | v.y = -(p.getY() - height * 0.5 + this.offsetY) / this.scale;
60 | return v;
61 | }
62 |
63 | return null;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/framework/SimulationBody.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2022 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples.framework;
26 |
27 | import java.awt.Color;
28 | import java.awt.Graphics2D;
29 | import java.awt.geom.AffineTransform;
30 | import java.awt.geom.Ellipse2D;
31 |
32 | import org.dyn4j.dynamics.Body;
33 | import org.dyn4j.dynamics.BodyFixture;
34 | import org.dyn4j.geometry.Convex;
35 |
36 | /**
37 | * Custom Body class to add drawing functionality.
38 | * @author William Bittle
39 | * @version 3.2.1
40 | * @since 3.0.0
41 | */
42 | public class SimulationBody extends Body {
43 | /** The color of the object */
44 | protected Color color;
45 |
46 | /**
47 | * Default constructor.
48 | */
49 | public SimulationBody() {
50 | this.color = Graphics2DRenderer.getRandomColor();
51 | }
52 |
53 | /**
54 | * Constructor.
55 | * @param color a set color
56 | */
57 | public SimulationBody(Color color) {
58 | this.color = color;
59 | }
60 |
61 | /**
62 | * Draws the body.
63 | *
64 | * Only coded for polygons and circles.
65 | * @param g the graphics object to render to
66 | * @param scale the scaling factor
67 | */
68 | public void render(Graphics2D g, double scale) {
69 | this.render(g, scale, this.color);
70 | }
71 |
72 | /**
73 | * Draws the body.
74 | *
75 | * Only coded for polygons and circles.
76 | * @param g the graphics object to render to
77 | * @param scale the scaling factor
78 | * @param color the color to render the body
79 | */
80 | public void render(Graphics2D g, double scale, Color color) {
81 | // point radius
82 | final int pr = 4;
83 |
84 | // save the original transform
85 | AffineTransform ot = g.getTransform();
86 |
87 | // transform the coordinate system from world coordinates to local coordinates
88 | AffineTransform lt = new AffineTransform();
89 | lt.translate(this.transform.getTranslationX() * scale, this.transform.getTranslationY() * scale);
90 | lt.rotate(this.transform.getRotationAngle());
91 |
92 | // apply the transform
93 | g.transform(lt);
94 |
95 | // loop over all the body fixtures for this body
96 | for (BodyFixture fixture : this.fixtures) {
97 | this.renderFixture(g, scale, fixture, color);
98 | }
99 |
100 | // draw a center point
101 | Ellipse2D.Double ce = new Ellipse2D.Double(
102 | this.getLocalCenter().x * scale - pr * 0.5,
103 | this.getLocalCenter().y * scale - pr * 0.5,
104 | pr,
105 | pr);
106 | g.setColor(Color.WHITE);
107 | g.fill(ce);
108 | g.setColor(Color.DARK_GRAY);
109 | g.draw(ce);
110 |
111 | // set the original transform
112 | g.setTransform(ot);
113 | }
114 |
115 | /**
116 | * Renders the given fixture.
117 | * @param g the graphics object to render to
118 | * @param scale the scaling factor
119 | * @param fixture the fixture to render
120 | * @param color the color to render the fixture
121 | */
122 | protected void renderFixture(Graphics2D g, double scale, BodyFixture fixture, Color color) {
123 | // get the shape on the fixture
124 | Convex convex = fixture.getShape();
125 |
126 | // brighten the color if asleep
127 | if (this.isAtRest()) {
128 | color = color.brighter();
129 | }
130 |
131 | // render the fixture
132 | Graphics2DRenderer.render(g, convex, scale, color);
133 | }
134 |
135 | /**
136 | * Returns this body's color.
137 | * @return Color
138 | */
139 | public Color getColor() {
140 | return this.color;
141 | }
142 |
143 | /**
144 | * Sets the body's color
145 | * @param color the color
146 | */
147 | public void setColor(Color color) {
148 | this.color = color;
149 | }
150 | }
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/framework/input/AbstractInputHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2022 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples.framework.input;
26 |
27 | import java.util.ArrayList;
28 | import java.util.List;
29 |
30 | public abstract class AbstractInputHandler implements InputHandler {
31 | private boolean enabled;
32 | private boolean additive;
33 | private final List dependentBehaviors;
34 |
35 | public AbstractInputHandler() {
36 | this.enabled = true;
37 | this.additive = false;
38 | this.dependentBehaviors = new ArrayList();
39 | }
40 |
41 | @Override
42 | public boolean isEnabled() {
43 | return this.enabled;
44 | }
45 |
46 | @Override
47 | public void setEnabled(boolean flag) {
48 | this.enabled = flag;
49 | }
50 |
51 | public List getDependentBehaviors() {
52 | return this.dependentBehaviors;
53 | }
54 |
55 | @Override
56 | public boolean isDependentBehaviorActive() {
57 | boolean result = false;
58 | for (InputHandler behavior : this.dependentBehaviors) {
59 | if (behavior.isActive()) {
60 | result = true;
61 | }
62 | }
63 | if (this.additive) return !result;
64 | return result;
65 | }
66 |
67 | @Override
68 | public boolean isDependentBehaviorsAdditive() {
69 | return this.additive;
70 | }
71 |
72 | @Override
73 | public void setDependentBehaviorsAdditive(boolean flag) {
74 | this.additive = flag;
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/framework/input/AbstractKeyboardInputHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2022 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples.framework.input;
26 |
27 | import java.awt.Component;
28 | import java.awt.event.KeyAdapter;
29 | import java.awt.event.KeyEvent;
30 |
31 | public abstract class AbstractKeyboardInputHandler extends AbstractInputHandler implements InputHandler {
32 | protected final Component component;
33 | protected final Key[] keys;
34 |
35 | private final KeyAdapter keyAdapter;
36 |
37 | public AbstractKeyboardInputHandler(Component component, Key... keys) {
38 | this.component = component;
39 | this.keys = keys;
40 | this.keyAdapter = new CustomKeyListener();
41 | }
42 |
43 | public AbstractKeyboardInputHandler(Component component, int... keys) {
44 | this.component = component;
45 | this.keyAdapter = new CustomKeyListener();
46 | this.keys = new Key[keys.length];
47 | for (int i = 0; i < keys.length; i++) {
48 | this.keys[i] = new Key(keys[i]);
49 | }
50 |
51 | }
52 |
53 | private boolean isKeyMatch(int key, int modifiers) {
54 | for (int i = 0; i < this.keys.length; i++) {
55 | if (this.keys[i].key == key && this.keys[i].modifiers == modifiers)
56 | return true;
57 | }
58 | return false;
59 | }
60 |
61 | /**
62 | * Custom key adapter to listen for key events.
63 | * @author William Bittle
64 | * @version 3.2.1
65 | * @since 3.2.0
66 | */
67 | private class CustomKeyListener extends KeyAdapter {
68 | @Override
69 | public void keyPressed(KeyEvent e) {
70 | if (e.isConsumed()) return;
71 | // System.out.println(e.getKeyChar() + " " + e.getKeyCode() + " " + e.getModifiersEx());
72 | if (isKeyMatch(e.getKeyCode(), e.getModifiersEx())) {
73 | if (isEnabled() && !isDependentBehaviorActive()) {
74 | onKeyPressed();
75 | }
76 | }
77 | }
78 |
79 | @Override
80 | public void keyReleased(KeyEvent e) {
81 | if (e.isConsumed()) return;
82 |
83 | if (isKeyMatch(e.getKeyCode(), e.getModifiersEx())) {
84 | if (isEnabled() && !isDependentBehaviorActive()) {
85 | onKeyReleased();
86 | }
87 | }
88 | }
89 | }
90 |
91 | @Override
92 | public void install() {
93 | this.component.addKeyListener(this.keyAdapter);
94 | }
95 |
96 | @Override
97 | public void uninstall() {
98 | this.component.removeKeyListener(this.keyAdapter);
99 | }
100 |
101 | protected void onKeyPressed() {
102 |
103 | }
104 |
105 | protected void onKeyReleased() {
106 |
107 | }
108 | }
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/framework/input/AbstractMouseInputHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2022 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples.framework.input;
26 |
27 | import java.awt.Component;
28 | import java.awt.Point;
29 | import java.awt.event.MouseAdapter;
30 | import java.awt.event.MouseEvent;
31 | import java.awt.event.MouseWheelEvent;
32 |
33 | public abstract class AbstractMouseInputHandler extends AbstractInputHandler implements InputHandler {
34 |
35 | protected final Component component;
36 | protected final int button;
37 |
38 | private final MouseAdapter mouseAdapter;
39 |
40 | private Point dragCurrent;
41 | private Point dragStart;
42 |
43 | public AbstractMouseInputHandler(Component component, int button) {
44 | this.component = component;
45 | this.button = button;
46 | this.mouseAdapter = new CustomMouseAdapter();
47 | }
48 |
49 | /**
50 | * A custom mouse adapter to track mouse drag events.
51 | * @author William Bittle
52 | * @version 3.2.1
53 | * @since 3.2.0
54 | */
55 | private final class CustomMouseAdapter extends MouseAdapter {
56 | @Override
57 | public void mousePressed(MouseEvent e) {
58 | if (e.isConsumed()) return;
59 |
60 | if (e.getButton() == button) {
61 | // store the mouse click postion for use later
62 | dragCurrent = new Point(e.getX(), e.getY());
63 | dragStart = dragCurrent;
64 | if (isEnabled() && !isDependentBehaviorActive()) {
65 | onMousePressed(dragStart);
66 | }
67 | }
68 | }
69 |
70 | @Override
71 | public void mouseDragged(MouseEvent e) {
72 | if (e.isConsumed()) return;
73 |
74 | dragCurrent = new Point(e.getX(), e.getY());
75 | if (isEnabled() && !isDependentBehaviorActive() && dragStart != null) {
76 | onMouseDrag(dragStart, dragCurrent);
77 | }
78 | }
79 |
80 | @Override
81 | public void mouseReleased(MouseEvent e) {
82 | if (e.isConsumed()) return;
83 |
84 | if (e.getButton() == button) {
85 | dragCurrent = null;
86 | dragStart = null;
87 | if (isEnabled() && !isDependentBehaviorActive()) {
88 | onMouseRelease();
89 | }
90 | }
91 | }
92 |
93 | @Override
94 | public void mouseWheelMoved(MouseWheelEvent e) {
95 | if (e.isConsumed()) return;
96 |
97 | double wheelRotation = e.getWheelRotation();
98 | if (isEnabled() && !isDependentBehaviorActive()) {
99 | onMouseWheel(wheelRotation);
100 | }
101 | }
102 | }
103 |
104 | @Override
105 | public void install() {
106 | this.component.addMouseListener(this.mouseAdapter);
107 | this.component.addMouseMotionListener(this.mouseAdapter);
108 | this.component.addMouseWheelListener(this.mouseAdapter);
109 | }
110 |
111 | @Override
112 | public void uninstall() {
113 | this.component.removeMouseListener(this.mouseAdapter);
114 | this.component.removeMouseMotionListener(this.mouseAdapter);
115 | this.component.removeMouseWheelListener(this.mouseAdapter);
116 | }
117 |
118 | @Override
119 | public void setEnabled(boolean flag) {
120 | super.setEnabled(flag);
121 | if (!flag) {
122 | this.dragCurrent = null;
123 | this.dragStart = null;
124 | }
125 | }
126 |
127 | protected void onMousePressed(Point point) {
128 |
129 | }
130 |
131 | protected void onMouseDrag(Point start, Point current) {
132 |
133 | }
134 |
135 | protected void onMouseRelease() {
136 |
137 | }
138 |
139 | protected void onMouseWheel(double rotation) {
140 |
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/framework/input/BooleanStateKeyboardInputHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2022 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples.framework.input;
26 |
27 | import java.awt.Component;
28 |
29 | public class BooleanStateKeyboardInputHandler extends AbstractKeyboardInputHandler {
30 | /** If the key state is active (pressed) */
31 | private boolean active;
32 |
33 | /** True if the active state has been handled */
34 | private boolean hasBeenHandled;
35 |
36 | public BooleanStateKeyboardInputHandler(Component component, Key... keys) {
37 | super(component, keys);
38 | this.active = false;
39 | this.hasBeenHandled = false;
40 | }
41 |
42 | public BooleanStateKeyboardInputHandler(Component component, int... keys) {
43 | super(component, keys);
44 | this.active = false;
45 | this.hasBeenHandled = false;
46 | }
47 |
48 | @Override
49 | protected void onKeyPressed() {
50 | super.onKeyPressed();
51 |
52 | // save the old state
53 | boolean active = this.active;
54 |
55 | // set the state to active
56 | this.active = true;
57 |
58 | // if the state transitioned from inactive to active
59 | // flag that it needs to be handled
60 | if (!active) {
61 | this.hasBeenHandled = false;
62 | }
63 | }
64 |
65 | @Override
66 | protected void onKeyReleased() {
67 | super.onKeyReleased();
68 | this.active = false;
69 | }
70 |
71 | @Override
72 | public boolean isActive() {
73 | return this.active;
74 | }
75 |
76 | public boolean isActiveButNotHandled() {
77 | if (this.hasBeenHandled)
78 | return false;
79 |
80 | return this.active;
81 | }
82 |
83 | public void setHasBeenHandled(boolean hasBeenHandled) {
84 | this.hasBeenHandled = hasBeenHandled;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/framework/input/BooleanStateMouseInputHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2022 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples.framework.input;
26 |
27 | import java.awt.Component;
28 | import java.awt.Point;
29 |
30 | public final class BooleanStateMouseInputHandler extends AbstractMouseInputHandler {
31 | private final Object lock;
32 |
33 | private boolean active;
34 | private Point location;
35 | private boolean hasBeenHandled;
36 |
37 | public BooleanStateMouseInputHandler(Component component, int button) {
38 | super(component, button);
39 | this.lock = new Object();
40 | }
41 |
42 | @Override
43 | protected void onMousePressed(Point point) {
44 | super.onMousePressed(point);
45 | synchronized (this.lock) {
46 | boolean active = this.active;
47 |
48 | this.active = true;
49 | this.location = point;
50 |
51 | // if the state transitioned from inactive to active
52 | // flag that it needs to be handled
53 | if (!active) {
54 | this.hasBeenHandled = false;
55 | }
56 | }
57 | }
58 |
59 | @Override
60 | protected void onMouseRelease() {
61 | this.active = false;
62 | super.onMouseRelease();
63 | }
64 |
65 | @Override
66 | public void setEnabled(boolean flag) {
67 | super.setEnabled(flag);
68 | if (!flag) {
69 | this.clearState();
70 | }
71 | }
72 |
73 | @Override
74 | public void uninstall() {
75 | super.uninstall();
76 | this.clearState();
77 | }
78 |
79 | private void clearState() {
80 | this.active = false;
81 | this.location = null;
82 | this.hasBeenHandled = false;
83 | }
84 |
85 | public Point getMouseLocation() {
86 | synchronized (this.lock) {
87 | return this.location;
88 | }
89 | }
90 |
91 | @Override
92 | public boolean isActive() {
93 | return this.active;
94 | }
95 |
96 | public boolean isActiveButNotHandled() {
97 | if (this.hasBeenHandled)
98 | return false;
99 |
100 | return this.active;
101 | }
102 |
103 | public void setHasBeenHandled(boolean hasBeenHandled) {
104 | this.hasBeenHandled = hasBeenHandled;
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/framework/input/ExportCodeKeyboardInputHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2022 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples.framework.input;
26 |
27 | import java.awt.Component;
28 |
29 | import org.dyn4j.samples.framework.SimulationBody;
30 | import org.dyn4j.world.World;
31 |
32 | public class ExportCodeKeyboardInputHandler extends AbstractKeyboardInputHandler {
33 | private final World world;
34 |
35 | public ExportCodeKeyboardInputHandler(Component component, int key, World world) {
36 | super(component, new Key(key));
37 | this.world = world;
38 | }
39 |
40 | @Override
41 | protected void onKeyPressed() {
42 | super.onKeyPressed();
43 | System.out.println(CodeExporter.export("SampleExport", this.world));
44 | }
45 |
46 | @Override
47 | public boolean isActive() {
48 | return false;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/framework/input/InputHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2022 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples.framework.input;
26 |
27 | import java.util.List;
28 |
29 | public interface InputHandler {
30 | public void install();
31 | public void uninstall();
32 | public boolean isEnabled();
33 | public void setEnabled(boolean flag);
34 | public boolean isActive();
35 |
36 | public List getDependentBehaviors();
37 | public boolean isDependentBehaviorActive();
38 | public boolean isDependentBehaviorsAdditive();
39 | public void setDependentBehaviorsAdditive(boolean flag);
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/framework/input/Key.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2022 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples.framework.input;
26 |
27 | /**
28 | * Represents a key code and modifiers.
29 | * @author William Bittle
30 | * @since 5.0.0
31 | * @version 5.0.0
32 | */
33 | public final class Key {
34 | public final int key;
35 | public final int modifiers;
36 |
37 | public Key(int key) {
38 | this.key = key;
39 | this.modifiers = 0;
40 | }
41 |
42 | public Key(int key, int modifiers) {
43 | this.key = key;
44 | this.modifiers = modifiers;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/framework/input/MousePanningInputHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2022 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples.framework.input;
26 |
27 | import java.awt.Component;
28 | import java.awt.Point;
29 | import java.awt.event.MouseEvent;
30 |
31 | import org.dyn4j.geometry.Vector2;
32 |
33 | public final class MousePanningInputHandler extends AbstractMouseInputHandler implements InputHandler {
34 | private final Object lock;
35 |
36 | private boolean panning;
37 | private Point start;
38 |
39 | private double x;
40 | private double y;
41 |
42 | public MousePanningInputHandler(Component component) {
43 | super(component, MouseEvent.BUTTON1);
44 | this.panning = false;
45 | this.lock = new Object();
46 | }
47 |
48 | @Override
49 | protected void onMousePressed(Point point) {
50 | super.onMousePressed(point);
51 | this.handleMouseStart(point);
52 | }
53 |
54 | @Override
55 | protected void onMouseDrag(Point start, Point current) {
56 | super.onMouseDrag(start, current);
57 | this.handleMouseDrag(current);
58 | }
59 |
60 | @Override
61 | protected void onMouseRelease() {
62 | this.clearPanningState();
63 | super.onMouseRelease();
64 | }
65 |
66 | @Override
67 | public void setEnabled(boolean flag) {
68 | super.setEnabled(flag);
69 | if (!flag) {
70 | this.clearPanningState();
71 | }
72 | }
73 |
74 | @Override
75 | public boolean isActive() {
76 | return this.panning;
77 | }
78 |
79 | @Override
80 | public void uninstall() {
81 | super.uninstall();
82 | this.clearPanningState();
83 | }
84 |
85 | private boolean handleMouseStart(Point start) {
86 | this.panning = true;
87 | this.start = start;
88 | return true;
89 | }
90 |
91 | private boolean handleMouseDrag(Point current) {
92 | this.panning = true;
93 |
94 | double x = current.getX() - this.start.getX();
95 | double y = current.getY() - this.start.getY();
96 |
97 | // input from the mouse should be queued for processing
98 | // to avoid mid-render changes to the camera
99 | // input from AWT is coming in from the main thread of
100 | // AWT, but rendering is performed on a different thread
101 | // as such we should lock on the changes just to be sure
102 | // we don't lose information
103 | synchronized (this.lock) {
104 | this.x += x;
105 | this.y -= y;
106 | }
107 |
108 | this.start = current;
109 |
110 | return true;
111 | }
112 |
113 | private void clearPanningState() {
114 | this.panning = false;
115 | this.start = null;
116 | }
117 |
118 | public Vector2 getOffsetAndReset() {
119 | synchronized (this.lock) {
120 | Vector2 offset = new Vector2(this.x, this.y);
121 | this.x = 0;
122 | this.y = 0;
123 | return offset;
124 | }
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/framework/input/MousePickingInputHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2022 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples.framework.input;
26 |
27 | import java.awt.Component;
28 | import java.awt.Point;
29 | import java.awt.event.MouseEvent;
30 | import java.util.Iterator;
31 |
32 | import org.dyn4j.dynamics.BodyFixture;
33 | import org.dyn4j.dynamics.joint.Joint;
34 | import org.dyn4j.dynamics.joint.PinJoint;
35 | import org.dyn4j.geometry.AABB;
36 | import org.dyn4j.geometry.Vector2;
37 | import org.dyn4j.samples.framework.Camera;
38 | import org.dyn4j.samples.framework.SimulationBody;
39 | import org.dyn4j.world.World;
40 | import org.dyn4j.world.result.DetectResult;
41 |
42 | public class MousePickingInputHandler extends AbstractMouseInputHandler implements InputHandler {
43 | private final Object lock;
44 | private final Camera camera;
45 | private final World world;
46 |
47 | // state maintained by the main thread
48 | private boolean dragging;
49 | private Vector2 point;
50 | private SimulationBody body;
51 |
52 | // state maintained by the render thread
53 | private Joint mouseHandle;
54 |
55 | public MousePickingInputHandler(Component component, Camera camera, World world) {
56 | super(component, MouseEvent.BUTTON1);
57 | this.lock = new Object();
58 | this.camera = camera;
59 | this.world = world;
60 | }
61 |
62 | @Override
63 | protected void onMousePressed(Point point) {
64 | super.onMousePressed(point);
65 | this.handleMouseStartOrDrag(point);
66 | }
67 |
68 | @Override
69 | protected void onMouseDrag(Point start, Point current) {
70 | super.onMouseDrag(start, current);
71 | this.handleMouseStartOrDrag(current);
72 | }
73 |
74 | @Override
75 | protected void onMouseRelease() {
76 | this.onReleaseCleanUp();
77 | super.onMouseRelease();
78 | }
79 |
80 | @Override
81 | public void setEnabled(boolean flag) {
82 | super.setEnabled(flag);
83 | if (!flag) {
84 | this.onReleaseCleanUp();
85 | }
86 | }
87 |
88 | @Override
89 | public boolean isActive() {
90 | return this.dragging;
91 | }
92 |
93 | @Override
94 | public void uninstall() {
95 | super.uninstall();
96 | this.onReleaseCleanUp();
97 | }
98 |
99 | private boolean handleMouseStartOrDrag(Point point) {
100 | Vector2 p = this.camera.toWorldCoordinates(this.component.getWidth(), this.component.getHeight(), point);
101 |
102 | synchronized (this.lock) {
103 | this.point = p;
104 |
105 | if (!this.dragging) {
106 | SimulationBody body = this.getBodyAt(p);
107 | if (body != null) {
108 | this.dragging = true;
109 | this.body = body;
110 | return true;
111 | }
112 | } else {
113 | return true;
114 | }
115 | }
116 |
117 | return false;
118 | }
119 |
120 | private void onReleaseCleanUp() {
121 | synchronized (this.lock) {
122 | this.point = null;
123 | this.body = null;
124 | this.dragging = false;
125 | }
126 | }
127 |
128 | public SimulationBody getBody() {
129 | if (this.mouseHandle != null) {
130 | return this.mouseHandle.getBody(0);
131 | }
132 | return null;
133 | }
134 |
135 | private SimulationBody getBodyAt(Vector2 p) {
136 | SimulationBody body = null;
137 |
138 | // detect bodies under the mouse pointer
139 | AABB aabb = new AABB(new Vector2(p.x, p.y), 0.0001);
140 | Iterator> it = this.world.detectIterator(aabb, null);
141 | while (it.hasNext()) {
142 | SimulationBody b = it.next().getBody();
143 |
144 | // ignore infinite bodies
145 | if (b.getMass().isInfinite()) {
146 | continue;
147 | }
148 |
149 | // check point contains and take the first
150 | // one found
151 | if (b.contains(p)) {
152 | body = b;
153 | break;
154 | }
155 | }
156 |
157 | return body;
158 | }
159 |
160 | private Joint createControlJoint(SimulationBody body, Vector2 p) {
161 | PinJoint pj = new PinJoint(body, new Vector2(p.x, p.y));
162 | pj.setSpringEnabled(true);
163 | pj.setSpringFrequency(4.0);
164 | pj.setSpringDamperEnabled(true);
165 | pj.setSpringDampingRatio(0.3);
166 | pj.setMaximumSpringForceEnabled(true);
167 | pj.setMaximumSpringForce(500);
168 | return pj;
169 | }
170 |
171 | public void updateMousePickingState() {
172 | boolean dragging = false;
173 | Vector2 point = null;
174 | SimulationBody body = null;
175 |
176 | synchronized (this.lock) {
177 | dragging = this.dragging;
178 | point = this.point;
179 | body = this.body;
180 | }
181 |
182 | // 1. mouse picking begins
183 | if (dragging && this.mouseHandle == null && point != null) {
184 | // create a joint with the body
185 | Joint joint = this.createControlJoint(body, point);
186 | this.mouseHandle = joint;
187 | this.world.addJoint(joint);
188 | this.onPickingStart(body);
189 | return;
190 | }
191 |
192 | // 2. mouse picking continues
193 | if (dragging && this.mouseHandle != null && point != null) {
194 | Joint joint = this.mouseHandle;
195 | if (joint instanceof PinJoint) {
196 | PinJoint> pj = (PinJoint>)joint;
197 | pj.setTarget(new Vector2(point.x, point.y));
198 | }
199 | return;
200 | }
201 |
202 | // 3. mouse picking ends
203 | if (!dragging) {
204 | if (this.mouseHandle != null) {
205 | this.world.removeJoint(this.mouseHandle);
206 | this.onPickingEnd(body);
207 | }
208 | this.mouseHandle = null;
209 | return;
210 | }
211 | }
212 |
213 | public void onPickingStart(SimulationBody body) {
214 |
215 | }
216 |
217 | public void onPickingEnd(SimulationBody body) {
218 |
219 | }
220 | }
221 |
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/framework/input/MouseZoomInputHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2022 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples.framework.input;
26 |
27 | import java.awt.Component;
28 |
29 | public final class MouseZoomInputHandler extends AbstractMouseInputHandler implements InputHandler {
30 | private final Object lock;
31 |
32 | private double scale;
33 |
34 | public MouseZoomInputHandler(Component component, int button) {
35 | super(component, button);
36 | this.lock = new Object();
37 | this.scale = 1.0;
38 | }
39 |
40 | @Override
41 | public boolean isActive() {
42 | return false;
43 | }
44 |
45 | @Override
46 | protected void onMouseWheel(double rotation) {
47 | super.onMouseWheel(rotation);
48 |
49 | // this happen sometimes on trackpads
50 | if (rotation == 0)
51 | return;
52 |
53 | // input from the mouse should be queued for processing
54 | // to avoid mid-render changes to the camera
55 | // input from AWT is coming in from the main thread of
56 | // AWT, but rendering is performed on a different thread
57 | // as such we should lock on the changes just to be sure
58 | // we don't lose information
59 | synchronized (this.lock) {
60 | if (rotation > 0) {
61 | this.scale *= 0.8;
62 | } else {
63 | this.scale *= 1.2;
64 | }
65 | }
66 | }
67 |
68 | public double getScaleAndReset() {
69 | synchronized (this.lock) {
70 | double scale = this.scale;
71 | this.scale = 1.0;
72 | return scale;
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/framework/input/ToggleStateKeyboardInputHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2022 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 | package org.dyn4j.samples.framework.input;
26 |
27 | import java.awt.Component;
28 |
29 | public class ToggleStateKeyboardInputHandler extends AbstractKeyboardInputHandler {
30 |
31 | private boolean active;
32 |
33 | public ToggleStateKeyboardInputHandler(Component component, Key... keys) {
34 | super(component, keys);
35 | this.active = false;
36 | }
37 |
38 | public ToggleStateKeyboardInputHandler(Component component, int... keys) {
39 | super(component, keys);
40 | this.active = false;
41 | }
42 |
43 | @Override
44 | protected void onKeyPressed() {
45 | super.onKeyPressed();
46 | this.active = !this.active;
47 | }
48 |
49 | public void setActive(boolean flag) {
50 | this.active = flag;
51 | }
52 |
53 | @Override
54 | public boolean isActive() {
55 | return this.active;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2016 William Bittle http://www.dyn4j.org/
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted
6 | * provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this list of conditions
9 | * and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 | * and the following disclaimer in the documentation and/or other materials provided with the
12 | * distribution.
13 | * * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
14 | * promote products derived from this software without specific prior written permission.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 |
26 | /**
27 | * A package containing sample applications to accelerate getting started.
28 | * @author William Bittle
29 | * @since 3.2.0
30 | * @version 3.2.0
31 | */
32 | package org.dyn4j.samples;
33 |
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/resources/Basketball.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dyn4j/dyn4j-samples/747a479d3a0059f73a4de62d33b6003d387d933e/src/main/java/org/dyn4j/samples/resources/Basketball.png
--------------------------------------------------------------------------------
/src/main/java/org/dyn4j/samples/resources/Crate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dyn4j/dyn4j-samples/747a479d3a0059f73a4de62d33b6003d387d933e/src/main/java/org/dyn4j/samples/resources/Crate.png
--------------------------------------------------------------------------------