Sunday, June 22, 2014

[libGDX] day 4 – animations with scene2d

Today we want to deal with scene2d.
As far as I found out yet, scene2d takes the work for simple animations (like fading images in or our) out of our hands. In scene2d there are three important objects:
At first you need a Stage-object that you create one and which handles a whole scene (like the menu-gui or the complete ingame).
An Actor is a 2D-object that is handled by the Stage. You can thing of an Actor as an image which saves lot more informations like position, scale, rotation or coloring.
Then there are Actions. Actions are animations like moving, scaling, rotating or fading which are then applied (if wanted with interpolation) to the actor.
A Stage has its own SpriteBatch, so we do not need our own anymore. We use Image-objects as a subclass of Actor, as they directly make a Texture to an actor.
Here’s the code that we need to create the tree with the christmas ball using scene2d:

public class TestGame implements ApplicationListener {

 Texture tree;
 TextureRegion christmasTree;
 Texture ball;
 OrthographicCamera camera;
 Stage stage;

 @Override
 public void create() {
  // load assets
  tree=new Texture(Gdx.files.internal("graphics/tree.png"));
  christmasTree=new TextureRegion(tree, 0, 0, 450,730);
  ball=new Texture(Gdx.files.internal("graphics/ball.png"));

  // create viewport
  camera=new OrthographicCamera();
  camera.setToOrtho(false, 800,480);

  stage=new Stage();
  stage.setCamera(camera);

  // our christmas tree
  Image ctree=new Image(christmasTree);
  ctree.setSize(296, 480); // scale the tree to the right size
  ctree.setPosition(400 - 148, 0); // center the tree
  stage.addActor(ctree);

  Image ballImage=new Image(ball);
  ballImage.setPosition(400 - 148+60, 170);

  stage.addActor(ballImage);

 }

 @Override
 public void render() {  

  Gdx.gl.glClearColor(1,1,1, 1);
  Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

  // update the stage
  stage.act();
  // draw the stage
  stage.draw();
 }

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

 @Override
 public void pause() {
 }

 @Override
 public void resume() {
 }

 @Override
 public void dispose() {
  // dispose all the trash :P
  tree.dispose();
  ball.dispose();
  stage.dispose();
 }
}
Impotant is to dispose all textures you loaded and the Stage in the dispose()-Method.
In a moment it will be as well important, that we do not only draw the stage, but call act() on it which does calculate all the interpolations for the actions.
Now we want the ball to appear slowly.
Therefore we first set the alpha-value of the image to 0 and then add a 2 second fadeIn-Action:
ballImage.setColor(1,1,1,0);
ballImage.addAction(Actions.fadeIn(2));
The class Actions gives you many Actions statically (there is an overview over all the methods).
We can directly add two Actions which are then executed at the same time:
ballImage.setOrigin(32,32);
ballImage.setColor(1,1,1,0);
ballImage.addAction(Actions.fadeIn(2));
ballImage.addAction(Actions.rotateBy(360,2));
We first set the origin of the image (the center) and then let it rotate around this point while the ball is fading in.
The same thing could be written with a parallel-Action:
ballImage.addAction(Actions.parallel(Actions.fadeIn(2),Actions.rotateBy(360,2)));
And the exact oposite with a sequence-Action:
ballImage.addAction(Actions.sequence((Actions.fadeIn(2),Actions.rotateBy(360,2)));
If you then take the Action delay() which just waites a certain time, you can build quite complex animations using this.
  
// our christmas tree
Image ctree=new Image(christmasTree);
ctree.setSize(296, 480); // scale the tree to the right size
ctree.setPosition(-300,0);
//ctree.setPosition(400 - 148, 0); // center the tree
ctree.addAction(Actions.moveTo(400-148, 0,1f));

stage.addActor(ctree);

Image ballImage=new Image(ball);
ballImage.setPosition(400 - 148+60, 170);

ballImage.setOrigin(32,32);
ballImage.setColor(1,1,1,0);
ballImage.addAction(Actions.sequence(Actions.delay(1),Actions.parallel(Actions.fadeIn(1),Actions.rotateBy(360,1))));
Here the christmas tree comes from the left for one second. Then the christmas ball fades in while it’s rotating.
Your task for today is to understand this complex code :D (snowflake from openclipart.org)
public class TestGame implements ApplicationListener {

 Texture tree;
 TextureRegion christmasTree;
 Texture ball;
 Texture snow;
 OrthographicCamera camera;
 Stage stage;

 @Override
 public void create() {
  // load assets
  tree=new Texture(Gdx.files.internal("graphics/tree.png"));
  christmasTree=new TextureRegion(tree, 0, 0, 450,730);
  ball=new Texture(Gdx.files.internal("graphics/ball.png"));
  snow=new Texture(Gdx.files.internal("graphics/snow.png"));

  // create viewport
  camera=new OrthographicCamera();
  camera.setToOrtho(false, 800,480);

  stage=new Stage();
  stage.setCamera(camera);

  // our christmas tree
  Image ctree=new Image(christmasTree);
  ctree.setSize(296, 480); // scale the tree to the right size
  ctree.setPosition(-300,0);
  ctree.addAction(Actions.moveTo(400-148, 0,1f));

  stage.addActor(ctree);

  Image ballImage=new Image(ball);
  ballImage.setPosition(400 - 148+60, 170);

  ballImage.setOrigin(32,32);
  ballImage.setColor(1,1,1,0);
  ballImage.addAction(Actions.sequence(Actions.delay(1),Actions.parallel(Actions.fadeIn(1),Actions.rotateBy(360,1))));

  stage.addActor(ballImage);

  // create the snowflakes
  for(int i=0;i<10;i++){
   spawnSnowflake();
  }

 }

 public void spawnSnowflake(){
  final Image snowflake=new Image(snow);
  snowflake.setOrigin(64,64);
  int x=(int) (Math.random()*800);
  snowflake.setPosition(x,480);
  snowflake.setScale((float) (Math.random()*0.8f+0.2f));
  // animate the snowflake randomly
  snowflake.addAction(Actions.parallel(
    Actions.forever(Actions.rotateBy(360,(float) (Math.random()*6))),
    Actions.sequence(Actions.moveTo(x,0,(float) (Math.random()*15)),Actions.fadeOut((float) (Math.random()*1)),
     new Action() { // we can define custom actions :)

     @Override
     public boolean act(float delta) {
      snowflake.remove(); // delete this snowflake
      spawnSnowflake(); // spawn a new snowflake
      return false;
     }
    }
    )));
  stage.addActor(snowflake);
 }

 @Override
 public void render() {  

  Gdx.gl.glClearColor(1,1,1, 1);
  Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

  // update the stage
  stage.act();
  // draw the stage
  stage.draw();
 }

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

 @Override
 public void pause() {
 }

 @Override
 public void resume() {
 }

 @Override
 public void dispose() {
  // dispose all the trash :P
  tree.dispose();
  ball.dispose();
  snow.dispose();
  stage.dispose();
 }

}
Now I have to play with scene2d and look for other cool things, it’s good for.
If you do not understand something, just ask!

No comments:

Post a Comment

Popular Posts