libGDX是一个非常好的跨平台游戏开发框架,只可惜在国内知名度不高。
特点
关于特点这块,可以参考一下度娘(有删减):
强兼容性
libgdx兼容多种平台系统(Windows、Linux、Max OS X...),包括移动系统Android(1.5版本+),另外,基于RoboVM可以实现iOS兼容
同时极强的兼容性为调试和开发提供了便利。你可以使用Android上面同样的代码在桌面PC上面编写,测试,调试你的应用(也就是说,你可以不需要打开Android模拟器,就可以调试用Libgdx引擎写的游戏应用)。
高效性
Libgdx主要是用Java写的,其中也掺杂了一些C/C++代码,这些代码是为了处理一些对性能要求很高的操作,比如物理引擎或者音频处理。作为用户,你只需要关注Java的封装就可以了,它已经把所有的本地代码封装好了。相比于其他android游戏引擎,libgdx的效率优势十分明显。
架构清晰
libgdx的主要构成如下所示
Libgdx由
audio
、files
、graphics
、math
、physics
、scenes
、utils
这些主要模块所组成,它们分别对应了Libgdx中的音频操作,文件读取,2D/3D渲染,Libgdx绘图相关运算,Box2D封装,2D/3D游戏组件,以及Libgdx内置工具类。它还提供了便于设计游戏的清晰架构
封装
它足够疯狂的使用jni封装了box2d的c++版本,使得其运行效率比其他同级的物理引擎如jbox2d快不少。现在流行的几个包含物理引擎Android游戏引擎(如Andengine、Rokon等),几乎都在用libgdx。
工具
Libgdx还拥有相当数量的开发工具。如Particle editor(粒子编辑器),Hiero bitmap font generator(文字生成工具),Texture packer(图片合并工具),TWL布局编辑器,Gdx Setup UI等。
网络
Libgdx最初大部分用于单机游戏或者弱联网游戏,不过经过不断优化,现在Libgdx提供了专门的网络模块。
程序结构
当然,如专栏标题一样,没有libGDX相关环境配置的教程
libGDX应用的生命周期
应用生命周期接口ApplicationListener类
libGDX通过com.badlogic.gdx.ApplicationListener
接口提供了应用的生命周期,开发者通过实现这些接口以实现游戏基本逻辑与周期:
- create() : 应用启动时调用一次
- resize(width,height) : 应用更改屏幕尺寸且不处于暂停状态时调用,在create(),resume()后也会调用一次
- render() : 应用初始化后不断调用
- pasue() : 应用失去焦点/暂停时(android切换别的应用或按下home键...,desktop最小化...)时调用,在dispose()前也会调用一次
- resume() : 应用恢复焦点时调用
- dispose() : 应用被销毁时调用
官方还给出了libGDX应用执行的流程: Tips:implements它的类一般都是应用主类。
ApplicationListener空实现类ApplicationAdapter
在实际开发中,通常不需要使用到ApplicationListener接口的所有方法,于是可以使用com.badlogic.gdx.ApplicationAdapter
类,它空实现了ApplicationListener的所有方法,可以选择性地实现方法,十分方便。:D
libGDX应用交互接口
在libGDX中,作为核心的com.badlogic.gdx
包( gdx.jar ),有着6大基础接口让应用与系统进行互动,分别是:
- Application : 即应用的实例,通常于启动器类被初始化并启动应用主类。还提供了对应用,系统信息的查询,通知,日志输出等
- Files : 暴露底层文件,提供了读取,修改文件的方法
- Input : 读取来自用户的输入
- Net : 提供从 HTTP / HTPPS 访问资源的方法,创建 TCP 服务和客户端 scokets
- Audio : 通过创建音乐和音效实例,通过播放音频的方法,还可以直接访问音频设备
- Graphics : 暴露 OpenGL ES 2.0 接口,得以获取渲染时间,世界宽高,帧率等方法
这些类在com.badlogic.gdx.Gdx
类中都有一个静态成员:
Gdx.app
Gdx.files
Gdx.input
Gdx.net
Gdx.audio
Gdx.graphics
libGDX程序启动器
libGDX应用并不是一开始就执行主类的,得有一个启动器类来启动窗口并开始执行主类。每个应用都会有一个启动器类:
package com.libGDX.test;
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
//启动器类
public class DesktopLauncher {
//程序在这里开始
public static void main(String[] args) {
//初始化窗口配置
LwjglApplicationConfiguration config=new LwjglApplicationConfiguration();
//设置窗口 名称"hello",宽高为200*200,不可改变大小
config.width=200;
config.height=200;
config.title="hello";
config.resizable=false;
//创建窗口, Demo 为主类名,必须 implements ApplicationListener 或 extends ApplicationAdapter
new LwjglApplication(new Demo(),config);
}
}
复制代码
libGDX日志输出
前面讲过, Application 类提供了日志输出的功能,代码如下:
//输出info日志
Gdx.app.log("my log","info");
//输出debug日志
Gdx.app.debug("my log","debug");
//输出error日志,还可附带一个Explosion对象
Gdx.app.error("my log","error");
Gdx.app.error("my log","error",explosion);
复制代码
还可通过setLogLevel()
限定输出级别
- Application.LOG_NONE : 不输出任何日志
- Application.LOG_DEBUG : 输出所有日志
- Application.LOG_INFO : 输出 info , error 日志
- Application.LOF_ERROR : 只输出 error 日志
libGDX de 尝试
好了,现在你已经掌握了这些基础知识了,现在,我们来测试一下,做一个根据事件输出不同日志的小程序:
//省略启动器类...
package com.libGDX.test;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
public class Test implements ApplicationListener {
@Override
public void create() {
//输出所有日志
Gdx.app.setLogLevel(Gdx.app.LOG_DEBUG);
//这里使用不同日志,区分日志轻重级别
Gdx.app.error("sysout","create");
}
@Override
public void dispose() {
Gdx.app.error("sysout","dispose");
}
@Override
public void pause() {
Gdx.app.log("sysout","pause");
}
@Override
public void render() {
Gdx.app.debug("log","render");
}
@Override
public void resize(int arg0, int arg1) {
Gdx.app.log("sysout","resize");
}
@Override
public void resume() {
Gdx.app.log("sysout","resume");
}
}
复制代码
接下来,我们运行一下,并以此进行
graph TD
最小化 --> 恢复 --> 退出
结果如下:
从中可以看出 render() 在不断运行,说明我们成功了!但不要急,我们将 logLevel 更改为 LOG_INFO ,再试试看:
可以看出,系统已经屏蔽了 render() 输出 ,那如果是 LOG_ERROR 呢?不用说: