LIBGDX 游戏引擎
LIBGDX 游戏引擎
一款使用OpenGL 的 Java 游戏引擎
介绍
libGDX is a cross-platform Java game development framework based on OpenGL (ES), designed for Windows, Linux, macOS, Android, web browsers, and iOS. It provides a robust and well-established environment for rapid prototyping and iterative development. Unlike other frameworks, libGDX does not impose a specific design or coding style, allowing you the freedom to create games according to your preferences.
github: https://github.com/libgdx/libgdx
Hello World
准备工作
- JDK: 建议 11-18. 我个人使用JDK11,感觉非常良好
- 开发工具,正常的java开发集成工具都可以,我个人使用JetBrain的Idea
- 依赖管理工具,libgdx使用的是gradle进行包管理,所以最好提前安装gradle。我本地安装的是7.4.2. 如果不提前手动下载,后面导入可能会麻烦一些。
- 初始化项目:
- 下载官方的初始化工具,目前地址: https://libgdx.com/wiki/start/project-generation (最新版)
- 或者可以下载 1.10 版,因为我就是用这个版本开发的。https://github.com/libgdx/libgdx/releases 可以在这里找到历史版本,选择1.10.0即可。
Init!
好了,现在我们可以尝试开始我们的第一个项目了。
首先,打开我们刚刚下载好的初始化工具: 
关于第6点打包模式,个人建议勾选desktop,方便桌面调试,或者直接开发桌面应用。andriod也推荐勾选,因为这个引擎起始主要是为了andriod游戏而做的,大部分资源文件都会放在andriod项目下。不管你开发的是什么应用。
至于更多的第三方依赖,暂时用不到,可以不需要管。然后,我们直接点击generate生成即可.
点击生成后,会自动在目标文件夹下生成初始化的代码,并且会尝试使用gradle导入依赖,但是此时极有可能因为本地JAVA_HOME等原因导入失败,这个失败我们可以先不去管,忽略它,直接使用我们的开发工具(我使用的IDEA)打开该项目即可。
在使用我们的开发工具打开项目后,首先建议修改默认的gradle配置,更改为自己下载好的版本。
这样,导入依赖会更快更方便,不然的话,我本地实测会比较慢。
然后接下来就让gradle自动构建就可以了。
Hello World
构建好之后,项目看起来应该是这个样子的:
其中,desktop目录中,存在一个名为DesktopLauncher的启动类,我们可以直接运行这个启动类。应该会看到一个应用程序启动,如下图:
如果看到这个画面,恭喜你,我们已经成功的初始化了一个游戏!
现在我们看到的仅仅是一个libgdx logo的图片以及红色背景。这显然不是我们最终想要的,我们至少想要一个自己的hello world
我们就需要认识一下core文件夹,下面有一个初始化自带的一个Class,MyGdxGame,它长这个样子:
1 | package com.mygdx.game; |
正是上面这段代码的render函数绘制出了我们的图片,这个其实也是整个程序的主逻辑。
如果我们想要更改渲染的东西,那么我们要做的工作就是想办法在这里渲染我们想要的东西
主要组件
Game Screen
com.badlogic.gdx.ApplicationListener 可以算作整个游戏的入口,我们需要手动实现它。它里面的render方法就是我们的主逻辑。但是但看这个接口,是有点抽象的,因为我们还不太了解具体该怎么做。幸好,libgdx给了我们一个比较好的实现类:com.badlogic.gdx.Game
我们现在已经看到Game类是实现了ApplicationListener接口的,那么我们可以试着把系统自动给我们生成的MyGdxGame类改成继承Game类来试一下.更改后:
1 | public class MyGdxGame extends Game { // 只有父类变成了Game |
然后再次运行,发现没有变化,那么就证明我们更换正确了。我们现在开始就可以使用这个Game当作游戏的起点了!
还有另外一个组件 Screen
Screen 是一个接口,代码如下:
1 | public interface Screen { |
这里的render方法可以用了来更好的实现我们的逻辑,因为参数附加了当前帧与上一帧相差的秒数(float),可以更好的更新我们的逻辑。
Game 中负责Screen的调度,我们可以通过 com.badlogic.gdx.Game#setScreen 方法来设置当前需要渲染以及更新的screen
Batch
Batch 是我们整个程序的画笔,这个画笔有很多类型,并且由于每种batch都没有一个统一的抽象规范,目前是没有所谓的batch基类的,我们只能找到一些各种实现类。比如我们上面见到的 com.badlogic.gdx.graphics.g2d.SpriteBatch ,就是专门用于绘制纹理图片的,还有可以绘制各种形状的 com.badlogic.gdx.graphics.glutils.ShapeRenderer,这个叫做render的类也是起到batch的作用。甚至还有可以绘制3D模型的 com.badlogic.gdx.graphics.g3d.ModelBatch
batch底层使用的起始都是opengl。这是一个计算机图形统一接口。
Camera
Camera顾名思义,就是我们整个游戏中的相机, 它的作用其实是处理我们游戏中的各种坐标变换,游戏视角的切换等等
Camera的底层其实是一个 四维矩阵,这一部分也是OpenGL的知识.
Input
Input是游戏中不可缺少的,负责处理用户输入,有了用户输入才能有交互,有了交互才能称之为游戏。
在LibGDX中,Input 相关的交互全在 Gdx.input 这个全局静态引用中。 Input 最基础的用法是:
1 | // 获取当前点击屏幕的坐标 |
除此之外,还有很多使用方法,直接调用这个引用即可。
需要注意:
- Gdx.input 这个全局静态引用的实现是基于你当前的系统来自动决定的。
- 上面这个获取坐标的方法获取到的其实是我们的屏幕坐标,也就是当前指针指向的像素点的坐标。这个坐标还需要使用我们的 Camera 换算才能被使用。Camera坐标换算可能需要在其他文章中仔细讲解.
除了上面的这种最基本的控制,LibGDX还给我们提供了一种更加方便的封装,那就是 com.badlogic.gdx.Input#setInputProcessor. 这个方法的参数 InputProcessor 是libgdx给我们封装好的一个输入处理接口,里面有几乎我们能用到的所有输入处理。我们只需要实现对应的输入处理方法即可。
同时,libgdx还内置了一个InputMultiplexer来同时处理多个Input,源码比较简单,就是内置了一个集合遍历,故不在此详述。
Asset
Asset,游戏资源,关于我们如何加载游戏资源,我们可以使用 Gdx.files 这个全局静态引用来获取我们所需要的文件。
获取到的文件是一个 com.badlogic.gdx.files.FileHandle, 我们可以使用这个handle来生成我们想要的各种游戏内素材,比如:
1 | Texture pic = new Texture(Gdx.files.internal("图片位置")); // 获取图片 |
这里文件位置使用的是internal。internal代表是从我们项目内部来获取资源的。
这也是我们初始代码获取默认图片的方式
关于几种file的获取方式,可以参考chatgpt的回答:
1 | Classpath (类路径): |
总之,我目前最常用的就是internal
LibGDX 内置 Enviroment
libgdx 内置了一些可以用来在程序运行中获取资源或者修改程序参数的功能类。这些enviroment被以单例模式放在了 com.badlogic.gdx.Gdx 类中。
其中每一项都会根据当前运行的系统来分别init。
1 | public class Gdx { |
比如,我们可以使用其中的 audio 来管理音频,可以使用files来管理文件资源,可以使用input来处理输入。