zoukankan      html  css  js  c++  java
  • android游戏开发框架libgdx的使用(十七)—TiledMap中角色的行动路径

    分享了一些素材,有兴趣的朋友可以看看:http://www.cnblogs.com/htynkn/archive/2012/01/19/game_resource.html

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

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

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

    2.按照固定路线移动

    3.不动

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

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

    towntown1

    然后绘制地图:

    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

  • 相关阅读:
    [转]常用数字处理算法的Verilog实现
    [转]Linux必学的60个命令
    [转]4位超前进位加法器代码及原理
    [转]FPGA & Verilog开发经验若干
    [转]Verilog中parameter和define的区别
    [转]VIM标记 mark 详解
    关于获取服务的需求列表
    Office 2007 探索之路 Outlook
    利用反射建立单一调用的WebService
    寻宝记
  • 原文地址:https://www.cnblogs.com/htynkn/p/libgdx_17.html
Copyright © 2011-2022 走看看