上文中,我们已经完成了一个地图,游戏角色,角色的移动,ui,场景切换等等功能。看似已经完成了一个游戏的大部分内容。似乎具备了对一个游戏开发的能力。但是实际上,我们的游戏角色和游戏地图间并不具备交互能力。换言之,我们没发知道我们的组件是否触碰在了一起,是否发生了交互。
当我们能够真正使用碰撞事件的时候,就能完成很多神奇的功能。比如刀砍到敌人,如何判定砍到人。比如进入商店区(可以购买商品,交接任务)。比如和一个npc对话。都需要碰撞事件监听。接下来我将为你展示如何为你的游戏添加碰撞事件。
1.源码解析:
核心类1:BoundingBoxComponent
此组件为实体添加一个碰撞盒子(模型池)
核心类2:CollidableComponent
此组件为实体添加碰撞监控
核心类3:HitBox
此类为碰撞盒子,可以规定模型在物理世界上的碰撞范围。
核心类4: CollisionHandler
碰撞时触发事件类,可以继承重写其中的触发事件,并且替换实体中的默认触发事件类。
2.实现
1.在实体工厂中增加两个实体的创建逻辑,我为他们增加了半径12的触发碰撞盒子,同时开启了碰撞事件监听。
@Spawns("player")
public Entity player(SpawnData data) {
Entity entity = FXGL.entityBuilder(data)
.type(EntityType.PLANE)
.with(new MoveComponent())
.bbox(new HitBox(new Point2D(0,0) , BoundingShape.circle(12)))
.collidable()
.build();
return entity;
}
@Spawns("npc")
public Entity npc(SpawnData data) {
ImageView imageView = new ImageView("assets/textures/player-drawing.png");
imageView.setFitHeight(64);
imageView.setFitWidth(64);
Entity entity = FXGL.entityBuilder(data)
.type(EntityType.NPC)
.view(imageView)
.bbox(new HitBox(new Point2D(0, 0) , BoundingShape.circle(40)))
.collidable()
.build();
return entity;
}
2.继承CollisionHandler,编写 PlayerCollisionHandler
public class PlayerCollisionHandler extends CollisionHandler {
/**
* 基类需要提供有参构造。制定两个实体类型
*/
public PlayerCollisionHandler() {
super(EntityType.PLANE, EntityType.NPC);
}
/**
* 初次碰撞时触发
*/
@Override
protected void onCollisionBegin(Entity player, Entity btn) {
//模拟点击按键p
FXGL.getInput().mockKeyPress(KeyCode.P);
}
}
在app类中重写方法,初始化物理
/**
* 初始化物理事件
*/
@Override
protected void initPhysics() {
FXGL.getPhysicsWorld().addCollisionHandler(new PlayerCollisionHandler());
}
当接近人物时,触发弹窗事件!
当然,我们可以稍稍修改此处,增加一个新的ui提示。并且改用增加点击事件的方式让交互更加具有动感。
靠近时在人物上方显示一个问号,并且添加给任务右键触发聊天框事件。离开时移除问号,并且移除右键点击事件。
具体代码将会在后续优化中发布(最近有点忙,更新可能会比较慢。)
您的支持是我最大的动力,如果有什么疑问,欢迎在评论区指出。如果觉得不错,请点个赞吧~