- 1 : Overview
- 2 : Environment SetUp
- 3 : Creating Project in libGDX
- 4 : Importing Projects in Eclipse
- 5 : Executing demo project for Windows
- 6 : Executing demo project for Android
- 7 : Executing demo project for HTML5
- 8 : Developing a real flappy bird game remake game using libGDX from scratch
- 9 : Environment Set Up for Game
- 10 : Understand basics of Game
- 11 : Exploring States and Game State Manager
- 12 : Create Play State and Make Bird Fly
- 13 : Building Obstacles and flying through them
- 14 : Collision and sound effect
- 15 : Porting the Game in Android Device
- 16 : libGDX More possibilities to Brisky Demo
- libGDX Example Code : Implementing Google Play Services Leader Boards in LibGDX
- libGDX Example Code : Text and line Animation
- libGDX Example Code : Experimenting Viewports with Text and Shape Animation for multiple screen Resolutions
- Step by Step Tutorial on libGDX
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 :
- Create a new Class under States package and name it PlayState
- extend it with State abstract class
- generate implement methods like we did it for menu state in previous tutorial
- generate constructor
- Lets add a bird texture in it .Use the below asset for bird and declare Texture for the bird
- Now we will add transition from Menu State to Play State
- Open MenuState class
- inside update method enter
-
handleInput();
-
- inside handleInput ()method add following code
-
if(Gdx.input.justTouched()){ gsm.push(new PlayState(gsm)); dispose(); }
-
- 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
- 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
- Variables in PlayState Class
-
private Texture bird; private Texture background;
-
- In PlayState Constructor
-
bird = new Texture("bird.png"); background = new Texture("playBg_menu.png");
-
- In Render method
-
sb.begin(); sb.draw(background, 0, 0, BriskyDemo.WIDTH, BriskyDemo.HEIGHT); sb.draw(bird,50,50); sb.end();
-
- Variables in PlayState Class
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
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
- position i.e. where is our bird right now in our game world
- velocity i.e. in which direction is it moving , up , down , left or right
- 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 } }
Table of Contents
- Overview of libGDX
- Environment SetUp
- Creating Project in libGDX
- Importing Projects in Eclipse
- Executing demo project for Windows
- Executing demo project for Android
- Executing demo project for HTML5
- Developing a real flappy bird game remake game using libGDX from scratch
- Environment Set Up for Game
- Understand basics of Game
- Exploring States and Game State Manager
- Create Play State and Make Bird Fly
- Building Obstacles and flying through them
- Collision and sound effect
- Porting the Game in Android Device
- libGDX More possibilities to Brisky Demo