android遊戲開發架構libgdx的使用(四)–舞台和演員

來源:互聯網
上載者:User

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

我們先看幾個遊戲再來理解何為舞台。

請仔細觀察圖片中的元素,有些東西是不能動,有些可以動,有些有特效,有些沒有。有些是按鈕,有些是圖片,但是其實它們都可以統一稱為演員(Actor)。

而整個遊戲介面就是我們的舞台。

再看一個射擊類遊戲

而其中的演員是

演員是遊戲設計中常用的一個對象,它接受舞台的統一管理,擁有一些公用的事件,比如觸摸,點擊,但是同時還有自身的響應和屬性。

而舞台就是容納演員的場所。它統一管理所有演員,接受輸入,同時提供一個方便的架構操作演員的時間變化。

我們來看一下Stage類:

protected final Group root;protected final SpriteBatch batch; protected Camera camera;

它擁有一個Group,一個SpriteBatch,還有一個相機。

SpriteBatch我們在前幾篇說過,這裡就不再重複了。

Group是一個類,用於容納和控制演員。但是這裡要注意Group本身其實也是繼承自Actor。

相機我們這裡跳過,以後再說,可以暫時理解成一個控制觀察視角和指標轉化的工具。

當我們擁有一個演員後就可以調用addActor方法加入舞台。

舞台可以擷取輸入,但是需要設定。

Gdx.input.setInputProcessor(stage);

下面來個列子,控制一個人物前進。

控制人物的按鈕:

將所需的圖片放到assert中

建立三個類:

FirstGame,實現介面ApplicationListener

FirstActor,繼承Actor

NarrowButton,繼承Actor

先看一下FirstGame

聲明一個Stage,然後執行個體化FirstActor和NarrowButton,將二者加入舞台中,最後設定輸入響應為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用於繪製。在構造方法中擷取到高度和寬度,以便於後期的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中代碼繪製部分和上面的以下,主要是有個點擊後控制人物行動的問題。

修改touchDown事件:

通過Group擷取到FirstActor,控制x值。

public boolean touchDown(float x, float y, int pointer) {         Actor actor = this.parent.findActor("renwu");         actor.x += 10;         return false;     }

效果:

到此為止一個最簡單的人物控制我們已經實現了。但是這個有執行個體還有很多可以改進的地方,比如方向按鈕沒有點擊效果,人物沒有移動效果。

我們可以使用Animation來實現。添加一張圖片

具體的原理我們看一下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];     } }

可以看出所謂的動畫其實是一張一張的圖片不斷切換(其實所有的動畫都是這個樣子的)。

我們構造一個圖片列表然後根據事件變動不停取出,重新繪製就形成動畫了。

注意一下傳入的時間和圖片列表大小的問題,修改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;@Overridepublic void draw(SpriteBatch batch, float parentAlpha) {stateTime += Gdx.graphics.getDeltaTime();TextureRegion currentFrame = animation.getKeyFrame(stateTime, true);batch.draw(currentFrame, this.x, this.y);}@Overridepublic 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;}}@Overridepublic boolean touchDown(float x, float y, int pointer) {// TODO Auto-generated method stubreturn false;}@Overridepublic void touchDragged(float x, float y, int pointer) {// TODO Auto-generated method stub}@Overridepublic 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轉為TextureRegion。這是因為在實際開發中的圖片是整合在一起的,比如所有角色要用的圖片都是放在一張圖裡,然後分割截取的,對應的輔助方法TextureRegion.split。

另外我們可以發現NarrowButton和FirstActor中有大量代碼重複了,可能有朋友覺得應該提取一下,其實libgdx已經幫我們做了,可以參考

這裡有一些常用的UI控制項,估計下一篇可以講到。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.