FXGL 攻略 02.组件
在FXGL中,实体的各种功能和表现都通过组件来进行实现。这很好理解,一个汽车实体,通过添加移动组件来使之具有移动能力,添加物理组件来监听碰撞效果等。
- 创建一个组件
新建一个moveComponent 作为飞机的移动功能组件。编写这个组件前,我们需要理解一个新的概念坐标。
移动的本质是在每次游戏刷新时将实体坐标更新,我们可以通过改变在X轴与Y轴的速度来作为每次游戏刷新时移动的坐标。对此可以写出
public class MoveComponent extends Component {
private double speedX = 0d;
private double speedY = 0d;
private double maxSpeed = 4d;
@Override
public void onUpdate(double tpf) {
if (speedX != 0d) {
//计算出该速度在x轴上每次刷新移动后的坐标
Vec2 dir = Vec2.fromAngle(entity.getRotation() - 360)
.mulLocal(speedX);
//改变实体的坐标
entity.translate(dir);
}
if (speedY != 0d) {
Vec2 dir = Vec2.fromAngle(entity.getRotation() - 90)
.mulLocal(speedY);
entity.translate(dir);
}
}
}
- 为组件添加方法
我们上面已经写好了一个可以在更新时移动的方法,那么接下来就需要将其扩展,我们知道我们需要有向上移动,向下移动,向左移动,向右移动等在移动中的方法。还需要有一个停止方法。
public class MoveComponent extends Component {
private double speedX = 0d;
private double speedY = 0d;
private double maxSpeed = 4d;
@Override
public void onUpdate(double tpf) {
if (speedX != 0d) {
Vec2 dir = Vec2.fromAngle(entity.getRotation() - 360)
.mulLocal(speedX);
entity.translate(dir);
}
if (speedY != 0d) {
Vec2 dir = Vec2.fromAngle(entity.getRotation() - 90)
.mulLocal(speedY);
entity.translate(dir);
}
}
public void up() {
speedY = maxSpeed;
}
public void left() {
speedX = -maxSpeed;
}
public void right() {
speedX = maxSpeed;
}
public void down(){
speedY = -maxSpeed;
}
public void stop() {
speedX = 0d;
speedY = 0d;
}
}
- 将组件绑定至实体
修改实体工厂类,注意,我们给实体的新增了移动组件以外,我们还为其新增了一个type属性,方便后面获取。
/**
1. 实体静态工厂
*/
public class CustomerEntityFactory {
public static Entity createEntity(EntityType type){
switch (type) {
case PLANE -> {
Entity entity = FXGL.entityBuilder().view("player.png").with(new MoveComponent()).build();
entity.setType(EntityType.PLANE);
return entity;
}
default -> {
return null;
}
}
}
}
- 接下来是测试阶段,注意,按钮绑定将在下一章详细讲解,这里只做展示。修改主程序。
public class GameApp extends GameApplication {
/**
* Initialize game objects.
*/
@Override
protected void initGame() {
FXGL.getGameWorld().addEntity(CustomerEntityFactory.createEntity(EntityType.PLANE));
FXGL.getInput().addAction(new UserAction("up") {
@Override
protected void onAction() {
super.onAction();
}
@Override
protected void onActionBegin() {
List<Entity> entitiesByType = FXGL.getGameWorld().getEntitiesByType(EntityType.PLANE);
entitiesByType.get(0).getComponent(MoveComponent.class).up();
}
@Override
protected void onActionEnd() {
List<Entity> entitiesByType = FXGL.getGameWorld().getEntitiesByType(EntityType.PLANE);
entitiesByType.get(0).getComponent(MoveComponent.class).stop();
}
}, KeyCode.W);
FXGL.getInput().addAction(new UserAction("down") {
@Override
protected void onAction() {
super.onAction();
}
@Override
protected void onActionBegin() {
List<Entity> entitiesByType = FXGL.getGameWorld().getEntitiesByType(EntityType.PLANE);
entitiesByType.get(0).getComponent(MoveComponent.class).down();
}
@Override
protected void onActionEnd() {
List<Entity> entitiesByType = FXGL.getGameWorld().getEntitiesByType(EntityType.PLANE);
entitiesByType.get(0).getComponent(MoveComponent.class).stop();
}
}, KeyCode.S);
FXGL.getInput().addAction(new UserAction("left") {
@Override
protected void onAction() {
super.onAction();
}
@Override
protected void onActionBegin() {
List<Entity> entitiesByType = FXGL.getGameWorld().getEntitiesByType(EntityType.PLANE);
entitiesByType.get(0).getComponent(MoveComponent.class).left();
}
@Override
protected void onActionEnd() {
List<Entity> entitiesByType = FXGL.getGameWorld().getEntitiesByType(EntityType.PLANE);
entitiesByType.get(0).getComponent(MoveComponent.class).stop();
}
}, KeyCode.A);
FXGL.getInput().addAction(new UserAction("right") {
@Override
protected void onAction() {
super.onAction();
}
@Override
protected void onActionBegin() {
List<Entity> entitiesByType = FXGL.getGameWorld().getEntitiesByType(EntityType.PLANE);
entitiesByType.get(0).getComponent(MoveComponent.class).right();
}
@Override
protected void onActionEnd() {
List<Entity> entitiesByType = FXGL.getGameWorld().getEntitiesByType(EntityType.PLANE);
entitiesByType.get(0).getComponent(MoveComponent.class).stop();
}
}, KeyCode.D);
}
@Override
protected void initSettings(GameSettings settings) {
settings.setTitle("demo");
settings.setHeight(720);
settings.setWidth(1080);
}
public static void main(String[] args) {
launch(args);
}
}
运行一下! 这个飞机它会动啦!