利用Java游戏引擎开发坦克大战

786 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

效果图

未命名的设计.gif

源码

pan.baidu.com/s/1ZOKo1n5F… 提取码:1234

主要功能

  • 键盘监听,接收游戏者的操作
  • 坦克在游戏界面中移动
  • 坦克发射子弹

实体

  • 背景
  • 敌我坦克
  • 敌我子弹
  • 爆炸动画

额外组件

  • 我方坦克移动并发射组件

依赖

<dependency>
    <groupId>com.github.almasb</groupId>
    <artifactId>fxgl</artifactId>
    <version>17</version>
</dependency>

代码

  • 游戏初始化
public class TanKeApp extends GameApplication {
    @Override
    protected void initSettings(GameSettings gameSettings) {
        gameSettings.setWidth(960);
        gameSettings.setHeight(640);
        gameSettings.setVersion("0.2");
        gameSettings.setTitle ("坦克大战");
    }
    public static void main(String[] args) {
        launch(args);
    }
}
  • 创建实体工程
public class HeroFactury implements EntityFactory {
    enum Phy1{ZIDAN,ENEMY}
    /**
     * 创建我方子弹
     * @param data
     * @return
     */
    @Spawns("zidan")
    public Entity newZiDan(SpawnData data){
        Texture texture = FXGL.texture("my/bulletB_2x.png").toColor(FXGLMath.randomColor ());
        Point2D point2D = data.get("point2D");
        double x = point2D.getX();
        double y = point2D.getY();
        Entity entity = FXGL.entityBuilder(data)
                .type(Phy1.ZIDAN)
                .viewWithBBox(texture)
                .with(new ProjectileComponent(point2D, 500))
                .with(new OffscreenCleanComponent())
                .collidable()
                .build();
        if (x==0.0&&y==-1.0){//up
            entity.setRotation(-90);
        }else if (x==0.0&&y==1.0){//d
            entity.setRotation(90);
        }
        else if (x==-1.0&&y==0.0){//l
            entity.setRotation(180);
        }else {//r
            entity.setRotation(0);
        }
        return entity;
    }
    /**
     * 创建敌方子弹
     * @param data
     * @return
     */
    @Spawns("dizdan")
    public Entity newDiZDan(SpawnData data){
        Texture texture = FXGL.texture("my/bulletB_2x.png").multiplyColor(Color.RED);
        Entity entity = FXGL.entityBuilder(data)
//                .type(Phy1.ZIDAN)
                .viewWithBBox(texture)
                .with(new ProjectileComponent(new Point2D(-1,0), 500))
                .with(new OffscreenCleanComponent())
                .with(new EnnmyZi())
                .collidable()
                .build();
        return entity;
    }
}
  • 加载背景
    @Spawns("bg")
    public Entity newBg(SpawnData data){
        return FXGL.entityBuilder()
                .view("LevelsBackground.jpg")
                .build();
    }
  • 加载我方坦克
    @Spawns("hero")
    public Entity newMyTanKe(SpawnData data){
        Entity entity = FXGL.entityBuilder()
                .viewWithBBox("my/LoadTank.png")
                .with(new MoveComponent())
                .with (new KeepOnScreenComponent ())
                .build();
        return entity;
    }
  • 我方坦克移动并发射子弹
public class MoveComponent extends Component {
    private boolean isMoving;
    private Dir dir;
    private LocalTimer localTimer=FXGL.newLocalTimer();
    enum Dir{UP,DOWN,LEFT,RIGHT}
    @Override
    public void onAdded() {
        FXGL.getInput().addAction(new UserAction("UP") {
            @Override
            protected void onAction() {
                if (isMoving) {
                    return;
                }
                isMoving=true;
                entity.setRotation(-90);
                dir=Dir.UP;
                entity.translateY(-5);

            }
        }, KeyCode.UP);
        FXGL.getInput().addAction(new UserAction("DOWN") {
            @Override
            protected void onAction() {
                if (isMoving) {
                    return;
                }
                isMoving=true;
                entity.setRotation(90);
                dir=Dir.DOWN;
                entity.translateY(+5);

            }
        }, KeyCode.DOWN);
        FXGL.getInput().addAction(new UserAction("LEFT") {
            @Override
            protected void onAction() {
                if (isMoving) {
                    return;
                }
                isMoving=true;
                entity.setRotation(180);
                dir=Dir.LEFT;
                entity.translateX(-5);

            }
        }, KeyCode.LEFT);
        FXGL.getInput().addAction(new UserAction("RIGHT") {
            @Override
            protected void onAction() {
                if (isMoving) {
                    return;
                }
                isMoving=true;
                entity.setRotation(0);
                dir=Dir.RIGHT;
                entity.translateX(5);

            }
        }, KeyCode.RIGHT);

        FXGL.getInput().addAction(new UserAction("SPACE") {
            @Override
            protected void onAction() {
                //间隔2秒钟
                if (!localTimer.elapsed(Duration.seconds(0.25))){
                    return;
                }
                localTimer.capture();
                Point2D point2D;
                if (dir==Dir.UP){
                    point2D=new Point2D(0,-1);
                }else if (dir==Dir.DOWN){
                    point2D=new Point2D(0,1);
                }else if (dir==Dir.LEFT){
                    point2D=new Point2D(-1,0);
                }else{
                    point2D=new Point2D(1,0);
                }
                FXGL.spawn("zidan",new SpawnData(entity.getCenter().getX(),entity.getCenter().getY())
                        .put("point2D",point2D));
            }
        },KeyCode.SPACE);
    }

    @Override
    public void onUpdate(double tpf) {

        isMoving=false;
    }
}
  • 敌方坦克
    @Spawns("enemy")
    public Entity newDiTanKe(SpawnData data){
        Texture texture = FXGL.texture("my/LoadTank.png").toColor(FXGLMath.randomColor ());
        Entity build = FXGL.entityBuilder(new SpawnData(FXGL.random(0,800), FXGL.random(0,500)))
                .type(Phy1.ENEMY)
                .viewWithBBox(texture)
                .collidable()
                .with(new KeepOnScreenComponent())
                .with(new RandomMoveComponent(new Rectangle2D(0,0,960,640),100,0))
                .build();
        return build;
    }
  • 爆炸
    @Spawns("bar")
    public Entity newBarrel(SpawnData data){
        ArrayList<Image> list = new ArrayList<>();
        list.add(FXGL.image("barrel/barrelExplode1.png"));
        list.add(FXGL.image("barrel/barrelExplode2.png"));
        list.add(FXGL.image("barrel/barrelExplode3.png"));
        list.add(FXGL.image("barrel/barrelExplode4.png"));
        list.add(FXGL.image("barrel/barrelExplode5.png"));
        list.add(FXGL.image("barrel/barrelExplode6.png"));
        list.add(FXGL.image("barrel/barrelExplode7.png"));
        list.add(FXGL.image("barrel/barrelExplode8.png"));
        list.add(FXGL.image("barrel/barrelExplode9.png"));
        list.add(FXGL.image("barrel/barrelExplode10.png"));
        AnimationChannel ac = new AnimationChannel(list, Duration.seconds(0.35));
        AnimatedTexture at = new AnimatedTexture(ac);
        at.play();
        return FXGL.entityBuilder(data)
                .view(at)
                .with(new ExpireCleanComponent(Duration.seconds(0.35)))
                .build();
    }