Use of the android game development framework libgdx (4)-stage and actors

Source: Internet
Author: User
Tags libgdx

Let's take a look at a few games first to understand what is a stage.

Please observe the elements in the image carefully. Some items cannot be moved, some can be moved, some have special effects, and some do not. Some are buttons and some are images, but they can all be called actors ).

The entire game interface is our stage.

Let's look at another shooting game.

The actors are

Actors are a common object in game design. They accept unified management of the stage and have some public events, such as touch and click, but they also have their own responses and attributes.

The stage is a place for actors. It manages all actors in a unified manner, accepts input, and provides a convenient framework for operating actor time changes.

Let's take a look at the Stage class:


Protected final Group root;

Protected final SpriteBatch batch;

Protected Camera camera;

It has a Group, a SpriteBatch, and a camera.

SpriteBatch, as we have mentioned in the previous articles, will not be repeated here.

A Group is a class used to hold and control actors. However, it should be noted that the Group itself actually inherits from the Actor.

The camera is skipped here. Later, it can be understood as a tool for controlling the viewing angle and indicator conversion.

When we have an actor, we can call the addActor method to join the stage.

You can obtain the input on the stage, but you need to set it.


Gdx. input. setInputProcessor (stage );

The following is a column to control the movement of a person.

Button for controlling characters:

Put the desired image in assert

Three new classes are created:

FirstGame to implement the ApplicationListener Interface

FirstActor, inherited from Actor

NarrowButton, inherited from Actor

Let's take a look at FirstGame.

Declare a Stage, instantiate FirstActor and NarrowButton, add the two to the Stage, and finally set the input response to 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;

 

@ 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

 

}

}

Let's take a look at FirstActor.

Declare a Texture for painting. The height and width are obtained in the constructor to facilitate later hit time judgment.


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 ();

}

}

The Code plotting section in NarrowButton and the following section above mainly address the issue of controlling the actions of people after clicking.

Modify the touchDown event:

Get FirstActor through Group and control the value of x.


Public boolean touchDown (float x, float y, int pointer ){

Actor actor = this. parent. findActor ("renwu ");

Actor. x + = 10;

Return false;

}

Effect:

So far, we have implemented the simplest character control. However, there are still many examples to be improved. For example, the direction button does not have the effect of clicking and the character does not have the effect of moving.

We can use Animation. Add an image

For details, let's take a look at the Animation class:


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

* 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];

}

}

We can see that the so-called animation is actually a constant switching of an image (in fact, all animations look like this ).

We construct an image list and retrieve it continuously based on event changes. re-draw the image to form an animation.

Pay attention to the input time and image list size. Modify the FirstActor Code as follows:


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 );

Repeated sframe = new TextureRegion [30];

For (int I = 0; I <30; I ++ ){

If (I % 2 = 0 ){

Repeated sframe [I] = region1;

} Else {

Repeated sframe [I] = region2;

}

}

Animation = new Animation (0.25f, walksFrame );

}

}

Effect:

Note that we need to convert Texture to TextureRegion. This is because the images in actual development are integrated. For example, all the images used by the role are placed in a single segment, and then separated and intercepted. The corresponding auxiliary method is TextureRegion. split.

In addition, we can find that there are a large number of code duplicates in NarrowButton and FirstActor. Some may think we should extract the Code. In fact, libgdx has already helped us. For more information, see

There are some common UI controls, which can be discussed in the next article.

 


Author: Huang yunkun
Source: http://www.cnblogs.com/htynkn/

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.