• Sponsored Links

Step 12: Step by Step libGDX Tutorial : Create Play State and Make Bird Fly

Share this :

Create Play State and Make Bird Fly

We are done with the Menu State in last section and now we are going to move ahead to make our Play State . Play State is the state where actual playing of the game will happen i.e. Bird will jump , there will be pipes and score , music , bird will die which will make it to move to next State i.e. Game Over State  . Lets start to code and do following steps :

  1. Create a new Class under States package and name it PlayState
  2. extend it with State abstract class
  3. generate implement methods like we did it for menu state in previous tutorial
  4. generate constructor
  5. Lets add a bird texture in it .Use the below asset for bird and declare Texture for the bird
  6. Brisky Bird Asset
  7. Now we will add transition from Menu State to Play State
    1. Open MenuState class
    2. inside update method enter
      1. handleInput();
    3. inside handleInput ()method  add following code
      1. if(Gdx.input.justTouched()){
        gsm.push(new PlayState(gsm));
        dispose();
        }
    4. This will check if user had clicked or touched the menu state . If he has touched it should open Play State and dispose the current menu state
  8. Before Testing it lets create our Play State to Have Bird Image and a Background Image . Lets keep background Texture same as we have for our Menu State . Lets add following code to Play State
    1. Variables in PlayState Class
      1. private Texture bird;
        private Texture background;
    2. In PlayState Constructor
      1. bird = new Texture("bird.png");
        background = new Texture("playBg_menu.png");
    3. In Render method
      1. sb.begin();
        sb.draw(background, 0, 0, BriskyDemo.WIDTH, BriskyDemo.HEIGHT);
        sb.draw(bird,50,50);
        sb.end();

Once we are done with this . Hit Run . After we see Menu State , Click any key and we will be shown with our Play State as in Below Screenshot

Play Statewith bird

Play State with bird

Lets Now show a little part of our game world using the Orthographic Camera add following code in PlayState Class constructor

cam.setToOrtho(false, BriskyDemo.WIDTH / 2, BriskyDemo.HEIGHT / 2);

add following in the render method

sb.setProjectionMatrix(cam.combined);

Now we will create a new Bird Class and will use that class to set position of bird texture on screen allowing it to jump up and down .

create a new package named sprites a new java class called Bird inside sprites package

This bird class needs

  1. position i.e. where is our bird right now in our game world
  2. velocity i.e. in which direction is it moving , up , down , left or right
  3. Texture i.e. what needs to be drawn to the screen

Lets Create these . First of all lets add following variables to the bird class

private static final int GRAVITY = -15;  // Static Value for Gravity 
public  static  int MOVEMENT = 100;      // Static Variable Movement 
private Vector3 position;                // To keep Position of out Bird
private Vector3 velocity;                // Keep Velocity
private  Texture bird;                    //Bird Texture
private Sound flap;                      //Voice of Flap
private Rectangle bounds;                // Required for collision

A constructor with x and y parameters as starting positions :

public Bird(int x, int y ){
position = new Vector3(x,y,0); // z axis is 0 because we are not using it
velocity = new Vector3(0,0,0);
bird = new Texture("bird.png");
bounds = new Rectangle(x,y,bird.getWidth(),bird.getHeight());
flap = Gdx.audio.newSound(Gdx.files.internal("wing.ogg"));
}

Here we can see Constructor takes x and y as 2 int parameters . These 2 are basically the position coordinates of our Bird . Position Variable is initialized with x and y as the parameters input to the constructor . Velocity which we will use to compute the velocity of the bird is initialized as 0 . bird is given the Texture of bird Image .  bounds is a rectangle which we can see is a container for our Bird . We will use this bounds rectangle later to see if collision of bird has occurred with other objects i.e. Pipes  .flap is the sound object which , we will use when ever the bird jumps .

The file wing.ogg can be downloaded from this page

Lets add below code to the update function of bird class

 

 

public void update(float dt){

if (position.y > 0)
velocity.add(0, GRAVITY, 0);// adding GRAVITY to the velocity
velocity.scl(dt); // we are scaling velocity with delta time

position.add(MOVEMENT * dt , velocity.y,0);

if (position.y < 0)
position.y = 0;
velocity.scl(1/dt); //reversing the velocity scaling was done to basically adding scaled version of velocity to position

bounds.setPosition(position.x,position.y);
}

Here we see that if position.y  > 0 i.e.whenever bird is inside the viewport i.e. visible n screen its velocity should be -GRAVITY in the y axis i.e. if bird is above ground , it should go down towards ground with a velocity  = -15 as defined by GRAVITY variable .

velocity.scl(dt) scales the velocity with delta time

position.add(MOVEMENT * dt , velocity.y,0);  means we want our bird to move in x axis with 100 pixels ofcourse scaled to delta time  and velocity s y position whatever it will be according to GRAVITY .

if (position.y < 0)
position.y = 0;
velocity.scl(1/dt); //reversing the velocity scaling was done to basically adding scaled version of velocity to position

Here we do it so if position of bird in y axis becomes equal to 0 then it shoudnt go further down but should stay at the ground only .

finally bounds.setPosition(position.x,position.y); sets the bounds to the current position , as we discussed earlier bounds will be used to find out the collision of bird .

 

Lets also add the below 5 functions as well to the bird class

public Vector3 getPosition() {
return position;
}

public Texture getTexture(){
return bird;
}

public void jump(){
velocity.y = 250;
flap.play(0.3f);
}

public Rectangle getBounds(){
return bounds;
}

public void dispose( ){
bird.dispose();
flap.dispose();
}

 

Here we understand that getPosition is to get position of Bird , getTexture is to get Texture , getBounds will give position of bound rectangle .

dispose function is to dispose our bird Texture and flap sound whenever we will be disposing the bird .

jump is the important function here as this will make the bird jump and we will call it whenever player taps the screen in play state . Basically it adds 250 pixels to birds position in y direction and also adds the sound of flap .

 

Lets add following code to the PlayState.java

if (Gdx.input.justTouched())
    bird.jump();

This basically will make the bird jump whenever user clicks or taps while in PlayState .

 

Execute the code and you will see the bird jumping whenever we click while in Play State .

 

Full Code will today is as below .

BriskyDemo.java

package com.versionpb.briskybird;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;

import States.GameStateManager;
import States.MenuState;

public class BriskyDemo extends ApplicationAdapter {
public static final int WIDTH = 480;
public static final int HEIGHT = 600;
public static final String TITLE = "Brisky Bird Demo";

Texture img;
private GameStateManager gsm;
private SpriteBatch batch;

@Override
public void create () {
gsm = new GameStateManager();
batch = new SpriteBatch();
Gdx.gl.glClearColor(1, 0, 0, 1);
gsm.push(new MenuState(gsm));
}

@Override
public void render () {

Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

gsm.update(Gdx.graphics.getDeltaTime());
gsm.render(batch);
}
}

 

Bird.java

package Sprites;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector3;

public class Bird {
private static final int GRAVITY = -15;
public static int MOVEMENT = 100;
private Vector3 position;
private Vector3 velocity;
private Texture bird;
private Sound flap;
private Rectangle bounds;

public Bird(int x, int y ){
position = new Vector3(x,y,0); // z axis is 0 because we are not using it
velocity = new Vector3(0,0,0);
bird = new Texture("bird.png");
bounds = new Rectangle(x,y,bird.getWidth()/3,bird.getHeight());
flap = Gdx.audio.newSound(Gdx.files.internal("wing.ogg"));
}

public void update(float dt){

if (position.y > 0)
velocity.add(0, GRAVITY, 0);// adding GRAVITY to the velocity
velocity.scl(dt); // we are scaling velocity with delta time

position.add(MOVEMENT * dt , velocity.y,0);

if (position.y < 0)
position.y = 0;
velocity.scl(1/dt); //reversing the velocity scaling was done to basically adding scaled version of velocity to position

bounds.setPosition(position.x,position.y);
}

public Vector3 getPosition() {
return position;
}

public Texture getTexture(){
return bird;
}

public void jump(){
velocity.y = 250;
flap.play(0.3f);
}

public Rectangle getBounds(){
return bounds;
}

public void dispose( ){
bird.dispose();
flap.dispose();
}

}

 

GameStateManager.java -- > No change today so take it from previous section

State,java --> No change

MenuState.java

 

package States;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.versionpb.briskybird.BriskyDemo;

public class MenuState extends State {

private Texture background; //New Texture explained here
private Texture playBtn;

public MenuState(GameStateManager gsm) {
super(gsm);
background = new Texture("playBg_menu.png");
playBtn = new Texture("playButton.png");

}

@Override
public void handleInput() {
if(Gdx.input.justTouched()){
gsm.push(new PlayState(gsm));
dispose();
}

}

@Override
public void update(float dt) {
handleInput();

}

@Override
public void render(SpriteBatch sb) {
sb.begin();
sb.draw(background, 0, 0, BriskyDemo.WIDTH, BriskyDemo.HEIGHT);
sb.draw(playBtn,(BriskyDemo.WIDTH/2) - (playBtn.getWidth() / 2), BriskyDemo.HEIGHT/2);
sb.end();

}

@Override
public void dispose() {
background.dispose();
playBtn.dispose();

}

}

PlayState.java

 

package States;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.versionpb.briskybird.BriskyDemo;

import Sprites.Bird;

public class PlayState extends State {
private Bird bird; //add this line
private Texture background;

public PlayState(GameStateManager gsm) {
super(gsm);
cam.setToOrtho(false, BriskyDemo.WIDTH / 2, BriskyDemo.HEIGHT / 2);
bird = new Bird(50,50);

background = new Texture("playBg_menu.png");
}

@Override
public void handleInput() {
if(Gdx.input.justTouched())
bird.jump();


}

@Override
public void update(float dt) {
// TODO Auto-generated method stub
handleInput();
bird.update(dt);

}

@Override
public void render(SpriteBatch sb) {
sb.setProjectionMatrix(cam.combined);
sb.begin();
sb.draw(background, 0, 0, BriskyDemo.WIDTH, BriskyDemo.HEIGHT);
//sb.draw(bird,50,50);
sb.draw(bird.getTexture(), bird.getPosition().x,bird.getPosition().y);
sb.end();

}

@Override
public void dispose() {
// TODO Auto-generated method stub

}

}

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *

− 2 = 8