新聞中心
大家先要有舞臺和演員的概念,下面通過一個游戲截圖來說明:

創(chuàng)新互聯(lián)從2013年創(chuàng)立,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元全椒做網(wǎng)站,已為上家服務(wù),為全椒各地企業(yè)和個人服務(wù),聯(lián)系電話:13518219792
請仔細(xì)觀察圖片中的元素,有些東西是不能動,有些可以動,有些有特效,有些沒有,有各種圖片,但是其實(shí)它們都可以統(tǒng)一稱為演員(Actor)。圖中用框標(biāo)出的就是演員。而整個游戲界面就是我們的舞臺。
演員是游戲設(shè)計(jì)中常用的一個對象,它接受舞臺的統(tǒng)一管理,擁有一些公共的事件,比如觸摸,點(diǎn)擊,但是同時還有自身的響應(yīng)和屬性;而舞臺就是容納演員的場所。它統(tǒng)一管理所有演員,接受輸入,同時提供一個方便的框架操作演員的時間變化。
Stage類
我們來看一下Stage類:
protected final Group root;
protected final SpriteBatch batch;
protected Camera camera;
它擁有一個Group,一個SpriteBatch,還有一個相機(jī)。
SpriteBatch我們在前幾篇說過,這里就不再重復(fù)了。
Group是一個類,用于容納和控制演員。但是這里要注意Group本身其實(shí)也是繼承自Actor。
相機(jī)我們這里跳過,以后再說,可以暫時理解成一個控制觀察視角和指標(biāo)轉(zhuǎn)化的工具。
當(dāng)我們擁有一個演員后就可以調(diào)用addActor方法加入舞臺。
舞臺可以獲取輸入,但是需要設(shè)置。
Gdx.input.setInputProcessor(stage);
舞臺和演員實(shí)例分享
下面來個列子,控制一個人物前進(jìn)。
控制人物的按鈕:
將所需的圖片放到assert中:
新建三個類:
FirstGame,實(shí)現(xiàn)接口ApplicationListener
FirstActor,繼承Actor
NarrowButton,繼承Actor
先看一下FirstGame
聲明一個Stage,然后實(shí)例化FirstActor和NarrowButton,將二者加入舞臺中,最后設(shè)置輸入響應(yīng)為Stage。
- package com.cnblogs.htynkn.listener;
- import java.util.Date;
- import java.util.Random;
- import javax.microedition.khronos.opengles.GL;
- import Android.util.Log;
- import com.badlogic.gdx.ApplicationListener;
- import com.badlogic.gdx.Gdx;
- import com.badlogic.gdx.graphics.GL10;
- import com.badlogic.gdx.graphics.g2d.BitmapFont;
- import com.badlogic.gdx.scenes.scene2d.Stage;
- import com.cnblogs.htynkn.domain.FirstActor;
- import com.cnblogs.htynkn.domain.NarrowButton;
- public class FirstGame implements ApplicationListener {
- private Stage stage;
- private FirstActor firstActor;
- private NarrowButton button;
- @Override
- public void create() {
- stage = new Stage(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(),
- true);
- firstActor = new FirstActor("renwu");
- button = new NarrowButton("narrow");
- stage.addActor(firstActor);
- stage.addActor(button);
- Gdx.input.setInputProcessor(stage);
- }
- @Override
- public void dispose() {
- stage.dispose();
- }
- @Override
- public void pause() {
- // TODO Auto-generated method stub
- }
- @Override
- public void render() {
- Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
- stage.act(Gdx.graphics.getDeltaTime());
- stage.draw();
- }
- @Override
- public void resize(int width, int height) {
- // TODO Auto-generated method stub
- }
- @Override
- public void resume() {
- // TODO Auto-generated method stub
- }
- }
再看一下FirstActor。
聲明一個Texture用于繪制。在構(gòu)造方法中獲取到高度和寬度,以便于后期的hit時間判斷。
- package com.cnblogs.htynkn.domain;
- import com.badlogic.gdx.Gdx;
- import com.badlogic.gdx.graphics.Texture;
- import com.badlogic.gdx.graphics.g2d.SpriteBatch;
- import com.badlogic.gdx.scenes.scene2d.Actor;
- public class FirstActor extends Actor {
- Texture texture;
- @Override
- public void draw(SpriteBatch batch, float parentAlpha) {
- batch.draw(texture, this.x, this.y);
- }
- @Override
- public Actor hit(float x, float y) {
- if (x > 0 && y > 0 && this.height > y && this.width > x) {
- return this;
- } else {
- return null;
- }
- }
- @Override
- public boolean touchDown(float x, float y, int pointer) {
- // TODO Auto-generated method stub
- return false;
- }
- @Override
- public void touchDragged(float x, float y, int pointer) {
- // TODO Auto-generated method stub
- }
- @Override
- public void touchUp(float x, float y, int pointer) {
- // TODO Auto-generated method stub
- }
- public FirstActor(String name) {
- super(name);
- texture = new Texture(Gdx.files.internal("actor1.gif"));
- this.height = texture.getHeight();
- this.width = texture.getWidth();
- }
- }
NarrowButton中代碼繪制部分和上面的以下,主要是有個點(diǎn)擊后控制人物行動的問題。
修改touchDown事件:
通過Group獲取到FirstActor,控制x值。
- public boolean touchDown(float x, float y, int pointer) {
- Actor actor = this.parent.findActor("renwu");
- actor.x += 10;
- return false;
- }
效果:
到此為止一個最簡單的人物控制我們已經(jīng)實(shí)現(xiàn)了。但是這個有實(shí)例還有很多可以改進(jìn)的地方,比如方向按鈕沒有點(diǎn)擊效果,人物沒有移動效果。
我們可以使用Animation來實(shí)現(xiàn)。添加一張圖片:
具體的原理我們看一下Animation類:
- public class Animation {
- final TextureRegion[] keyFrames;
- public float frameDuration;
- /** Constructor, storing the frame duration and key frames.
- *
- * @param frameDuration the time between frames in seconds.
- * @param keyFrames the {@link TextureRegion}s representing the frames. */
- public Animation (float frameDuration, List keyFrames) {
- this.frameDuration = frameDuration;
- this.keyFrames = new TextureRegion[keyFrames.size()];
- for(int i = 0, n = keyFrames.size(); i < n; i++) {
- this.keyFrames[i] = (TextureRegion)keyFrames.get(i);
- }
- }
- /** Constructor, storing the frame duration and key frames.
- *
- * @param frameDuration the time between frames in seconds.
- * @param keyFrames the {@link TextureRegion}s representing the frames. */
- public Animation (float frameDuration, TextureRegion... keyFrames) {
- this.frameDuration = frameDuration;
- this.keyFrames = keyFrames;
- }
- /** Returns a {@link TextureRegion} based on the so called state time. This is the amount of seconds an object has spent in the
- * state this Animation instance represents, e.g. running, jumping and so on. The mode specifies whether the animation is
- * looping or not.
- * @param stateTime the time spent in the state represented by this animation.
- * @param looping whether the animation is looping or not.
- * @return the TextureRegion representing the frame of animation for the given state time. */
- public TextureRegion getKeyFrame (float stateTime, boolean looping) {
- int frameNumber = (int)(stateTime / frameDuration);
- if (!looping) {
- frameNumber = Math.min(keyFrames.length - 1, frameNumber);
- } else {
- frameNumber = frameNumber % keyFrames.length;
- }
- return keyFrames[frameNumber];
- }
- }
可以看出所謂的動畫其實(shí)是一張一張的圖片不斷切換(其實(shí)所有的動畫都是這個樣子的)。
我們構(gòu)造一個圖片列表然后根據(jù)事件變動不停取出,重新繪制就形成動畫了。
注意一下傳入的時間和圖片列表大小的問題,修改FirstActor代碼如下:
- package com.cnblogs.htynkn.domain;
- import com.badlogic.gdx.Gdx;
- import com.badlogic.gdx.graphics.Texture;
- import com.badlogic.gdx.graphics.g2d.Animation;
- import com.badlogic.gdx.graphics.g2d.SpriteBatch;
- import com.badlogic.gdx.graphics.g2d.TextureRegion;
- import com.badlogic.gdx.scenes.scene2d.Actor;
- public class FirstActor extends Actor {
- Texture texture1;
- Texture texture2;
- Animation animation;
- TextureRegion[] walksFrame;
- float stateTime;
- @Override
- public void draw(SpriteBatch batch, float parentAlpha) {
- stateTime += Gdx.graphics.getDeltaTime();
- TextureRegion currentFrame = animation.getKeyFrame(stateTime, true);
- batch.draw(currentFrame, this.x, this.y);
- }
- @Override
- public Actor hit(float x, float y) {
- Gdx.app.log("INFO", x + " " + this.width);
- if (x > 0 && y > 0 && this.height > y && this.width > x) {
- return this;
- } else {
- return null;
- }
- }
- @Override
- public boolean touchDown(float x, float y, int pointer) {
- // TODO Auto-generated method stub
- return false;
- }
- @Override
- public void touchDragged(float x, float y, int pointer) {
- // TODO Auto-generated method stub
- }
- @Override
- public void touchUp(float x, float y, int pointer) {
- // TODO Auto-generated method stub
- }
- public FirstActor(String name) {
- super(name);
- texture1 = new Texture(Gdx.files.internal("actor1.gif"));
- texture2 = new Texture(Gdx.files.internal("actor2.gif"));
- this.height = texture1.getHeight();
- this.width = texture1.getWidth();
- TextureRegion region1;
- TextureRegion region2;
- region1 = new TextureRegion(texture1);
- region2 = new TextureRegion(texture2);
- walksFrame = new TextureRegion[30];
- for (int i = 0; i < 30; i++) {
- if (i % 2 == 0) {
- walksFrame[i] = region1;
- } else {
- walksFrame[i] = region2;
- }
- }
- animation = new Animation(0.25f, walksFrame);
- }
- }
效果:
這里注意一下,為什么我們要Texture轉(zhuǎn)為TextureRegion。這是因?yàn)樵趯?shí)際開發(fā)中的圖片是集成在一起的,比如所有角色要用的圖片都是放在一張圖里,然后分割截取的,對應(yīng)的輔助方法TextureRegion.split。
另外我們可以發(fā)現(xiàn)NarrowButton和FirstActor中有大量代碼重復(fù)了,可能有朋友覺得應(yīng)該提取一下,其實(shí)libgdx已經(jīng)幫我們做了,可以參考
圖片分享:
這里有一些常用的UI控件,估計(jì)下一篇可以講到。
標(biāo)題名稱:Android游戲引擎libgdx使用教程4:舞臺和演員的游戲?qū)嵗?
分享鏈接:http://m.fisionsoft.com.cn/article/coosoge.html


咨詢
建站咨詢
