上一講,我們已經實現了點擊play進入游戲界面但僅僅是個黑屏
?今天,我們就試著編寫代碼讓它出現游戲的一些簡單場景。還是在上一講的代碼基礎上,我們創建兩個類: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 | package ?com.zhf.mylibgdx; /** ? * 統一管理世界中各個部分 ? * @author ZHF ? * ? */ public ?class ?World { ???? /**世界監聽器接口**/ ???? public ?interface ?WorldListener { ???????? //跳躍 ???????? public ?void ?jump (); ???????? //高跳 ???????? public ?void ?highJump (); ???????? //碰撞 ???????? public ?void ?hit (); ???????? //收集金幣 ???????? public ?void ?coin (); ???? } ????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ????? //寬和高 ???? public ?static ?final ?float ?WORLD_WIDTH =? 10 ; ???? public ?static ?final ?float ?WORLD_HEIGHT =? 15 ?*? 20 ; ???? //狀態 ???? public ?static ?final ?int ?WORLD_STATE_RUNNING =? 0 ;?? //運行 ???? public ?static ?final ?int ?WORLD_STATE_NEXT_LEVEL =? 1 ;?? //下一關 ???? public ?static ?final ?int ?WORLD_STATE_GAME_OVER =? 2 ;?? //游戲結束 ???? //世界監聽器 ???? public ??WorldListener listener; ????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ????? public ?World(WorldListener listener) { ???????? this .listener = listener; ???? } } |
2.WorldRenderer類:
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 | package ?com.zhf.mylibgdx; import ?com.badlogic.gdx.graphics.OrthographicCamera; import ?com.badlogic.gdx.graphics.g2d.SpriteBatch; import ?com.badlogic.gdx.graphics.g2d.TextureRegion; /** ? * 用來把每個對象關聯相應的圖片資源,同時控制相機,實現動畫。 ? * @author ZHF ? * ? */ public ?class ?WorldRenderer { ???? //寬和高 ???? static ?final ?float ?FRUSTUM_WIDTH =? 10 ; ???? static ?final ?float ?FRUSTUM_HEIGHT =? 15 ; ?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ????? World world;?? //世界 ???? OrthographicCamera cam;?? //相機 ???? SpriteBatch batch;?? //用于繪畫 ???? TextureRegion background;?? //背景圖片 ?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ????? public ?WorldRenderer(SpriteBatch batch, World world) { ???????? this .world = world; ???????? //OrthographicCamera 被定義成 寬度為10,高度為15,同樣的也把相機對準中心點。 ???????? this .cam =? new ?OrthographicCamera(FRUSTUM_WIDTH, FRUSTUM_HEIGHT); ???????? //它指定了和屏幕一樣大小的 OrthographicCamera ,并把相機對準屏幕的中心。 ???????? this .cam.position.set(FRUSTUM_WIDTH /? 2 , FRUSTUM_HEIGHT /? 2 ,? 0 ); ???????? this .batch = batch; ???? } ?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ????? /**渲染**/ ???? public ?void ?render () { ???????? cam.update(); ???????? //它的作用都是通過把映射矩陣綁定給SpritBatch,告訴SpritBatch怎么去繪制圖形 ???????? batch.setProjectionMatrix(cam.combined); ???????? //渲染背景 ???????? renderBackground(); ???????? //渲染游戲中各種元素(Bob,跳板,松鼠,彈簧。。)下一講中會具體講到 //????? renderObjects(); ???? } ?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ????? /**渲染背景**/ ???? public ?void ?renderBackground () { ???????? batch.disableBlending(); ???????? batch.begin(); ???????? //繪制背景 ???????? batch.draw(Assets.backgroundRegion, cam.position.x - FRUSTUM_WIDTH /? 2 , cam.position.y - FRUSTUM_HEIGHT /? 2 , FRUSTUM_WIDTH, ???????????? FRUSTUM_HEIGHT); ???????? batch.end(); ???? } } |
? ?接下來,就是在GameScreen中調用這兩個類,完成框架的連接搭建。
聲明:
1 2 3 4 | //游戲場景 World world; WorldRenderer renderer; WorldListener worldListener; |
實例化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | //實例化場景 ???????? worldListener =? new ?WorldListener() { ???????????? @Override ???????????? public ?void ?jump () { //????????????? Assets.playSound(Assets.jumpSound); ???????????? } ???????????? @Override ???????????? public ?void ?highJump () { //????????????? Assets.playSound(Assets.highJumpSound); ???????????? } ???????????? @Override ???????????? public ?void ?hit () { //????????????? Assets.playSound(Assets.hitSound); ???????????? } ???????????? @Override ???????????? public ?void ?coin () { //????????????? Assets.playSound(Assets.coinSound); ???????????? } ???????? }; ???????? world =? new ?World(worldListener); ???????? renderer =? new ?WorldRenderer(batcher, world); |
調用:在GameScreen的draw()方法中調用
1 2 | //繪制游戲主場景 renderer.render(); |
運行一下代碼,發現我們的黑屏沒有了!
? ? 這里我需要再啰嗦幾句,相機的掌握是比較抽象的,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、跳板,彈簧、松鼠、金幣、城堡,以及源碼是如何定義他們的。
源碼下載:http://down.51cto.com/data/895165
? ? ?本文轉自zhf651555765 51CTO博客,原文鏈接:http://blog.51cto.com/smallwoniu/1263323,如需轉載請自行聯系原作者