FXGL 学习笔记一 《GameApplication的执行顺序》

前言

学习使用java开发游戏。FXGL是基于javaFX的一个游戏引擎框架。对于java开发来说,上手简单。本笔记为记录FXGL中常用的一些API和注意要点。后续自己开发过程中,如果发现问题或者描述不对的地方,再进行修改。

学习过程参考 LeeWyatt 的 FXGL基础入门教程

环境

依赖

xml 复制代码
<dependency>
    <groupId>com.github.almasb</groupId>
    <artifactId>fxgl</artifactId>
    <version>17</version>
</dependency>

正文

编写一个最简单的游戏启动类,

  1. 创建一个maven项目
  2. 添加fxgl依赖
  3. 编写TestApp主类(一般启动类使用App结尾)
  4. 在module-info.java模块类中,开启并引入fxgl

代码

java 复制代码
package com.cah.api;

import com.almasb.fxgl.app.GameApplication;
import com.almasb.fxgl.app.GameSettings;
import com.almasb.fxgl.dsl.FXGL;
import com.almasb.fxgl.time.LocalTimer;
import javafx.util.Duration;

import java.util.Map;

/**
 * <p> Api主类 </p>
 *
 * @author hongtool
 * @date 2023/8/13
 */
public class ApiApp extends GameApplication {
    
    /** 计时器 */
    private LocalTimer timer;
    
    public static void main(String[] args) {
        // 开始执行
        launch(args);
    }
    
    /** 最先执行 */
    public ApiApp() {
        System.out.println("构造器==》" + Thread.currentThread().getName());
    }
    
    /** 第二步,执行游戏初始化设置 */
    @Override
    protected void initSettings(GameSettings gameSettings) {
        // 可以设置 游戏的 标题、图标、版本、宽度、高度等,具体的内容稍后参考《GameSettings》学习资料
        // 图标资源,参考 《FXGL 资源分类》学习资料
        System.out.println("ApiApp.initSettings==》" + Thread.currentThread().getName());
        // 注意:在此方法中,不要执行"FXGL."的静态方法。会出错。因为这时候FXGL的相关属性引擎尚未加载
    }
    
    /** 第三步,执行游戏的输入监听 */
    @Override
    protected void initInput() {
        // 包括键盘输入,鼠标输入等
        System.out.println("ApiApp.initInput==》" + Thread.currentThread().getName());
    }
    
    /** 第四步,资源预加载初始化 */
    @Override
    protected void onPreInit() {
        // 预加载游戏背景音乐,设置是否开启背景音乐和音效等。
        System.out.println("ApiApp.onPreInit==》" + Thread.currentThread().getName());
    }
    
    /** 第五步,初始化游戏参数 */
    @Override
    protected void initGameVars(Map<String, Object> vars) {
        // 通过map的形式,保存游戏中的通用参数。
        // 在其他地方使用 FXGL.getip(key)的方式进行获取,FXGL.set(key,value)的方式进行重新赋值
        System.out.println("ApiApp.initGameVars==》" + Thread.currentThread().getName());
    }
    
    /** 第六步,初始化游戏(重点) */
    @Override
    protected void initGame() {
        // 初始化计时器(为什么要在这里初始化呢?因为)
        timer = FXGL.newLocalTimer();
        System.out.println("ApiApp.initGame==》" + Thread.currentThread().getName());
    }
    
    /** 第七步,初始化游戏物理引擎(重点) */
    @Override
    protected void initPhysics() {
        // 物理碰撞事件等
        System.out.println("ApiApp.initPhysics==》" + Thread.currentThread().getName());
    }
    
    /** 第八步,初始化UI界面 */
    @Override
    protected void initUI() {
        System.out.println("ApiApp.initUI==》" + Thread.currentThread().getName());
    }
    
    /** 最后一步,游戏每一帧都会调用改方法。默认为60帧 */
    @Override
    protected void onUpdate(double tpf) {
        // 如果计时器走过1秒,则打印
        if(timer.elapsed(Duration.seconds(1))) {
            // 重置计时器
            timer.capture();
            System.out.println("ApiApp.onUpdate==》" + Thread.currentThread().getName());
        }
    }
    
}

结果

运行main方法,查看执行结果

txt 复制代码
构造器==》main
ApiApp.initSettings==》main

ApiApp.initInput==》JavaFX Application Thread
ApiApp.onPreInit==》JavaFX Application Thread
ApiApp.initGameVars==》FXGL Background Thread 1
ApiApp.initGame==》FXGL Background Thread 1
ApiApp.initPhysics==》FXGL Background Thread 1
ApiApp.initUI==》FXGL Background Thread 1
22:50:57.515 [FXGL Background Thread 1 ] INFO  FXGLApplication      - Game initialization took: 0.002 sec

ApiApp.onUpdate==》JavaFX Application Thread
ApiApp.onUpdate==》JavaFX Application Thread
ApiApp.onUpdate==》JavaFX Application Thread
ApiApp.onUpdate==》JavaFX Application Thread

开发菜单页面

initSettings方法中,添加开启菜单代码

java 复制代码
@Override
protected void initSettings(GameSettings gameSettings) {
    gameSettings.setMainMenuEnabled(true);
    System.out.println("ApiApp.initSettings==》" + Thread.currentThread().getName());
}

操作过程

  1. 运行main方法
  2. 等待游戏启动,观察日志为运行了四分方法,顺序为:构造器>initSettings>initInput>onPreInit;其他的方式都没有执行
  3. 点击【NEW GAME】按钮,发现执行了initGameVars>initGame>initPhysics>initUI>一直调用onUpdate
  4. 这时按【Esc】按键,暂停游戏,发现onUpdate没有执行
  5. 点击【MAIN MENU】按钮,返回主菜单界面。
  6. 再次点击【NEW GAME】按钮,发现也是执行了第3点的方法。但是线程名称名称不一样,说明启动了新线程执行,但是onUpdate还是主线程在执行。

总结

通过重写方法,打印日志,和操作分析,可以观察 GameApplication 各个方法的执行顺序与用途。

相关推荐
xlsw_2 小时前
java全栈day20--Web后端实战(Mybatis基础2)
java·开发语言·mybatis
神仙别闹3 小时前
基于java的改良版超级玛丽小游戏
java
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭4 小时前
SpringBoot如何实现缓存预热?
java·spring boot·spring·缓存·程序员
暮湫4 小时前
泛型(2)
java
超爱吃士力架4 小时前
邀请逻辑
java·linux·后端
南宫生4 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
转码的小石4 小时前
12/21java基础
java
李小白664 小时前
Spring MVC(上)
java·spring·mvc
GoodStudyAndDayDayUp4 小时前
IDEA能够从mapper跳转到xml的插件
xml·java·intellij-idea
装不满的克莱因瓶5 小时前
【Redis经典面试题六】Redis的持久化机制是怎样的?
java·数据库·redis·持久化·aof·rdb