FXGL 学习笔记二 《Entity的创建方式》

140 阅读4分钟

前言

笔记内容在代码中

实体类型枚举

package com.cah.api.entity;

/**
 * <p> 实体类型枚举 </p>
 *
 * @author hongtool
 * @date 2023/8/14
 */
public enum EntityTypeEnum {
    
    // 长方形
    RECTANGLE,
    // 正方形
    SQUARE,
    // 圆形
    ROUNDNESS
    
}

创建实体的多种方式

package com.cah.api.entity;

import com.almasb.fxgl.app.GameApplication;
import com.almasb.fxgl.app.GameSettings;
import com.almasb.fxgl.dsl.FXGL;
import com.almasb.fxgl.entity.Entity;
import com.almasb.fxgl.entity.SpawnData;
import com.almasb.fxgl.physics.BoundingShape;
import com.almasb.fxgl.physics.HitBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;

/**
 * <p> 实体创建 </p>
 * 在游戏中,大部分物体都可以称为实体。角色,敌人,子弹,物品等。
 * 实体如下基本属性
 * 1.view:显示展示实体内容(图片)
 * 2.bbox:碰撞体积(用于做物理碰撞事件,如果没有设置,这时获取宽与高都为0)
 * 3.type:类型,标识该实体属于什么,如主角,敌人,子弹
 * 4.transform: 位置
 * @author hongtool
 * @date 2023/8/14
 */
public class EntityApp extends GameApplication {
    
    public static void main(String[] args) {
        launch(args);
    }
    
    @Override
    protected void initSettings(GameSettings gameSettings) {
    
    }
    
    @Override
    protected void initGame() {
        // 创建实体
        Entity entity = FXGL.entityBuilder()
                // 设置实体类型-长方形
                .type(EntityTypeEnum.RECTANGLE)
                // 设置实体初始位置
                .at(100, 100)
                // 黑色的长方形
                .view(new Rectangle(20, 40, Color.BLACK))
                .build();
        // 将实体添加到游戏中(如果没有该方法,则创建的实体不会添加到游戏中,游戏界面看不见)
        FXGL.getGameWorld().addEntity(entity);
        System.out.printf("entity-w:%s--h:%s%n", entity.getWidth(), entity.getHeight());
        
        // 创建并添加 buildAndAttach();
        Entity entity1 = FXGL.entityBuilder()
                .type(EntityTypeEnum.SQUARE)
                .at(200, 100)
                // 红色的正方形
                .view(new Rectangle(20, 20, Color.RED))
                .buildAndAttach();
        System.out.printf("entity1-w:%s--h:%s%n", entity1.getWidth(), entity1.getHeight());
        
        // 如果.at(x, y) 的方法可以替换成 .entityBuilder(new SpawnData(x, y))
        Entity entity2 = FXGL.entityBuilder(new SpawnData(200, 200))
                .type(EntityTypeEnum.ROUNDNESS)
                // 蓝色的圆形
                .view(new Circle(20, Color.BLUE))
                .buildAndAttach();
        System.out.printf("entity2-w:%s--h:%s%n", entity2.getWidth(), entity2.getHeight());
        
        // 以上几个没有设置bbox,则宽与高都为0,这里设置了bbox,宽与高则有值
        Entity entity3 = FXGL.entityBuilder(new SpawnData(300, 200))
                .type(EntityTypeEnum.ROUNDNESS)
                // 蓝色的圆形
                .view(new Circle(20, Color.PINK))
                // 设置碰撞体积(圆形的碰撞体积)
                .bbox(new HitBox(BoundingShape.circle(20)))
                .buildAndAttach();
        System.out.printf("entity3-w:%s--h:%s%n", entity3.getWidth(), entity3.getHeight());
        
        // 如果显示与碰撞一致,则可以简写
        Entity entity4 = FXGL.entityBuilder(new SpawnData(300, 300))
                .type(EntityTypeEnum.SQUARE)
                // 黄色的正方形
                .viewWithBBox(new Rectangle(30, 30, Color.YELLOW))
                .buildAndAttach();
        System.out.printf("entity4-w:%s--h:%s%n", entity4.getWidth(), entity4.getHeight());
        
        // 视图可以有多个组合
        Entity entity5 = FXGL.entityBuilder(new SpawnData(400, 300))
                .type(EntityTypeEnum.SQUARE)
                .view(new Text("绿色"))
                // 绿色的正方形
                .viewWithBBox(new Rectangle(30, 30, Color.GREEN))
                .buildAndAttach();
        System.out.printf("entity5-w:%s--h:%s%n", entity5.getWidth(), entity5.getHeight());
        
        // 通过实体工厂创建,在ShapeEntityFactory中编写方法,并且使用@Spawns指定名称
        // 注意,使用实体工厂的时候,需要添加该工厂
        FXGL.getGameWorld().addEntityFactory(new ShapeEntityFactory());
        
        // 只创建实体,不添加到游戏世界中
        Entity entity10 = FXGL.getGameWorld().create("ROUNDNESS", new SpawnData(400, 100));
        
        // 以spawn方式创建的Entity,默认直接添加到游戏世界中。
        // 没有指定位置,默认在左上角
        Entity entity6 = FXGL.getGameWorld().spawn("ROUNDNESS");
    
        // 上面方法的简写,并且拥有初始指定位置
        Entity entity7 = FXGL.spawn("ROUNDNESS", new SpawnData(300, 100));
        
    
        // 如果多个相同的实体,但是用途不一样,可以在@Spawns中指定多个名称,用逗号“,”分割
    
        Entity entity8 = FXGL.spawn("RECTANGLE", new SpawnData(400, 200));
        Entity entity9 = FXGL.spawn("SQUARE", new SpawnData(500, 200));
        
        Entity entity11 = FXGL.spawn("RECTANGLE1",
                new SpawnData(500, 300)
                        .put("w", 60D)
                        .put("h", 60)
                        .put("color", Color.BLACK));
        // 从 entity 中获取 SpawnData 数据
        System.out.println("entity11-->w:" + entity11.getDouble("w"));
        System.out.println("entity11-->h:" + entity11.getInt("h"));
        System.out.println("entity11-->color:" + entity11.getObject("color"));
        
        // 从 entity 中,获取所有的参数
        entity11.getProperties().keys().forEach(key ->
                // 这里有一个key是type,与 entity中设置的type是不一样的。这里指的就是 spawn 的 entityName
                System.out.println(key + " : " + entity11.getProperties().getValue(key))
        );
        
    }
    
}

实体工厂(重点)

package com.cah.api.entity;

import com.almasb.fxgl.dsl.FXGL;
import com.almasb.fxgl.entity.Entity;
import com.almasb.fxgl.entity.EntityFactory;
import com.almasb.fxgl.entity.SpawnData;
import com.almasb.fxgl.entity.Spawns;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;

/**
 * <p> 形状实体工厂 </p>
 *
 * @author hongtool
 * @date 2023/8/14
 */
public class ShapeEntityFactory implements EntityFactory {

    /**
     * 功能描述: 创建一个长方形 <br/>
     *
     * @param spawnData 初始位置
     * @return "com.almasb.fxgl.entity.Entity"
     */
    @Spawns("ROUNDNESS")
    public Entity createRoundness(SpawnData spawnData) {
        Entity entity = FXGL.entityBuilder(spawnData)
                // 设置实体类型-圆形
                .type(EntityTypeEnum.ROUNDNESS)
                // 黑色的长方形
                .view(new Circle(20, Color.LAVENDER))
                .build();
        return entity;
    }
    
    @Spawns("RECTANGLE,SQUARE")
    public Entity createRectangle(SpawnData spawnData) {
        Entity entity = FXGL.entityBuilder(spawnData)
                // 设置实体类型-长方形
                .type(EntityTypeEnum.RECTANGLE)
                // 黑色的长方形
                .view(new Rectangle(40, 50, Color.DARKBLUE))
                .build();
        return entity;
    }
    
    @Spawns("RECTANGLE1")
    public Entity createRectangle1(SpawnData spawnData) {
        // 矩形的参数从 spawnData 中获取
        Entity entity = FXGL.entityBuilder(spawnData)
                .type(EntityTypeEnum.RECTANGLE)
                .view(new Rectangle(spawnData.get("w"), spawnData.<Integer>get("h"), spawnData.get("color")))
                .build();
        return entity;
    }
    
    /*
     快速创建实体(自定义快捷代码块)
     1.File->settings->Editor->Live Templates
     2.选中java相关的(或者自己添加一个组),然后右边添加 Live Template
     3.输入关键字: glet, 输入描述: 创建FXGL实体
     4.在 Template text 中输入以下内容
        @Spawns("$NAME$")
        public Entity create$SNAME$(SpawnData spawnData) {
            // 矩形的参数从 spawnData 中获取
            Entity entity = FXGL.entityBuilder(spawnData)
                    $END$
                    .build();
            return entity;
        }
     5.勾选 java 可用
     6.设置 NAME 为 *entity*; 设置 SNAME 为 capitalize(NAME) 最后的勾选起来
     */
    
    /** 输入关键字 glet 回车,就可以得到以下效果 */
    @Spawns("Element")
    public Entity createElement(SpawnData spawnData) {
        // 矩形的参数从 spawnData 中获取
        Entity entity = FXGL.entityBuilder(spawnData)
                
                .build();
        return entity;
    }

}

总结

待完善实体的属性与组件内容