前些日子的文章介绍了tiledmap的主角出现和移动等等问题。相对于主角游戏自然还应该有敌人(?)。
与主角不同的是,这些元素的移动时程序控制的,一般有3种。
1.随主角的移动变化,靠近主角或远离主角
2.按照固定路线移动
3.不动
第一种的话完全是看你的游戏逻辑决定,和tiledmap关系不大。第二种的话我们可以避免硬编码(把移动路径写入程序代码中),而采用tiledmap实现,下面我们来看看具体过程。
还是新建一张地图,我选用的大小是50*30,块大小:32*32。
town
town1
然后绘制地图:
adancedmap
我们假定敌人从地图中间的那条路走到左边的角上。路径如下:
adancedmap
现在新建一个对象层,命名为wayPoints。在几个关键的地方标注上对象,命名为wayPoint1,wayPoint2…
adancedmap
处理好地图后拷贝到项目中。
advancelibgdx
现在新建一个Enemy类,继承Image。
现在来整理一下思路,首先我们要得到所有的wayPoint.而第一个wayPoint就是角色的初始化点。那么Enemy类首先需要一个Vector2列表,然后继承Image需要一个TextureRegion。
所以构造函数为
- public Enemy(List<Vector2> vector2s, TextureRegion region) {
- super(region);
- this.vector2s = vector2s;
- currentIndex = 0;
- this.x = vector2s.get(currentIndex).x;
- this.y = vector2s.get(currentIndex).y;
- }
初始点有了,如何移动呢?我们先来看一下坐标
advancelibgdx2
我们现在在点1位置,将要移动到点2位置。只需计算x,y,z长度,然后求出对应的moveX和moveY就可以了。
- float x = Math.abs(v1.x - v2.x);
- float y = Math.abs(v1.y - v2.y);
- float z = (float) MathUtil.distanceBetweenTwoPoints(v1, v2);
- float moveX = 0f;
- float moveY = 0f;
- moveX = (x / z) * stepLength;
- moveY = (y / z) * stepLength;
- if (this.x < v2.x) {
- this.x += moveX;
- } else {
- this.x -= moveX;
- }
- if (this.y < v2.y) {
- this.y += moveY;
- } else {
- this.y -= moveY;
- }
distanceBetweenTwoPoints是我自己写的方法,计算两点距离。
现在我们的Enemy类就可以很正常的移动到下一个点了。
但当它接近下一个点的时候可以发现它在不停的颤抖。这是因为我们没有处理当Enemy到达下一个点时对点序列的更新。
当它和下一个点的距离很小时我们认定它到达下一个点,更新序列以保证它继续向下一个点移动。
- int nextIndex = currentIndex + 1 >= vector2s.size() - 1 ? vector2s
- .size() - 1 : currentIndex + 1;
- Vector2 v1 = vector2s.get(currentIndex);
- Vector2 v2 = vector2s.get(nextIndex);
- if (MathUtil.distanceBetweenTwoPoints(new Vector2(this.x, this.y), v2) < 1) {
- currentIndex = currentIndex + 1 < vector2s.size() - 1 ? currentIndex + 1
- : vector2s.size() - 1;
- nextIndex = currentIndex + 1 >= vector2s.size() - 1 ? vector2s
- .size() - 1 : currentIndex + 1;
- v1 = vector2s.get(currentIndex);
- v2 = vector2s.get(nextIndex);
- }
基本没有问题了,我们看一下效果:
advancelibgdx3
因为手机不好截图,所以用的java桌面项目。
Enemy用的图片是这张
Enemy
用TextureRegion[][] regions = TextureRegion.split(texture, 25, 33);切分,去2行3列。
完整代码:
- package com.cnblogs.htynkn.game;
- import java.util.ArrayList;
- import java.util.List;
- import javax.swing.text.ZoneView;
- import javax.swing.text.html.MinimalHTMLWriter;
- import com.badlogic.gdx.ApplicationListener;
- import com.badlogic.gdx.Gdx;
- import com.badlogic.gdx.InputMultiplexer;
- import com.badlogic.gdx.InputProcessor;
- import com.badlogic.gdx.files.FileHandle;
- import com.badlogic.gdx.graphics.Color;
- import com.badlogic.gdx.graphics.GL10;
- import com.badlogic.gdx.graphics.OrthographicCamera;
- import com.badlogic.gdx.graphics.Texture;
- import com.badlogic.gdx.graphics.g2d.BitmapFont;
- import com.badlogic.gdx.graphics.g2d.SpriteBatch;
- import com.badlogic.gdx.graphics.g2d.TextureAtlas;
- import com.badlogic.gdx.graphics.g2d.TextureRegion;
- import com.badlogic.gdx.graphics.g2d.tiled.TileAtlas;
- import com.badlogic.gdx.graphics.g2d.tiled.TileMapRenderer;
- import com.badlogic.gdx.graphics.g2d.tiled.TileSet;
- import com.badlogic.gdx.graphics.g2d.tiled.TiledLayer;
- import com.badlogic.gdx.graphics.g2d.tiled.TiledLoader;
- import com.badlogic.gdx.graphics.g2d.tiled.TiledMap;
- import com.badlogic.gdx.graphics.g2d.tiled.TiledObject;
- import com.badlogic.gdx.graphics.g2d.tiled.TiledObjectGroup;
- import com.badlogic.gdx.graphics.glutils.ShaderProgram;
- import com.badlogic.gdx.math.MathUtil;
- import com.badlogic.gdx.math.Vector2;
- import com.badlogic.gdx.math.Vector3;
- import com.badlogic.gdx.scenes.scene2d.Actor;
- import com.badlogic.gdx.scenes.scene2d.Stage;
- import com.badlogic.gdx.scenes.scene2d.ui.Image;
- import com.badlogic.gdx.scenes.scene2d.ui.Label;
- import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;
- import com.cnblogs.htynkn.actors.Enemy;
- public class MapDemo implements ApplicationListener, InputProcessor {
- Stage stage;
- float width;
- float height;
- private TiledMap map;
- private TileAtlas atlas;
- private TileMapRenderer tileMapRenderer;
- Vector3 camDirection = new Vector3(1, 1, 0);
- Vector2 maxCamPosition = new Vector2(0, 0);
- Vector3 moveVector = new Vector3(0, 0, 0);
- Enemy enemy;
- int i = 0;
- @Override
- public void create() {
- final String path = "map/";
- final String mapname = "adancedmap";
- FileHandle mapHandle = Gdx.files.internal(path + mapname + ".tmx");
- map = TiledLoader.createMap(mapHandle);
- atlas = new TileAtlas(map, new FileHandle("map/"));
- tileMapRenderer = new TileMapRenderer(map, atlas, 10, 10);
- maxCamPosition.set(tileMapRenderer.getMapWidthUnits(), tileMapRenderer
- .getMapHeightUnits());
- width = Gdx.graphics.getWidth();
- height = Gdx.graphics.getHeight();
- stage = new Stage(width, height, true);
- List<Vector2> list = new ArrayList<Vector2>();
- //获取所有wayPoints
- for (TiledObjectGroup group : map.objectGroups) {
- for (TiledObject object : group.objects) {
- if (object.name.startsWith("wayPoint")) {
- System.out.println(object.name + " X:" + object.x + " Y:"
- + object.y);
- list
- .add(new Vector2(object.x, maxCamPosition.y
- - object.y));
- }
- }
- }
- TextureAtlas region = new TextureAtlas(Gdx.files.internal("imgs/pack"));
- Texture texture = region.findRegion("Enemy").getTexture();
- TextureRegion[][] regions = TextureRegion.split(texture, 25, 33);
- enemy = new Enemy(list, regions[1][2]);
- stage.addActor(enemy);
- InputMultiplexer inputMultiplexer = new InputMultiplexer();
- inputMultiplexer.addProcessor(this);
- inputMultiplexer.addProcessor(stage);
- Gdx.input.setInputProcessor(inputMultiplexer);
- }
- @Override
- public void dispose() {
- // TODO Auto-generated method stub
- }
- @Override
- public void pause() {
- // TODO Auto-generated method stub
- }
- @Override
- public void render() {
- Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
- OrthographicCamera c = (OrthographicCamera) stage.getCamera();
- c.position.set(enemy.x, enemy.y, 0);
- stage.act(Gdx.graphics.getDeltaTime());
- tileMapRenderer.render(c);
- stage.draw();
- }
- @Override
- public void resize(int width, int height) {
- // TODO Auto-generated method stub
- }
- @Override
- public void resume() {
- // TODO Auto-generated method stub
- }
- @Override
- public boolean keyDown(int keycode) {
- return false;
- }
- @Override
- public boolean keyTyped(char character) {
- // TODO Auto-generated method stub
- return false;
- }
- @Override
- public boolean keyUp(int keycode) {
- // TODO Auto-generated method stub
- return false;
- }
- @Override
- public boolean scrolled(int amount) {
- // TODO Auto-generated method stub
- return false;
- }
- @Override
- public boolean touchDown(int x, int y, int pointer, int button) {
- return false;
- }
- @Override
- public boolean touchDragged(int x, int y, int pointer) {
- // TODO Auto-generated method stub
- return false;
- }
- @Override
- public boolean touchMoved(int x, int y) {
- // TODO Auto-generated method stub
- return false;
- }
- @Override
- public boolean touchUp(int x, int y, int pointer, int button) {
- Gdx.app.log("Info", "touchUp: x:" + x + " y: " + y + " pointer: "
- + pointer + " button: " + button);
- return false;
- }
- }
分割线=====================================分割线
- package com.cnblogs.htynkn.actors;
- import java.util.ArrayList;
- import java.util.List;
- import com.badlogic.gdx.graphics.g2d.SpriteBatch;
- import com.badlogic.gdx.graphics.g2d.TextureRegion;
- import com.badlogic.gdx.math.MathUtil;
- import com.badlogic.gdx.math.Vector2;
- import com.badlogic.gdx.scenes.scene2d.Actor;
- import com.badlogic.gdx.scenes.scene2d.ui.Image;
- public class Enemy extends Image {
- List<Vector2> vector2s = new ArrayList<Vector2>();
- int currentIndex;
- float stepLength = 1f;
- public Enemy(List<Vector2> vector2s, TextureRegion region) {
- super(region);
- this.vector2s = vector2s;
- currentIndex = 0;
- this.x = vector2s.get(currentIndex).x;
- this.y = vector2s.get(currentIndex).y;
- }
- @Override
- public void draw(SpriteBatch batch, float parentAlpha) {
- super.draw(batch, parentAlpha);
- }
- @Override
- public Actor hit(float x, float y) {
- return null;
- }
- @Override
- public void act(float delta) {
- int nextIndex = currentIndex + 1 >= vector2s.size() - 1 ? vector2s
- .size() - 1 : currentIndex + 1;
- Vector2 v1 = vector2s.get(currentIndex);
- Vector2 v2 = vector2s.get(nextIndex);
- if (MathUtil.distanceBetweenTwoPoints(new Vector2(this.x, this.y), v2) < 1) {
- currentIndex = currentIndex + 1 < vector2s.size() - 1 ? currentIndex + 1
- : vector2s.size() - 1;
- nextIndex = currentIndex + 1 >= vector2s.size() - 1 ? vector2s
- .size() - 1 : currentIndex + 1;
- v1 = vector2s.get(currentIndex);
- v2 = vector2s.get(nextIndex);
- }
- float x = Math.abs(v1.x - v2.x);
- float y = Math.abs(v1.y - v2.y);
- float z = (float) MathUtil.distanceBetweenTwoPoints(v1, v2);
- float moveX = 0f;
- float moveY = 0f;
- moveX = (x / z) * stepLength;
- moveY = (y / z) * stepLength;
- if (this.x < v2.x) {
- this.x += moveX;
- } else {
- this.x -= moveX;
- }
- if (this.y < v2.y) {
- this.y += moveY;
- } else {
- this.y -= moveY;
- }
- System.out.println("pos: " + this.x + "," + this.y + " v1:"
- + v1.toString() + " v2:" + v2.toString() + " d:" + z + " move:"
- + moveX + " , " + moveY);
- super.act(delta);
- }
- }
文章中用到的地图文件和相关资源:http://www.ctdisk.com/file/4279808
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。