LibGDX游戏引擎-12-动作Action类的运用

libgdx的作者刻意的使用了舞台、演员,为了方便我们去开发游戏,其实在作者还提供给我们了一个更重要的类,那就是Action类,也叫动作类或演出类,很多朋友希望我能讲解下关于新版本的Action类是如何使用的,其实Action类分为2种,一种是负责演员表现的表现类,另一种是负责控制表现类的控制类。

一、表现类

包括旋转、放缩、移动、淡入、淡出、延迟等动作

注意:Action中所有动作都是static静态的,因此直接使用即可而不需要去实例化,直接通过Actions类进行生产即可。

(1)AlphaAction 类**:**负责改变演员的透明度。


AlphaAction alphah = Actions.alpha(0.6f, 20);


参数①:要达到的透明度的值,0 - 1 的一个数值

参数②:达到时间,即经过多少时间达到指定的透明度

(2)ColorAction 类**:**负责改变演员的颜色。



ColorAction color= Actions.color(Color.RED, 20);




参数①:要达到的颜色的值,一般是Color 类型

参数②:达到时间,即经过多少时间达到指定的颜色



### (3)DelayAction 类**:**负责延迟执行演员动作。

DelayAction delay = Actions.delay(20.0f);


参数①:要延迟执行的时间,一般是float 类型。


### (4)fade in / fade out 效果**通过在固定的时间内改变演员的透明度,同时实现淡入淡出类,这个其实是AlphaAction的一个特例。

AlphaAction alpha = Actions.fadeIn(duration);
AlphaAction alpha = Actions.fadeOut(duration);
方法①:fadeIn(float duration)在传入的时间内,透明度从初始值达到 1 ,实现淡入的效果。


方法②:[fadeOut](file:///E:/libgdx-0.9.7/docs/api/com/badlogic/gdx/scenes/scene2d/actions/Actions.html#fadeOut(float))(float <wbr />duration)**在传入的时间内,透明度从初始值达到 0 ,实现淡出的效果。


### (5)MoveToAction 类**:**负责改变演员的位置

MoveToAction moveto = Actions.moveTo(240, 160, duration);



参数①:要达到的坐标值

参数②:达到时间,即经过多少时间达到指定的坐标

(6)RotatoToAction 类**:**负责实现演员的旋转效果


RotateToAction rotateto = Actions.rotateTo(rotate, duration);



参数①:要旋转的角度

参数②:达到该旋转角度的时间,即经过多少时间达到指定的角度

(7)ScaleToAction 类**:**负责改变演员大小的类,即沿X轴或者Y轴放缩大小,实现改变Actor大小的效果


ScaleToAction scaleto = Actions.scaleTo(scale, scale, duration);



参数①:X轴要达到的放缩比例

参数②:Y轴要达到的放缩比例

参数③:经过多少时间达到指定的放缩比例


以上所讲述的七个类,就是基本的表现类,当然在Api中还有一些其他的类,如moveBy、scaleBy等表现类,当然用法基本和上述同名的类一样,这里就不讲解了,估计大家都能理解。

>
很多动画效果,都可以通过不同的表现类来组合实现,当然组和这些类就需要专门的控制类来管理,下面我们就来讲解下控制类。

请见下一页


二、控制**类**


不同的表现类通过组合实现,我们就可以得到不同的动画效果,当然了,这就需要我们使用控制类来管理我们的表现类,控制类相对于表现类来说比较少,只有四个,即:Sequence 类、Repeat 类、Parallel 类、Forever 类。


###

(1) SequenceAction 类:按顺序执行Actions


功能用途:**[sequence](file:///E:/libgdx-0.9.7/docs/api/com/badlogic/gdx/scenes/scene2d/actions/Actions.html#sequence(com.badlogic.gdx.scenes.scene2d.Action,%20com.badlogic.gdx.scenes.scene2d.Action,%20com.badlogic.gdx.scenes.scene2d.Action,%20com.badlogic.gdx.scenes.scene2d.Action))([Action](file:///E:/libgdx-0.9.7/docs/api/com/badlogic/gdx/scenes/scene2d/Action.html "class in com.badlogic.gdx.scenes.scene2d") <wbr />action1, <wbr />[Action](file:///E:/libgdx-0.9.7/docs/api/com/badlogic/gdx/scenes/scene2d/Action.html "class in com.badlogic.gdx.scenes.scene2d") <wbr />action2, <wbr />[Action](file:///E:/libgdx-0.9.7/docs/api/com/badlogic/gdx/scenes/scene2d/Action.html "class in com.badlogic.gdx.scenes.scene2d") <wbr />action3, .....)


SequenceAction alpha = Actions.sequence(Actions.fadeIn(duration), endAction );


参数传入的都是需要使用的Action,sequence他会按照传入的参数顺序,全部按顺序执行的。

**

###

(2) **ParallelAction 类:**并行执行传入的Action类


功能用途:[parallel](file:///E:/libgdx-0.9.7/docs/api/com/badlogic/gdx/scenes/scene2d/actions/Actions.html#parallel(com.badlogic.gdx.scenes.scene2d.Action,%20com.badlogic.gdx.scenes.scene2d.Action,%20com.badlogic.gdx.scenes.scene2d.Action))([Action](file:///E:/libgdx-0.9.7/docs/api/com/badlogic/gdx/scenes/scene2d/Action.html "class in com.badlogic.gdx.scenes.scene2d") <wbr />action1, <wbr />[Action](file:///E:/libgdx-0.9.7/docs/api/com/badlogic/gdx/scenes/scene2d/Action.html "class in com.badlogic.gdx.scenes.scene2d") <wbr />action2, <wbr />[Action](file:///E:/libgdx-0.9.7/docs/api/com/badlogic/gdx/scenes/scene2d/Action.html "class in com.badlogic.gdx.scenes.scene2d") <wbr />action3)


ParallelAction Paction = Actions.parallel(moveto,  rotateto, alpha);


无论传入的先后如何,都是并行执行的,即同时执行的。





###

### (3) RepeatAction 类**重复执行传入的Action。


功能用途:[repeat](file:///E:/libgdx-0.9.7/docs/api/com/badlogic/gdx/scenes/scene2d/actions/Actions.html#repeat(int,%20com.badlogic.gdx.scenes.scene2d.Action))(int <wbr />count, <wbr />[Action](file:///E:/libgdx-0.9.7/docs/api/com/badlogic/gdx/scenes/scene2d/Action.html "class in com.badlogic.gdx.scenes.scene2d") <wbr />repeatedAction)


RepeatAction repeatedAction = Actions.repeat(3, Paction);


第一个参数是重复执行的次数,第二个是执行的Action。






###

### (4) foreverAction **:其实这个也是一个RepeateAction,只不过他的次数是无穷的,他所需要传入的是一个RepeatAction。


功能用途:[forever](file:///E:/libgdx-0.9.7/docs/api/com/badlogic/gdx/scenes/scene2d/actions/Actions.html#forever(com.badlogic.gdx.scenes.scene2d.Action))([Action](file:///E:/libgdx-0.9.7/docs/api/com/badlogic/gdx/scenes/scene2d/Action.html "class in com.badlogic.gdx.scenes.scene2d") <wbr />repeatedAction)


RepeatAction foreverAction = Actions.forever(RepeatAction);

传入的是一个重复Action,次数是无穷的,当时他的类型也是一个重复Action。




三、Run方法

所有Actions结束后,调用该方法,需要传入Runnable的一个方法。

这里为什么要单独拿出来一个Actions中的方法,单独解释呢?主要是因为这个方法很特别,他虽然也是是一个Action类,但是却封装在了Action类中,表面上看起来很另类,但是其实他是作者的一种经典思维的体现,那么下面我们就来学习下,这个Run方法。

功能用途:[run](file:///E:/libgdx-0.9.7/docs/api/com/badlogic/gdx/scenes/scene2d/actions/Actions.html#run(java.lang.Runnable))(java.lang.Runnable <wbr />runnable)

需要传入一个Runnnable的参数,同时需要重写Run方法,他是唯一一个不同于其他封装在Action里面的方法。

Action endAction = Actions.run(new Runnable() {
@Override
public void run() {
System.out.println(“All action is completed”);
}
});

这个方法,他的用途就是在于,他是负责在所有动作结束后调用的,一般我们做游戏,在所有的动作结束后,需要执行一些我们想要的事件,例如弹出游戏结束的界面,或者一个窗口等等,这样我们就需要使用run方法,来实现这些功能,这也是0.98版本libgdx的一个改进,他删除了之前的compelet的一个接口,而使用了一二润方法,这样很简便,实用。


文章内容参考-奋斗小土豆丶的博文,特此说明!

 

 

四、实例代码

1.所用素材 :图片(白色球,可能因为背景原因会看不到) boll 图片(银色星星)star

 

2.功能分析:

(1)设计一个滑屏可以出现星星和圆球效果的项目。

(2)使用星星和圆球实现旋转、移动、淡入淡出效果。

(3)所有动作结束后,打印一句话,解释动作结束后,执行的动作。

3.创建舞台,实例化需要用的纹理图片,同时实现输入接口,来处理触屏事件。

stage = new Stage();
starTexture = new Texture(Gdx.files.internal(“study/action/star.png”));
ballTexture = new Texture(Gdx.files.internal(“study/action/ball.png”));
Gdx.input.setInputProcessor(this);

4.重写touchDragged方法,触摸屏幕时实例化出小球或星星

@Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
createStar(MathUtils.randomBoolean(),
screenX, 480 - screenY,MathUtils.random(10, 20));
return false;
}

5.实例化出小球或星星

//利用随机boolean来随机创建ball或star
private void createStar(boolean randomBoolean, int x, int y, int size) {
if (randomBoolean == true) {
image = new Image(starTexture);
} else if (randomBoolean == false) {
image = new Image(ballTexture);

    }
    this.setAction(image);
    image.setPosition(x - size / 2, y - size / 2);
    image.setSize(size, size);
    stage.addActor(image);
}</pre>

6.编写setAction(image)方法,把传进行的image对象(image也是actor)进行动作设置

public void setAction(final Image image) {
float duration = MathUtils.random(1, 5);
float scale = MathUtils.random(0.5f, 2.0f);
float rotate = MathUtils.random(360);

    Action endAction = Actions.run(new Runnable() {
        @Override
        public void run() {
            System.out.println("All action is completed");
        }
    });

    MoveToAction moveto = Actions.moveTo(320, 240, duration);
    ScaleToAction scaleto = Actions.scaleTo(scale, scale, duration);
    RotateToAction rotateto = Actions.rotateTo(rotate, duration);
    SequenceAction alpha = Actions.sequence(Actions.fadeIn(duration),Actions.fadeOut(duration), endAction);
    ParallelAction Paction = Actions.parallel(moveto, scaleto, rotateto,alpha);
    RepeatAction repeatedAction = Actions.repeat(3, Paction);
    RepeatAction foreverAction = Actions.forever(repeatedAction);

    image.addAction(Paction);
    //image.addAction(foreverAction);
    //image.addAction(repeatedAction);

}</pre>

7.在Render方法中进行舞台刷新

Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act();
stage.draw();

完整代码:

package com.mygdx.game;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.scenes.scene2d.Action;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
import com.badlogic.gdx.scenes.scene2d.actions.MoveToAction;
import com.badlogic.gdx.scenes.scene2d.actions.ParallelAction;
import com.badlogic.gdx.scenes.scene2d.actions.RepeatAction;
import com.badlogic.gdx.scenes.scene2d.actions.RotateToAction;
import com.badlogic.gdx.scenes.scene2d.actions.ScaleToAction;
import com.badlogic.gdx.scenes.scene2d.actions.SequenceAction;
import com.badlogic.gdx.scenes.scene2d.ui.Image;

/**

  • @author Administrator
    /
    public class MyGdxGame extends ApplicationAdapter implements InputProcessor {
    Texture starTexture;
    Texture ballTexture;
    Stage stage;
    Image image;

    @Override
    public void create() {

    stage = new Stage();
    starTexture = new Texture(Gdx.files.internal("study/action/star.png"));
    ballTexture = new Texture(Gdx.files.internal("study/action/ball.png"));
    Gdx.input.setInputProcessor(this);
    

    }

    @Override
    public void render() {

    Gdx.gl.glClearColor(0, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    stage.act();
    stage.draw();
    

    }

    public void setAction(final Image image) {

    float duration = MathUtils.random(1, 5);
    float scale = MathUtils.random(0.5f, 2.0f);
    float rotate = MathUtils.random(360);
    
    Action endAction = Actions.run(new Runnable() {
        @Override
        public void run() {
            System.out.println("All action is completed");
        }
    });
    
    MoveToAction moveto = Actions.moveTo(320, 240, duration);
    ScaleToAction scaleto = Actions.scaleTo(scale, scale, duration);
    RotateToAction rotateto = Actions.rotateTo(rotate, duration);
    SequenceAction alpha = Actions.sequence(Actions.fadeIn(duration),Actions.fadeOut(duration), endAction);
    ParallelAction Paction = Actions.parallel(moveto, scaleto, rotateto,alpha);
    RepeatAction repeatedAction = Actions.repeat(3, Paction);
    RepeatAction foreverAction = Actions.forever(repeatedAction);
    
    image.addAction(Paction);
    //image.addAction(foreverAction);
    //image.addAction(repeatedAction);
    

    }

    @Override
    public boolean touchDragged(int screenX, int screenY, int pointer) {

    createStar(MathUtils.randomBoolean(), 
            screenX, 480 - screenY,MathUtils.random(10, 20));
    return false;
    

    }

    //利用随机boolean来随机创建ball或star
    private void createStar(boolean randomBoolean, int x, int y, int size) {

    if (randomBoolean == true) {
        image = new Image(starTexture);
    } else if (randomBoolean == false) {
        image = new Image(ballTexture);
    
    }
    this.setAction(image);
    image.setPosition(x - size / 2, y - size / 2);
    image.setSize(size, size);
    stage.addActor(image);
    

    }

    @Override
    public boolean keyDown(int keycode) {

    return false;
    

    }

    @Override
    public boolean keyUp(int keycode) {

    return false;
    

    }

    @Override
    public boolean keyTyped(char character) {

    return false;
    

    }

    @Override
    public boolean touchDown(int screenX, int screenY, int pointer, int button) {

    return false;
    

    }

    @Override
    public boolean touchUp(int screenX, int screenY, int pointer, int button) {

    return false;
    

    }

    @Override
    public boolean mouseMoved(int screenX, int screenY) {

    return false;
    

    }

    @Override
    public boolean scrolled(int amount) {

    return false;
    

    }
    }