本文接上文: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")), 002740));   
  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(110);  
  38. Vector2 maxCamPosition = new Vector2(00);  
  39. Vector3 moveVector = new Vector3(000);  
  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, 1010);  
  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")), 002740));  
  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(010);  
  158. Gdx.app.log("方向变动""向上");  
  159. break;  
  160. case 2:  
  161. moveVector.set(0, -10);  
  162. Gdx.app.log("方向变动""向下");  
  163. break;  
  164. case 3:  
  165. moveVector.set(-100);  
  166. Gdx.app.log("方向变动""向左");  
  167. break;  
  168. case 4:  
  169. moveVector.set(100);  
  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就行了。可以很明显看出,我们的忍者水平很高…行走地图完全没有障碍,而且如果你一直走的话会发现地图会消失一部分,这些问题接下的文章会慢慢解决的。

本文发布:Android开发网
本文地址:http://www.jizhuomi.com/android/game/431.html
2014年3月18日
发布:鸡啄米 分类:Android游戏开发 浏览: 评论:1