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

http://www.cnblogs.com/htynkn/archive/2012/01/13/libgdx_13.html

本文紧跟上文,地址:android游戏开发框架libgdx的使用(十二)—TiledMap地图的使用

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

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

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

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

取名为play1

我们的主角是:

思路是我们遍历map中的所有Object,如果名字和我们设定的play1一致,那么就实例化一个Image,位置和Object一致,添加到舞台。

关键代码:

for (TiledObjectGroup group : map.objectGroups) {             for (TiledObject object : group.objects) {                 if ("play1".equals(object.name)) {                     player = new Image(new TextureRegion(new Texture(Gdx.files                             .internal("map/player.png")), 0, 0, 27, 40));                     player.x = object.x;                     player.y = tileMapRenderer.getMapHeightUnits() - object.y; //map是左上角,Stage是左下角                     stage.addActor(player);                 }             }         }

效果如下:

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

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

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

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

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

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

确定了在新坐标系下的触碰点的象限,在判断x,y的大小就可以知道方向了。

代码如下:

Vector3 tmp = new Vector3(x, y, 0);        stage.getCamera().unproject(tmp);        float newx = tmp.x - player.x;        float newy = tmp.y - player.y;        if (newx > 0 && newy > 0) {            if (newx > newy) {                ChangeDirect(4);            } else {                ChangeDirect(1);            }        } else if (newx > 0 && newy < 0) {            if (newx > -newy) {                ChangeDirect(4);            } else {                ChangeDirect(2);            }        } else if (newx < 0 && newy > 0) {            if (-newx > newy) {                ChangeDirect(3);            } else {                ChangeDirect(1);            }        } else {            if (-newx > -newy) {                ChangeDirect(3);            } else {                ChangeDirect(2);            }        }

直接移动Camera位置可以移动地图,但是我们的主角却从地图上消失了…处理办法是将你希望仍然显示在地图上的Actor的坐标随着Camera一起移动。

代码如下:

private void CameraMove(Vector3 vector3) {        stage.getCamera().position.add(vector3);        for (Actor actor : stage.getActors()) {            actor.x += vector3.x;            actor.y += vector3.y;        }    }

完整代码:

package com.cnblogs.htynkn.game;

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.TextureRegion;import com.badlogic.gdx.graphics.g2d.tiled.TileAtlas;import com.badlogic.gdx.graphics.g2d.tiled.TileMapRenderer;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.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;

public class firstGame implements ApplicationListener, InputProcessor {

    Stage stage;    float width;    float height;    private TiledMap map;    private TileAtlas atlas;    private TileMapRenderer tileMapRenderer;    Image player;    Vector3 camDirection = new Vector3(1, 1, 0);    Vector2 maxCamPosition = new Vector2(0, 0);    Vector3 moveVector = new Vector3(0, 0, 0);    boolean isPress;

    // Image image;

    @Override    public void create() {        final String path = "map/";        final String mapname = "tilemap";        FileHandle mapHandle = Gdx.files.internal(path + mapname + ".tmx");        map = TiledLoader.createMap(mapHandle);        atlas = new TileAtlas(map, Gdx.files.internal("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);        Label label = new Label("FPS:", new LabelStyle(new BitmapFont(Gdx.files                .internal("font/blue.fnt"),                Gdx.files.internal("font/blue.png"), false), Color.WHITE),                "fpsLabel");        label.y = height - label.getPrefHeight();        label.x = 0;        stage.addActor(label);

        for (TiledObjectGroup group : map.objectGroups) {            for (TiledObject object : group.objects) {                if ("play1".equals(object.name)) {                    player = new Image(new TextureRegion(new Texture(Gdx.files                            .internal("map/player.png")), 0, 0, 27, 40));                    player.x = object.x;                    player.y = tileMapRenderer.getMapHeightUnits() - object.y; // map是左上角,Stage是左下角                    stage.addActor(player);                }            }        }

        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();        if (isPress) {            CameraMove(moveVector);        }        ((Label) stage.findActor("fpsLabel")).setText("FPS: "                + Gdx.graphics.getFramesPerSecond());        stage.act(Gdx.graphics.getDeltaTime());        tileMapRenderer.render(c);        stage.draw();    }

    private void CameraMove(Vector3 vector3) {        stage.getCamera().position.add(vector3);        for (Actor actor : stage.getActors()) {            actor.x += vector3.x;            actor.y += vector3.y;        }    }

    @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) {        // TODO Auto-generated method stub        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;    }

    private void ChangeDirect(int typeId) {        switch (typeId) {        case 1:            moveVector.set(0, 1, 0);            Gdx.app.log("方向变动", "向上");            break;        case 2:            moveVector.set(0, -1, 0);            Gdx.app.log("方向变动", "向下");            break;        case 3:            moveVector.set(-1, 0, 0);            Gdx.app.log("方向变动", "向左");            break;        case 4:            moveVector.set(1, 0, 0);            Gdx.app.log("方向变动", "向右");            break;        }    }

    @Override    public boolean touchDown(int x, int y, int pointer, int button) {        Vector3 tmp = new Vector3(x, y, 0);        stage.getCamera().unproject(tmp);        float newx = tmp.x - player.x;        float newy = tmp.y - player.y;        if (newx > 0 && newy > 0) {            if (newx > newy) {                ChangeDirect(4);            } else {                ChangeDirect(1);            }        } else if (newx > 0 && newy < 0) {            if (newx > -newy) {                ChangeDirect(4);            } else {                ChangeDirect(2);            }        } else if (newx < 0 && newy > 0) {            if (-newx > newy) {                ChangeDirect(3);            } else {                ChangeDirect(1);            }        } else {            if (-newx > -newy) {                ChangeDirect(3);            } else {                ChangeDirect(2);            }        }        isPress = true;        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) {        isPress = false;        Gdx.app.log("Info", "touchUp: x:" + x + " y: " + y + " pointer: "                + pointer + " button: " + button);        return false;    }}

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

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

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

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

时间: 2024-11-08 11:50:49

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

android游戏开发框架libgdx的使用(二十一)—使用TTF字库支持中文

TTF字库 TTF(TrueTypeFont)是Apple公司和Microsoft公司共同推出的字体文件格式,随着windows的流行,已经变成最常用的一种字体文件表示方式,应用范围非常广. 如果是Windows操作系统,可以从Fonts文件夹中找到很多字库.也可以从网上下载. 我推荐YaHei.Consolas字库,看着很爽,反正我的eclipse就是用的这个字库. gdx-setup-ui的使用 从libgdx下载0.96版本,可以看到文件结构如下: libgdx-chinese-1 强烈运

Android游戏框架Libgdx使用入门

转载自:http://blog.csdn.net/cping1982/article/details/6176191 Libgdx作者博客:http://www.badlogicgames.com/ Libgdx项目地址:http://code.google.com/p/libgdx/ Libgdx是一款支持2D与3D游戏开发的游戏类库,兼容大多数微机平台(标准JavaSE实现,能执行在Mac.Linux.Windows等系统)与Android平台(Android1.5以上就可以使用.Andro

Android游戏源代码合集(主要是AndEngine和Libgdx的)

近期在网络上看到有网友抱怨Android游戏源代码找不到,所以小弟收集了一些AndEngine和Libgdx的游戏源代码,以Eclipseproject的形式配置好环境,再陆续发出(某引擎避嫌,不在此列). 虽说这些游戏,主要是由Libgdx与AndEngine开发的源代码组成.但其实,能算游戏的,开源的,举凡有点价值的Android游戏源代码,小弟也会陆续收集(比方Replicaisland没用不论什么引擎,可代码有价值,所以这次也放进来了),更会在博客中一一给出. 只是,有两类游戏不在此列,

Android游戏源码合集(主要是AndEngine和Libgdx的)

近在网络上看到有网友抱怨Android游戏源码找不到,所以小弟收集了一些AndEngine和Libgdx的游戏源码,以Eclipse工程的形式配置好环境,再陆续发出(某引擎避嫌,不在此列). 虽说这些游戏,主要是由Libgdx与AndEngine开发的源码组成.但事实上,能算游戏的,开源的,举凡有点价值的Android游戏源码,小弟也会陆续收集(比如Replicaisland没用任何引擎,可代码有价值,所以这次也放进来了),更会在博客中一一给出. 不过,有两类游戏不在此列,一是游戏源码虽然乍看下

本人第一个android游戏《新连连看》上架

经过艰苦奋战了几天,本人的第一个android游戏<新连连看>最终完毕了第一个版本号,比較简陋.另一部分功能保留没有开放.等第二个版本号再上.用的libgdx框架.可能不是非常出名,可是本人认为真的是非常好用的. 希望大家先去玩一下,然后给我提一些改进的意见.稍后我会进行改进.并在完好后发布源代码供讨论.批评. 传送门:http://app.lenovo.com/app/14452187.html ------------------------------------------------

看大师讲解Android快速开发框架EasyAndroid

前几天做了小应用,感觉小有成就,名字叫"长见识了",是一款趣味答题类的游戏,题目各种火爆各种经典,下载地址,看似一个简单的答题小游戏却是五脏俱全,从开发流程上都进行了严格的规范,大家有空可以下载玩玩~ 在这个应用中,用到了我以前集成的一个快速开发框架-EasyAndroid,这个框架我以前在做项目的时候总结,整理出来的,对于快速开发Android应用非常实用. 其实,Android应用的开发并不难,我们拿到一款Android应用后,百分之九十以上无外乎有这么几个功能: 1,IOC Mo

android快速开发框架

一.依赖注入DI通过依赖注入减少View.服务.资源简化初始化,事件绑定等重复繁琐工作1. AndroidAnnotations(Code Diet) android快速开发框架项目地址:https://github.com/excilys/androidannotations文档介绍:https://github.com/excilys/androidannotations/wiki官方网站:http://androidannotations.org/特点:(1)依赖注入:包括view,ext

教你如何选择Android游戏引擎

我们进行Android游戏开发时选择游戏引擎是必须的,但是该如何选择呢?哪个Android游戏引擎更加适合自己呢?本文就提供了三个游戏引擎的对比说明,阐述了它们各自的特点,为大家选择引擎提供了参照. 1.Ronkon 如果不是想帮助作者解决一大堆兼容性问题的话还是不要使用这个引擎,我在上面浪费了1天半,就只是为了把实例程序跑起来.开始还以为是我水平菜,结果一堆人没跑起来,和我一样都是黑屏.虽然它文档做得好但我还是放弃了,本来Android平台兼容性就是老大难,在来个半吊子的引擎我可没本事搞定.

Android 八款开源 Android 游戏引擎

原文地址 本文内容 Angle Rokon LGame AndEngine libgdx jPCT Alien3d Catcake 最近无意间看到一篇关于 Android 搜索引擎的文章,于是搜索了,学不学是其次,主要是要有这方面的知识--技多不压身嘛~ 下面罗列出八款常见的 Android 游戏引擎,以供参考.收费.下载量过小.不公开源码,以及鄙人不知道(-_-)的引擎不在此列. Angle Angle 是一款专为 Android 平台设计的,适合快速开发的 2D 游戏引擎,基于 OpenGL