您的位置:首页 > 移动开发 > Android开发

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

2012-11-05 09:56 946 查看
分享了一些素材,有兴趣的朋友可以看看:/article/4897305.html

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

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

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

2.按照固定路线移动

3.不动

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

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





图片分享:





然后绘制地图:





图片分享:

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





图片分享:

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





图片分享:

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





图片分享:

现在新建一个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;

}
复制代码

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





图片分享:

我们现在在点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);

}
复制代码

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





图片分享:

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

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐