JBox2D和JavaFX:事件与力量

本文介绍如何在JBox2D和JavaFX中创建关节,如RevoluteJoint,将物体约束在一起,并在用户按键时施加力以控制动态Box的行为。示例展示了关节如何阻止Box掉落并限制其运动。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在昨天的示例中,您看到了如何创建一个简单的世界并使用WorldView进行显示,以及如何提供自定义渲染器。 现在,我们将添加一些用户输入。 我们将创建一个类似于弹球机中的鳍状肢的控件。

为此,我们将创建一个关节。 在JBox2D中,关节用于将物体约束到世界或彼此约束。 我们将创建一个静态圆形的Body,它将用作我们的鳍状肢的轴,并通过RevoluteJoint将Box绑定到它。

为了简化代码,我们首先定义一个JointBuilder基类和一个RevoluteJointBuilder:

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:

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-Example:

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();
 }
}

这将显示我们的场景,您将看到关节如何防止动态Box掉落到地面以及如何限制其运动。

下一步是允许用户对其进行控制。 为此,我们将在用户按下按键时施加力。 在场景实例化之后添加以下内容:

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);
 }

}
 });

现在就这样。 在本教程的下一部分中,我们将做一些更多的自定义渲染,并创建一些不错的自定义节点。

参考:Eppleton博客上,来自我们JCG合作伙伴 Toni Epple的JBox2D和JavaFX的事件和影响


翻译自: https://www.javacodegeeks.com/2012/05/jbox2d-and-javafx-events-and-forces.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值