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

Android游戲引擎libgdx使用教程17:TiledMap中角色的行動路徑

編輯:Android游戲開發

       前些日子的文章介紹了tiledmap的主角出現和移動等等問題。相對於主角游戲自然還應該有敵人(?)。

       與主角不同的是,這些元素的移動時程序控制的,一般有3種。

       1.隨主角的移動變化,靠近主角或遠離主角

       2.按照固定路線移動

       3.不動

       第一種的話完全是看你的游戲邏輯決定,和tiledmap關系不大。第二種的話我們可以避免硬編碼(把移動路徑寫入程序代碼中),而采用tiledmap實現,下面我們來看看具體過程。

       還是新建一張地圖,我選用的大小是50*30,塊大小:32*32。

Android游戲引擎libgdx使用教程16:TiledMap中角色的行動路徑

town

Android游戲引擎libgdx使用教程16:TiledMap中角色的行動路徑

town1

       然後繪制地圖:

Android游戲引擎libgdx使用教程16:TiledMap中角色的行動路徑

adancedmap

       我們假定敵人從地圖中間的那條路走到左邊的角上。路徑如下:

Android游戲引擎libgdx使用教程16:TiledMap中角色的行動路徑

adancedmap

       現在新建一個對象層,命名為wayPoints。在幾個關鍵的地方標注上對象,命名為wayPoint1,wayPoint2…

Android游戲引擎libgdx使用教程16:TiledMap中角色的行動路徑

adancedmap

       處理好地圖後拷貝到項目中。

Android游戲引擎libgdx使用教程16:TiledMap中角色的行動路徑

advancelibgdx

       現在新建一個Enemy類,繼承Image。

       現在來整理一下思路,首先我們要得到所有的wayPoint.而第一個wayPoint就是角色的初始化點。那麼Enemy類首先需要一個Vector2列表,然後繼承Image需要一個TextureRegion。

       所以構造函數為

Java代碼
  1. public Enemy(List<Vector2> 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. }  

       初始點有了,如何移動呢?我們先來看一下坐標

Android游戲引擎libgdx使用教程16:TiledMap中角色的行動路徑

advancelibgdx2

       我們現在在點1位置,將要移動到點2位置。只需計算x,y,z長度,然後求出對應的moveX和moveY就可以了。

Java代碼
  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到達下一個點時對點序列的更新。

       當它和下一個點的距離很小時我們認定它到達下一個點,更新序列以保證它繼續向下一個點移動。

Java代碼
  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. }  

       基本沒有問題了,我們看一下效果:

Android游戲引擎libgdx使用教程16:TiledMap中角色的行動路徑

advancelibgdx3

       因為手機不好截圖,所以用的java桌面項目。

       Enemy用的圖片是這張

Android游戲引擎libgdx使用教程16:TiledMap中角色的行動路徑

Enemy

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

       完整代碼:

Java代碼
  1. package com.cnblogs.htynkn.game;  
  2.   
  3. import java.util.ArrayList;   
  4. import java.util.List;  
  5.   
  6. import javax.swing.text.ZoneView;   
  7. import javax.swing.text.html.MinimalHTMLWriter;  
  8.   
  9. import com.badlogic.gdx.ApplicationListener;   
  10. import com.badlogic.gdx.Gdx;   
  11. import com.badlogic.gdx.InputMultiplexer;   
  12. import com.badlogic.gdx.InputProcessor;   
  13. import com.badlogic.gdx.files.FileHandle;   
  14. import com.badlogic.gdx.graphics.Color;   
  15. import com.badlogic.gdx.graphics.GL10;   
  16. import com.badlogic.gdx.graphics.OrthographicCamera;   
  17. import com.badlogic.gdx.graphics.Texture;   
  18. import com.badlogic.gdx.graphics.g2d.BitmapFont;   
  19. import com.badlogic.gdx.graphics.g2d.SpriteBatch;   
  20. import com.badlogic.gdx.graphics.g2d.TextureAtlas;   
  21. import com.badlogic.gdx.graphics.g2d.TextureRegion;   
  22. import com.badlogic.gdx.graphics.g2d.tiled.TileAtlas;   
  23. import com.badlogic.gdx.graphics.g2d.tiled.TileMapRenderer;   
  24. import com.badlogic.gdx.graphics.g2d.tiled.TileSet;   
  25. import com.badlogic.gdx.graphics.g2d.tiled.TiledLayer;   
  26. import com.badlogic.gdx.graphics.g2d.tiled.TiledLoader;   
  27. import com.badlogic.gdx.graphics.g2d.tiled.TiledMap;   
  28. import com.badlogic.gdx.graphics.g2d.tiled.TiledObject;   
  29. import com.badlogic.gdx.graphics.g2d.tiled.TiledObjectGroup;   
  30. import com.badlogic.gdx.graphics.glutils.ShaderProgram;   
  31. import com.badlogic.gdx.math.MathUtil;   
  32. import com.badlogic.gdx.math.Vector2;   
  33. import com.badlogic.gdx.math.Vector3;   
  34. import com.badlogic.gdx.scenes.scene2d.Actor;   
  35. import com.badlogic.gdx.scenes.scene2d.Stage;   
  36. import com.badlogic.gdx.scenes.scene2d.ui.Image;   
  37. import com.badlogic.gdx.scenes.scene2d.ui.Label;   
  38. import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;   
  39. import com.cnblogs.htynkn.actors.Enemy;  
  40.   
  41. public class MapDemo implements ApplicationListener, InputProcessor {  
  42.   
  43. Stage stage;   
  44. float width;   
  45. float height;   
  46. private TiledMap map;   
  47. private TileAtlas atlas;   
  48. private TileMapRenderer tileMapRenderer;   
  49. Vector3 camDirection = new Vector3(1, 1, 0);   
  50. Vector2 maxCamPosition = new Vector2(0, 0);   
  51. Vector3 moveVector = new Vector3(0, 0, 0);   
  52. Enemy enemy;   
  53. int i = 0;  
  54.   
  55. @Override   
  56. public void create() {   
  57. final String path = "map/";   
  58. final String mapname = "adancedmap";   
  59. FileHandle mapHandle = Gdx.files.internal(path + mapname + ".tmx");   
  60. map = TiledLoader.createMap(mapHandle);  
  61.   
  62. atlas = new TileAtlas(map, new FileHandle("map/"));   
  63. tileMapRenderer = new TileMapRenderer(map, atlas, 10, 10);   
  64. maxCamPosition.set(tileMapRenderer.getMapWidthUnits(), tileMapRenderer   
  65. .getMapHeightUnits());  
  66.   
  67. width = Gdx.graphics.getWidth();   
  68. height = Gdx.graphics.getHeight();   
  69. stage = new Stage(width, height, true);   
  70.   
  71. List<Vector2> list = new ArrayList<Vector2>();   
  72. //獲取所有wayPoints   
  73. for (TiledObjectGroup group : map.objectGroups) {   
  74. for (TiledObject object : group.objects) {   
  75. if (object.name.startsWith("wayPoint")) {   
  76. System.out.println(object.name + " X:" + object.x + " Y:"   
  77. + object.y);   
  78. list   
  79. .add(new Vector2(object.x, maxCamPosition.y   
  80. - object.y));   
  81. }   
  82. }   
  83. }   
  84. TextureAtlas region = new TextureAtlas(Gdx.files.internal("imgs/pack"));   
  85. Texture texture = region.findRegion("Enemy").getTexture();   
  86. TextureRegion[][] regions = TextureRegion.split(texture, 25, 33);   
  87. enemy = new Enemy(list, regions[1][2]);   
  88. stage.addActor(enemy);   
  89. InputMultiplexer inputMultiplexer = new InputMultiplexer();   
  90. inputMultiplexer.addProcessor(this);   
  91. inputMultiplexer.addProcessor(stage);   
  92. Gdx.input.setInputProcessor(inputMultiplexer);   
  93. }  
  94.   
  95. @Override   
  96. public void dispose() {   
  97. // TODO Auto-generated method stub  
  98.   
  99. }  
  100.   
  101. @Override   
  102. public void pause() {   
  103. // TODO Auto-generated method stub  
  104.   
  105. }  
  106.   
  107. @Override   
  108. public void render() {   
  109. Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);   
  110. OrthographicCamera c = (OrthographicCamera) stage.getCamera();   
  111. c.position.set(enemy.x, enemy.y, 0);   
  112. stage.act(Gdx.graphics.getDeltaTime());   
  113. tileMapRenderer.render(c);   
  114. stage.draw();   
  115. }  
  116.   
  117. @Override   
  118. public void resize(int width, int height) {   
  119. // TODO Auto-generated method stub  
  120.   
  121. }  
  122.   
  123. @Override   
  124. public void resume() {   
  125. // TODO Auto-generated method stub  
  126.   
  127. }  
  128.   
  129. @Override   
  130. public boolean keyDown(int keycode) {   
  131. return false;   
  132. }  
  133.   
  134. @Override   
  135. public boolean keyTyped(char character) {   
  136. // TODO Auto-generated method stub   
  137. return false;   
  138. }  
  139.   
  140. @Override   
  141. public boolean keyUp(int keycode) {   
  142. // TODO Auto-generated method stub   
  143. return false;   
  144. }  
  145.   
  146. @Override   
  147. public boolean scrolled(int amount) {   
  148. // TODO Auto-generated method stub   
  149. return false;   
  150. }  
  151.   
  152. @Override   
  153. public boolean touchDown(int x, int y, int pointer, int button) {   
  154. return false;   
  155. }  
  156.   
  157. @Override   
  158. public boolean touchDragged(int x, int y, int pointer) {   
  159. // TODO Auto-generated method stub   
  160. return false;   
  161. }  
  162.   
  163. @Override   
  164. public boolean touchMoved(int x, int y) {   
  165. // TODO Auto-generated method stub   
  166. return false;   
  167. }  
  168.   
  169. @Override   
  170. public boolean touchUp(int x, int y, int pointer, int button) {   
  171. Gdx.app.log("Info", "touchUp: x:" + x + " y: " + y + " pointer: "   
  172. + pointer + " button: " + button);   
  173. return false;   
  174. }   
  175. }  

分割線=====================================分割線

Java代碼
  1. package com.cnblogs.htynkn.actors;  
  2.   
  3. import java.util.ArrayList;   
  4. import java.util.List;  
  5.   
  6. import com.badlogic.gdx.graphics.g2d.SpriteBatch;   
  7. import com.badlogic.gdx.graphics.g2d.TextureRegion;   
  8. import com.badlogic.gdx.math.MathUtil;   
  9. import com.badlogic.gdx.math.Vector2;   
  10. import com.badlogic.gdx.scenes.scene2d.Actor;   
  11. import com.badlogic.gdx.scenes.scene2d.ui.Image;  
  12.   
  13. public class Enemy extends Image {  
  14.   
  15. List<Vector2> vector2s = new ArrayList<Vector2>();   
  16. int currentIndex;   
  17. float stepLength = 1f;  
  18.   
  19. public Enemy(List<Vector2> vector2s, TextureRegion region) {   
  20. super(region);   
  21. this.vector2s = vector2s;   
  22. currentIndex = 0;   
  23. this.x = vector2s.get(currentIndex).x;   
  24. this.y = vector2s.get(currentIndex).y;   
  25. }  
  26.   
  27. @Override   
  28. public void draw(SpriteBatch batch, float parentAlpha) {   
  29. super.draw(batch, parentAlpha);   
  30. }  
  31.   
  32. @Override   
  33. public Actor hit(float x, float y) {   
  34. return null;   
  35. }   
  36. @Override   
  37. public void act(float delta) {   
  38. int nextIndex = currentIndex + 1 >= vector2s.size() - 1 ? vector2s   
  39. .size() - 1 : currentIndex + 1;   
  40. Vector2 v1 = vector2s.get(currentIndex);   
  41. Vector2 v2 = vector2s.get(nextIndex);   
  42. if (MathUtil.distanceBetweenTwoPoints(new Vector2(this.x, this.y), v2) < 1) {   
  43. currentIndex = currentIndex + 1 < vector2s.size() - 1 ? currentIndex + 1   
  44. : vector2s.size() - 1;   
  45. nextIndex = currentIndex + 1 >= vector2s.size() - 1 ? vector2s   
  46. .size() - 1 : currentIndex + 1;   
  47. v1 = vector2s.get(currentIndex);   
  48. v2 = vector2s.get(nextIndex);   
  49. }   
  50. float x = Math.abs(v1.x - v2.x);   
  51. float y = Math.abs(v1.y - v2.y);   
  52. float z = (float) MathUtil.distanceBetweenTwoPoints(v1, v2);   
  53. float moveX = 0f;   
  54. float moveY = 0f;   
  55. moveX = (x / z) * stepLength;   
  56. moveY = (y / z) * stepLength;   
  57. if (this.x < v2.x) {   
  58. this.x += moveX;   
  59. } else {   
  60. this.x -= moveX;   
  61. }   
  62. if (this.y < v2.y) {   
  63. this.y += moveY;   
  64. } else {   
  65. this.y -= moveY;   
  66. }   
  67. System.out.println("pos: " + this.x + "," + this.y + " v1:"   
  68. + v1.toString() + " v2:" + v2.toString() + " d:" + z + " move:"   
  69. + moveX + " , " + moveY);   
  70. super.act(delta);   
  71. }   
  72. }  

文章中用到的地圖文件和相關資源:http://www.ctdisk.com/file/4279808

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