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

转载声明:http://www.cnblogs.com/htynkn/archive/2012/01/13/libgdx_13.html

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

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

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

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

取名为play1

我们的主角是:

思路是我们遍历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         }

效果如下:

然后现在来试试让主角动起来。

首先是我们如何控制,android设备的话优先选用触控。如果我们按住前方不放,主角向前。按住上方不放,主角向上。

那么如何确定我们按住的是哪个方向呢?

如图所示,黄色的是Stage,粉红的边框是整个Map,有部分显示,有一部分没有显示。右下角的绿色点是主角的位置,我们假定红色的点是我们的触碰点。

认定红色的触碰点为向前,我在提供一个方案,但是方法不唯一哈,我这样确定方向也不一定是最符合用户体验的。

以主角的位置为原点重现建立坐标系,得到触碰点的新坐标x,y.

图片分享:

确定了在新坐标系下的触碰点的象限,在判断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 
  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 }

最终效果:(图像加载可能有点慢)

 (...传不上来)无语中...

 

我不知道怎么录制手机屏幕,所以只有用模拟机演示,但是真机(中兴V880)速度很流畅,完全没问题。

如果有多个角色,方法是一样的,多建几个Object就行了。可以很明显看出,我们的忍者水平很高…行走地图完全没有障碍,而且如果你一直走的话会发现地图会消失一部分,这些问题接下的文章会慢慢解决的。

posted @ 2013-02-04 21:02  王世桢  阅读(203)  评论(0)    收藏  举报