Для этого мы создадим Джойнт. В JBox2D суставы используются для привязки тел к миру или друг к другу. Мы создадим статическое круглое тело, которое будет служить осью для нашего флиппера, и свяжем с ним ящик с помощью RevoluteJoint.
Чтобы упростить код, мы сначала определим базовый класс JointBuilder и RevoluteJointBuilder:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
public abstract class JointBuilder, T extends JointDef> {protected World world; protected T jointDef;protected JointBuilder(World world, T jointDef) { this.world = world; this.jointDef = jointDef; }public K bodyA(Body a) { jointDef.bodyA = a; return (K) this; }public K bodyB(Body b) { jointDef.bodyB = b; return (K) this; }public K userData(Object userData) { jointDef.userData = userData; return (K) this; }public K type(JointType type) { jointDef.type = type; return (K) this; }public K collideConnected(boolean coco) { jointDef.collideConnected = coco; return (K) this; }public Joint build() { return world.createJoint(jointDef); }} |
А вот RevoluteJointBuilder:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
public class RevoluteJointBuilder extends JointBuilder {public RevoluteJointBuilder(World world, Body a, Body b, Vec2 anchor) { super(world, new RevoluteJointDef()); jointDef.initialize(a, b, anchor); }public RevoluteJointBuilder enableLimit(boolean enable) { jointDef.enableLimit = enable; return this; }public RevoluteJointBuilder enableMotor(boolean motor) { jointDef.enableMotor = motor; return this; }public RevoluteJointBuilder localAnchorA(Vec2 localAnchorA) { jointDef.localAnchorA = localAnchorA; return this; }public RevoluteJointBuilder localAnchorB(Vec2 localAnchorB) { jointDef.localAnchorB = localAnchorB; return this; }public RevoluteJointBuilder lowerAngle(float lowerAngle) { jointDef.lowerAngle = lowerAngle; return this; }public RevoluteJointBuilder maxMotorTorque(float maxMotorTorque) { jointDef.maxMotorTorque = maxMotorTorque; return this; }public RevoluteJointBuilder motorSpeed(float motorSpeed) { jointDef.motorSpeed = motorSpeed; return this; }public RevoluteJointBuilder referenceAngle(float referenceAngle) { jointDef.referenceAngle = referenceAngle; return this; }public RevoluteJointBuilder upperAngle(float upperAngle) { jointDef.upperAngle = upperAngle; return this; }} |
Теперь мы можем изменить наш HelloWorld-пример следующим образом:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
public class HelloWorld extends Application {public static void main(String[] args) { Application.launch(args); }@Override public void start(Stage primaryStage) { World world = new World(new Vec2(0, -2f), true); primaryStage.setTitle("Hello World!"); NodeManager.addCircleProvider(new MyNodeProvider());new CircleBuilder(world).userData("ball").position(0.1f, 4).type(BodyType.DYNAMIC).restitution(1).density(2).radius(.15f).friction(.3f).build(); final Body flipperBody = new BoxBuilder(world).position(0, 2).type(BodyType.DYNAMIC).halfHeight(.02f).halfWidth(.2f).density(2).friction(0).userData("flipper").build(); Vec2 axis = flipperBody.getWorldCenter().add(new Vec2(.21f, 0)); Body axisBody = new CircleBuilder(world).position(axis).type(BodyType.STATIC).build(); new RevoluteJointBuilder(world, flipperBody, axisBody, axis).upperAngle(.6f).lowerAngle(-.6f) .enableMotor(true).enableLimit(true).maxMotorTorque(10f).motorSpeed(0f).build(); Scene scene = new Scene(new WorldView(world, 200, 400, 50), 500, 600);// ground new BoxBuilder(world).position(0, -1f).halfHeight(1).halfWidth(5).build(); primaryStage.setScene(scene ); primaryStage.show(); }} |
Это отобразит нашу сцену, и вы увидите, как сустав предотвращает падение динамического бокса на землю и как он ограничивает его движение.
Следующий шаг — позволить пользователю управлять им. Для этого мы будем применять силу, когда пользователь нажимает клавишу. Добавьте это после создания экземпляра сцены:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
scene.setOnKeyPressed(new EventHandler() {@Override public void handle(KeyEvent ke) {if (ke.getCode() == KeyCode.LEFT) { flipperBody.applyTorque(-15f); }} });scene.setOnKeyReleased(new EventHandler() {@Override public void handle(KeyEvent ke) {if (ke.getCode() == KeyCode.LEFT) { flipperBody.applyTorque(15f); }} }); |
Это все на данный момент. В следующих частях этого урока мы сделаем немного больше пользовательского рендеринга и создадим несколько хороших пользовательских узлов.
Ссылка: События и силы с JBox2D и JavaFX от нашего партнера JCG Тони Эппла в блоге Eppleton .