天天看點

libgdx遊戲引擎開發筆記(十)SuperJumper遊戲例子的講解(篇四)---- 主遊戲界面内部架構編寫

上一講,我們已經實作了點選play進入遊戲界面但僅僅是個黑屏

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

 今天,我們就試着編寫代碼讓它出現遊戲的一些簡單場景。還是在上一講的代碼基礎上,我們建立兩個類:World 和 WorldRenderer 

1.Word類:

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

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

<code>/**</code>

<code> </code><code>* 統一管理世界中各個部分</code>

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

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

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

<code>public</code> <code>class</code> <code>World {</code>

<code>    </code><code>/**世界監聽器接口**/</code>

<code>    </code><code>public</code> <code>interface</code> <code>WorldListener {</code>

<code>        </code><code>//跳躍</code>

<code>        </code><code>public</code> <code>void</code> <code>jump ();</code>

<code>        </code><code>//高跳</code>

<code>        </code><code>public</code> <code>void</code> <code>highJump ();</code>

<code>        </code><code>//碰撞</code>

<code>        </code><code>public</code> <code>void</code> <code>hit ();</code>

<code>        </code><code>//收集金币</code>

<code>        </code><code>public</code> <code>void</code> <code>coin ();</code>

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

<code>                                                                                                                                                                                                                                                                                 </code> 

<code>    </code><code>//寬和高</code>

<code>    </code><code>public</code> <code>static</code> <code>final</code> <code>float</code> <code>WORLD_WIDTH = </code><code>10</code><code>;</code>

<code>    </code><code>public</code> <code>static</code> <code>final</code> <code>float</code> <code>WORLD_HEIGHT = </code><code>15</code> <code>* </code><code>20</code><code>;</code>

<code>    </code><code>//狀态</code>

<code>    </code><code>public</code> <code>static</code> <code>final</code> <code>int</code> <code>WORLD_STATE_RUNNING = </code><code>0</code><code>;  </code><code>//運作</code>

<code>    </code><code>public</code> <code>static</code> <code>final</code> <code>int</code> <code>WORLD_STATE_NEXT_LEVEL = </code><code>1</code><code>;  </code><code>//下一關</code>

<code>    </code><code>public</code> <code>static</code> <code>final</code> <code>int</code> <code>WORLD_STATE_GAME_OVER = </code><code>2</code><code>;  </code><code>//遊戲結束</code>

<code>    </code><code>//世界監聽器</code>

<code>    </code><code>public</code>  <code>WorldListener listener;</code>

<code>    </code><code>public</code> <code>World(WorldListener listener) {</code>

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

<code>}</code>

2.WorldRenderer類:

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

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

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

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

<code> </code><code>* 用來把每個對象關聯相應的圖檔資源,同時控制相機,實作動畫。</code>

<code>public</code> <code>class</code> <code>WorldRenderer {</code>

<code>    </code><code>static</code> <code>final</code> <code>float</code> <code>FRUSTUM_WIDTH = </code><code>10</code><code>;</code>

<code>    </code><code>static</code> <code>final</code> <code>float</code> <code>FRUSTUM_HEIGHT = </code><code>15</code><code>;</code>

<code>                                                                                                                                                                                                                                                                      </code> 

<code>    </code><code>World world;  </code><code>//世界</code>

<code>    </code><code>OrthographicCamera cam;  </code><code>//相機</code>

<code>    </code><code>SpriteBatch batch;  </code><code>//用于繪畫</code>

<code>    </code><code>TextureRegion background;  </code><code>//背景圖檔</code>

<code>    </code><code>public</code> <code>WorldRenderer(SpriteBatch batch, World world) {</code>

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

<code>        </code><code>//OrthographicCamera 被定義成 寬度為10,高度為15,同樣的也把相機對準中心點。</code>

<code>        </code><code>this</code><code>.cam = </code><code>new</code> <code>OrthographicCamera(FRUSTUM_WIDTH, FRUSTUM_HEIGHT);</code>

<code>        </code><code>//它指定了和螢幕一樣大小的 OrthographicCamera ,并把相機對準螢幕的中心。</code>

<code>        </code><code>this</code><code>.cam.position.set(FRUSTUM_WIDTH / </code><code>2</code><code>, FRUSTUM_HEIGHT / </code><code>2</code><code>, </code><code>0</code><code>);</code>

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

<code>    </code><code>/**渲染**/</code>

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

<code>        </code><code>cam.update();</code>

<code>        </code><code>//它的作用都是通過把映射矩陣綁定給SpritBatch,告訴SpritBatch怎麼去繪制圖形</code>

<code>        </code><code>batch.setProjectionMatrix(cam.combined);</code>

<code>        </code><code>//渲染背景</code>

<code>        </code><code>renderBackground();</code>

<code>        </code><code>//渲染遊戲中各種元素(Bob,跳闆,松鼠,彈簧。。)下一講中會具體講到</code>

<code>//      renderObjects();</code>

<code>    </code><code>/**渲染背景**/</code>

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

<code>        </code><code>batch.disableBlending();</code>

<code>        </code><code>batch.begin();</code>

<code>        </code><code>//繪制背景</code>

<code>        </code><code>batch.draw(Assets.backgroundRegion, cam.position.x - FRUSTUM_WIDTH / </code><code>2</code><code>, cam.position.y - FRUSTUM_HEIGHT / </code><code>2</code><code>, FRUSTUM_WIDTH,</code>

<code>            </code><code>FRUSTUM_HEIGHT);</code>

<code>        </code><code>batch.end();</code>

   接下來,就是在GameScreen中調用這兩個類,完成架構的連接配接搭建。

聲明:

<code>//遊戲場景</code>

<code>World world;</code>

<code>WorldRenderer renderer;</code>

<code>WorldListener worldListener;</code>

執行個體化:

<code>//執行個體化場景</code>

<code>        </code><code>worldListener = </code><code>new</code> <code>WorldListener() {</code>

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

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

<code>//              Assets.playSound(Assets.jumpSound);</code>

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

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

<code>//              Assets.playSound(Assets.highJumpSound);</code>

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

<code>//              Assets.playSound(Assets.hitSound);</code>

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

<code>//              Assets.playSound(Assets.coinSound);</code>

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

<code>        </code><code>world = </code><code>new</code> <code>World(worldListener);</code>

<code>        </code><code>renderer = </code><code>new</code> <code>WorldRenderer(batcher, world);</code>

調用:在GameScreen的draw()方法中調用

<code>//繪制遊戲主場景</code>

<code>renderer.render();</code>

運作一下代碼,發現我們的黑屏沒有了!

    這裡我需要再啰嗦幾句,相機的掌握是比較抽象的,WorldRenderer 中 OrthographicCamera的定義就的得先說說遊戲是怎麼進行的:為什麼要把 WorldRender中的OrthographicCamera  定義10 *15,實際上就是把螢幕320*480 映射成每個機關為32像素。這是因為遊戲中的素材基本都是基于32像素為機關建構,同時螢幕的分辨率也可以被分解成以32像素為機關。

遊戲中,我們的主角Bob會不斷進行跳躍,但是他的最高點始終不會超過螢幕的中點,他停留在最高點的過程中會通過移動所有的物體來造成他看上去好像在往上跳,實際上他一直停留在螢幕中點的高度。同時,我們需要為每一關定義一個長度,也就是,需要‘跳’多高才能到達城堡,順利通關。并且要準備好整一關的過程中,哪裡應該出現什麼物體,然後根據Bob到達的高度不停的切換這些物體。

想象一下有一段被垂直放置的膠卷,這就是我們的一個關卡,也就是一個World,它準備好了一個關卡的長度,并且設定好了所有的物體。而我們的Bob和WorldRender中的OrthographicCamera 一開始被放置在膠卷的底部,Bob開始不斷的跳躍,當超過螢幕中點的高度時則OrthographicCamera 會被往上移動,并且所有進入OrthographicCamera 的物體都會被繪制。直到到達最高點,或Bob死亡。

是以 WorldRender中的OrthographicCamera 被設定成 10 *15 。

并且而在World類中,定義了兩個變量:

   public static final float WORLD_WIDTH = 10;

   public static final float WORLD_HEIGHT = 15 * 20;

同樣的關卡的寬帶也被定義為10個機關,與WorldRender中的一緻(因為我們不需要在X方向進行移動);而高度定義成15*20 這就是一關的長度,也就是Bob要'跳'的高度。

從上面的分析可以得出,分别設定兩個不同 OrthographicCamera  ,就是因為不同場景的需求。并且 在WorldRender中的OrthographicCamera 其實也可以被設定成 320*480 隻是為了簡便,才把機關設為32像素變成 10*15。 是以不管是哪個OrthographicCamera它提供的隻是一個映射資訊,而這個映射的資訊真正的使用者是SpriteBatch,它會根據映射資訊的不同來決定究竟要把圖檔繪制在什麼位置上,以及該不該繪制這些元素。

   即使GameScreen和WorldRender使用的是同一個SpriteBatch,隻要在恰當的時候綁定相應的投影矩陣,兩者是互不影響的。

    後面說了好多,全是文字,大家先了解着,在下一講中我們将加入各種對象:Bob、跳闆,彈簧、松鼠、金币、城堡,以及源碼是如何定義他們的。

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

繼續閱讀