-
Libgdx
是一款支持
2D
< br>与
3D
游戏开发的游戏类库,
兼
容大多数微机平台
(标准
JavaSE
实现,
能运行在
Mac
、
Linux
、
Windows
等系统)与
Android
平台(
A
ndroid1.5
以上即可使用,
Android2.1
p>
以上可满功率发挥),
Libgdx
由
audio
、
files
、
graphics
、
math
、
phy
sics
、
scenes
、
utils
这些主要类库所组成,它们
分别对应了
Libgdx
中的音频操作,文件读取,
2D/3D
渲染,
Libgdx
绘图
相关运算,
Box2D
封装,
2D/3
D
游戏组件(
3D
部分目前无组件),
以及
Libgdx
内置工具类。
p>
Libgdx
主要构成如下所示(
Libg
dx
作者
wiki
提供):
下面开始,我将就
Libgdx
的具体实现,开始讲解如何正确使用
Libgdx
类库
。
不过在正式开始之前,我们首先还得讲讲
< br>Gdx
类。
关于
Libgdx
中的
Gdx
类
:
单从表面上看,
Gdx
类占用空间不足
2KB
,甚至不具备一行可以被直接执行的函数,并没
什么重要好说。
然而,真实的
Gdx
却是
Libgdx
类库运行的核心所在,没有它你将寸
步难行,不单运行
Graphics
、
Input
、
Files
、
Audio
、
AndroidApplicati
on
等
Libgdx
关键部分所必需的
实例会在
Libgdx
初始化时注入
G
dx
中对应的
graphics
、
p>
input
、
files
< br>、
audio
、
app
等静态变量里面,就
连
Libgdx
对
OpenGL
接口(或
OpenGLES
,视
Libgdx
运
行平台而定,以下统称
OpenGL
)
的
GL10
、
GL11
、
GL20
、
GLCommo
n
等封装类也会在
Graphics
实
例化时分别注入到
gl10
、
gl11
、
gl20
、
gl
这四个同样位于
Gdx
的静态变量
当中
(在
Graphics
中也会继续
保留它们的引
用,
因此无论你执行
10
还是
10
,
其
实都在调用同一个静态变量)
。
事实上,如果你想不使用
Gdx
而正常运行
Libgdx
,那么除了重构源码,就再没有任何办法
可想了。
PS:
如果你不清楚自己究竟在什么环境使用
< br>Libgdx
,
其实也不必强分
gl10
或
gl11
,
大可以通
过
方式调用
Libgdx
中对于
OpenGL
接口的默认封装
(执行某些非多版本共有接口时,
依
旧需要使用对应版本专属
gl
)。
<
/p>
想要使用
Libgdx
,却不明白
Gdx
是干什么用的,那么一切就都是空谈。
下面开始,我将具体讲解
Libgdx
中的图像处理与游戏组件部分:
关
于
Libgdx
的图像处理部分:
Mesh:
本质上讲,
Libgdx
中所有可见的
3D
物体首先都是一个
Mesh
(
网格,或者说三维网格形式
的高级图元)。
Mesh
是如何生成的呢?众所周知,数学上讲的立体几何由点、线、面三部
分组成
,
无论多么复杂的图像也可以分解为无数细小的这三部分,
或者
说可以由非常基础的
N
个这三部分所组合而成;到了
3D
游戏开发时,当我们要构建复杂的
3D
图像,首先会以
一系列有序的
vertice
s
(顶点)构成这些具体的点、线、三角要素,即构成绘图基本图元
(
Primitives
),再将基本图元组合成更完整的
高级图元也就是具体
3D
对象。因此,如果对
< br>Mesh
概念进行简单的理解,其实它就是一个象征完整图像的基本图元集合体,
Libgdx
先让
我们把一个个细分的
vertices
组成基本图元,再由
Mesh
类将基本图元制成更加复杂的高级
图元展示出来。
p>
具体可见
Li
bgdx
作者提供的
returntomarchfeld
p>
示例,基本效果如下图所示:
(勿看
FPS
,一切信真机)
< br>
PS:
如果对此类认识不足
,可以去玩玩模拟人生,下个修改器尝试编辑角色或物品造型后就
懂了
< br>……
PS
指
postscript
(备注,又可解释为附言、后记)的缩写
Texture:
Li
bgdx
所提供的游戏纹理用类,
其实质可理解为保存在显存中
的
Image
,
它以贴图的方式通
p>
过
OpenGL
将图片显示到游戏界面之上
。
Libgdx
的纹理可以直接从指定文件路径加载,也
可以通过它提供的
Pixmap
类凭空创建<
/p>
(它的
Texture(int width, int
height, Format format)
构造
内部直接
调用了
Pixmap
,不是必须在外部生成
Pixmap
后注入)。另外在加载
Texture
时,
个人建议通过
Libgdx
提供的
xture
函数调用,该方法内部提供了
p>
Texture
缓存管理,能够避免无意义的资源重复加载。此外,
Texture
通常会与
Textur
eRegion
类配套
使用,利用
Te
xtureRegion
包装
Texture
< br>后,再利用
SpriteBatch
进行绘制,可以很方
便的修
订
Texture
为我们需要的
显示范围。还有,
Libgdx
中
Sp
rite
类为
TextureRegion
子类,因此
能够将
Sprite
当
作
TextureRegion
来使用,只是
< br>Sprite
类比
TextureRegion
有所扩展。不过
Libgdx
的
SpriteCache
类并没有继承
Sprite<
/p>
或
TextureRegion
,所以起
不到
TextureRegion
的
作
用,只能构建一组静态贴图集合罢了,特此说明。
view
plaincopy to clipboardprint?
1.
// Libgdx
的
Texture
与
Sp
rite
使用
2.
public
class
Main
extends
AndroidApplication {
3.
class
TestSprite
implements
ApplicationListener {
4.
//
准备绘图用
SpriteBatch
5.
SpriteBatch spriteBatch;
6.
//
准备游戏精灵
7.
Sprite sprite;
8.
//
准备图片加载用
Texture
9.
Texture texture;
10.
public
void
create() {
11.
//
构建
SpriteBatch
12.
spriteBatch =
new
SpriteBatch();
13.
//
构建
Texture
,图像宽与高大小都必须为
2
的整数次幂,否则提
示异常
14.
// PS:
在
Android
环境使用
L
ibgdx
的
internal
加载时
必须文件必须位于
assets
目录下
15.
texture =
new
Texture(al(
));
16.
//
以指定
Texture
构建
Sprite
17.
sprite =
new
Sprite(texture);
18.
//
定位到
100, 180(Libgdx
使用标准笛卡尔坐标系,自左下
0,0
开始
< br>)
19.
ition(
100
,
180
);
20.
}
21.
public
void
render() {
22.
//
清屏
23.
r(_COLOR_BUFFER_BIT);
24.
//
初始化绘图调用
25.
();
26.
//
绘制精灵到游戏屏幕
27.
(spriteBatch);
28.
//
结束绘图调用
29.
();
30.
}
31.
public
void
dispose() {
32.
//
释放占用的资源
33.
34.
35.
36.
e();
e();
}
public
void
resume() {
37.
}
38.
public
void
pause() {
39.
}
40.
public
void
resize(
int
width,
int
height) {
41.
}
42.
}
43.
public
void
onCreate(Bundle bundle)
{
44.
super
.onCreate(bundle);
45.
//
初始化游戏屏幕,并设置是否支持
GLES 2.0
,如果您对向下兼容没什么需
要选择
true
p>
即可
(2.1
以上
)
,否则选择
false
。
46.
initialize(
new
TestSprite(),
true
);
47.
}
48.
}
Pixmap:
Libgdx
p>
所提供的像素级图像渲染用类,由于
Libgdx
< br>目前以
JNI
方式自带图像解码器,所以
我们可以直接将
Pixmap
理解为一个
Android
中
Bitmap
的替代者,
两者间实现细节虽有差别,
但具体作用却大同小
异。
Pixmap
支持
Alpha
p>
、
LuminanceAlpha
、
RGB565
、
RGBA4444
、
RGB888
、
RGB
A8888
等五种图像彩色模式,支持
png
< br>、
jpg
、
bmp
等三种图像文件的读取和
加载。一般来说,
Pixm
ap
必须和
Texture
混用才能真
正显示画面。不过在事实上,
Libgdx
的
< br>Texture
里已经内置有
Pixmap
了。
view
plaincopy to clipboardprint?
1.
// Libgdx
的
Pixmap
使用
2.
public
class
Main
extends
AndroidApplication {
3.
4.
class
TestPixmap
implements
ApplicationListener {
5.
//
准备绘图用
SpriteBatch
6.
SpriteBatch spriteBatch;
7.
// Pixmap
p>
是
Libgdx
提供的针对
opengl
像素操作的上级封装,它可以凭空构建
一
个像素贴图,
8.
//
但是它的现实必须通过
Text
ure
。
9.
Pixmap pixmap;
10.
//
准备
Texture
11.
Texture texture;
12.
public
void
create() {
13.
//
构建
SpriteBatch
14.
spriteBatch =
new
SpriteBatch();
15.
//
构建
Pixmap
(在
Android
环境使用
internal
加载模式时,文件必须放置
于
assets
文件夹下)
16.
pixmap =
new
Pixmap(al(
));
17.
//
绘制一个蓝方块到
Ball
p>
图像之上
18.
19.
20.
21.
or(.r, .g,
.b,
.a);
ctangle(
15
,
15
,
40
,
40
);
//
以指定
Pixmap
构建
Textu
re
22.
texture =
new
Texture(pixmap);
23.
//
注入
Texture
后的
pixmap
已经
没用,可以注销
24.
e();
25.
}
26.
public
void
dispose() {
27.
e();
28.
e();
29.
}
30.
public
void
pause() {
31.
}
32.
public
void
render() {
33.
//
清屏
34.
r(_COLOR_BUFFER_BIT);
35.
//
初始化绘图调用
36.
();
37.
//
绘制精灵到游戏屏幕
38.
(texture,
100
,
180
);
39.
//
结束绘图调用
40.
();
41.
}
42.
public
void
resize(
int
width,
int
height) {
43.
}
44.
public
void
resume() {
45.
}
46.
}
47.
public
void
onCreate(Bundle bundle)
{
48.
super
.onCreate(bundle);
49.
//
初始化游戏屏幕,并设置是否支持
GLES 2.0
,如果您对向下兼容没什么需
要选择
true
p>
即可
(2.1
以上
)
,否则选择
false
。
50.
initialize(
new
TestPixmap(),
true
);
51.
}
52.
}
BitmapFont:
Libg
dx
所提供的
OpenGL
文字用类,
构造
BitmapFont
时需要一个描述文字构成的
fnt
文件,
和一个提供文字图片的
png
文件(
PS:
在<
/p>
Libgdx
的
包下有提供内置字
库,目前仅支持英文、数字和常见符号),同
SpriteBatch
相配合时能够完成一些基础的文
字绘图
。值得一提的是,我们也可以使用
BitmapFontCache
类将
BitmapFont
包装成了一个
< br>静态的
Font
实例,以避免大量贴图时产生的不必要损
耗。
view
plaincopy to clipboardprint?
1.
//libgdx
的文字显示
2.
public
class
Main
extends
AndroidApplication {
3.
class
TestFont
extends
Game {
4.
// SpriteBatch
是
libgdx
提供的
opengl<
/p>
封装,
可以在其中执行一些常规的图像渲
染,
5.
//
< br>并且
libgdx
所提供的大多数图形功能也是围绕它建
立的。
6.
SpriteBatch spriteBatch;
7.
// BitmapFont
是
libgdx
提供的文字显示用类,内部将图片转化为可供
p>
opengl
调用的
8.
//
文字贴图
(
默认不支持中文
)
。
9.
BitmapFont font;
10.
public
void
create() {
11.
//
构建
SpriteBatch
用
于图像处理
(
内部调用
opengl<
/p>
或
opengles)
12.
spriteBatch =
new
SpriteBatch();
13.
//
构建
BitmapFont
,必
须有一个
fnt
文件描述文字构成,一个图片文件提供
文字用图
14.
15.
16.
17.
font =
new
BitmapFont(al(
),
.internal(
),
false
);
}
public
void
render() {
18.
//
调用清屏
19.
r(_COLOR_BUFFER_BIT);
20.
//
初始要有
begin
起始
21.
();
22.
//
显示文字到屏幕指定位置
23.
// PS:Libgdx
采用标准笛卡尔坐标系,自左下
p>
0,0
开始
24.
25.
26.
27.
(spriteBatch,
+
mesPerSecond(),
5
,
475
);
(spriteBatch,
,
255
,
255
);
//
结束要有
end
结尾
28.
();
29.
}
30.
public
void
resize(
int
width,
int
height) {
31.
}
32.
public
void
pause() {
33.
}
34.
public
void
resume() {
35.
}
36.
public
void
dispose() {
37.
//
释放占用的资源
38.
39.
40.
41.
42.
e();
e();
}
}
public
void
onCreate(Bundle bundle)
{
43.
super
.onCreate(bundle);
44.
//
初始化游戏屏幕,并设置是否支持
GLES 2.0
,如果您对向下兼容没什么需
要选择
true
p>
即可
(2.1
以上
)
,否则选择
false
。
45.
initialize(
new
TestFont(),
true
);
46.
}
47.
}
48.
SpriteBatch:
Lib
gdx
所提供的纹理渲染器,
本质上是
OpenGL
的简易封装体,
具体实现上与
XNA
中的
SpriteBatch
类非常近似,每次调用
SpriteBatch
类都必须以<
/p>
begin
函数开头,以
end
函数结尾。由于
Libgdx
中
SpriteBatch
提供的功能还非常有限,所以在完全不懂
OpenGL
的前提下使用其进行游戏开发或许有一定难度。
ShaderProgram:
L
ibgdx
所提供的着色器,在
Android
环境使用时需要
GLES2.0
或以上版本才能完整<
/p>
支持的高级渲染功能之一,内部封装着
GLES2.0
专用的顶点着色与片断着色
Shader
Mod
el
,
它的本质作用是对
3D
对象表面进行渲染处理,
此物性能基本取决于
G
PU
(除
了
Google
Nexus
系列手机暂未见能完全跑出速度的机型)。
view plaincopy to
clipboardprint?
1.
//libgdx
的
ShaderProgram
使用
2.
public
class
Main
extends
AndroidApplication {
3.
class
TestShader
implements
ApplicationListener {
4.
ShaderProgram shader;
5.
Texture texture;
6.
Texture texture2;
7.
Mesh mesh;
8.
public
void
create() {
9.
//
以下命令供
GPU
使用
(
不支持
GLES2.
0
就不用跑了
)
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
String
vertexShader =
n
+
n
+
n
+
n
+
n
+
gl_Position = a_position;
n
+
v_texCoord = a_texCoord;
n
+
n
;
String fragmentShader =
+
+
+
n
+
n
+
n
+
n
+
n
+
texture2D( s_texture2,
v_texCoord);n
27.
+
n
;
28.
//
构建
ShaderProgram
29.
shader =
new
ShaderProgram(vertexShader, fragmentShader);
30.
//
构建网格对象
31.
32.
33.
34.
35.
36.
37.
mesh =
new
Mesh(
true
,
4
,
6
,
new
VertexAttribute(on,
2
,
),
new
VertexAttribute(
eCoordinates,
2
,
));
float
[] vertices
= { -
0
.5f,
0
.5f,
0
.0f,
0
.0f,
-
0
.5f,
-
0
.5f,
0
.0f,
1
.0f,
0
.5f,
-
0
.5f,
1
.0f,
1
.0f,
0
.5f,
0
.5f,
1
.0f,
0
.0f };
short
[] indices = {
0
,
1
,
2
,
0
,
2
,
3
};
//
注入定点坐标
38.
tices(vertices);
39.
ices(indices);
40.
//
以
Pixmap
生成两个指定内容的
Texture
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
Pixmap
pixmap =
new
Pixmap(
256
,
256
, 8888);
or(
1
,
1
,
1
,
1
);
();
or(
0
,
0
,
0
,
1
);
ne(
0
,
0
,
256
,
256
);
ne(
256
,
0
,
0
,
256
);
texture =
new
Texture(pixmap);
e();
pixmap =
new
Pixmap(
256
,
256
, 8888);
or(
1
,
1
,
1
,
1
);
();
or(
0
,
0
,
0
,
1
);
ne(
128
,
0
,
128
,
256
);
texture2 =
new
Texture(pixmap);
e();
}
public
void
dispose() {
58.
}
59.
public
void
pause() {
60.
}
61.
public
void
render() {
62.
// PS:
由于使用了
Shader
Program
,因此必须配合
gl20
模式(否则缺少关键
opengles
接口)
63.
64.
65.
66.
67.
68.
69.
port(
0
,
0
, th(), cs
.getHeight());
r(_COLOR_BUFFER_BIT);
veTexture(_TEXTURE0);
();
veTexture(_TEXTURE1);
();
70.
//
开始使用
ShaderProg
ram
渲染
71.
72.
73.
74.
75.
();
formi(
,
0
);
formi(
,
1
);
(shader, _TRIANGLES);
//
结束
ShaderProgram
渲染
76.
();
77.
}
78.
public
void
resize(
int
width,
int
height) {
79.
}
80.
public
void
resume() {
81.
}
82.
}
83.
public
void
onCreate(Bundle bundle)
{
84.
super
.onCreate(bundle);
85.
//
初始化游戏屏幕,并设置是否支持
GLES 2.0
,如果您对向下兼容没什么需
要选择
true
p>
即可
(2.1
以上
)
,否则选择
false
。
86.
initialize(
new
TestShader(),
true
);
87.
}
88.
}
FrameBuffer:
Lib
gdx
所提供的帧缓冲器,在
Android
< br>环境使用时需要
GLES2.0
或以上版本才能完整支持
的高级渲染功能之一,也就是常说的
FrameBuffer
Object
(
FBO
)功能封装(用
过
JavaSE
或
JavaME
开发游戏的朋友,绘图时大概都接触过双缓存这个概念,虽然有所差别,不过将
FrameBuffer
理解成起近似作用也未尝不可)此物性能彻底取决于<
/p>
GPU
(除了
Google
Nexus
系列手机暂未见能完全跑出速度的机型)。
view plaincopy to
clipboardprint?
1.
//libgdx
的
FrameBuffer
使用
2.
public
class
Main
extends
AndroidApplication {
3.
class
TestFrameBuffer
implements
ApplicationListener {
4.
FrameBuffer frameBuffer;
5.
Mesh mesh;
6.
ShaderProgram
meshShader;
7.
Texture
texture;
8.
SpriteBatch spriteBatch;
9.
// PS:
如果不支持
GLES2.0
就不用试了
10.
public
void
create() {
11.
mesh =
new
Mesh(
true
,
3
,
0
,
new
VertexAttribute(on,
3
,
12.
13.
14.
15.
16.
17.
18.
),
new
VertexAttribute(acked,
4
,
),
new
VertexAttribute(eCoordinates,
2
,
));
float
c1 =
tBits(
255
,
0
,
0
,
255
);
float
c2 =
tBits(
255
,
0
,
0
,
255
);
float
c3 =
tBits(
0
,
0
,
255
,
255
);
tices(
new
float
[] {
-
0
.5f,
-
0
.5f,
0
, c1,
0
,
0
,
0
.5f,
19.
-
0
.5f,
0
, c2,
1
,
0
,
0
,
0
.5f,
0
, c3,
0
.5f,
1
});
20.
texture =
new
Texture(al(
));
21.
spriteBatch =
new
SpriteBatch();
22.
frameBuffer =
new
FrameBuffer(565,
128
,
128
,
true
);
23.
String
vertexShader =
n
24.
+
25.
+
+
26.
+
+
27.
n
28.
+
n
29.
+
v_Color =
a_Color;
30.
+
v_texCoords
= a_texCoords;n
31.
+
gl_Position =
a_Position; n
32.
+
n
;
33.
String
fragmentShader =
34.
+
35.
+
36.
+
37.
+
38.
n
39.
+
n
40.
+
41.
+
;
42.
meshShader =
new
ShaderProgram(vertexShader, fragmentShader);
43.
if
(iled() ==
false
)
44.
throw
new
IllegalStateException(());
45.
}
46.
public
void
dispose() {
47.
}
48.
public
void
pause() {
49.
}
50.
public
void
render() {
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
();
20().glViewport(
0
,
0
, th(),
ght());
20().glClearColor(0f, 1f, 0f,
1
);
20().glClear(_COLOR_BUFFER_BIT);
20().glEnable(_TEXTURE_2D);
();
();
formi(
,
0
);
(meshShader, _TRIANGLES);
();
();
20().glViewport(
0
,
0
, th(),
ght());
20().glClearColor(
0
.2f,
0
.2f,
0
.2f,
1
);
20().glClear(_COLOR_BUFFER_BIT);
();
(orBufferTexture(),
0
,
0
,
256
,
256
,
0
,
0
,
orBufferTexture().getWidth(),
orBufferTexture().getHeight(),
false
,
true
);
();
}
public
void
resize(
int
width,
int
height) {
75.
}
76.
public
void
resume() {
77.
}
78.
}
79.
public
void
onCreate(Bundle bundle)
{
80.
super
.onCreate(bundle);
81.
//
初始化游戏屏幕,并设置是否支持
GLES 2.0
,如果您对向下兼容没什么需
要选择
true
p>
即可
(2.1
以上
)
,否则选择
false
。
82.
initialize(
new
TestFrameBuffer(),
true
);
83.
}
84.
}
关于
Libgdx
< br>的游戏组件部分:
在最近更
新的
Libgdx
中,与游戏显示相关度最高的包总共有两个,
一个是
graphics
包,其
中包含
着
Libgdx
为进行
OpenGL<
/p>
渲染所提供的功能实现,
而另一个,
就是
下面介绍的
scenes
包,这里包含着
Libgdx
所提供的可以直接使用到游戏中的游戏组件,共分
scenes2d
以及
scenes3d
两大部分(
3D
部分暂无内容)。其中
2D
部分的核心在于
Actor
类
,
Libgdx
所有
2D
组件使用都围绕着
Actor
展开。
对于
Libgdx
中游戏组
件使用的简单关系说明:
AndroidApplication
(Activity
的子类,
只有启动类继承了
Andro
idApplication
并执行才能启动
Libgdx
p>
类库
)
ApplicationListener
(
仅可在初始化时注入
ApplicationListener
,此后除非替换
Activity
否则无
法切换
ApplicationListener) -
Game
(ApplicationListener
的
libgdx
抽象实现,
< br>其中
Screen
可切
换
)
Screen
(基本函数与
ApplicationListener
近乎一
致,唯一差别在于可以通过
Game
类用
setScreen
函数进行切换,如不使用
Game
类则可无视它的存在)
Stage
(
游戏场景用类,
用以管理添加其中的具体<
/p>
Actor
,
管理
Actor
的手段在于内置的
Group
类)
|
Group
(本身为
Actor
的具体实现,能够处理注入其
中的
Actor
,也能以递归方式管理注入
其中的其它
Group
)
|
Actor
(游戏用演员或者说角
色,与
Action
类组合使用时可以产生不同种类的
“
动画行为
”
,
Action
部分的具体实现基本与
Coco
s2D
一致)
|
Image
、
Button
、
p>
Label
等
(
细分
Actor
的具体实现,以重载方式响应事件,除
Group
外相互
间不能组合叠加,事件能否传
递取决于上级组件是否设置了相关监听)
view
plaincopy to clipboardprint?
1.
//Libgdx
中
Actor
的使用
2.
public
class
Main
extends
AndroidApplication {
3.
class
TestActor
implements
ApplicationListener {
4.
Stage stage;
5.
public
void
create() {
6.
//
构建等值于屏幕大小的场景
7.
stage =
new
Stage(th(), ght(),
false
);
8.
//
构建
Button
9.
Button btn
=
new
Button(
,
xture(
)
10.
.get()) {
11.
// PS:
因为
Libgdx
的
touchDown
< br>有内部实现,所以重载
touchDown
时必
须调用
super
方法(肯定没
LGame
方便啦
^^~
)<
/p>
12.
protected
boolean
touchDown(
float
x,
float
y,
int
pointer) {
13.
super
.touchDown(x, y,
pointer);
14.
(
,
+x+
+y);
15.
return
true
;
16.
}
17.
};
18.
btn.x =
55
;
19.
btn.y =
55
;
20.
or(btn);
21.
//
注入
Stage
监听,让
Stage
响应窗体事件,必须。(否则无论
注入
Stage
什么
Actor
都不会响应事件)
22.
utProcessor(stage);
23.
}
24.
public
void
dispose() {
25.
e();
26.
}
27.
public
void
pause() {
28.
}
29.
public
void
render() {
30.
//
绘制
stage
到屏幕
31.
();
32.
// PS:Libgdx
无论游戏业务或游戏绘图刷新都经过
render
33.
//
传递屏幕刷新时间给
stage
,以执行内部业务操作,如果没有这步,则所
有注入
Stage
中
Actor
的
act
方法无法执行
34.
(taTime());
35.
}
36.
public
void
resize(
int
width,
int
height) {
37.
}
38.
public
void
resume() {
39.
}
40.
}
41.
public
void
onCreate(Bundle bundle)
{
42.
super
.onCreate(bundle);
43.
//
初始化游戏屏幕,并设置是否支持
GLES 2.0
,如果您对向下兼容没什么需
要选择
true
p>
即可
(2.1
以上
)
,否则选择
false
。
44.
initialize(
new
TestActor(),
true
);
45.
}
46.
}
view plaincopy to
clipboardprint?
1.
//Libgdx
中
Action
的使用
2.
public
class
Main
extends
AndroidApplication {
3.
class
TestAction
implements
ApplicationListener {
4.
Stage stage;
5.
Texture texture;
6.
public
void
create() {
7.
//
构建场景
8.
stage =
new
Stage(th(),
9.
ght(),
false
);
10.
//
构建纹理
11.
texture =
new
Texture(al(
));
12.
ter(, );
13.
//
构建图像精灵
14.
15.
16.
17.
18.
19.
20.
21.
22.
Image img
=
new
Image(
, texture);
= =
100
;
img.x = img.y =
100
;
//
依次让图像使用下列动作(
PS:“$$”
符号为调用对应
p>
Action
类的静态函数
名,就那么起的
罢了(不过有缓存)
……
)
(Forever.$$(Sequence.$$(Sc
aleTo.$$(
1
.1f,
1
.1f,
0
.3f),
ScaleTo.$$(1f, 1f,
0
.3f))));
or(img);
}
public
void
render() {
23.
r(_COLOR_BUFFER_BIT);
24.
(taTime());
25.
();
26.
}
27.
public
void
dispose() {
28.
e();
29.
e();
30.
}
31.
public
void
pause() {
32.
}
33.
public
void
resize(
int
width,
int
height) {
34.
}
35.
public
void
resume() {
36.
}
37.
}
38.
public
void
onCreate(Bundle bundle)
{
39.
super
.onCreate(bundle);
40.
//
初始化游戏屏幕,并设置是否支持
GLES 2.0
,如果您对向下兼容没什么需
要选择
true
p>
即可
(2.1
以上
)
,否则选择
false
。
41.
initialize(
new
TestAction(),
true
);
42.
}
43.
}
就目前来说,
Libgdx
可用的游戏组件相对比较稀少,部分功能或者需要用户自行实现。不
过最
近有一位网名
moritz
的手机游戏
“
半全职
”
开发者
(因为他自己说手机游戏并不是他唯一
的收入来源)已经加入
Libgdx
项目,未来将重点改进
Libgdx
的
scene2d
部分,鉴于
Libgdx
作者为此特意写了一篇名为
“welcome
moritz”
的博文,
moritz
此人应该是有一定能力的家伙,
对于
Lingdx
未来表现大约还是值得期待的(话说,莫非
moritz
只对改造
Libgdx
的
2D
p>
模块
有兴趣?
Libgdx
作者博文中提到目前
moritz
开发的
3D
游戏没有使用
Libgdx
——
那啥,先
把
3D
组件部分做出来吧,现在是
NULL
啊
……
)。
在
Libgdx
的
SVN
,也
有一些具体的游戏示例,大家可以下载后亲身体验其效果。
P
S
:为体现
Libgdx
最新特性,上
述示例使用的
Libgdx
是
2
月
1
日从
Libgd
x SVN
下载的版
本(
2011
p>
年
1
月
28
日更新版),请自行下载相关类库,以保证所用版本维持在最新。
附录,使用
Libgdx
时的几点注意事项:
1
、
Libgdx
使用笛卡尔坐标系
(
初始坐标为左下
0,0)
,而
JavaSE
、
JavaME
以及标准
Android
系统(还有
LGame
引擎)使用的是屏幕坐
标系(初始坐标为左上
0,0
),程序员在使用时必
须分清差别,以免不知道如何定位(通常笛卡尔系
Y
轴由下向上延伸,屏幕系
Y
轴由上向
下延伸)。
2
、
在
Android
环境使用
Lib
gdx
的
al
方法时
< br>(即
FileHandle
类以
al
模式工作),要读取的文件必须置于
Assets
文件夹下才能读取,在
Linux
、
Mac
、
Windows
环境下则可以置于除
jar
内部外的任何可读取位置。
3
、
Libgdx<
/p>
以
native
方式自带图像解码器,通
过其提供的
Pixmap
可以对指定图像进行像素
级渲染操作,
从而不依赖
Android
的
Bitmap
加载处理图像,
< br>不过目前只支持
png
、
jpg
、
bmp
三种图片格式。
4
、
Libgdx
要求在游戏中使用的图片宽与高皆为
2
的整数
次幂,
否则会产生一个
Gdx
异常并<
/p>
禁止加载行为
(texture width and
height must be powers of
two)
。
5
、
Libgdx
以
Applicat
ionListener
作为游戏的基础界面容器,
其作用近似
LGame
中的
Screen
,
但并不完全一致,
因为
Libgdx
并没有提供可以直接切换
Applicatio
nListener
的函数。
目前最
新
版本的
Libgdx
中提供了
Game
类
(
ApplicationList
ener
子类,
本身为抽象类)
和一个
供
Game
类调用的
Screen
p>
类用以解决此问题。具体的
Libgdx
切
换游戏画面方法是,先用继承
Game
类的游戏窗体进行
initialize
让基础画面显示,再让具体的细分游戏模块继承
Screen
类进行
不同游戏画面的具
体绘图,而后
Game
类通过
setS
creen
方法进行画面切换。
<
/p>
6
、
Libgdx
的图像加载处理(以及部分渲染),音频播放和自带的
Box2D
封装皆通过
JNI
方式实现,
因此
必须在
libs
文件夹下添加
arme
abi
(或高版本
Android
系统
支持的
armeabi-v7a
)
文件
夹以及相关
so
文件
Android<
/p>
版
Libgdx
才能正常运行。
7
、千万不要以模
拟器上的
Libgdx
运行速度判定其性能,否则很容易产生误
判
(也不建议用
性能不好的真机运行)
ProjectionViewportCamera
learn about a viewport's proportions,
how to specify a projection, and to use
Camera
Updated Mar 18, 2011
by
manifa...@
Introduction
In the
MyFirstTriangle
and
ColorMeshTexture tutorials, we learned the basics
of setting up and
rendering meshes. Did
you notice, however, that the triangles we created
appear stretched?
Lets start with an
example that will make this issue clear.
Creating a Square
Create a
new libgdx desktop project named
projection-viewport-camera
.
Create a class
called
ProjectionViewportCamera
that implements
ApplicationListener
and put it in the
package
tionviewportcamera
. For full
instruction on how to set up a
libgdx
desktop (and Android) project, look at the
MyFirstTriangle
tutorial.
Unlike in that tutorial,
we're going to
show a square instead of a rectangle. Here's the
code
for
ProjectionViewportCamera
:
package
com
.
example
.
projectionview
portcamera
;
import
com
.
badlogic
.
gdx
.
ApplicationListener
;
import
com
.<
/p>
badlogic
.
gdx
.
Gdx
;
import
com
.
badlogic
.
gdx
.
graphics
.
Color
p>
;
import
com
.
badlogic
.
gdx
.
graphics
.
GL10
;
import
com
.
badlogic
.
gdx
.
graphics
.
Mesh
;
import
com
.
badlogic
.
gdx
.
graphics
.
VertexAttribute
;
import
com
.
badlogic
.
gdx
< br>.
graphics
.
Vert
exAttributes
.
Usage
;
public
class
ProjectionViewportCamera
implements
ApplicationListener
{
private
Mesh
squarePartOne
;
private
Mesh
squarePartTwo
;
@Override
public
void
create
()
{
if
(
squarePartOne
==
null
)
{
squarePartOne
=
new
Mesh
(
true
,
3
,
3
,
new
VertexAttribu
te
(
Usage
.
< br>Position
,
3
,
),
new
VertexAttribu
te
(
Usage
.
< br>ColorPacked
,
4
,
));
squarePartOne
.
setVertices
(
new
float
[]
{
-
0.5f
,
-
0.5f
,
0
,
Col
or
.
toFloatBits
(
p>
128
,
0
,
0
,
255
),
0.5f
,
-
0.5f
,
0
,
Col
or
.
toFloatBits
(
p>
192
,
0
,
0
,
255
),
-
0.5f
,
0.5f
,
0
,
Col
or
.
toFloatBits
(
p>
192
,
0
,
0
,
255
)
});
squarePartOne
.
setIndices
(
new
short
[]
{
0
,
1
,
2
});
}
if
(
squarePartTwo
==
null
)
{
squarePartTwo
=
new
Mesh
(
true
,
3
,
3
,
new
VertexAttribu
te
(
Usage
.
< br>Position
,
3
,
),
new
VertexAttribu
te
(
Usage
.
< br>ColorPacked
,
4
,
));
squarePartTwo
.
setVertices
(
new
float
[]
{
0.5f
,
-
0.5f
,
0
,
Col
or
.
toFloatBits
(
p>
192
,
0
,
0
,
255
),
-
0.5f
,
0.5f
,
0
,
Col
or
.
toFloatBits
(
p>
192
,
0
,
0
,
255
),
0.5f
,
0.5f
,
0
,
Col
or
.
toFloatBits
(
p>
255
,
0
,
0
,
255
)
});
squarePartTwo
.
setIndices
(
new
short
[]
{
0
,
1
,
2
});
}
}
@Override
public
void
dispose
()
{
}
@Override
public
void
pause
()
{
}
@Override
public
void
render
()
{
Gdx
.
gl
.
glClear
(
GL10
.
GL_COLOR_BUFFER_BIT
);
squarePartOne
.
render
(
GL10
.
GL_TRIANGLES
,
0
,
3
);
squarePartTwo
.
render
< br>(
GL10
.
GL_TRIAN
GLES
,
0
,
3
);
}
@Override
public
void
resize
(
int
width
,
int
height
)
{
}
@Override
public
void
resume
()
{
}
}
It's very
similar to the class described in the
MyFirstTriangleTutorial except that it has two
triangles instead of one. The two
triangles are positioned to form a square, with
corners at
position (x, y) coordinates
(-0.5, -0.5), (0.5, -0.5), (0.5, 0.5), and (0.5,
-0.5). When you run the
desktop app it
should look like this:
Obviously, even though we specified the
coordinates of a square, the resulting shape
turned
out to be a wide rectangle.
Before tackling this issue, I will digress for a
moment and offer a
rendering
optimzation for this square.
The two
triangles each have a vertex at (0.5, -0.5) and a
vertex at (-0.5, 0.5). We can eliminate
the duplication of vertices at
identical coordinates by implementing the square
using
triangle
strips
. Using triangle
strips allow the two triangles to share vertices
and therefore use memory
more
efficiently (check out
Jeff LaMarche's
tutorial
for a better illustration).
Here's the new
implementation:
package
com
.
example
.
projectionview
portcamera
;
import
com
.
badlogic
.
gdx
.
ApplicationListener
;
import
com
.<
/p>
badlogic
.
gdx
.
Gdx
;
import
com
.
badlogic
.
gdx
.
graphics
.
Color
p>
;
import
com
.
badlogic
.
gdx
.
graphics
.
GL10
;
import
com
.
badlogic
.
gdx
.
graphics
.
Mesh
;
import
com
.
badlogic
.
gdx
.
graphics
.
VertexAttribute
;
import
com
.
badlogic
.
gdx
< br>.
graphics
.
Vert
exAttributes
.
Usage
;
public
class
ProjectionViewportCamera
implements
ApplicationListener
{
private
Mesh
squareMesh
;
@Override
public
void
create
()
{
if
(
squareMesh
==
null
)
{
squareMesh
=
new
Mesh
(
true
,
4
,
4
,
new
VertexAttribu
te
(
Usage
.
< br>Position
,
3
,
),
new
VertexAttribu
te
(
Usage
.
< br>ColorPacked
,
4
,
));
squareMesh
.
setVertices
(
new
float
[]
{
-
0.5f
,
-
0.5f
,
0
,
Col
or
.
toFloatBits
(
p>
128
,
0
,
0
,
255
),
0.5f
,
-
0.5f
,
0
,
Col
or
.
toFloatBits
(
p>
192
,
0
,
0
,
255
),
-
0.5f
,
0.5f
,
0
,
Col
or
.
toFloatBits
(
p>
192
,
0
,
0
,
255
),
0.5f
,
0.5f
,
0
,
Col
or
.
toFloatBits
(
p>
255
,
0
,
0
,
255
)
});
squareMesh
.
setIndices
(
new
short
[]
{
0
,
1
,
2
,
3
});
16
}
}
@Override
public
void
dispose
()
{
}
@Override
public
void
pause
()
{
}
@Override
public
void
render
()
{
Gdx
.
gl
.
glClear
(
GL10
.
GL_COLOR_BUFFER_BIT
);
squareMesh
.
render
(
GL10
.
GL_TRIANGLE_STRIP
,
0
,
4
);
}
@Override
public
void
resize
(
int
width
,
int
height
)
{
}
@Override
public
void
resume
()
{
}
}
The two
triangles have been combined in a single mesh with
four vertices and four indices.
Inside
render()
, we specify that
the square was defined using triangle strips.
Fewer vertices
are necessary and the
code is simpler too.
Viewport
Back to the issue of the stretched
square. By default the viewport reveals a
rectangular area
with a left edge at x
= -1, right edge at x = 1, top edge at y = 1, and
bottom edge at y = -1.
Here's a picture
of what a blank area like that would look like if
we were to create
mockup:
When we place out red square onto that
area, the result looks like this: