欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JavaFx-物理引擎 (dyn4j) 教程 §1简介与前期准备

程序员文章站 2024-02-06 23:38:10
...

1.dyn4j简介

dyn4j (dynamic for java) 是github上的大佬William Bittle开发的一款2D物理引擎。(介绍就是这么草率,想看更详细的可以去官网 )

官网首页:
JavaFx-物理引擎 (dyn4j) 教程 §1简介与前期准备

2.教程概述

这个系列的教程,不出意外的话,将会带大家了解dyn4j物理引擎的运作方式各个类和方法的使用一些特性,并根据需要进行封装,最终使用JavaFx做成一个可视化的物理引擎。由于国内外有关这款物理引擎的资源极少,本教程可能会有讲得不详细的地方,但对最终效果影响不大。

3.前期准备

首先你得会Java,最好也了解一下JavaFx。然后有高中物理知识的基础就更好啦!
本教程将使用Java8 64位,编辑器是MyEclipse,以及dyn4j 4.0.0(下载地址)。dyn4j是纯Java开发的,因此只需要在工程中导入jar包就可以使用,Java9及以上版本可以根据需求添加Module-info.java,具体的配置方法不在此赘述。
为了方便后续教程,请创建如下项目结构:
JavaFx-物理引擎 (dyn4j) 教程 §1简介与前期准备
Main类将作为程序入口,Simulation类将主要负责管理物理引擎。两个java文件如下:
Main.java:

package com.application;

public class Main {
	public static void main(String[] args) {
		
	}
}

Simulation.java:

package com.physics;

public class Simulation {
	
}

没错,啥都没有,成功水了几行教程。
如果你想验证你的项目中dyn4j是否导入成功,可以尝试将Main类改成:

package com.application;

import org.dyn4j.dynamics.Body;
import org.dyn4j.world.World;

public class Main {
	public static void main(String[] args) {
		World<Body> world=new World<Body>();//暂时不需要理解这行代码
	}
}

不报错的话你就成功了嗷!

4.Get Started!!!

水了那么多字,终于可以开始写代码了。 我们将通过一个案例来熟悉dyn4j物理引擎的基本逻辑。
案例要求:创建一个小球,使之做*落体运动。创建一个地面,使小球落在地面上。以0.1秒为间隔输出小球的高度(无需实时输出)。
因为大家现在还啥都没学,我将直接给出代码,对照代码进行讲解。

package com.application;

import org.dyn4j.dynamics.Body;
import org.dyn4j.geometry.Ellipse;
import org.dyn4j.geometry.MassType;
import org.dyn4j.geometry.Rectangle;
import org.dyn4j.geometry.Vector2;
import org.dyn4j.world.World;

public class Main {
	public static void main(String[] args) {
		
		/*------创建世界------*/
		World<Body> world=new World<Body>();//创建世界
		world.setGravity(new Vector2(0,-10));//重力加速度设为10m·s^(-2)
		//以下是另外两种写法
		// world.setGravity(0,-10);
		// world.setGravity(Vector2.create(10,-Math.PI/2));
		world.getSettings().setStepFrequency(0.001);//设置步频,两次计算间隔1毫秒
		/*------创建世界------*/
		
		/*------创建实体------*/
		Body ball=new Body();//创建容器存放小球
		ball.addFixture(new Ellipse(0.1,0.1));//创建小球并加入容器,宽高均为0.1m,即半径0.05m
		ball.getTransform().setTranslationY(10);//将小球的Y坐标设为10m
		ball.setMass(MassType.NORMAL);//自动计算小球的质量
		
		Body ground=new Body();//同样的方法创建地面
		ground.addFixture(new Rectangle(100,0.1));//地面是一个长方形,宽100m,高0.1m
		ground.getTransform().setTranslationY(-0.05);//将地面下移0.05m,保证地面上沿的Y坐标为0
		ground.setMass(MassType.INFINITE);//将质量设为无穷大,即不会发生位移或旋转
		
		world.addBody(ball);//将刚才创建的两个Body加入世界
		world.addBody(ground);
		/*------创建实体------*/
		
		/*------模拟------*/
		double oldValue=-1,cur;
		while(true) {
			
			world.step(100);//步进100,刚才设置了步频是0.001s,计算100次就相当于过了0.1s
			
			cur=ball.getTransform().getTranslationY();//获取小球Y坐标,即高度
			
			if(cur==oldValue) break;//如果新的高度等于旧的高度,说明小球停止运动,结束程序
			oldValue=cur;//更新旧高度
			
			System.out.printf("%fm\n",cur);//按要求输出
		}
		/*------模拟------*/
	}
}

以上代码的输出结果:

9.949500m
9.799000m
9.548500m
9.198000m
8.747500m
8.197000m
7.546500m
6.796000m
5.945500m
4.995000m
3.944500m
2.794000m
1.543500m
0.193000m
0.045000m

可以发现一共输出15次,通过高中物理知识即可简单验证,这个结果是正确的。


以上就是这个案例的完整代码,建议先尝试理解代码,再看以下内容。

以上代码中,在模拟之前我们创建了这样一个世界:
JavaFx-物理引擎 (dyn4j) 教程 §1简介与前期准备这图是PPT画的

通过代码,我们可以了解到dyn4j的一些基本逻辑:
(了解即可,不必完全掌握)

所有的模拟都要在World中进行,也就是说,一个World对象管理一个模拟,其中包括一些参数,比如上面代码中的重力加速度,以及后面要讲到的精度等乱七八糟的零碎信息。所有的Body也要通过World的addBody方法加入到世界中,才能被模拟。
事实上,World类中还可以加入Joint,用来关联、约束实体,还可以加入碰撞检测等监听器以实现更多功能,如果有机会将在后续教程中讲解。

Body是一个实体,它拥有形状、尺寸、质量、位置等物理性质。一个Body对象中需要通过addFixture方法加入BodyFixture对象 (上面代码中,Rectangle和Ellipse类均继承自BodyFixture),才会生效。
我们可以这样理解:Body本质上是一个容器,一个Body对象中可以加入若干个BodyFixture对象,这些BodyFixture对象就像零件一样,共同组成一个实体,因此说Body是一个实体也没错。
细心的同学可以发现,当你敲出addFixture这个方法名时,代码补全会提示你两类方法(不会有哪个狠人用记事本写代码吧?不会吧不会吧? ),一类是传入BodyFixture对象,另一类是传入Convex对象,即凸多边形(这个物理引擎不支持凹多边形)。本教程中不会讲解Convex类,但相信在大家学过BodyFixture类之后,可以自己通过文档等手段掌握Convex的使用方法!

dyn4j中有平面向量这个概念,由Vector2类实现。你可以在上面代码中设置重力加速度的位置,找到两种创建Vector2对象的方法。第一种是new Vector2(x值, y值),第二种是调用 Vector2.create(大小,方向) 这个静态方法。其中方向是弧度制,且 -π≤方向≤π。坐标、力、多边形等功能的实现都离不开Vector2,你不必现在就理解Vector2。

如果你看到这里,恭喜你,这篇教程你看完了!!!
建议尝试一下模拟方块的*落体,可以翻翻文档之类的,看看如何给方块加一个初始的角度等,反正电脑在你手里,多尝试一些东西不好玩么?
你可能会觉得以上内容晦涩难懂,这很正常,因为我们还没有写UI,全靠想象。不出意外下篇教程我就会写UI啦!

如果看得人多,我会出下一期的!创作不易,希望有经济能力的话可以打赏一波!
JavaFx-物理引擎 (dyn4j) 教程 §1简介与前期准备
JavaFx-物理引擎 (dyn4j) 教程 §1简介与前期准备