Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android游戲 >> Android游戲開發 >> Android游戲引擎libgdx使用教程13:TiledMap中的角色和角色移動

Android游戲引擎libgdx使用教程13:TiledMap中的角色和角色移動

編輯:Android游戲開發

       本文接上文:Android游戲引擎libgdx使用教程12:如何使用TiledMap地圖

       地圖我們創建好了接下來就是主角的出現。其實上文介紹了如何TiledMap和Stage的結合,角色的處理就簡單了。

       可以繼承Actor類創建主角類,我就偷個懶,用Image代替。

       編輯我們的TMX文件,添加一個對象層。

Android游戲引擎libgdx使用教程13:TiledMap中的角色和角色移動

      在主角要出現的地方加個形狀。

Android游戲引擎libgdx使用教程13:TiledMap中的角色和角色移動

      取名為play1。

       我們的主角是: 

       Android游戲引擎libgdx使用教程13:TiledMap中的角色和角色移動

       思路是我們遍歷map中的所有Object,如果名字和我們設定的play1一致,那麼就實例化一個Image,位置和Object一致,添加到舞台。

       關鍵代碼:

Java代碼
  1. for (TiledObjectGroup group : map.objectGroups) {   
  2. for (TiledObject object : group.objects) {   
  3. if ("play1".equals(object.name)) {   
  4. player = new Image(new TextureRegion(new Texture(Gdx.files   
  5. .internal("map/player.png")), 0, 0, 27, 40));   
  6. player.x = object.x;   
  7. player.y = tileMapRenderer.getMapHeightUnits() - object.y; //map是左上角,Stage是左下角   
  8. stage.addActor(player);   
  9. }   
  10. }   
  11. }  

       效果如下:

Android游戲引擎libgdx使用教程13:TiledMap中的角色和角色移動

       然後現在來試試讓主角動起來。

       首先是我們如何控制,android設備的話優先選用觸控。如果我們按住前方不放,主角向前。按住上方不放,主角向上。

       那麼如何確定我們按住的是哪個方向呢?

Android游戲引擎libgdx使用教程13:TiledMap中的角色和角色移動

       如圖所示,黃色的是Stage,粉紅的邊框是整個Map,有部分顯示,有一部分沒有顯示。右下角的綠色點是主角的位置,我們假定紅色的點是我們的觸碰點。

       認定紅色的觸碰點為向前,我在提供一個方案,但是方法不唯一哈,我這樣確定方向也不一定是最符合用戶體驗的。

       以主角的位置為原點重現建立坐標系,得到觸碰點的新坐標x,y。

Android游戲引擎libgdx使用教程13:TiledMap中的角色和角色移動

       確定了在新坐標系下的觸碰點的象限,在判斷x,y的大小就可以知道方向了。

       代碼如下:

Java代碼
  1. Vector3 tmp = new Vector3(x, y, 0);  
  2. stage.getCamera().unproject(tmp);  
  3. float newx = tmp.x - player.x;  
  4. float newy = tmp.y - player.y;  
  5. if (newx > 0 && newy > 0) {  
  6. if (newx > newy) {  
  7. ChangeDirect(4);  
  8. } else {  
  9. ChangeDirect(1);  
  10. }  
  11. } else if (newx > 0 && newy < 0) {  
  12. if (newx > -newy) {  
  13. ChangeDirect(4);  
  14. } else {  
  15. ChangeDirect(2);  
  16. }  
  17. } else if (newx < 0 && newy > 0) {  
  18. if (-newx > newy) {  
  19. ChangeDirect(3);  
  20. } else {  
  21. ChangeDirect(1);  
  22. }  
  23. } else {  
  24. if (-newx > -newy) {  
  25. ChangeDirect(3);  
  26. } else {  
  27. ChangeDirect(2);  
  28. }  
  29. }  

       直接移動Camera位置可以移動地圖,但是我們的主角卻從地圖上消失了…處理辦法是將你希望仍然顯示在地圖上的Actor的坐標隨著Camera一起移動。

       代碼如下:

Java代碼
  1. private void CameraMove(Vector3 vector3) {  
  2. stage.getCamera().position.add(vector3);  
  3. for (Actor actor : stage.getActors()) {  
  4. actor.x += vector3.x;  
  5. actor.y += vector3.y;  
  6. }  
  7. }  

       完整代碼:

Java代碼
  1. package com.cnblogs.htynkn.game;  
  2.   
  3. import com.badlogic.gdx.ApplicationListener;  
  4. import com.badlogic.gdx.Gdx;  
  5. import com.badlogic.gdx.InputMultiplexer;  
  6. import com.badlogic.gdx.InputProcessor;  
  7. import com.badlogic.gdx.files.FileHandle;  
  8. import com.badlogic.gdx.graphics.Color;  
  9. import com.badlogic.gdx.graphics.GL10;  
  10. import com.badlogic.gdx.graphics.OrthographicCamera;  
  11. import com.badlogic.gdx.graphics.Texture;  
  12. import com.badlogic.gdx.graphics.g2d.BitmapFont;  
  13. import com.badlogic.gdx.graphics.g2d.TextureRegion;  
  14. import com.badlogic.gdx.graphics.g2d.tiled.TileAtlas;  
  15. import com.badlogic.gdx.graphics.g2d.tiled.TileMapRenderer;  
  16. import com.badlogic.gdx.graphics.g2d.tiled.TiledLoader;  
  17. import com.badlogic.gdx.graphics.g2d.tiled.TiledMap;  
  18. import com.badlogic.gdx.graphics.g2d.tiled.TiledObject;  
  19. import com.badlogic.gdx.graphics.g2d.tiled.TiledObjectGroup;  
  20. import com.badlogic.gdx.math.Vector2;  
  21. import com.badlogic.gdx.math.Vector3;  
  22. import com.badlogic.gdx.scenes.scene2d.Actor;  
  23. import com.badlogic.gdx.scenes.scene2d.Stage;  
  24. import com.badlogic.gdx.scenes.scene2d.ui.Image;  
  25. import com.badlogic.gdx.scenes.scene2d.ui.Label;  
  26. import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;  
  27.   
  28. public class firstGame implements ApplicationListener, InputProcessor {  
  29.   
  30. Stage stage;  
  31. float width;  
  32. float height;  
  33. private TiledMap map;  
  34. private TileAtlas atlas;  
  35. private TileMapRenderer tileMapRenderer;  
  36. Image player;  
  37. Vector3 camDirection = new Vector3(1, 1, 0);  
  38. Vector2 maxCamPosition = new Vector2(0, 0);  
  39. Vector3 moveVector = new Vector3(0, 0, 0);  
  40. boolean isPress;  
  41.   
  42. // Image image;  
  43.   
  44. @Override  
  45. public void create() {  
  46. final String path = "map/";  
  47. final String mapname = "tilemap";  
  48. FileHandle mapHandle = Gdx.files.internal(path + mapname + ".tmx");  
  49. map = TiledLoader.createMap(mapHandle);  
  50. atlas = new TileAtlas(map, Gdx.files.internal("map/"));  
  51. tileMapRenderer = new TileMapRenderer(map, atlas, 10, 10);  
  52. maxCamPosition.set(tileMapRenderer.getMapWidthUnits(), tileMapRenderer  
  53. .getMapHeightUnits());  
  54.   
  55. width = Gdx.graphics.getWidth();  
  56. height = Gdx.graphics.getHeight();  
  57. stage = new Stage(width, height, true);  
  58. Label label = new Label("FPS:", new LabelStyle(new BitmapFont(Gdx.files  
  59. .internal("font/blue.fnt"),  
  60. Gdx.files.internal("font/blue.png"), false), Color.WHITE),  
  61. "fpsLabel");  
  62. label.y = height - label.getPrefHeight();  
  63. label.x = 0;  
  64. stage.addActor(label);  
  65.   
  66. for (TiledObjectGroup group : map.objectGroups) {  
  67. for (TiledObject object : group.objects) {  
  68. if ("play1".equals(object.name)) {  
  69. player = new Image(new TextureRegion(new Texture(Gdx.files  
  70. .internal("map/player.png")), 0, 0, 27, 40));  
  71. player.x = object.x;  
  72. player.y = tileMapRenderer.getMapHeightUnits() - object.y; // map是左上角,Stage是左下角  
  73. stage.addActor(player);  
  74. }  
  75. }  
  76. }  
  77.   
  78. InputMultiplexer inputMultiplexer = new InputMultiplexer();  
  79. inputMultiplexer.addProcessor(this);  
  80. inputMultiplexer.addProcessor(stage);  
  81. Gdx.input.setInputProcessor(inputMultiplexer);  
  82. }  
  83.   
  84. @Override  
  85. public void dispose() {  
  86. // TODO Auto-generated method stub  
  87.   
  88. }  
  89.   
  90. @Override  
  91. public void pause() {  
  92. // TODO Auto-generated method stub  
  93.   
  94. }  
  95.   
  96. @Override  
  97. public void render() {  
  98. Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);  
  99. OrthographicCamera c = (OrthographicCamera) stage.getCamera();  
  100. if (isPress) {  
  101. CameraMove(moveVector);  
  102. }  
  103. ((Label) stage.findActor("fpsLabel")).setText("FPS: "  
  104. + Gdx.graphics.getFramesPerSecond());  
  105. stage.act(Gdx.graphics.getDeltaTime());  
  106. tileMapRenderer.render(c);  
  107. stage.draw();  
  108. }  
  109.   
  110. private void CameraMove(Vector3 vector3) {  
  111. stage.getCamera().position.add(vector3);  
  112. for (Actor actor : stage.getActors()) {  
  113. actor.x += vector3.x;  
  114. actor.y += vector3.y;  
  115. }  
  116. }  
  117.   
  118. @Override  
  119. public void resize(int width, int height) {  
  120. // TODO Auto-generated method stub  
  121.   
  122. }  
  123.   
  124. @Override  
  125. public void resume() {  
  126. // TODO Auto-generated method stub  
  127.   
  128. }  
  129.   
  130. @Override  
  131. public boolean keyDown(int keycode) {  
  132. // TODO Auto-generated method stub  
  133. return false;  
  134. }  
  135.   
  136. @Override  
  137. public boolean keyTyped(char character) {  
  138. // TODO Auto-generated method stub  
  139. return false;  
  140. }  
  141.   
  142. @Override  
  143. public boolean keyUp(int keycode) {  
  144. // TODO Auto-generated method stub  
  145. return false;  
  146. }  
  147.   
  148. @Override  
  149. public boolean scrolled(int amount) {  
  150. // TODO Auto-generated method stub  
  151. return false;  
  152. }  
  153.   
  154. private void ChangeDirect(int typeId) {  
  155. switch (typeId) {  
  156. case 1:  
  157. moveVector.set(0, 1, 0);  
  158. Gdx.app.log("方向變動", "向上");  
  159. break;  
  160. case 2:  
  161. moveVector.set(0, -1, 0);  
  162. Gdx.app.log("方向變動", "向下");  
  163. break;  
  164. case 3:  
  165. moveVector.set(-1, 0, 0);  
  166. Gdx.app.log("方向變動", "向左");  
  167. break;  
  168. case 4:  
  169. moveVector.set(1, 0, 0);  
  170. Gdx.app.log("方向變動", "向右");  
  171. break;  
  172. }  
  173. }  
  174.   
  175. @Override  
  176. public boolean touchDown(int x, int y, int pointer, int button) {  
  177. Vector3 tmp = new Vector3(x, y, 0);  
  178. stage.getCamera().unproject(tmp);  
  179. float newx = tmp.x - player.x;  
  180. float newy = tmp.y - player.y;  
  181. if (newx > 0 && newy > 0) {  
  182. if (newx > newy) {  
  183. ChangeDirect(4);  
  184. } else {  
  185. ChangeDirect(1);  
  186. }  
  187. } else if (newx > 0 && newy < 0) {  
  188. if (newx > -newy) {  
  189. ChangeDirect(4);  
  190. } else {  
  191. ChangeDirect(2);  
  192. }  
  193. } else if (newx < 0 && newy > 0) {  
  194. if (-newx > newy) {  
  195. ChangeDirect(3);  
  196. } else {  
  197. ChangeDirect(1);  
  198. }  
  199. } else {  
  200. if (-newx > -newy) {  
  201. ChangeDirect(3);  
  202. } else {  
  203. ChangeDirect(2);  
  204. }  
  205. }  
  206. isPress = true;  
  207. return false;  
  208. }  
  209.   
  210. @Override  
  211. public boolean touchDragged(int x, int y, int pointer) {  
  212. // TODO Auto-generated method stub  
  213. return false;  
  214. }  
  215.   
  216. @Override  
  217. public boolean touchMoved(int x, int y) {  
  218. // TODO Auto-generated method stub  
  219. return false;  
  220. }  
  221.   
  222. @Override  
  223. public boolean touchUp(int x, int y, int pointer, int button) {  
  224. isPress = false;  
  225. Gdx.app.log("Info", "touchUp: x:" + x + " y: " + y + " pointer: "  
  226. + pointer + " button: " + button);  
  227. return false;  
  228. }  
  229. }  

       我不知道怎麼錄制手機屏幕,所以只有用模擬機演示,但是真機速度很流暢,完全沒問題。

       如果有多個角色,方法是一樣的,多建幾個Object就行了。可以很明顯看出,我們的忍者水平很高…行走地圖完全沒有障礙,而且如果你一直走的話會發現地圖會消失一部分,這些問題接下的文章會慢慢解決的。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved