android游戏开发框架libgdx的使用(十三)—TiledMap中的角色和角色移动

转自:http://www.apkbus.com/android-19771-1-1.html

 

本文紧跟上文,地址:android游戏开发框架libgdx的使用(十二)—TiledMap地图的使用

地图我们创建好了接下来就是主角的出现。其实上文介绍了如何TiledMap和Stage的结合,角色的处理就简单了。

可以继承Actor类创建主角类,我就偷个懒,用Image代替。

编辑我们的TMX文件,添加一个对象层。


2012011317211665.jpg

 

2012-1-17 22:22 上传
下载附件(18.68 KB)

在主角要出现的地方加个形状


2012011317215189.jpg

 

2012-1-17 22:22 上传
下载附件(80.36 KB)

取名为play1


2012011317221921.jpg

 

2012-1-17 22:22 上传
下载附件(65.96 KB)

我们的主角是:


2012011317223148.png

 

2012-1-17 22:22 上传
下载附件(809 Bytes)


思路是我们遍历map中的所有Object,如果名字和我们设定的play1一致,那么就实例化一个Image,位置和Object一致,添加到舞台。

关键代码:

  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. }
复制代码

效果如下:2012011317232054.jpg

2012-1-17 22:22 上传
下载附件(199.47 KB)


然后现在来试试让主角动起来。首先是我们如何控制,android设备的话优先选用触控。如果我们按住前方不放,主角向前。按住上方不放,主角向上。那么如何确定我们按住的是哪个方向呢?2012011317234294.png

2012-1-17 22:22 上传
下载附件(11.94 KB)




如图所示,黄色的是Stage,粉红的边框是整个Map,有部分显示,有一部分没有显示。右下角的绿色点是主角的位置,我们假定红色的点是我们的触碰点。认定红色的触碰点为向前,我在提供一个方案,但是方法不唯一哈,我这样确定方向也不一定是最符合用户体验的。以主角的位置为原点重现建立坐标系,得到触碰点的新坐标x,y.2012011317235814.png

2012-1-17 22:22 上传
下载附件(7.74 KB)




确定了在新坐标系下的触碰点的象限,在判断x,y的大小就可以知道方向了。代码如下:




  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一起移动。代码如下:

  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. }
复制代码

完整代码:

  1. package com.cnblogs.htynkn.game;

  2. import com.badlogic.gdx.ApplicationListener;
  3. import com.badlogic.gdx.Gdx;
  4. import com.badlogic.gdx.InputMultiplexer;
  5. import com.badlogic.gdx.InputProcessor;
  6. import com.badlogic.gdx.files.FileHandle;
  7. import com.badlogic.gdx.graphics.Color;
  8. import com.badlogic.gdx.graphics.GL10;
  9. import com.badlogic.gdx.graphics.OrthographicCamera;
  10. import com.badlogic.gdx.graphics.Texture;
  11. import com.badlogic.gdx.graphics.g2d.BitmapFont;
  12. import com.badlogic.gdx.graphics.g2d.TextureRegion;
  13. import com.badlogic.gdx.graphics.g2d.tiled.TileAtlas;
  14. import com.badlogic.gdx.graphics.g2d.tiled.TileMapRenderer;
  15. import com.badlogic.gdx.graphics.g2d.tiled.TiledLoader;
  16. import com.badlogic.gdx.graphics.g2d.tiled.TiledMap;
  17. import com.badlogic.gdx.graphics.g2d.tiled.TiledObject;
  18. import com.badlogic.gdx.graphics.g2d.tiled.TiledObjectGroup;
  19. import com.badlogic.gdx.math.Vector2;
  20. import com.badlogic.gdx.math.Vector3;
  21. import com.badlogic.gdx.scenes.scene2d.Actor;
  22. import com.badlogic.gdx.scenes.scene2d.Stage;
  23. import com.badlogic.gdx.scenes.scene2d.ui.Image;
  24. import com.badlogic.gdx.scenes.scene2d.ui.Label;
  25. import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;

  26. public class firstGame implements ApplicationListener, InputProcessor {

  27. Stage stage;
  28. float width;
  29. float height;
  30. private TiledMap map;
  31. private TileAtlas atlas;
  32. private TileMapRenderer tileMapRenderer;
  33. Image player;
  34. Vector3 camDirection = new Vector3(1, 1, 0);
  35. Vector2 maxCamPosition = new Vector2(0, 0);
  36. Vector3 moveVector = new Vector3(0, 0, 0);
  37. boolean isPress;

  38. // Image image;

  39. @Override
  40. public void create() {
  41. final String path = "map/";
  42. final String mapname = "tilemap";
  43. FileHandle mapHandle = Gdx.files.internal(path + mapname + ".tmx");
  44. map = TiledLoader.createMap(mapHandle);
  45. atlas = new TileAtlas(map, Gdx.files.internal("map/"));
  46. tileMapRenderer = new TileMapRenderer(map, atlas, 10, 10);
  47. maxCamPosition.set(tileMapRenderer.getMapWidthUnits(), tileMapRenderer
  48. .getMapHeightUnits());

  49. width = Gdx.graphics.getWidth();
  50. height = Gdx.graphics.getHeight();
  51. stage = new Stage(width, height, true);
  52. Label label = new Label("FPS:", new LabelStyle(new BitmapFont(Gdx.files
  53. .internal("font/blue.fnt"),
  54. Gdx.files.internal("font/blue.png"), false), Color.WHITE),
  55. "fpsLabel");
  56. label.y = height - label.getPrefHeight();
  57. label.x = 0;
  58. stage.addActor(label);

  59. for (TiledObjectGroup group : map.objectGroups) {
  60. for (TiledObject object : group.objects) {
  61. if ("play1".equals(object.name)) {
  62. player = new Image(new TextureRegion(new Texture(Gdx.files
  63. .internal("map/player.png")), 0, 0, 27, 40));
  64. player.x = object.x;
  65. player.y = tileMapRenderer.getMapHeightUnits() - object.y; // map是左上角,Stage是左下角
  66. stage.addActor(player);
  67. }
  68. }
  69. }

  70. InputMultiplexer inputMultiplexer = new InputMultiplexer();
  71. inputMultiplexer.addProcessor(this);
  72. inputMultiplexer.addProcessor(stage);
  73. Gdx.input.setInputProcessor(inputMultiplexer);
  74. }

  75. @Override
  76. public void dispose() {
  77. // TODO Auto-generated method stub

  78. }

  79. @Override
  80. public void pause() {
  81. // TODO Auto-generated method stub

  82. }

  83. @Override
  84. public void render() {
  85. Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
  86. OrthographicCamera c = (OrthographicCamera) stage.getCamera();
  87. if (isPress) {
  88. CameraMove(moveVector);
  89. }
  90. ((Label) stage.findActor("fpsLabel")).setText("FPS: "
  91. + Gdx.graphics.getFramesPerSecond());
  92. stage.act(Gdx.graphics.getDeltaTime());
  93. tileMapRenderer.render(c);
  94. stage.draw();
  95. }

  96. private void CameraMove(Vector3 vector3) {
  97. stage.getCamera().position.add(vector3);
  98. for (Actor actor : stage.getActors()) {
  99. actor.x += vector3.x;
  100. actor.y += vector3.y;
  101. }
  102. }

  103. @Override
  104. public void resize(int width, int height) {
  105. // TODO Auto-generated method stub

  106. }

  107. @Override
  108. public void resume() {
  109. // TODO Auto-generated method stub

  110. }

  111. @Override
  112. public boolean keyDown(int keycode) {
  113. // TODO Auto-generated method stub
  114. return false;
  115. }

  116. @Override
  117. public boolean keyTyped(char character) {
  118. // TODO Auto-generated method stub
  119. return false;
  120. }

  121. @Override
  122. public boolean keyUp(int keycode) {
  123. // TODO Auto-generated method stub
  124. return false;
  125. }

  126. @Override
  127. public boolean scrolled(int amount) {
  128. // TODO Auto-generated method stub
  129. return false;
  130. }

  131. private void ChangeDirect(int typeId) {
  132. switch (typeId) {
  133. case 1:
  134. moveVector.set(0, 1, 0);
  135. Gdx.app.log("方向变动", "向上");
  136. break;
  137. case 2:
  138. moveVector.set(0, -1, 0);
  139. Gdx.app.log("方向变动", "向下");
  140. break;
  141. case 3:
  142. moveVector.set(-1, 0, 0);
  143. Gdx.app.log("方向变动", "向左");
  144. break;
  145. case 4:
  146. moveVector.set(1, 0, 0);
  147. Gdx.app.log("方向变动", "向右");
  148. break;
  149. }
  150. }

  151. @Override
  152. public boolean touchDown(int x, int y, int pointer, int button) {
  153. Vector3 tmp = new Vector3(x, y, 0);
  154. stage.getCamera().unproject(tmp);
  155. float newx = tmp.x - player.x;
  156. float newy = tmp.y - player.y;
  157. if (newx > 0 && newy > 0) {
  158. if (newx > newy) {
  159. ChangeDirect(4);
  160. } else {
  161. ChangeDirect(1);
  162. }
  163. } else if (newx > 0 && newy < 0) {
  164. if (newx > -newy) {
  165. ChangeDirect(4);
  166. } else {
  167. ChangeDirect(2);
  168. }
  169. } else if (newx < 0 && newy > 0) {
  170. if (-newx > newy) {
  171. ChangeDirect(3);
  172. } else {
  173. ChangeDirect(1);
  174. }
  175. } else {
  176. if (-newx > -newy) {
  177. ChangeDirect(3);
  178. } else {
  179. ChangeDirect(2);
  180. }
  181. }
  182. isPress = true;
  183. return false;
  184. }

  185. @Override
  186. public boolean touchDragged(int x, int y, int pointer) {
  187. // TODO Auto-generated method stub
  188. return false;
  189. }

  190. @Override
  191. public boolean touchMoved(int x, int y) {
  192. // TODO Auto-generated method stub
  193. return false;
  194. }

  195. @Override
  196. public boolean touchUp(int x, int y, int pointer, int button) {
  197. isPress = false;
  198. Gdx.app.log("Info", "touchUp: x:" + x + " y: " + y + " pointer: "
  199. + pointer + " button: " + button);
  200. return false;
  201. }
  202. }
复制代码



我不知道怎么录制手机屏幕,所以只有用模拟机演示,但是真机(中兴V880)速度很流畅,完全没问题。如果有多个角色,方法是一样的,多建几个Object就行了。可以很明显看出,我们的忍者水平很高…行走地图完全没有障碍,而且如果你一直走的话会发现地图会消失一部分,这些问题接下的文章会慢慢解决的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值