简单的android游戏开发实例教程

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

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

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

开发实例教程-android开发简单实例">

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

取名为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;
    }
}

时间: 2024-08-01 14:58:41

简单的android游戏开发实例教程的相关文章

简单实用的ajax开发实例教程代码

// aien,i@ruboy.com,1034555083 // ajax(a,b,c,d,e,f,g); // 参数说明:a-请求方法:b-请求的地址:c-请求的数据,a为post时有效:d-回调函数,函数里面的this引用是xmlhttp对象:e-是否异步,除非设置为false,否则为异步调用:f,g-登录用户名和密码 function ajax(a,b,c,d,e,f,g){     a = a.touppercase();     if(e===false){e=false;}else

网页游戏开发入门教程三(简单程序应用)_php实例

网页游戏开发入门教程二(游戏模式+系统)http://www.jb51.net/article/20724.htm 一.选择开发语言 后台:java .net php 前台:flex javascript ajax 数据库:mysql mssql 用哪种组合,真的不重要.重要的是时间和成本.复杂的地方在数据的交互和完善,而不在技术或效果的实现.往往遇到一些问题.比如地图如何编?人物移动如何实现?其实这些问题从技术上实现都比较容易.难在实现后,数据如何交互.没有解决数据交互的问题,实现这些技术点的

Android 游戏开发入门简单示例_Android

 在Android系统上开发游戏是Android开发学习者所向往的,有成就感也有乐趣,还能取得经济上的报酬.那怎样开发Android游戏呢?下面介绍一个简单的入门实例.        一.创建新工程        首先,我们在Eclipse中新建一个名为Movement的工程,并且选择合适的Android SDK,在这里,我们选用的API是比较低的1.5版本,这样可以让其适应性更强.接下来,我们新建两个类,一个是UpdateThread类,一个是SurfaceView类,它们在项目中分别是负责处

【ANDROID游戏开发十六】ANDROID GESTURE之【触摸屏手势识别】操作!利用触摸屏手势实现一个简单切换图片的功能!

本站文章均为 李华明Himi 原创,转载务必在明显处注明:  转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/android-game/337.html ----------------------- 『很多童鞋说我的代码运行后,点击home或者back后会程序异常,如果你也这样遇到过,那么你肯定没有仔细读完Himi的博文,第十九篇Himi专门写了关于这些错误的原因和解决方法,这里我在博客都补充说明下,省的童鞋们总疑惑这一块:请点击下面联系进入阅读:

Android 游戏开发入门简单示例

在Android系统上开发游戏是Android开发学习者所向往的,有成就感也有乐趣,还能取得经济上的报酬.那怎样开发Android游戏呢?下面介绍一个简单的入门实例. 一.创建新工程 首先,我们在Eclipse中新建一个名为Movement的工程,并且选择合适的Android SDK,在这里,我们选用的API是比较低的1.5版本,这样可以让其适应性更强.接下来,我们新建两个类,一个是UpdateThread类,一个是SurfaceView类,它们在项目中分别是负责处理线程和画面的两个类,在接下来

【ANDROID游戏开发之一】设置全屏以及绘画简单的图形

本站文章均为 李华明Himi 原创,转载务必在明显处注明:  转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/android-game/263.html 『很多童鞋说我的代码运行后,点击home或者back后会程序异常,如果你也这样遇到过,那么你肯定没有仔细读完Himi的博文,第十九篇Himi专门写了关于这些错误的原因和解决方法,这里我在博客都补充说明下,省的童鞋们总疑惑这一块:请点击下面联系进入阅读: [Android游戏开发十九](必看篇)Sur

【ANDROID游戏开发二十一】ANDROID OS设备谎言分辨率的解决方案!以及简单阐述游戏引擎如何使用!

本站文章均为 李华明Himi 原创,转载务必在明显处注明:  转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/android-game/356.html 刚才一群里的兄弟问的一问题,稍微研究下,这里一起分享:新建的Emulator -配置为:WAGA800  其分辨率是 800*480 的设备模拟器,当我们程序中在取得其 Height和 Width的时候发现,总是 320*533 ,明显是系统对我们撒了谎!如下图:   下面是官方文档原文: http

《Android游戏开发详解》一1.4 关于位的一切(位和字节的简单介绍)

1.4 关于位的一切(位和字节的简单介绍) Android游戏开发详解 在我们继续深入之前,值得先细致地介绍如何具体把值存储到变量中.我前面提到,不同的基本数据类型具有不同的位大小.例如,一个int有32位而一个long有64位.你可能会问,那么,到底什么是位? 位(bit)是一个二进制位的简称.换句话说,如果你有一个只有0和1的二进制数,每个数字就是1位.达到8位的时候,例如,(10101001),你就有了1字节. 对于位,你需要记住的一点是:拥有的位越多,所能表示的数值也越多.为了说明这一点

Android游戏开发学习之引擎用法实例详解_Android

本文实例讲述了Android游戏开发学习之引擎用法.分享给大家供大家参考.具体如下: 汽车引擎是汽车的心脏,其决定了汽车的性能和稳定性,是人们在购车时相当关注的.而游戏中的物理引擎就如汽车的引擎一样,占据了非常重要的位置.一款好的物理引擎可以非常真实地模拟现实世界,使得游戏更加逼真,提供更好的娱乐体验. 一.JBox2D简介 JBox2D是开源物理引擎Box2D的Java版本,可以直接用于Android.由于JBox2D的图形渲染使用的是Processing库,因此在Android平台上使用JB