android游戏开发框架libgdx的使用(十七)—TiledMap中角色的行动路径

来源:互联网 发布:linux mysql 客户端 编辑:程序博客网 时间:2024/05/22 01:28

转自:http://www.apkbus.com/forum.php?mod=viewthread&tid=44511&extra=page%3D1%26filter%3Dauthor%26orderby%3Ddateline%26orderby%3Ddateline

前些日子的文章介绍了tiledmap的主角出现和移动等等问题。相对于主角游戏自然还应该有敌人(?)。

与主角不同的是,这些元素的移动时程序控制的,一般有3种。

1.随主角的移动变化,靠近主角或远离主角

2.按照固定路线移动

3.不动

第一种的话完全是看你的游戏逻辑决定,和tiledmap关系不大。第二种的话我们可以避免硬编码(把移动路径写入程序代码中),而采用tiledmap实现,下面我们来看看具体过程。

还是新建一张地图,我选用的大小是50*30,块大小:32*32。


201201191828581472.png

2012-4-29 16:43 上传
下载附件(448.83 KB)


201201191829128035.png

2012-4-29 16:43 上传
下载附件(243.72 KB)


然后绘制地图:


201201191830033699.png

2012-4-29 16:43 上传
下载附件(370.32 KB)



我们假定敌人从地图中间的那条路走到左边的角上。路径如下:


201201191830547761.png

2012-4-29 16:43 上传
下载附件(394.13 KB)



现在新建一个对象层,命名为wayPoints。在几个关键的地方标注上对象,命名为wayPoint1,wayPoint2…


201201191831441671.png

2012-4-29 16:43 上传
下载附件(399.2 KB)



处理好地图后拷贝到项目中。


201201191831454571.jpg

2012-4-29 16:43 上传
下载附件(17.29 KB)



现在新建一个Enemy类,继承Image。

现在来整理一下思路,首先我们要得到所有的wayPoint.而第一个wayPoint就是角色的初始化点。那么Enemy类首先需要一个Vector2列表,然后继承Image需要一个TextureRegion。

所以构造函数为

  1. public Enemy(List vector2s, TextureRegion region) {
  2. super(region);
  3. this.vector2s = vector2s;
  4. currentIndex = 0;
  5. this.x = vector2s.get(currentIndex).x;
  6. this.y = vector2s.get(currentIndex).y;
  7. }
复制代码

初始点有了,如何移动呢?我们先来看一下坐标


201201191831499748.jpg

2012-4-29 16:43 上传
下载附件(41.43 KB)



我们现在在点1位置,将要移动到点2位置。只需计算x,y,z长度,然后求出对应的moveX和moveY就可以了。

  1. float x = Math.abs(v1.x - v2.x);
  2. float y = Math.abs(v1.y - v2.y);
  3. float z = (float) MathUtil.distanceBetweenTwoPoints(v1, v2);
  4. float moveX = 0f;
  5. float moveY = 0f;
  6. moveX = (x / z) * stepLength;
  7. moveY = (y / z) * stepLength;
  8. if (this.x < v2.x) {
  9. this.x += moveX;
  10. } else {
  11. this.x -= moveX;
  12. }
  13. if (this.y < v2.y) {
  14. this.y += moveY;
  15. } else {
  16. this.y -= moveY;
  17. }
复制代码

distanceBetweenTwoPoints是我自己写的方法,计算两点距离。

现在我们的Enemy类就可以很正常的移动到下一个点了。

但当它接近下一个点的时候可以发现它在不停的颤抖。这是因为我们没有处理当Enemy到达下一个点时对点序列的更新。

当它和下一个点的距离很小时我们认定它到达下一个点,更新序列以保证它继续向下一个点移动。

  1. int nextIndex = currentIndex + 1 >= vector2s.size() - 1 ? vector2s
  2. .size() - 1 : currentIndex + 1;
  3. Vector2 v1 = vector2s.get(currentIndex);
  4. Vector2 v2 = vector2s.get(nextIndex);
  5. if (MathUtil.distanceBetweenTwoPoints(new Vector2(this.x, this.y), v2) < 1) {
  6. currentIndex = currentIndex + 1 < vector2s.size() - 1 ? currentIndex + 1
  7. : vector2s.size() - 1;
  8. nextIndex = currentIndex + 1 >= vector2s.size() - 1 ? vector2s
  9. .size() - 1 : currentIndex + 1;
  10. v1 = vector2s.get(currentIndex);
  11. v2 = vector2s.get(nextIndex);
  12. }
复制代码

基本没有问题了,我们看一下效果:


201201191832578089.gif

2012-4-29 16:43 上传
下载附件(1.2 MB)



因为手机不好截图,所以用的java桌面项目。

Enemy用的图片是这张

201201191832594826.png

 

2012-4-29 16:43 上传
下载附件(25.98 KB)

用TextureRegion[][] regions = TextureRegion.split(texture, 25, 33);切分,去2行3列。

完整代码:

  1. package com.cnblogs.htynkn.game;

  2. import java.util.ArrayList;
  3. import java.util.List;

  4. import javax.swing.text.ZoneView;
  5. import javax.swing.text.html.MinimalHTMLWriter;

  6. import com.badlogic.gdx.ApplicationListener;
  7. import com.badlogic.gdx.Gdx;
  8. import com.badlogic.gdx.InputMultiplexer;
  9. import com.badlogic.gdx.InputProcessor;
  10. import com.badlogic.gdx.files.FileHandle;
  11. import com.badlogic.gdx.graphics.Color;
  12. import com.badlogic.gdx.graphics.GL10;
  13. import com.badlogic.gdx.graphics.OrthographicCamera;
  14. import com.badlogic.gdx.graphics.Texture;
  15. import com.badlogic.gdx.graphics.g2d.BitmapFont;
  16. import com.badlogic.gdx.graphics.g2d.SpriteBatch;
  17. import com.badlogic.gdx.graphics.g2d.TextureAtlas;
  18. import com.badlogic.gdx.graphics.g2d.TextureRegion;
  19. import com.badlogic.gdx.graphics.g2d.tiled.TileAtlas;
  20. import com.badlogic.gdx.graphics.g2d.tiled.TileMapRenderer;
  21. import com.badlogic.gdx.graphics.g2d.tiled.TileSet;
  22. import com.badlogic.gdx.graphics.g2d.tiled.TiledLayer;
  23. import com.badlogic.gdx.graphics.g2d.tiled.TiledLoader;
  24. import com.badlogic.gdx.graphics.g2d.tiled.TiledMap;
  25. import com.badlogic.gdx.graphics.g2d.tiled.TiledObject;
  26. import com.badlogic.gdx.graphics.g2d.tiled.TiledObjectGroup;
  27. import com.badlogic.gdx.graphics.glutils.ShaderProgram;
  28. import com.badlogic.gdx.math.MathUtil;
  29. import com.badlogic.gdx.math.Vector2;
  30. import com.badlogic.gdx.math.Vector3;
  31. import com.badlogic.gdx.scenes.scene2d.Actor;
  32. import com.badlogic.gdx.scenes.scene2d.Stage;
  33. import com.badlogic.gdx.scenes.scene2d.ui.Image;
  34. import com.badlogic.gdx.scenes.scene2d.ui.Label;
  35. import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;
  36. import com.cnblogs.htynkn.actors.Enemy;

  37. public class MapDemo implements ApplicationListener, InputProcessor {

  38. Stage stage;
  39. float width;
  40. float height;
  41. private TiledMap map;
  42. private TileAtlas atlas;
  43. private TileMapRenderer tileMapRenderer;
  44. Vector3 camDirection = new Vector3(1, 1, 0);
  45. Vector2 maxCamPosition = new Vector2(0, 0);
  46. Vector3 moveVector = new Vector3(0, 0, 0);
  47. Enemy enemy;
  48. int i = 0;

  49. @Override
  50. public void create() {
  51. final String path = "map/";
  52. final String mapname = "adancedmap";
  53. FileHandle mapHandle = Gdx.files.internal(path + mapname + ".tmx");
  54. map = TiledLoader.createMap(mapHandle);

  55. atlas = new TileAtlas(map, new FileHandle("map/"));
  56. tileMapRenderer = new TileMapRenderer(map, atlas, 10, 10);
  57. maxCamPosition.set(tileMapRenderer.getMapWidthUnits(), tileMapRenderer
  58. .getMapHeightUnits());

  59. width = Gdx.graphics.getWidth();
  60. height = Gdx.graphics.getHeight();
  61. stage = new Stage(width, height, true);

  62. List list = new ArrayList();
  63. //获取所有wayPoints
  64. for (TiledObjectGroup group : map.objectGroups) {
  65. for (TiledObject object : group.objects) {
  66. if (object.name.startsWith("wayPoint")) {
  67. System.out.println(object.name + " X:" + object.x + " Y:"
  68. + object.y);
  69. list
  70. .add(new Vector2(object.x, maxCamPosition.y
  71. - object.y));
  72. }
  73. }
  74. }
  75. TextureAtlas region = new TextureAtlas(Gdx.files.internal("imgs/pack"));
  76. Texture texture = region.findRegion("Enemy").getTexture();
  77. TextureRegion[][] regions = TextureRegion.split(texture, 25, 33);
  78. enemy = new Enemy(list, regions[1][2]);
  79. stage.addActor(enemy);
  80. InputMultiplexer inputMultiplexer = new InputMultiplexer();
  81. inputMultiplexer.addProcessor(this);
  82. inputMultiplexer.addProcessor(stage);
  83. Gdx.input.setInputProcessor(inputMultiplexer);
  84. }

  85. @Override
  86. public void dispose() {
  87. // TODO Auto-generated method stub

  88. }

  89. @Override
  90. public void pause() {
  91. // TODO Auto-generated method stub

  92. }

  93. @Override
  94. public void render() {
  95. Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
  96. OrthographicCamera c = (OrthographicCamera) stage.getCamera();
  97. c.position.set(enemy.x, enemy.y, 0);
  98. stage.act(Gdx.graphics.getDeltaTime());
  99. tileMapRenderer.render(c);
  100. stage.draw();
  101. }

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

  105. }

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

  109. }

  110. @Override
  111. public boolean keyDown(int keycode) {
  112. return false;
  113. }

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

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

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

  129. @Override
  130. public boolean touchDown(int x, int y, int pointer, int button) {
  131. return false;
  132. }

  133. @Override
  134. public boolean touchDragged(int x, int y, int pointer) {
  135. // TODO Auto-generated method stub
  136. return false;
  137. }

  138. @Override
  139. public boolean touchMoved(int x, int y) {
  140. // TODO Auto-generated method stub
  141. return false;
  142. }

  143. @Override
  144. public boolean touchUp(int x, int y, int pointer, int button) {
  145. Gdx.app.log("Info", "touchUp: x:" + x + " y: " + y + " pointer: "
  146. + pointer + " button: " + button);
  147. return false;
  148. }
  149. }
复制代码

分割线=====================================分割线

  1. package com.cnblogs.htynkn.actors;

  2. import java.util.ArrayList;
  3. import java.util.List;

  4. import com.badlogic.gdx.graphics.g2d.SpriteBatch;
  5. import com.badlogic.gdx.graphics.g2d.TextureRegion;
  6. import com.badlogic.gdx.math.MathUtil;
  7. import com.badlogic.gdx.math.Vector2;
  8. import com.badlogic.gdx.scenes.scene2d.Actor;
  9. import com.badlogic.gdx.scenes.scene2d.ui.Image;

  10. public class Enemy extends Image {

  11. List vector2s = new ArrayList();
  12. int currentIndex;
  13. float stepLength = 1f;

  14. public Enemy(List vector2s, TextureRegion region) {
  15. super(region);
  16. this.vector2s = vector2s;
  17. currentIndex = 0;
  18. this.x = vector2s.get(currentIndex).x;
  19. this.y = vector2s.get(currentIndex).y;
  20. }

  21. @Override
  22. public void draw(SpriteBatch batch, float parentAlpha) {
  23. super.draw(batch, parentAlpha);
  24. }

  25. @Override
  26. public Actor hit(float x, float y) {
  27. return null;
  28. }
  29. @Override
  30. public void act(float delta) {
  31. int nextIndex = currentIndex + 1 >= vector2s.size() - 1 ? vector2s
  32. .size() - 1 : currentIndex + 1;
  33. Vector2 v1 = vector2s.get(currentIndex);
  34. Vector2 v2 = vector2s.get(nextIndex);
  35. if (MathUtil.distanceBetweenTwoPoints(new Vector2(this.x, this.y), v2) < 1) {
  36. currentIndex = currentIndex + 1 < vector2s.size() - 1 ? currentIndex + 1
  37. : vector2s.size() - 1;
  38. nextIndex = currentIndex + 1 >= vector2s.size() - 1 ? vector2s
  39. .size() - 1 : currentIndex + 1;
  40. v1 = vector2s.get(currentIndex);
  41. v2 = vector2s.get(nextIndex);
  42. }
  43. float x = Math.abs(v1.x - v2.x);
  44. float y = Math.abs(v1.y - v2.y);
  45. float z = (float) MathUtil.distanceBetweenTwoPoints(v1, v2);
  46. float moveX = 0f;
  47. float moveY = 0f;
  48. moveX = (x / z) * stepLength;
  49. moveY = (y / z) * stepLength;
  50. if (this.x < v2.x) {
  51. this.x += moveX;
  52. } else {
  53. this.x -= moveX;
  54. }
  55. if (this.y < v2.y) {
  56. this.y += moveY;
  57. } else {
  58. this.y -= moveY;
  59. }
  60. System.out.println("pos: " + this.x + "," + this.y + " v1:"
  61. + v1.toString() + " v2:" + v2.toString() + " d:" + z + " move:"
  62. + moveX + " , " + moveY);
  63. super.act(delta);
  64. }
  65. }
复制代码

文章中用到的地图文件和相关资源:android游戏开发框架libgdx的使用(十七)—TiledMap中角色的行动路径.rar.rar(729.62 KB, 下载次数: 30)

2012-4-29 16:45 上传
点击文件名下载附件
下载积分: 下载豆 -2

原创粉丝点击