@Override
public void handle(ActionEvent event) {
draw(gc);
update();
}
});
mTimeline.getKeyFrames().add(frame);
mTimeline.play();
}
public void initObjects(){
createPolygon(10, 500, (int) getWidth() - 10 * 2, 10, 0.3f, 0.6f, true);
createPolygon(10, 10, 10, 500, 0.3f, 0.6f, true);
createPolygon((int) getWidth() - 10 * 2, 10, 10, 500, 0.3f, 0.6f, true);
float restitution[] = new float[] { 0.9f, 0.9f, 0.9f, 0.9f, 0.75f, 0.9f, 1.0f, 0.6f, 0.8f, 0.4f, 0.9f, 0.9f,
0.9f, 0.9f, 0.75f, 0.9f, 1.0f, 0.6f, 0.8f, 0.4f, 0.9f, 0.9f, 0.9f, 0.9f, 0.75f, 0.9f, 1.0f, 0.6f, 0.8f,
0.4f, 0.9f, 0.9f, 0.9f, };
for (int i = 0; i < restitution.length; i++) {
createCircle(80 + i * 20, 5 * i, 15, 0.3f, restitution[i], false);
}
}
public void draw(GraphicsContext gc) {
gc.clearRect(0, 0, getWidth(), getHeight());
gc.setFill(Color.BLACK);
gc.fillRect(0, 0, getWidth(), getHeight());
for(WBody mBody : bodys){
mBody.draw(gc);
}
}
public void update() {
for(WBody body : bodys){
body.update();
}
world.step(1.0f / 60.0f, 8, 3);
}
/**
* 创建矩形
*/
public void createPolygon(float x, float y, float w, float h, float friction, float restitution, boolean isStatic) {
// 创建多边形皮肤
PolygonShape shape = new PolygonShape();
shape.setAsBox(w / 2 / RATE, h / 2 / RATE);
FixtureDef fd = new FixtureDef();
fd.shape = shape;
fd.density = 1.0f; // 设置密度
fd.friction = friction; // 设置摩擦力
fd.restitution = restitution; // 设置多边形的恢复力
// 设置刚体初始坐标
bd.type = isStatic BodyType.STATIC : BodyType.DYNAMIC;
bd.position.set((x + w / 2) / RATE, (y + h / 2) / RATE);
// 创建物体
Body body = world.createBody(bd); // 物理世界创建物体
// 此方法改变了
// body.createShape(pDef); //为body添加皮肤
body.createFixture(fd);
WBoxBody boxBody = new WBoxBody(w, h, body, Color.WHITE);
boxBody.setLocation(x, y);
bodys.add(boxBody);
}
/**
* 创建圆形
*/
public void createCircle(float x, float y, float r, float friction, float restitution, boolean isStatic) {
CircleShape shape = new CircleShape();
shape.m_radius = r / RATE;
FixtureDef fd = new FixtureDef();
fd.shape = shape;
fd.density = 1.0f;
fd.friction = friction;
fd.restitution = restitution;
// 创建刚体
bd.type = isStatic BodyType.STATIC : BodyType.DYNAMIC;
bd.position.set((x + r) / RATE, (y + r) / RATE);
// 创建一个body
Body body = world.createBody(bd);
body.createFixture(fd);
WCircleBody circleBody = new WCircleBody(body, r, Color.RED);
circleBody.setLocation(x, y);
bodys.add(circleBody);
}
}
在这个CanvasScreen里,主要做了以下几个操作。
1.创建了JBox2D的世界World
2.创建了一个Timeline,增加了一个Keyframe,通过无限循环来模拟游戏的更新操作。
3.通过createPolygon和createCircle来创建Body并初始化WBody元素。这里需要注意Body的position为中心位置,而我们绘制的Object是以左上为position,需要自行处理一下。还有就是屏幕与世界的比例RATE,在进行position的时候的处理。
4.在keyframe中,绘制WBody列表并在update中更新WBody列表。
5.更新World,我们在update中world.step(...)进行更新JBox的World里的物理变化。如果没有world.step,所有的物理操作将无法进行。
接下来是我们的主类。
[java]
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class MainClass extends Application {
private static final int WIDTH = 800;
private static final int HEIGHT = 600;
@Override
public void start(Stage primaryStage) {
CanvasScreen mCanvas = new CanvasScreen(WIDTH, HEIGHT);
Group root = new Group();
root.getChildren().add(mCanvas);