PS:禁止拷贝形式转载,转载请以URL形式
PS:FXGL 准备写成一个系列,所以在该系列未完成前,该系列文章除了目录会被修改其他内容均可能被删改。
1. 简介
本章介绍如何将实体添加到物理世界中并如何添加处理其物理碰撞事件
2. 添加物理世界
view():将实体添加到视图场景并标识其大小和形状bbox():将实体添加到物理世界并标识其大小和形状
FXGL.entityBuilder()
.view(new Rectangle(20, 20, Color.AQUA))
.bbox(BoundingShape.box(20,20))
.buildAndAttach();
上述代码可以简写为
viewWithBBox():将实体添加到视图场景和物理世界中并标识其大小和形状
FXGL.entityBuilder()
.at(FXGL.getAppCenter())
.viewWithBBox(new Rectangle(20, 20, Color.AQUA))
.buildAndAttach();
3. 物理对象调试
setDeveloperMenuEnabled(boolean enable):开启时,按键1打开开发者菜单
@Override
protected void initSettings(GameSettings gameSettings) {
gameSettings.setDeveloperMenuEnabled(true);
}
调试:实体添加到物理世界但是没有添加到场景中时,
public class PhysicsWorldApp extends GameApplication {
@Override
protected void initSettings(GameSettings gameSettings) {
gameSettings.setDeveloperMenuEnabled(true);
}
@Override
protected void initGame() {
FXGL.entityBuilder()
.at(FXGL.getAppCenter())
//.view(new Rectangle(20, 20, Color.AQUA))
.bbox(BoundingShape.box(20,20))
//.viewWithBBox(new Rectangle(20, 20, Color.AQUA))
.buildAndAttach();
}
public static void main(String[] args) {
launch(args);
}
}
调试:实体添加到物理世界和游戏场景中但是物理世界位置和游戏场景的位置不一致
HitBox(Point2D orgin,BoundingShape shape):orgin 该物理世界下物体偏移坐标,shape 物理世界下的形状大小
public class PhysicsWorldApp extends GameApplication {
@Override
protected void initSettings(GameSettings gameSettings) {
gameSettings.setDeveloperMenuEnabled(true);
}
@Override
protected void initGame() {
FXGL.entityBuilder()
.at(FXGL.getAppCenter())
.view(new Rectangle(20, 20, Color.AQUA))
.bbox(new HitBox(new Point2D(20,20),BoundingShape.box(20,20)))
.buildAndAttach();
}
public static void main(String[] args) {
launch(args);
}
}
2. 简单碰撞
一个实体代表一个物理形状与其他添加到物理世界中实体的碰撞处理
type():设置实体类型,用于物理碰撞检测的必要条件viewWithBBox():设置游戏场景以及物理对象大小和形状。必须设置BBox其物理世界下的形状大小,用于物理碰撞检测的必要条件collidable():可碰撞。用于物理碰撞检测的必要条件
public class PhysicsWorldApp extends GameApplication {
public enum Type {
BLUE, RED;
}
Entity blue;
@Override
protected void initSettings(GameSettings gameSettings) {
gameSettings.setDeveloperMenuEnabled(true);
}
@Override
protected void initInput() {
FXGL.onKey(KeyCode.LEFT, () -> blue.translateX(-3));
FXGL.onKey(KeyCode.RIGHT, () -> blue.translateX(3));
}
@Override
protected void initGameVars(Map<String, Object> vars) {
vars.put("status", "未接触");
}
@Override
protected void initGame() {
FXGL.entityBuilder()
.at(FXGL.getAppCenter())
.type(Type.RED)
.viewWithBBox(new Rectangle(20, 20, Color.RED))
.collidable()
.buildAndAttach();
blue = FXGL.entityBuilder()
.at(FXGL.getAppCenter().getX() + 50, FXGL.getAppCenter().getY())
.type(Type.BLUE)
.viewWithBBox(new Rectangle(20, 20, Color.BLUE))
.collidable()
.buildAndAttach();
}
@Override
protected void initPhysics() {
FXGL.getPhysicsWorld().addCollisionHandler(new CollisionHandler(Type.RED, Type.BLUE) {
@Override
protected void onCollisionBegin(Entity a, Entity b) {
FXGL.set("status", "已接触");
}
@Override
protected void onCollisionEnd(Entity a, Entity b) {
FXGL.set("status", "未接触");
}
});
}
@Override
protected void initUI() {
Text text = FXGL.getUIFactoryService().newText("", Color.BLACK, 22);
text.textProperty().bind(FXGL.getWorldProperties().stringProperty("status"));
FXGL.addUINode(text, FXGL.getAppCenter().getX(), 22);
}
public static void main(String[] args) {
launch(args);
}
}
3. 复杂碰撞
一个实体包含多个物理形状与其他物理实体的碰撞处理
onHitBoxTrigger():判断触碰的具体是哪一个HitBox物理模型- PS:如果已经接触到了
upBox没有离开所属实体再去触碰downBox是不会触发onHitBoxTrigger事件的
public class PhysicsWorld2App extends GameApplication {
public enum Type {
BLUE, RED;
}
Entity blue;
@Override
protected void initSettings(GameSettings gameSettings) {
}
@Override
protected void initInput() {
FXGL.onKey(KeyCode.LEFT, () -> blue.translateX(-3));
FXGL.onKey(KeyCode.RIGHT, () -> blue.translateX(3));
FXGL.onKey(KeyCode.UP, () -> blue.translateY(-3));
FXGL.onKey(KeyCode.DOWN, () -> blue.translateY(3));
}
@Override
protected void initGameVars(Map<String, Object> vars) {
vars.put("status", "未接触");
}
@Override
protected void initGame() {
Rectangle up = new Rectangle(20, 60, Color.BLACK);
Rectangle down = new Rectangle(20, 60, Color.BROWN);
down.setTranslateY(60);
HitBox upBox = new HitBox("up", BoundingShape.box(20, 60));
HitBox downBox = new HitBox("down", new Point2D(0, 60), BoundingShape.box(20, 60));
FXGL.entityBuilder()
.at(FXGL.getAppCenter().getX() + 100, FXGL.getAppCenter().getY())
.type(Type.RED)
.view(up)
.view(down)
.bbox(upBox)
.bbox(downBox)
.collidable()
.buildAndAttach();
blue = FXGL.entityBuilder()
.at(FXGL.getAppCenter().getX() + 50, FXGL.getAppCenter().getY())
.type(Type.BLUE)
.viewWithBBox(new Rectangle(20, 20, Color.BLUE))
.collidable()
.buildAndAttach();
}
@Override
protected void initPhysics() {
FXGL.getPhysicsWorld().addCollisionHandler(new CollisionHandler(Type.RED, Type.BLUE) {
@Override
protected void onHitBoxTrigger(Entity a, Entity b, HitBox boxA, HitBox boxB) {
FXGL.set("status", "击中了" + boxA.getName());
}
});
}
@Override
protected void initUI() {
Text text = FXGL.getUIFactoryService().newText("", Color.BLACK, 22);
text.textProperty().bind(FXGL.getWorldProperties().stringProperty("status"));
FXGL.addUINode(text, FXGL.getAppCenter().getX(), 22);
}
public static void main(String[] args) {
launch(args);
}
}