LibGDX游戏引擎-8舞台类的使用(Stage)

舞台类相比于演员类来说,更容易理解,它其实从功能的角度来说就是负责管理演员和Group类的平台,他本身的存在就是为了管理,而不是去负责演出,他就像一个导演一样,只负责管理,具体如何表演,那不是舞台所负责的事情。我们通过实现一个游戏中常见的商店系统来学习舞台类
Stage类
API定义:

包含拥有层次结构的一个二维场景,场景中有许多演员。处理视图和分配的输入事件。舞台负责操作视角,和处理分配输入事件。

 

功能作用:

  • 1 充满整个屏幕。
  • 2 设置视角和使用的相机,调配 Actor、Group 与 Screen 之间的关系转换(包括坐标)。
  • 3 接收输入事件,并将它分配给演员。(通过gdx.input.setinputprocessor(Stage)来实现)
  • 4 处理输入事件的不同阶段,即之前或之后。(inputmultiplexer)如果一个演员通过返回TRUE从输入的方法中处理一个事件,那么Stage的输入方法也会返回true,导致随后的inputprocessors不接收事件。
    使用方法:

Stage(float width, float height, boolean keepAspectRatio, SpriteBatch batch)

  • (1)第一个参数:设置舞台的宽度。
  • (2)第二个参数:设置舞台的高度。
  • (3)第三个参数:是负责是否让舞台铺满屏幕,如果这个值是假的话,舞台的尺寸就是你设置的大小。如果是真的话,就铺满屏幕。
  • (4)第四个参数:就是传入你所声明的Spirtibatch。

    常用:

    stage = new Stage(800, 480, false, batch);

    stage.addActor(image_stage_background);

    Gdx.input.setInputProcessor(stage);

    stage.act();

    stage.draw();
    功能分析:
    这次我们通过一个游戏中的商店系统来实现多舞台的使用,同时了解舞台是如何切换的。一个简单的游戏商店需要有4个元素:

  • (1)商店按钮,按钮应该在游戏的画面内部。

  • (2)商店货架,陈列出售的物品。
  • (3)商品,出售的商品,点击商品需要有返回效果。
  • (4)购买结束状态,这里就弹出“购买成功”作为结束状态。
    编码步骤:

我们还是使用上次教程的超级玛丽的例子,这次我们加入一个开始界面,和一个商店系统。

(1)首先加入一个开始画面,这里我们使用Image控件,将它铺满屏幕。同时我们再使用一个image控件,作为新游戏按钮

openStage = new Stage(800, 480, false, batch);
//开始游戏舞台
Texture texture_open = new Texture(Gdx.files.internal(“data/open.png”));
Texture texture_button = new Texture(Gdx.files.internal(“data/btn_newgame.png”));
Texture texture_button2 = new Texture(Gdx.files.internal(“data/btn_shop.png”));
image_openStage_background = new Image(new TextureRegion(texture_open,800,480));
image_openStage_background.setPosition(0,0);
image_openStage_btn_newGame = new Image(texture_button);
image_openStage_btn_newGame.setPosition(80,380);
image_openStage_btn_shop = new Image(texture_button2);
image_openStage_btn_shop.setPosition(80,80);
openStage.addActor(image_openStage_background);
openStage.addActor(image_openStage_btn_newGame);
openStage.addActor(image_openStage_btn_shop);

(2)使用一个布尔类型的变量来控制舞台的切换,这里我们就使用GameIsRunning。为了是开始界面的舞台
能启动,我们重写button的touchdown方法,将GameIsRunning赋值为真。

public static boolean GameIsRunning = false;
public static boolean ShopIsRunning = false;
public static boolean SuccessIsRunning = false;

(3)在render()方法中进行判断,然后将openStage画出来。

(4)通过上面的办法,我们就初步的实现了一个双舞台的切换,首先是在开始舞台上,
随后通过点击“新游戏”进入主游戏界面。

我们要做的游戏商店,上面也提到了,并不是仅仅有2个舞台,他有3个舞台以上,所以我们需要在主游戏舞台上面,

再引入变量,来控制第二、第三个舞台的切换。其实原理是一样的。这里我们引入ShopIsRunning和SuccessIsRunning

分别来控制shop舞台和success舞台。

//重置舞台监听
public void setStage(){
if(GameIsRunning){
Gdx.input.setInputProcessor(stage);
}else{
Gdx.input.setInputProcessor(openStage);
if(ShopIsRunning){
Gdx.input.setInputProcessor(shopStage);
if(SuccessIsRunning){
Gdx.input.setInputProcessor(successStage);
}
}
}
}
//重置舞台绘制
public void stageRender(){
if(GameIsRunning){
stage.act();
stage.draw();
}else{
openStage.act();
openStage.draw();
if(ShopIsRunning){
shopStage.act();
shopStage.draw();
if(SuccessIsRunning){
successStage.act();
successStage.draw();
}
}
}
}

(5)加入监听,同时通过重写touchdown方法来修改变量,从而控制舞台切换。

image_openStage_btn_newGame.addListener(new InputListener(){
@Override
public boolean touchDown(InputEvent event, float x, float y,
int pointer, int button) {
GameIsRunning = true;
return true;
}
});

(6)游戏初始化和设置图片位置。

batch = new SpriteBatch();
stage = new Stage(800, 480, false, batch);
openStage = new Stage(800, 480, false, batch);
shopStage = new Stage(800, 480, false, batch);
successStage = new Stage(800, 480, false, batch);

//开始游戏舞台
Texture texture_open = new Texture(Gdx.files.internal(“data/open.png”));
Texture texture_button = new Texture(Gdx.files.internal(“data/btn_newgame.png”));
Texture texture_button2 = new Texture(Gdx.files.internal(“data/btn_shop.png”));
image_openStage_background = new Image(new TextureRegion(texture_open,800,480));
image_openStage_background.setPosition(0,0);
image_openStage_btn_newGame = new Image(texture_button);
image_openStage_btn_newGame.setPosition(80,380);
image_openStage_btn_shop = new Image(texture_button2);
image_openStage_btn_shop.setPosition(80,80);
openStage.addActor(image_openStage_background);
openStage.addActor(image_openStage_btn_newGame);
openStage.addActor(image_openStage_btn_shop);

//商店舞台
Texture texture_shop = new Texture(Gdx.files.internal(“data/shop.png”));
image_shopStage_background = new Image(new TextureRegion(texture_shop,0,85,512,350));
image_shopStage_btn_heart = new Image(new TextureRegion(texture_shop,0,0,102,85));
image_shopStage_btn_coin = new Image(new TextureRegion(texture_shop,102,0,102,85));
image_shopStage_btn_close = new Image(new TextureRegion(texture_shop,300,10,50,40));
image_shopStage_background.setPosition(0, 0);
image_shopStage_background.setSize(480,320);
image_shopStage_btn_heart.setPosition(190,50);
image_shopStage_btn_coin.setPosition(50,50);
image_shopStage_btn_close.setPosition(400,275);
shopStage.addActor(image_shopStage_background);
shopStage.addActor(image_shopStage_btn_heart);
shopStage.addActor(image_shopStage_btn_coin);
shopStage.addActor(image_shopStage_btn_close);

//购买舞台
image_successStage_success = new Image(new TextureRegion(texture_shop,512,0,255,255));
image_successStage_success.setPosition(100,100);
successStage.addActor(image_successStage_success);

//游戏舞台
image_stage_background = new Image(new Texture(Gdx.files.internal(“data/background.jpg”)));
Gdx.input.setInputProcessor(stage);
Person p = new Person(100,170);
stage.addActor(image_stage_background);
stage.addActor(p);
stage.addActor(p.btn_L);
stage.addActor(p.btn_R);
 

至此,整个程序就算完成了。下面贴出整个例子的源码:(下一页)

例子源码:使用到的(Person类请见 7 演员类的使用 Actor 类)

 

package com.qsuron;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.InputListener;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Image;

public class MyDemo implements ApplicationListener{
public static boolean GameIsRunning = false;
public static boolean ShopIsRunning = false;
public static boolean SuccessIsRunning = false;
SpriteBatch batch;
Image image_stage_background,
image_openStage_background,
image_openStage_btn_newGame,
image_openStage_btn_shop,
image_shopStage_background,
image_shopStage_btn_heart,
image_shopStage_btn_coin,
image_shopStage_btn_close,
image_successStage_success;
Stage stage,
openStage,
shopStage,
successStage;

@Override
public void create() {
batch = new SpriteBatch();
stage = new Stage(800, 480, false, batch);
openStage = new Stage(800, 480, false, batch);
shopStage = new Stage(800, 480, false, batch);
successStage = new Stage(800, 480, false, batch);

//开始游戏舞台
Texture texture_open = new Texture(Gdx.files.internal(“data/open.png”));
Texture texture_button = new Texture(Gdx.files.internal(“data/btn_newgame.png”));
Texture texture_button2 = new Texture(Gdx.files.internal(“data/btn_shop.png”));
image_openStage_background = new Image(new TextureRegion(texture_open,800,480));
image_openStage_background.setPosition(0,0);
image_openStage_btn_newGame = new Image(texture_button);
image_openStage_btn_newGame.setPosition(80,380);
image_openStage_btn_shop = new Image(texture_button2);
image_openStage_btn_shop.setPosition(80,80);
openStage.addActor(image_openStage_background);
openStage.addActor(image_openStage_btn_newGame);
openStage.addActor(image_openStage_btn_shop);

//商店舞台
Texture texture_shop = new Texture(Gdx.files.internal(“data/shop.png”));
image_shopStage_background = new Image(new TextureRegion(texture_shop,0,85,512,350));
image_shopStage_btn_heart = new Image(new TextureRegion(texture_shop,0,0,102,85));
image_shopStage_btn_coin = new Image(new TextureRegion(texture_shop,102,0,102,85));
image_shopStage_btn_close = new Image(new TextureRegion(texture_shop,300,10,50,40));
image_shopStage_background.setPosition(0, 0);
image_shopStage_background.setSize(480,320);
image_shopStage_btn_heart.setPosition(190,50);
image_shopStage_btn_coin.setPosition(50,50);
image_shopStage_btn_close.setPosition(400,275);
shopStage.addActor(image_shopStage_background);
shopStage.addActor(image_shopStage_btn_heart);
shopStage.addActor(image_shopStage_btn_coin);
shopStage.addActor(image_shopStage_btn_close);

//购买舞台
image_successStage_success = new Image(new TextureRegion(texture_shop,512,0,255,255));
image_successStage_success.setPosition(100,100);
successStage.addActor(image_successStage_success);

//游戏舞台
image_stage_background = new Image(new Texture(Gdx.files.internal(“data/background.jpg”)));
Gdx.input.setInputProcessor(stage);
Person p = new Person(100,170);
stage.addActor(image_stage_background);
stage.addActor(p);
stage.addActor(p.btn_L);
stage.addActor(p.btn_R);

//设置监听
this.setListener();
}

public void setListener() {
image_openStage_btn_newGame.addListener(new InputListener(){
@Override
public boolean touchDown(InputEvent event, float x, float y,
int pointer, int button) {
GameIsRunning = true;
return true;
}
});
image_openStage_btn_shop.addListener(new InputListener(){
@Override
public boolean touchDown(InputEvent event, float x, float y,
int pointer, int button) {
ShopIsRunning = true;
return true;
}
});
image_shopStage_btn_heart.addListener(new InputListener() {
@Override
public boolean touchDown(InputEvent event, float x, float y,
int pointer, int button) {
SuccessIsRunning = true;
return true;
}
});
image_shopStage_btn_coin.addListener(new InputListener() {
@Override
public boolean touchDown(InputEvent event, float x, float y,
int pointer, int button) {
SuccessIsRunning = true;
return true;
}
});
image_shopStage_btn_close.addListener(new InputListener(){
@Override
public boolean touchDown(InputEvent event, float x, float y,
int pointer, int button) {
ShopIsRunning = false;
return true;
}
});
image_successStage_success.addListener(new InputListener(){
@Override
public boolean touchDown(InputEvent event, float x, float y,
int pointer, int button) {
SuccessIsRunning = false;
return true;
}
});
}

//重置舞台监听
public void setStage(){
if(GameIsRunning){
Gdx.input.setInputProcessor(stage);
}else{
Gdx.input.setInputProcessor(openStage);
if(ShopIsRunning){
Gdx.input.setInputProcessor(shopStage);
if(SuccessIsRunning){
Gdx.input.setInputProcessor(successStage);
}
}
}
}

//重置舞台绘制
public void stageRender(){
if(GameIsRunning){
stage.act();
stage.draw();
}else{
openStage.act();
openStage.draw();
if(ShopIsRunning){
shopStage.act();
shopStage.draw();
if(SuccessIsRunning){
successStage.act();
successStage.draw();
}
}
}
}

@Override
public void dispose() {
batch.dispose();
stage.dispose();
openStage.dispose();
shopStage.dispose();
successStage.dispose();
}

@Override
public void render() {
Gdx.gl.glClearColor(0,0,0, 0);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
this.stageRender();
this.setStage();
}

@Override
public void resize(int width, int height) {
}

@Override
public void pause() {
}

@Override
public void resume() {
}

}
 

这个例子,只是比较简单的舞台切换,当然了,正常游戏中是不这样设置舞台切换的,

这里只是拿最浅显易懂的东西来给大家说明,Stage类的使用和简单的切换,大家千万别以为游戏中就要这么使用。

希望大家通过简单的代码能理解Stage类的使用,能明白他的原理就可以了。