天天看點

libgdx遊戲引擎開發筆記(六)舞台、演員、動畫綜合講解

   今天要講解的舞台和演員是libgdx遊戲引擎中重要的兩個類,先簡單介紹一下,待會用個顯示動畫的執行個體來綜合應用一下!

先上一張圖:

<a target="_blank" href="http://blog.51cto.com/attachment/201307/110321826.png"></a>

   在這張圖中,我們可以看到有動的小鳥,不動的按鈕,有特效,沒有特效。。。。等等這些都稱之為演員,而管理這些演員的自然就是舞台了。

一.介紹

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

<code>package</code> <code>com.zhf.android_libgdx_animation;</code>

<code>import</code> <code>com.badlogic.gdx.backends.android.AndroidApplication;</code>

<code>import</code> <code>android.os.Bundle;</code>

<code>public</code> <code>class</code> <code>MainActivity </code><code>extends</code> <code>AndroidApplication{</code>

<code>    </code><code>@Override</code>

<code>    </code><code>protected</code> <code>void</code> <code>onCreate(Bundle savedInstanceState) {</code>

<code>        </code><code>super</code><code>.onCreate(savedInstanceState);</code>

<code>        </code><code>//在此啟動遊戲,MyGame實作了ApplicationListener的類</code>

<code>        </code><code>initialize(</code><code>new</code> <code>MyGame(), </code><code>false</code><code>);</code>

<code>         </code><code>//specifying the configuration for the GLSurfaceView.</code>

<code>        </code><code>//第二個參數如果設為true,則在opengl 2.0可用的情況下會使用opengl 2.0。</code>

<code>    </code><code>}</code>

<code>}</code>

主界面:

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

<code>import</code> <code>com.badlogic.gdx.ApplicationListener;</code>

<code>import</code> <code>com.badlogic.gdx.Gdx;</code>

<code>import</code> <code>com.badlogic.gdx.assets.AssetManager;</code>

<code>import</code> <code>com.badlogic.gdx.graphics.GL10;</code>

<code>import</code> <code>com.badlogic.gdx.graphics.Texture;</code>

<code>import</code> <code>com.badlogic.gdx.scenes.scene2d.Stage;</code>

<code>public</code> <code>class</code> <code>MyGame </code><code>implements</code> <code>ApplicationListener {</code>

<code>    </code><code>private</code> <code>Stage stage;  </code><code>//舞台</code>

<code>    </code><code>private</code> <code>MyActor myActor; </code><code>//演員</code>

<code>    </code><code>private</code> <code>AssetManager assetmanager;</code>

<code>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  </code> 

<code>    </code><code>boolean</code> <code>hasinit;  </code><code>//是否已經初始化</code>

<code>    </code><code>public</code> <code>void</code> <code>create() {</code>

<code>        </code><code>//建立一個舞台</code>

<code>        </code><code>stage = </code><code>new</code> <code>Stage(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), </code><code>true</code><code>);</code>

<code>        </code><code>//執行個體化AssetMangager</code>

<code>        </code><code>assetmanager = </code><code>new</code> <code>AssetManager();</code>

<code>        </code><code>//傳入AssetManger的引用,便于動畫的資源初始化,但是注意了,隻有在調用iniResourse()後資源才被初始化</code>

<code>        </code><code>myActor = </code><code>new</code> <code>MyActor(assetmanager);</code>

<code>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      </code> 

<code>        </code><code>// //把資源加入載入清單,在asset檔案夾下animal下有29張圖檔</code>

<code>        </code><code>for</code> <code>(</code><code>int</code> <code>i = </code><code>1</code><code>; i &lt; </code><code>30</code><code>; i++) {</code>

<code>            </code><code>assetmanager.load(</code><code>"animal/"</code> <code>+ i + </code><code>".png"</code><code>, Texture.</code><code>class</code><code>);</code>

<code>            </code><code>/*manager.load()方法隻是将資源放入加載清單,而真正的加載要不停地調用manager.update()才可以,且update()函數有一個傳回值,載入完成傳回true,未完成傳回false.*/</code>

<code>        </code><code>}</code>

<code>    </code><code>public</code> <code>void</code> <code>dispose() {</code>

<code>        </code><code>myActor.dispose();</code>

<code>        </code><code>assetmanager.clear();</code>

<code>        </code><code>assetmanager.dispose();</code>

<code>    </code><code>public</code> <code>void</code> <code>pause() {</code>

<code>    </code><code>public</code> <code>void</code> <code>render() {</code>

<code>        </code><code>Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);  </code><code>//清屏</code>

<code>        </code><code>Gdx.gl.glClearColor(0f,0f,0f,0f);</code>

<code>        </code><code>stage.act(Gdx.graphics.getDeltaTime());</code>

<code>        </code><code>stage.draw();</code>

<code>        </code><code>// 加載完成且之前沒有初始化過MyActor,且在手觸摸螢幕時初始化MyActor,加入MyActor對象</code>

<code>        </code><code>if</code><code>(!hasinit &amp;&amp; assetmanager.update() &amp;&amp; Gdx.input.isTouched()) {</code>

<code>            </code><code>myActor.initResource(); </code><code>//初始化圖檔資源</code>

<code>            </code><code>stage.addActor(myActor);  </code><code>//加入演員</code>

<code>            </code><code>hasinit = </code><code>true</code><code>;</code>

<code>    </code><code>public</code> <code>void</code> <code>resize(</code><code>int</code> <code>arg0, </code><code>int</code> <code>arg1) {</code>

<code>    </code><code>public</code> <code>void</code> <code>resume() {</code>

一個演員類:

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

<code>import</code> <code>java.util.ArrayList;</code>

<code>import</code> <code>com.badlogic.gdx.graphics.g2d.Animation;</code>

<code>import</code> <code>com.badlogic.gdx.graphics.g2d.SpriteBatch;</code>

<code>import</code> <code>com.badlogic.gdx.graphics.g2d.TextureRegion;</code>

<code>import</code> <code>com.badlogic.gdx.scenes.scene2d.Actor;</code>

<code>import</code> <code>com.badlogic.gdx.utils.Disposable;</code>

<code>/**</code>

<code> </code><code>* 演員是遊戲設計中常用的一個對象,它接受舞台的統一管理,擁有一些公共**的事件,比如觸摸,點選,但是同時還有自身的響應和屬性。</code>

<code> </code><code>* 實作Disposable接口,為的是能及時釋放記憶體。</code>

<code> </code><code>* @author ZHF</code>

<code> </code><code>*</code>

<code> </code><code>*/</code>

<code>public</code> <code>class</code> <code>MyActor </code><code>extends</code> <code>Actor </code><code>implements</code> <code>Disposable{</code>

<code>    </code><code>ArrayList&lt;Texture&gt; TexArray = </code><code>new</code> <code>ArrayList&lt;Texture&gt;();</code>

<code>    </code><code>ArrayList&lt;TextureRegion&gt; TexReArray = </code><code>new</code> <code>ArrayList&lt;TextureRegion&gt;();</code>

<code>    </code><code>Animation animation;  </code><code>//動畫</code>

<code>    </code><code>TextureRegion[] walksFrame;</code>

<code>    </code><code>float</code> <code>stateTime;</code>

<code>    </code><code>TextureRegion currentFrame; </code><code>// 目前幀</code>

<code>    </code><code>AssetManager manager;</code>

<code>    </code><code>public</code> <code>MyActor(AssetManager manager) {</code>

<code>        </code><code>this</code><code>.manager = manager;</code>

<code>    </code><code>/**</code>

<code>     </code><code>*</code>

<code>     </code><code>* 這是一個系統自動調用的方法,描述這個演員Actor執行個體怎麼繪制,draw()方法并不需要我們人工去調用,而是在把Actor加入舞台Stage中後,</code>

<code>     </code><code>* 在ApplicationListener的render</code>

<code>     </code><code>* ()函數中不停地調用stage.draw(),系統會自動調用已經加入stage中的actor的draw()方法,也就将actor一起繪制出來了</code>

<code>     </code><code>*/</code>

<code>    </code><code>public</code> <code>void</code> <code>draw(SpriteBatch batch, </code><code>float</code> <code>parentAlpha) {</code>

<code>        </code><code>stateTime += Gdx.graphics.getDeltaTime();</code>

<code>        </code><code>// 得到下一幀</code>

<code>        </code><code>currentFrame = animation.getKeyFrame(stateTime, </code><code>true</code><code>); </code><code>// 循環</code>

<code>        </code><code>// 以(0,0)繪制為起點(左下角為100,100)畫出動畫,大小128*128</code>

<code>        </code><code>batch.draw(currentFrame, </code><code>100</code><code>, </code><code>100</code><code>, </code><code>128</code><code>, </code><code>128</code><code>);</code>

<code>    </code><code>public</code> <code>Actor hit(</code><code>float</code> <code>x, </code><code>float</code> <code>y, </code><code>boolean</code> <code>touchable) {</code>

<code>        </code><code>return</code> <code>this</code><code>;</code>

<code>    </code><code>// 初始化方法,在Progress中的AssetManager初始化完成後通知AnimalActor初始化</code>

<code>    </code><code>public</code> <code>void</code> <code>initResource() {</code>

<code>        </code><code>Texture tex;</code>

<code>        </code><code>int</code> <code>j;</code>

<code>            </code><code>TexArray.add(manager.get(</code><code>"animal/"</code><code>+i+</code><code>".png"</code><code>, Texture.</code><code>class</code><code>));</code>

<code>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        </code> 

<code>        </code><code>for</code> <code>(</code><code>int</code> <code>i = </code><code>0</code><code>; i &lt; TexArray.size(); i++) {</code>

<code>            </code><code>tex = TexArray.get(i);</code>

<code>            </code><code>TextureRegion temTexRe = </code><code>new</code> <code>TextureRegion(tex);</code><code>//區域</code>

<code>            </code><code>TexReArray.add(temTexRe); </code><code>//添加進去</code>

<code>        </code><code>j = TexReArray.size();  </code><code>//數組長度</code>

<code>        </code><code>walksFrame = </code><code>new</code> <code>TextureRegion[j];  </code><code>//裝區域的數組</code>

<code>        </code><code>for</code><code>(</code><code>int</code> <code>i= </code><code>0</code><code>; i &lt; j; i++) {</code>

<code>            </code><code>walksFrame[i] = TexReArray.get(i);  </code><code>//将集合中的“區域”給了數組</code>

<code>        </code><code>//設定的0.06s一幀</code>

<code>        </code><code>animation = </code><code>new</code> <code>Animation(</code><code>0</code><code>.06f, walksFrame);</code>

<code>        </code><code>for</code> <code>(</code><code>int</code> <code>i = </code><code>0</code><code>; i &lt;TexArray.size(); i++) {</code>

<code>            </code><code>TexArray.get(i).dispose();</code>

效果圖:

<a target="_blank" href="http://blog.51cto.com/attachment/201307/162224920.png"></a>

分析:

1.在MyGame類中,我們執行個體化了舞台和演員,在render()中讓舞台開始繪畫,裡面所添加的各種演員就會自動調用自己的draw()進行繪畫,不需要手動調用的哦!

   2.這裡們還使用了AssetManager:一個資源異步加載和資源自動管理類,簡單介紹一下:

  2.1什麼時候需要資源預加載?

       (資源預加載的目的很明确,提升使用者體驗。當然就開發者而言,比較好的預加載實作方式還可以友善管理。)

   1.資源數量大:音樂、圖檔、視訊什麼的,如果你的遊戲這些東西太多,推薦使用

   2.部分資源反複使用:有些資源會反複使用到,比如一些背景音樂,一些小圖示

     2.2下面資源類型可以由AssetManager直接建立:

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

    加載某個資源很簡單:

<code>manager.load(</code><code>"data/testin.png"</code><code>, Texture.</code><code>class</code><code>);</code>

<code>manager.load(</code><code>"data/ testin.fnt"</code><code>, BitmapFont.</code><code>class</code><code>);</code>

 2.3. 在加載前,AssetManager需要知道加載什麼類型的資源,這個功能通過資源加載器實作。有兩個變量,同步資源加載器SynchronourAssetLoader和異步資源加載器AsynchronousAssetLoader。前者加載任何資源都在渲染程序中,後者加載資源在另外一個線程中。比如說,一個Texture需要一個Pixmap,然後加載OpenGL依賴于渲染線程。

       2.4.<code>manager.load()方法隻是将資源放入加載清單,而真正的加載要不停地調用manager.update()才可以,這個方法也是render()中系統自己調用的哦!</code>

<code></code>

<code>  ok! 有點扯遠了哈!Stage和Actor的簡單使用就是這些,同時我們也應該關注AssetManager,這個資源管理類!</code>

<b>     本文轉自zhf651555765 51CTO部落格,原文連結:http://blog.51cto.com/smallwoniu/1258251</b><b>,如需轉載請自行聯系原作者</b>

繼續閱讀