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

  • 相关阅读:
    Azkaban的使用
    Azkaban安装
    Kafka 启动失败,报错Corrupt index found以及org.apache.kafka.common.protocol.types.SchemaException: Error reading field 'version': java.nio.BufferUnderflowException
    Kafka 消费者设置分区策略及原理
    Kafka利用Java API自定义生产者,消费者,拦截器,分区器等组件
    zookeeper群起总是有那么几个节点起不来的问题解决
    flume 启动agent报No appenders could be found for logger的解决
    Flume 的监控方式
    Flume 自定义 组件
    Source r1 has been removed due to an error during configuration java.lang.IllegalArgumentException: Required parameter bind must exist and may not be null & 端口无法连接
  • 原文地址:https://www.cnblogs.com/htynkn/p/libgdx_17.html
Copyright © 2011-2022 走看看