博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
libgdx游戏引擎开发笔记(六)舞台、演员、动画综合讲解
阅读量:5871 次
发布时间:2019-06-19

本文共 6465 字,大约阅读时间需要 21 分钟。

   今天要讲解的舞台和演员是libgdx游戏引擎中重要的两个类,先简单介绍一下,待会用个显示动画的实例来综合应用一下!

先上一张图:

   在这张图中,我们可以看到有动的小鸟,不动的按钮,有特效,没有特效。。。。等等这些都称之为演员,而管理这些演员的自然就是舞台了。

一.介绍

1.Actor 演员类:

  定义:在二维场景图中,一个演员拥有的位置,矩形的大小,起点,规模,旋转,和颜色等属性。位置对应且不成比例。演员的位置是相对于演员的父母,它的起点是相对位置,同时可用于缩放和旋转。一个演员也有一个行动,可以操纵的演员在时间段内活动,同时可以加入监听来实现演员接收事件通知。

   演员是游戏设计中常用的一个对象,它接受舞台的统一管理,拥有一些公共的事件,比如触摸,点击,但是同时还有自身的响应和属性


2.Stage 舞台类:

   定义:包含拥有层次结构的一个二维场景,场景中有许多演员。期处理视图和分配的输入事件。舞台负责操作视角,和处理分配输入事件。

    一个Stage可以充满整个屏幕。设置视角(一般是浮点型和布尔类型),同时设置阶段内使用的相机,调配 Actor、Group 与 Screen 之间的关系转换(包括坐标)。一个Stage必须负责接收输入事件,同时将它分配给演员。这通常是通过Stage的gdx.input.setinputprocessor来实现。一个inputmultiplexer可用来处理输入事件的不同阶段,即之前或之后。如果一个演员通过返回TRUE从输入的方法中处理一个事件,那么Stage的输入方法也会返回true,导致随后的inputprocessors不接收事件。

可以参那副结构图就更明了了


3.Aniamation 动画类:

 定义:动画是由多个帧,在设定的时间间隔序列显示。比如,一个走路的人一个动画可以通过运行时播放这些图像无限拍照他了。简单的说就是管理动画,设置随即播放模式和播放顺序。


二.代码实现

  1.功能:点击屏幕出现宠物的移动动画(不清楚的直接看注解哦!)

   2.代码:


程序入口:

1
2
3
4
5
6
7
8
9
10
11
12
13
package 
com.zhf.android_libgdx_animation;
import 
com.badlogic.gdx.backends.android.AndroidApplication;
import 
android.os.Bundle;
public 
class 
MainActivity 
extends 
AndroidApplication{
    
@Override
    
protected 
void 
onCreate(Bundle savedInstanceState) {
        
super
.onCreate(savedInstanceState);
        
//在此启动游戏,MyGame实现了ApplicationListener的类
        
initialize(
new 
MyGame(), 
false
);
         
//specifying the configuration for the GLSurfaceView.
        
//第二个参数如果设为true,则在opengl 2.0可用的情况下会使用opengl 2.0。
    
}
}


主界面:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package 
com.zhf.android_libgdx_animation;
import 
com.badlogic.gdx.ApplicationListener;
import 
com.badlogic.gdx.Gdx;
import 
com.badlogic.gdx.assets.AssetManager;
import 
com.badlogic.gdx.graphics.GL10;
import 
com.badlogic.gdx.graphics.Texture;
import 
com.badlogic.gdx.scenes.scene2d.Stage;
public 
class 
MyGame 
implements 
ApplicationListener {
    
private 
Stage stage;  
//舞台
    
private 
MyActor myActor; 
//演员
    
private 
AssetManager assetmanager;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
    
boolean 
hasinit;  
//是否已经初始化
    
@Override
    
public 
void 
create() {
        
//新建一个舞台
        
stage = 
new 
Stage(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), 
true
);
        
//实例化AssetMangager
        
assetmanager = 
new 
AssetManager();
        
//传入AssetManger的引用,便于动画的资源初始化,但是注意了,只有在调用iniResourse()后资源才被初始化
        
myActor = 
new 
MyActor(assetmanager);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
        
// //把资源加入载入列表,在asset文件夹下animal下有29张图片
        
for 
(
int 
i = 
1
; i < 
30
; i++) {
            
assetmanager.load(
"animal/" 
+ i + 
".png"
, Texture.
class
);
            
/*manager.load()方法只是将资源放入加载列表,而真正的加载要不停地调用manager.update()才可以,且update()函数有一个返回值,载入完成返回true,未完成返回false.*/
        
}
    
}
    
@Override
    
public 
void 
dispose() {
        
myActor.dispose();
        
assetmanager.clear();
        
assetmanager.dispose();
    
}
    
@Override
    
public 
void 
pause() {
    
}
    
@Override
    
public 
void 
render() {
        
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);  
//清屏
        
Gdx.gl.glClearColor(0f,0f,0f,0f);
        
stage.act(Gdx.graphics.getDeltaTime());
        
stage.draw();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
        
// 加载完成且之前没有初始化过MyActor,且在手触摸屏幕时初始化MyActor,加入MyActor对象
        
if
(!hasinit && assetmanager.update() && Gdx.input.isTouched()) {
            
myActor.initResource(); 
//初始化图片资源
            
stage.addActor(myActor);  
//加入演员
            
hasinit = 
true
;
        
}
    
}
    
@Override
    
public 
void 
resize(
int 
arg0, 
int 
arg1) {
    
}
    
@Override
    
public 
void 
resume() {
    
}
}

一个演员类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package 
com.zhf.android_libgdx_animation;
import 
java.util.ArrayList;
import 
com.badlogic.gdx.Gdx;
import 
com.badlogic.gdx.assets.AssetManager;
import 
com.badlogic.gdx.graphics.Texture;
import 
com.badlogic.gdx.graphics.g2d.Animation;
import 
com.badlogic.gdx.graphics.g2d.SpriteBatch;
import 
com.badlogic.gdx.graphics.g2d.TextureRegion;
import 
com.badlogic.gdx.scenes.scene2d.Actor;
import 
com.badlogic.gdx.utils.Disposable;
/**
 
* 演员是游戏设计中常用的一个对象,它接受舞台的统一管理,拥有一些公共**的事件,比如触摸,点击,但是同时还有自身的响应和属性。
 
* 实现Disposable接口,为的是能及时释放内存。
 
* @author ZHF
 
*
 
*/
public 
class 
MyActor 
extends 
Actor 
implements 
Disposable{
    
ArrayList<Texture> TexArray = 
new 
ArrayList<Texture>();
    
ArrayList<TextureRegion> TexReArray = 
new 
ArrayList<TextureRegion>();
    
Animation animation;  
//动画
    
TextureRegion[] walksFrame;
    
float 
stateTime;
    
TextureRegion currentFrame; 
// 当前帧
    
AssetManager manager;
    
public 
MyActor(AssetManager manager) {
        
this
.manager = manager;
    
}
    
/**
     
*
     
* 这是一个系统自动调用的方法,描述这个演员Actor实例怎么绘制,draw()方法并不需要我们人工去调用,而是在把Actor加入舞台Stage中后,
     
* 在ApplicationListener的render
     
* ()函数中不停地调用stage.draw(),系统会自动调用已经加入stage中的actor的draw()方法,也就将actor一起绘制出来了
     
*/
    
@Override
    
public 
void 
draw(SpriteBatch batch, 
float 
parentAlpha) {
        
stateTime += Gdx.graphics.getDeltaTime();
        
// 得到下一帧
        
currentFrame = animation.getKeyFrame(stateTime, 
true
); 
// 循环
        
// 以(0,0)绘制为起点(左下角为100,100)画出动画,大小128*128
        
batch.draw(currentFrame, 
100
100
128
128
);
    
}
    
@Override
    
public 
Actor hit(
float 
x, 
float 
y, 
boolean 
touchable) {
        
return 
this
;
    
}
    
// 初始化方法,在Progress中的AssetManager初始化完成后通知AnimalActor初始化
    
public 
void 
initResource() {
        
Texture tex;
        
int 
j;
        
for 
(
int 
i = 
1
; i < 
30
; i++) {
            
TexArray.add(manager.get(
"animal/"
+i+
".png"
, Texture.
class
));
        
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         
        
for 
(
int 
i = 
0
; i < TexArray.size(); i++) {
            
tex = TexArray.get(i);
            
TextureRegion temTexRe = 
new 
TextureRegion(tex);
//区域
            
TexReArray.add(temTexRe); 
//添加进去
        
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         
        
j = TexReArray.size();  
//数组长度
        
walksFrame = 
new 
TextureRegion[j];  
//装区域的数组
        
for
(
int 
i= 
0
; i < j; i++) {
            
walksFrame[i] = TexReArray.get(i);  
//将集合中的“区域”给了数组
        
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         
        
//设置的0.06s一帧
        
animation = 
new 
Animation(
0
.06f, walksFrame);
    
}
    
@Override
    
public 
void 
dispose() {
        
for 
(
int 
i = 
0
; i <TexArray.size(); i++) {
            
TexArray.get(i).dispose();
        
}
    
}
}

效果图:

分析:

1.在MyGame类中,我们实例化了舞台和演员,在render()中让舞台开始绘画,里面所添加的各种演员就会自动调用自己的draw()进行绘画,不需要手动调用的哦!

   2.这里们还使用了AssetManager:一个资源异步加载和资源自动管理类,简单介绍一下:

  2.1什么时候需要资源预加载?

       (资源预加载的目的很明确,提升用户体验。当然就开发者而言,比较好的预加载实现方式还可以方便管理。)

   1.资源数量大:音乐、图片、视频什么的,如果你的游戏这些东西太多,推荐使用

   2.部分资源反复使用:有些资源会反复使用到,比如一些背景音乐,一些小图标

     2.2下面资源类型可以由AssetManager直接创建:

Pixmaps、Textures、BitmapFonts、TextureAtlases、TiledAtlases、TileMapRenderers 、  Music instances、 Sound instances、

    加载某个资源很简单:

1
2
manager.load(
"data/testin.png"
, Texture.
class
);
manager.load(
"data/ testin.fnt"
, BitmapFont.
class
);

 2.3. 在加载前,AssetManager需要知道加载什么类型的资源,这个功能通过资源加载器实现。有两个变量,同步资源加载器SynchronourAssetLoader和异步资源加载器AsynchronousAssetLoader。前者加载任何资源都在渲染进程中,后者加载资源在另外一个线程中。比如说,一个Texture需要一个Pixmap,然后加载OpenGL依赖于渲染线程。

       2.4.manager.load()方法只是将资源放入加载列表,而真正的加载要不停地调用manager.update()才可以,这个方法也是render()中系统自己调用的哦!

  ok! 有点扯远了哈!Stage和Actor的简单使用就是这些,同时我们也应该关注AssetManager,这个资源管理类!

   源码下载:

     本文转自zhf651555765 51CTO博客,原文链接:http://blog.51cto.com/smallwoniu/1258251,如需转载请自行联系原作者

你可能感兴趣的文章
【转】Linux下查看系统配置
查看>>
impdp导入job
查看>>
python 爬虫 常见安全措施
查看>>
python基础 - 变量与运算符
查看>>
指针和const笔记
查看>>
mac下设置eclipse自动提示
查看>>
cocos creator 重写源码按钮Button点击音频封装
查看>>
葡萄城报表-导出输出
查看>>
学习进度表02
查看>>
初识Linux的感受与对它的印象——20155328张钰清
查看>>
Linux 架构
查看>>
thinkphp5---使用自定义助手函数
查看>>
ZOJ - 3469 Food Delivery(区间DP)
查看>>
javascript中 IE事件处理程序中try catch用法
查看>>
Docker相关地址
查看>>
火狐自动填写表单autofill forms的用法和注意事项
查看>>
Django - - 基础 - - Django的View(视图)
查看>>
WebService连接postgresql( 失败尝试)
查看>>
Python实现简易端口扫描器
查看>>
Sql Server常见错误
查看>>