android遊戲開發架構libgdx的使用(十三)—TiledMap中的角色和角色移動

來源:互聯網
上載者:User

本文使用的libgdx是0.92版本,和現在的最新版可能有一些不一樣的地方。全文內容僅供參考。

本文緊跟上文,地址: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就行了。可以很明顯看出,我們的忍者水平很高…行走地圖完全沒有障礙,而且如果你一直走的話會發現地圖會消失一部分,這些問題接下的文章會慢慢解決的。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.