Opengl.

LibGDX Game Tutorial Part 2

Welcome to part 2 of the libgdx game tutorial . Today we are going to add code to our world class as well as the game renderer class and create our protagonist. 
Let’s get started with the game world class .This class is responsible for updating all our entities in the game world.the finished game class.

public class GameWorld {

 

 private GameState currentState;

 public int midPointY;

 

 private Cube cube;

 private FinalBar bar;

 private ScrollHandler scroller;

 private ScrollHandlerUpDown scroller2;

 private GameRenderer renderer;

 

    private int score=0;

    private int StarScore=0;

    private float runTime=0;

   

 public enum GameState{

  MENU,READY,RUNNING,GAMEOVER,HIGHSCORE,LEVEL2,LEVEL3

 }

 

 public GameWorld(int midPointY){

 

  currentState=GameState.MENU;

  this.midPointY=midPointY;

 

  setCube(new Cube(10,midPointY+88,60,60));

  scroller=new ScrollHandler(midPointY+66);

  scroller2=new ScrollHandlerUpDown(midPointY);

  setBar(new FinalBar(100,100,65,65,this));

 

           Gdx.input.setInputProcessor(new InputHandler(new InputHandler.DirectionListener(){

   

    @Override

    public void onUp(){

     

     if(cube.isAlive){

     

      cube.moveUp();

   

              }

 

      if(isGameOver()||isHighScore()){

       restart();

      }

         if(isMenu()){

                ready();

               

      }else if(isReady()){

       start();

               

      }

    }

   

    @Override

    public void onDown(){

     

     if(cube.isAlive){

     

      cube.moveDown();

   

            }

     

      if(isGameOver()||isHighScore()){

       restart();

      }

     

      if(isMenu()){

       ready();

      }

      else if(isReady()){

       start();

      }

    }

    @Override

    public void onRight(){

     

     if(cube.isAlive){

     

      cube.moveRight();

     

      }

     

               if(isGameOver()||isHighScore()){

                restart();

               }

               

               if(isMenu()){

       ready();

       

      }

               else if(isReady()){

       start();

      }

    }

    @Override

    public void onLeft(){

     

     if(cube.isAlive){

     

      cube.moveLeft();

     

      }

               if(isGameOver()||isHighScore()){

                restart();

               }

               if(isMenu()){

       ready();

      }

               else if(isReady()){

       start();

      }

    }

   }));

   

 }

 public void setRenderer(GameRenderer renderer) {

  this.renderer = renderer;

 }

 public void update(float delta){

 

   setRunTime(getRunTime() + delta);

   

  switch(currentState){

  case READY:

  case MENU:

   updateReady(delta);

   break;

   

  case RUNNING:

   updateRunning(delta);

   break;

   default:

    break;

   

 

  }

 

 }

 private void updateReady(float delta) {

  cube.updateReady(delta);

  scroller2.update(delta);

  scroller.update(delta);

 

 }

 private void updateRunning(float delta) {

 

  if(delta > .15f){

   delta = .15f;

  }

  cube.update(delta);

  bar.update();

  scroller.update(delta);

  scroller2.update(delta);

 

  if(scroller.collides(cube)||scroller.collides(cube) && cube.isAlive){

   scroller.stop();

   scroller2.stop();

   currentState=GameState.GAMEOVER;

   AssetLoader.dead.play();

   

   renderer.prepareTransition(255, 255, 255, .3f);

   

   if(score>AssetLoader.getHighScore()){

    AssetLoader.setHighScore(score);

    currentState=GameState.GAMEOVER;

   }

  }

  if(scroller2.collides(cube)||scroller.collides(cube) && cube.isAlive){

   scroller2.stop();

   scroller.stop();

   currentState=GameState.GAMEOVER;

   AssetLoader.dead.play();

   

   renderer.prepareTransition(255, 255, 255, .3f);

   

   if(score>AssetLoader.getHighScore()){

    AssetLoader.setHighScore(score);

    currentState=GameState.GAMEOVER;

   

   }

   

  }

  if(bar.collides(cube)){

   

    AssetLoader.coin.play();

   

    renderer.prepareTransition(255, 255, 255, .3f);

  }

 

  if(AssetLoader.getHighScore()>10){

 

  }

  else if(AssetLoader.getHighScore()>20){

 

  }

  else if(AssetLoader.getHighScore()>30){

   

  }

  if(AssetLoader.getStarScore()>5){

   

   

  }

 

 }

 public boolean isLevel2(){

  return currentState==GameState.LEVEL2;

 }

 public boolean isLevel3(){

  return currentState==GameState.LEVEL3;

 }

 public boolean isReady(){

  return currentState == GameState.READY;

 }

 public void level2() {

   currentState = GameState.LEVEL2;

   renderer.prepareTransition(355, 355, 355, .3f);

    }

 public void level3() {

   currentState = GameState.LEVEL3;

   renderer.prepareTransition(355, 355, 355, .3f);

 }

 

    public void start(){

     

     if(AssetLoader.getStarScore()>3){

     

   currentState=GameState.LEVEL2;

   level2();

   

  }else if(AssetLoader.getStarScore()>10){

   

   currentState=GameState.LEVEL3;

   level3();

  }

 if(AssetLoader.getHighScore()>20){

 

 

 }else if(AssetLoader.getHighScore()>40){

 

 

 }else{

  currentState = GameState.RUNNING;

 }

 }

    public void ready() {

  currentState = GameState.READY;

  renderer.prepareTransition(255, 255, 255, .3f);

 }

 public void restart(){

  score=0;

  setStarScore(0);

  scroller.onRestart();

  scroller2.onRestart();

  cube.onRestart(midPointY-5,10);

  bar.recur();

  ready();

 }

 public boolean isGameOver(){

 

  return currentState == GameState.GAMEOVER;

 

 }

 public boolean isHighScore(){

 

  return currentState==GameState.HIGHSCORE;

 }

 

 public int getScore(){

  return score;

 }

 public void addStarScore(int increment){

  setStarScore(getStarScore() + increment);

 }

 public void addScore(int increment){

  score += increment;

 }

 public Cube getCube() {

  return cube;

 }

 public void setCube(Cube cube) {

  this.cube = cube;

 }

 public ScrollHandler getScroller() {

  return scroller;

 }

 public void setScroller(ScrollHandler scroller) {

  this.scroller = scroller;

 }

 public ScrollHandlerUpDown getScroller2() {

  return scroller2;

 }

 public void setScroller2(ScrollHandlerUpDown scroller2) {

  this.scroller2 = scroller2;

 }

 public FinalBar getBar() {

  return bar;

 }

 public void setBar(FinalBar bar) {

  this.bar = bar;

 }

 public float getRunTime() {

  return runTime;

 }

 public void setRunTime(float runTime) {

  this.runTime = runTime;

 }

 public boolean isMenu(){

  return currentState==GameState.MENU;

 }

 public boolean isRunning() {

  return currentState == GameState.RUNNING;

 }

 

 

 public int getStarScore() {

  return StarScore;

 }

 public void setStarScore(int starScore) {

  StarScore = starScore;

 }

 

Now let’s take care of our rendering.This class draws and redraws our images to the screen .the finished game renderer.

public class GameRenderer {

       

 private GameWorld myWorld;

 private OrthographicCamera cam;

 private SpriteBatch batch;

 private ShapeRenderer shapeRender;

 private int midPointY;

 private int gameWidth;

 private Cube cube;

 private FinalBar bar;

 private Pipe pipe1,pipe2,pipe3;

 private PipeDown pipe6,pipe7;

 private ScrollHandler scroller;

 private ScrollHandlerUpDown scroller2;

 private Background bg;

 private TweenManager manager;

 private Value alpha = new Value();

 private Color transitionColor;

 public GameRenderer(GameWorld world,int gameWidth,int midPointY){

  setMyWorld(world);

  

  this.setGameWidth(gameWidth);

  this.setMidPointY(midPointY);

  

  cam=new OrthographicCamera();

  cam.setToOrtho(true,gameWidth,408);

  

  batch=new SpriteBatch();

  batch.setProjectionMatrix(cam.combined);

  

  shapeRender=new ShapeRenderer();

  shapeRender.setProjectionMatrix(cam.combined);

  

  initGameObjects();

  initAssets();

  

  transitionColor = new Color();

  prepareTransition(255, 255, 255, .5f);

 }
 private void initAssets() {
  

 }
 private void initGameObjects() {

  

         cube= myWorld.getCube();

         scroller=myWorld.getScroller();

      scroller2=myWorld.getScroller2();

      pipe1=scroller.getPipe1();

      pipe2=scroller.getPipe2();

      pipe3=scroller.getPipe3();

      pipe6=scroller2.getPipe6();

      pipe7=scroller2.getPipe7();

      bar=myWorld.getBar();

      

 }

    public void render(float delta,float runTime){

  

  Gdx.gl.glClearColor(1,1,1,0);

  Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

  

  if(myWorld.isRunning()){

  batch.begin();

  batch.draw(AssetLoader.bg,bg.getX(),bg.getY()-50,gameWidth,600);

  batch.draw(AssetLoader.egg,bar.getFinalBar().getX(),bar.getFinalBar().getY(),bar.getFinalBar().getWidth()+4,bar.getFinalBar().getHeight());

  

  batch.draw(AssetLoader.wood,pipe1.getBarUp().getX(),pipe1.getBarUp().getY(),pipe1.getBarUp().getWidth(),pipe1.getBarUp().getHeight());

  batch.draw(AssetLoader.wood,pipe2.getBarDown().getX(),pipe2.getBarDown().getY(),pipe2.getBarDown().getWidth(),pipe2.getBarDown().getHeight());

  batch.draw(AssetLoader.wood,pipe3.getBarSide().getX(),pipe3.getBarSide().getY(),pipe3.getBarSide().getWidth(),pipe1.getBarSide().getHeight());

  batch.draw(AssetLoader.wood,pipe6.getBarUp2().getX(),pipe6.getBarUp2().getY(),pipe6.getBarUp2().getWidth(),pipe6.getBarUp2().getHeight());

  batch.draw(AssetLoader.wood,pipe7.getBarDown2().getX(),pipe7.getBarDown2().getY(),pipe7.getBarDown2().getWidth(),pipe7.getBarDown2().getHeight());

  batch.end();
  

  if(bar.collides(cube)){

   batch.begin();

   batch.draw(AssetLoader.win,cube.getX(),cube.getY(),cube.getWidth(),cube.getHeight());

   batch.end();

  }else{

   batch.begin();

   batch.draw(AssetLoader.playerAnim.getKeyFrame(runTime),cube.getX(),cube.getY(),cube.getWidth(),cube.getHeight());

   batch.end();

  

  }

  

   //Score

  batch.begin();

  String score=myWorld.getScore()+””;

  AssetLoader.shadow.draw(batch,””+myWorld.getScore(),20-(3*score.length()),midPointY-180);

  AssetLoader.font.draw(batch,””+myWorld.getScore(),20-(3*score.length()-1),midPointY-179);

  batch.end();

  

  }else if(myWorld.isReady()){

   

       batch.begin();

       batch.draw(AssetLoader.bg,bg.getX(),bg.getY()-50,gameWidth,600);

       batch.draw(AssetLoader.egg,bar.getFinalBar().getX(),bar.getFinalBar().getY(),bar.getFinalBar().getWidth()+4,bar.getFinalBar().getHeight());

    

    batch.draw(AssetLoader.wood,pipe1.getBarUp().getX(),pipe1.getBarUp().getY(),pipe1.getBarUp().getWidth(),pipe1.getBarUp().getHeight());

    batch.draw(AssetLoader.wood,pipe2.getBarDown().getX(),pipe2.getBarDown().getY(),pipe2.getBarDown().getWidth(),pipe2.getBarDown().getHeight());

    batch.draw(AssetLoader.wood,pipe3.getBarSide().getX(),pipe3.getBarSide().getY(),pipe3.getBarSide().getWidth(),pipe1.getBarSide().getHeight());

    batch.draw(AssetLoader.wood,pipe6.getBarUp2().getX(),pipe6.getBarUp2().getY(),pipe6.getBarUp2().getWidth(),pipe6.getBarUp2().getHeight());


batch.draw(AssetLoader.wood,pipe7.getBarDown2().getX(),pipe7.getBarDown2().getY(),pipe7.getBarDown2().getWidth(),pipe7.getBarDown2().getHeight());

   

       batch.draw(AssetLoader.ready,gameWidth/6,midPointY-150,200,100);

       

     

    batch.end();

   

  }else if(myWorld.isMenu()){

     

   

           batch.begin();

           batch.draw(AssetLoader.bg,bg.getX(),bg.getY()-50,gameWidth,600);

        batch.draw(AssetLoader.wood,pipe1.getBarUp().getX(),pipe1.getBarUp().getY(),pipe1.getBarUp().getWidth(),pipe1.getBarUp().getHeight());

     batch.draw(AssetLoader.wood,pipe2.getBarDown().getX(),pipe2.getBarDown().getY(),pipe2.getBarDown().getWidth(),pipe2.getBarDown().getHeight());

     batch.draw(AssetLoader.wood,pipe3.getBarSide().getX(),pipe3.getBarSide().getY(),pipe3.getBarSide().getWidth(),pipe1.getBarSide().getHeight());

     batch.draw(AssetLoader.wood,pipe6.getBarUp2().getX(),pipe6.getBarUp2().getY(),pipe6.getBarUp2().getWidth(),pipe6.getBarUp2().getHeight());

     batch.draw(AssetLoader.wood,pipe7.getBarDown2().getX(),pipe7.getBarDown2().getY(),pipe7.getBarDown2().getWidth(),pipe7.getBarDown2().getHeight());

        batch.draw(AssetLoader.playerAnim.getKeyFrame(runTime),gameWidth/2-25,midPointY,cube.getWidth(),cube.getHeight());

     batch.draw(AssetLoader.title2,gameWidth/6,midPointY-150,200,100);

     batch.draw(AssetLoader.swipe, gameWidth/3,midPointY+66,100,50);

     batch.end();

         

    }

    else if(myWorld.isGameOver()){

   

 

      batch.begin();

      batch.draw(AssetLoader.bg,bg.getX(),bg.getY()-50,gameWidth,600);

   batch.draw(AssetLoader.wood,pipe1.getBarUp().getX(),pipe1.getBarUp().getY(),pipe1.getBarUp().getWidth(),pipe1.getBarUp().getHeight());

   batch.draw(AssetLoader.wood,pipe2.getBarDown().getX(),pipe2.getBarDown().getY(),pipe2.getBarDown().getWidth(),pipe2.getBarDown().getHeight());

   batch.draw(AssetLoader.wood,pipe3.getBarSide().getX(),pipe3.getBarSide().getY(),pipe3.getBarSide().getWidth(),pipe3.getBarSide().getHeight());

   batch.draw(AssetLoader.wood,pipe6.getBarUp2().getX(),pipe6.getBarUp2().getY(),pipe6.getBarUp2().getWidth(),pipe6.getBarUp2().getHeight());

   batch.draw(AssetLoader.wood,pipe7.getBarDown2().getX(),pipe7.getBarDown2().getY(),pipe7.getBarDown2().getWidth(),pipe7.getBarDown2().getHeight());

   

   batch.draw(AssetLoader.gameover,gameWidth/4,midPointY-180,150,75);

   

   @SuppressWarnings(“unused”)

   String score=myWorld.getScore()+””;

   AssetLoader.shadow.draw(batch,””+myWorld.getScore(),gameWidth/2-30,midPointY+1);

   AssetLoader.font.draw(batch,””+myWorld.getScore(),gameWidth/2-29,midPointY);

   batch.draw(AssetLoader.currentscore,gameWidth/3,midPointY-55,100,50);

   

   @SuppressWarnings(“unused”)

   int length2 = (“” + AssetLoader.getHighScore()).length();

   AssetLoader.shadow.draw(batch, “” + AssetLoader.getHighScore(),

     gameWidth/2-30, midPointY+120);

   

   AssetLoader.font.draw(batch, “” + AssetLoader.getHighScore(),

     gameWidth/2-29, midPointY+119);

            batch.draw(AssetLoader.highscore,gameWidth/3,midPointY+55,100,50);


   batch.draw(AssetLoader.retry,gameWidth/3,midPointY-100,100,50);

   

   batch.end();

  }else

  if(myWorld.isLevel2()){

   

   batch.begin();

   

   batch.draw(AssetLoader.bg2,bg.getX(),bg.getY(),gameWidth,600);

   batch.draw(AssetLoader.egg,bar.getFinalBar().getX(),bar.getFinalBar().getY(),bar.getFinalBar().getWidth()+4,bar.getFinalBar().getHeight());

   

   batch.draw(AssetLoader.stone,pipe6.getBarUp2().getX(),pipe6.getBarUp2().getY(),pipe6.getBarUp2().getWidth(),pipe6.getBarUp2().getHeight());

   batch.draw(AssetLoader.stone,pipe7.getBarDown2().getX(),pipe7.getBarDown2().getY(),pipe7.getBarDown2().getWidth(),pipe7.getBarDown2().getHeight());

   

   batch.end();


   

   if(bar.collides(cube)){

    batch.begin();

    batch.draw(AssetLoader.win,cube.getX(),cube.getY(),cube.getWidth(),cube.getHeight());

    batch.end();

   }else{

    batch.begin();

    batch.draw(AssetLoader.playerAnim.getKeyFrame(runTime),cube.getX(),cube.getY(),cube.getWidth(),cube.getHeight());

    batch.end();

   

   }

   

    //Score

   batch.begin();

   String score=myWorld.getScore()+””;

   AssetLoader.shadow.draw(batch,””+myWorld.getScore(),20-(3*score.length()),midPointY-180);

   AssetLoader.font.draw(batch,””+myWorld.getScore(),20-(3*score.length()-1),midPointY-179);

   batch.end();

   

  }

   

  drawTransition(delta);

 

    }

    public void prepareTransition(int r, int g, int b, float duration) {

     

  transitionColor.set(r / 255.0f, g / 255.0f, b / 255.0f, 1);

  alpha.setValue(1);

  Tween.registerAccessor(Value.class, new ValueAccessor());

  manager = new TweenManager();

  Tween.to(alpha, -1, duration).target(0)

    .ease(TweenEquations.easeOutQuad).start(manager);

 }


 private void drawTransition(float delta) {

 

  if (alpha.getValue() > 0) {

   manager.update(delta);

   Gdx.gl.glEnable(GL20.GL_BLEND);

   Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);

   shapeRender.begin(ShapeType.Filled);

   shapeRender.setColor(transitionColor.r, transitionColor.g,

     transitionColor.b, alpha.getValue());

   shapeRender.rect(0, 0, 136, 300);

   shapeRender.end();

   Gdx.gl.glDisable(GL20.GL_BLEND);


  }

 }


 public int getGameWidth() {

  return gameWidth;

 }


 public void setGameWidth(int gameWidth) {

  this.gameWidth = gameWidth;

 }


 public int getMidPointY() {

  return midPointY;

 }


 public void setMidPointY(int midPointY) {

  this.midPointY = midPointY;

 }


 public GameWorld getMyWorld() {

  return myWorld;

 }


 public void setMyWorld(GameWorld myWorld) {

  this.myWorld = myWorld;

 }


 public OrthographicCamera getCam() {

  return cam;

 }

 public void setCam(OrthographicCamera cam) {this.can=can;

 

The game renderer  needs  to get all the assets(Images and sound ) from the Assetloader class . The order in which  the images are drawn and updated is determined by the game states in the gameWorld class . So now we need to update our Assetloader . The finished class.

public static Texture bg5,ice,stone,star,bg3,bg2,collect,gold,can,many,win,pack,egg,logo,title,swipe,title2,gameover,retry,ready,highscore,currentscore,b
g; public static Sound dead,coin; public static BitmapFont font,shadow; public static Preferences prefs; public static TextureRegion pl1,pl2,pl3,pl4,wood; public static Animation playerAnim; public static void load(){ pack=new Texture(Gdx.files.internal(“pack.png”)); pack.setFilter(TextureFilter.Linear, TextureFilter.Linear); win=new Texture(Gdx.files.internal(“CUBED#.png”)); stone=new Texture(Gdx.files.internal(“stone.png”)); ice=new Texture(Gdx.files.internal(“ice.png”)); bg5=new Texture(Gdx.files.internal(“bg5.png”)); pl1=new TextureRegion(pack,1,1,195,125); pl1.flip(false, true); pl2=new TextureRegion(pack,198,1,195,125); pl2.flip(false, true); pl3=new TextureRegion(pack,393,1,195,125); pl3.flip(false, true); pl4=new TextureRegion(pack,588,1,195,125); pl4.flip(false, true); wood=new TextureRegion(pack,783,68,121,58); collect=new Texture(Gdx.files.internal(“collect.png”)); gold=new Texture(Gdx.files.internal(“gold.png”)); many=new Texture(Gdx.files.internal(“many.png”)); can=new Texture(Gdx.files.internal(“can.png”)); star=new Texture(Gdx.files.internal(“star.png”)); TextureRegion[]playerAni={pl1,pl2,pl3,pl3,pl2,pl1,pl1,pl2,pl3,pl3,pl2,pl1,pl1,pl2,pl3,pl3,pl2,pl1,pl1,pl2,pl3,pl4}; playerAnim=new Animation(0.01f,playerAni); playerAnim.setPlayMode(Animation.PlayMode.LOOP_PINGPONG); logo=new Texture(Gdx.files.internal(“logo.png”)); logo.setFilter(TextureFilter.Linear,TextureFilter.Linear); title=new Texture(Gdx.files.internal(“title.png”)); title.setFilter(TextureFilter.Linear,TextureFilter.Linear); swipe=new Texture(Gdx.files.internal(“swipe.png”)); swipe.setFilter(TextureFilter.Linear,TextureFilter.Linear); title2=new Texture(Gdx.files.internal(“title2.png”)); title2.setFilter(TextureFilter.Linear,TextureFilter.Linear); gameover=new Texture(Gdx.files.internal(“gameover.png”)); gameover.setFilter(TextureFilter.Linear,TextureFilter.Linear); retry=new Texture(Gdx.files.internal(“retry.png”)); retry.setFilter(TextureFilter.Linear,TextureFilter.Linear); ready=new Texture(Gdx.files.internal(“ready.png”)); ready.setFilter(TextureFilter.Linear,TextureFilter.Linear); highscore=new Texture(Gdx.files.internal(“highscore.png”)); highscore.setFilter(TextureFilter.Linear,TextureFilter.Linear); currentscore=new Texture(Gdx.files.internal(“currentScore.png”)); currentscore.setFilter(TextureFilter.Linear,TextureFilter.Linear); bg=new Texture(Gdx.files.internal(“bg.png”)); bg.setFilter(TextureFilter.Linear, TextureFilter.Linear); bg2=new Texture(Gdx.files.internal(“bg2.png”)); bg2.setFilter(TextureFilter.Linear,TextureFilter.Linear); bg3=new Texture(Gdx.files.internal(“bg4.png”)); egg=new Texture(Gdx.files.internal(“egg.png”)); egg.setFilter(TextureFilter.Linear, TextureFilter.Linear); dead=Gdx.audio.newSound(Gdx.files.internal(“dead.wav”)); coin=Gdx.audio.newSound(Gdx.files.internal(“coin.wav”)); font = new BitmapFont(Gdx.files.internal(“whitetext.fnt”)); font.getData().setScale(1.0f, -1.0f); shadow=new BitmapFont(Gdx.files.internal(“shadow.fnt”)); shadow.getData().setScale(1.0f,-1.0f); prefs=Gdx.app.getPreferences(“AnDi”); if(!prefs.contains(“highScore”)){ prefs.putInteger(“highScore”,0); } if(!prefs.contains(“highStar”)){ prefs.putInteger(“highScore”,0); } } public static void setHighScore(int val){ prefs.putInteger(“highScore”, val); prefs.flush(); } public static int getHighScore(){ return prefs.getInteger(“highScore”); } public static void setStarScore(int val){ prefs.putInteger(“highStar”, val); prefs.flush(); } public static int getStarScore(){ return prefs.getInteger(“highStar”); } public static void dispose(){ logo.dispose(); title.dispose(); swipe.dispose(); title2.dispose(); gameover.dispose(); retry.dispose(); ready.dispose(); currentscore.dispose(); highscore.dispose(); dead.dispose(); coin.dispose(); } }

Now let’s add our red bird to its world . Create a new class Cubed. The finished class.

public class Cube { private Vector2 position; private Vector2 velocity; private Vector2 acceleration; private int width; private int height; private Rectangle boundingRect,screenRect; public boolean isAlive; public Cube(float x,float y,int width,int height){ this.width=width; this.height=height; position=new Vector2(x,y); velocity=new Vector2(5,5); acceleration=new Vector2(0,0); boundingRect=new Rectangle(); screenRect=new Rectangle(0,0,Gdx.graphics.getWidth(),Gdx.graphics.getHeight()); isAlive=true; } public void update(float delta){ boundingRect.set(position.x,position.y,width,height); if(position.y < 0){ position.y+=1.5f; }else if(position.y+height>screenRect.height){ position.y-=1.5f; }else if(position.x<0){ position.x+=1.5f; }else if(position.x + width>screenRect.width){ position.x-=1.5f; } } public void updateReady(float delta){ if(position.y<0){ position.y+=velocity.y; } else if(position.y+height>screenRect.height){ position.y-=velocity.y; } } public void moveUp(){ position.y-=60; } public void moveDown(){ position.y +=70; } public void moveRight(){ position.x +=65; } public void moveLeft(){ position.x -=65; } public void die(){ isAlive=false; velocity.y=0; velocity.x=0; } public void onRestart(float y,float x){ position.y=y; position.x=x; velocity.x=0; velocity.y=0; acceleration.x=0; acceleration.y=0; isAlive=true; } public Vector2 getVelocity() { return velocity; } public void setVelocity(Vector2 velocity) { this.velocity = velocity; } public Vector2 getAcceleration() { return acceleration; } public void setAcceleration(Vector2 acceleration) { this.acceleration = acceleration; } public int getWidth() { return width; } public void setWidth(int width) { this.width = width; } public int getHeight() { return height; } public void setHeight(int height) { this.height = height; } public Rectangle getBoundingRect() { return boundingRect; } public void setBoundingRect(Rectangle boundingRect) { this.boundingRect = boundingRect; } public float getX() { return position.x; } public float getY() { return position.y; }


Thats it for our bird class . Now we need a way to control the bird . We want the bird to move in the direction the player swipes . Create a new class InputHandler . The finished class.

import com.badlogic.gdx.input.GestureDetector; public class InputHandler extends GestureDetector{ public interface DirectionListener{ void onLeft(); void onRight(); void onDown(); void onUp(); } public InputHandler(DirectionListener directionListener){ super(new DirectionGestureListener(directionListener)); } static class DirectionGestureListener extends GestureAdapter{ DirectionListener directionListener; public DirectionGestureListener(DirectionListener directionListener){ this.directionListener=directionListener; } @Override public boolean fling(float velocityX,float velocityY,int button){ if(Math.abs(velocityX)>Math.abs(velocityY)){ if(velocityX>0){ directionListener.onRight(); }else{ directionListener.onLeft(); } }else{ if(velocityY>0){ directionListener.onDown(); }else{ directionListener.onUp(); } } return super.fling(velocityX,velocityY,button); } } public InputHandler(GestureListener listener) { super(listener); } }


The bird needs to save its eggs . But our world does not have any eggs . so let’s make some . The eggs will be generated at randomly selected positions . If we tell java to randomly generate  a position for our eggs   it could easily  generate the position outside our world . So to avoid this we will create an emun which will store the possible positions where our eggs  can appear . We will then create a class that will randomly select from the enum we created . OK so let’s  implement this .  The finished random class. 

p

ublic enum FinalBarType { BAR_ROW(10,7.5f), BAR_LARGE2(88f,7.5f), BAR_ROW2(200,7.5f), BAR_COLUMN(88f,330), BAR_COLUMN2(10,330); protected Vector2 position; public Vector2 getPosition() { return position; } public void setPosition(Vector2 position) { this.position = position; } FinalBarType(float x, float y) { position = new Vector2(x, y); } }

The finished random selector class . This class selects a position from our enum.

import java.util.Random; import com.AnDi.GameActor.FinalBarType; public class RandomFinalBar { public static FinalBarType getRandomBarType(){ RandomEnumrandomEnum=new RandomEnum(FinalBarType.class); return randomEnum.random(); } @SuppressWarnings(“rawtypes”) private static class RandomEnum{ private static final Random RND=new Random(); private final E[]values; public RandomEnum(Classtoken){ values=token.getEnumConstants(); } public E random(){ return values[RND.nextInt(values.length)]; } } }

Now we create a class that ties all this together . This class is similar to the cubed class as they do the same function (we create bounding box etc). The finished class 

public class FinalBar { private Rectangle finalBar; private Vector2 position; public GameWorld gameWorld; private int width; private int height; private boolean isScored=false; public FinalBar(float x,float y,int width,int height,GameWorld gameWorld){ this.gameWorld=gameWorld; this.width=width; this.height=height; finalBar=new Rectangle(); position=new Vector2(x,y); } public void update(){ finalBar.set(position.x,position.y,width,height); } public void resetX(){ position.x=RandomFinalBar.getRandomBarType().getPosition().x; isScored=false; } public void resetY(){ position.y=RandomFinalBar.getRandomBarType().getPosition().y; isScored=false; } public void recur(){ if(RandomFinalBar.getRandomBarType().getPosition().x==position.x||RandomFinalBar.getRandomBarType().getPosition().x==position.x){ resetX(); } if(RandomFinalBar.getRandomBarType().getPosition().y==position.y||RandomFinalBar.getRandomBarType().getPosition().y==position.y){ resetY(); } } public boolean collides(Cube cube){ if(Intersector.overlaps(cube.getBoundingRect(),finalBar)){ resetX(); resetY(); if(!isScored()){ addScore(1); } } return false; } public void addScore(int increment){ gameWorld.addScore(increment); } public boolean isScored(){ return isScored; } public void setScored(boolean b){ isScored=b; } public Rectangle getFinalBar() { return finalBar; } public void setFinalBar(Rectangle finalBar) { this.finalBar = finalBar; } public Vector2 getPosition() { return position; } public void setPosition(Vector2 position) { this.position = position; } public int getWidth() { return width; } public void setWidth(int width) { this.width = width; } public int getHeight() { return height; } public void setHeight(int height) { this.height = height; } }

Now let’s  make our  moving blocks. The starting position for our moving blocks will  be generated  randomly like our eggs  but will move with a constant speed  from left to right and from bottom to top .Once out of the screen the blocks will be reset . the finished barType class. It will select our block starting position.

import java.util.Random; import com.AnDi.GameActor.Bar2Type; public class RandomUtils2 { public static Bar2Type getRandomBarType(){ RandomEnumrandomEnum=new RandomEnum(Bar2Type.class); return randomEnum.random(); } @SuppressWarnings(“rawtypes”) private static class RandomEnum{ private static final Random RND=new Random(); private final E[]values; public RandomEnum(Classtoken){ values=token.getEnumConstants(); } public E random(){ return values[RND.nextInt(values.length)]; } } }

The blocks enum class is identical to  the eggs enum class so you can use the same code but you will need to adjust the position(x coordinates and y coordinates )  .  You can create  more block enum classes in order to have more columns and rows of moving blocks . Now we need a class that will  update our blocks position . This class was borrowed from Kiloblot’s tutorial so if you dont understand how the code  works you can visit their tutorial.the finished scrollable and scrollableHandler classes.


protected Vector2 position,position2,position3,position4,position5; protected Vector2 velocity; protected int width; protected int height; protected boolean isScrolledLeft; public Scrollable(float x, float y, int width, int height, float scrollSpeed) { position = new Vector2(RandomUtils.getRandomBarType().getPosition().x,RandomUtils.getRandomBarType().getPosition().y); position2=new Vector2(RandomUtils2.getRandomBarType().getPosition().x,RandomUtils2.getRandomBarType().getPosition().y); position3 = new Vector2(RandomUtils3.getRandomBarType().getPosition().x,RandomUtils3.getRandomBarType().getPosition().y); velocity = new Vector2(scrollSpeed, 0); this.width = width; this.height = height; isScrolledLeft = false; } public void update(float delta) { position.add(velocity.cpy().scl(delta)); position2.add(velocity.cpy().scl(delta)); position3.add(velocity.cpy().scl(delta)); if (position.x + width < 0) { position.x=RandomUtils.getRandomBarType().getPosition().x; position.y=RandomUtils.getRandomBarType().getPosition().y; }else if(position2.x + width < 0){ position2.x=RandomUtils2.getRandomBarType().getPosition().x; position2.y=RandomUtils2.getRandomBarType().getPosition().y; }else if(position3.x + width <0){ position3.x=RandomUtils3.getRandomBarType().getPosition().x; position3.y=RandomUtils3.getRandomBarType().getPosition().y; } } public void reset(float newX) { position.x = RandomUtils.getRandomBarType().getPosition().x; position2.x = RandomUtils2.getRandomBarType().getPosition().x; position3.x=RandomUtils3.getRandomBarType().getPosition().x; } public void stop(){ velocity.x=0; } public boolean isScrolledLeft() { return isScrolledLeft; } public float getTailX() { return position.x + width; } public float getX() { return position.x; } public float getY() { return position.y; } public int getWidth() { return width; } public int getHeight() { return height; } public Vector2 getPosition2() { return position2; } public void setPosition2(Vector2 position2) { this.position2 = position2; } public Vector2 getPosition() { return position; } public void setPosition(Vector2 position) { this.position = position; } public Vector2 getPosition3() { return position3; } public void setPosition3(Vector2 position3) { this.position3 = position3; } public Vector2 getPosition4() { return position4; } public void setPosition4(Vector2 position4) { this.position4 = position4; } public Vector2 getPosition5() { return position5; } public void setPosition5(Vector2 position5) { this.position5 = position5; }

The scroll handler class.

public class ScrollHandler { private Pipe pipe1,pipe2,pipe3; public static final int SCROLL_SPEED=-130; public static final float PIPE_GAP=2.5f; public ScrollHandler(int midPointY){ pipe1 = new Pipe(RandomUtils.getRandomBarType().getPosition().x,RandomUtils.getRandomBarType().getPosition().y,65,65, SCROLL_SPEED); pipe2 = new Pipe(RandomUtils2.getRandomBarType().getPosition().x,RandomUtils2.getRandomBarType().getPosition().y,65,65, SCROLL_SPEED ); pipe3 = new Pipe(RandomUtils3.getRandomBarType().getPosition().x,RandomUtils3.getRandomBarType().getPosition().y,65,65, SCROLL_SPEED ); } public void update(float delta){ pipe1.update(delta); pipe2.update(delta); pipe3.update(delta); if(pipe1.isScrolledLeft()){ pipe1.reset(RandomUtils.getRandomBarType().getPosition().x); }else if(pipe2.isScrolledLeft()){ pipe2.reset(RandomUtils2.getRandomBarType().getPosition().x); }else if(pipe3.isScrolledLeft()){ pipe3.reset(RandomUtils3.getRandomBarType().getPosition().x); } } public void stop(){ pipe1.stop(); pipe2.stop(); pipe3.stop(); } public boolean collides(Cube cube){ return(Intersector.overlaps(cube.getBoundingRect(),pipe1.getBarUp()) || Intersector.overlaps(cube.getBoundingRect(),pipe2.getBarDown()) || Intersector.overlaps(cube.getBoundingRect(),pipe3.getBarSide()) ); } public void onRestart(){ pipe1.onRestart(210,SCROLL_SPEED); pipe2.onRestart(pipe1.getTailX()+5f,SCROLL_SPEED); pipe3.onRestart(pipe2.getTailX()+5f,SCROLL_SPEED); } public static float getPipeGap() { return PIPE_GAP; } public Pipe getPipe1() { return pipe1; } public void setPipe1(Pipe pipe1) { this.pipe1 = pipe1; } public Pipe getPipe2() { return pipe2; } public void setPipe2(Pipe pipe2) { this.pipe2 = pipe2; } public Pipe getPipe3() { return pipe3; } public void setPipe3(Pipe pipe3) { this.pipe3 = pipe3; }

Finally we make the place holder class for our blocks just like the cubed and finalbar class .

import com.AnDi.Common.RandomUtils; import com.AnDi.Common.RandomUtils2; import com.AnDi.Common.RandomUtils3; import com.badlogic.gdx.math.Intersector; import com.badlogic.gdx.math.Rectangle; public class Pipe extends Scrollable{ private Rectangle barUp,barDown,barSide; public Rectangle getBarUp() { return barUp; } public void setBarUp(Rectangle barUp) { this.barUp = barUp; } public Pipe(float x, float y, int width, int height, float scrollSpeed) { super(x, y, width, height, scrollSpeed); barUp=new Rectangle(); barDown=new Rectangle(); barSide=new Rectangle(); } @Override public void reset(float newX) { super.reset(newX); position.x=RandomUtils.getRandomBarType().getPosition().x; position2.x=RandomUtils2.getRandomBarType().getPosition().x; position.y=RandomUtils.getRandomBarType().getPosition().y; position2.y=RandomUtils2.getRandomBarType().getPosition().y; position3.x=RandomUtils3.getRandomBarType().getPosition().x; position3.y=RandomUtils3.getRandomBarType().getPosition().y; } public Rectangle getBarDown() { return barDown; } public void setBarDown(Rectangle barDown) { this.barDown = barDown; } public Rectangle getBarSide(){ return barSide; } public void setBarSide(Rectangle barSide){ this.barSide=barSide; } @Override public void update(float delta){ super.update(delta); barUp.set(position.x,position.y,width,height); barDown.set(position2.x,position2.y,width,height); barSide.set(position3.x,position3.y,width,height); } public boolean collides(Cube cube){ if(Intersector.overlaps(cube.getBoundingRect(),barUp) ||Intersector.overlaps(cube.getBoundingRect(),barDown) ||Intersector.overlaps(cube.getBoundingRect(),barSide)){ } return false; } public void onRestart(float x,float scrollSpeed){ velocity.x=scrollSpeed; reset(x); } }

The final class  we need to create in our project is the menu class .

public class MenuScreen implements Screen{ private TweenManager manager; private SpriteBatch batcher; private Sprite sprite; private CDGame game; public MenuScreen(CDGame game) { this.game = game; } @Override public void show() { sprite = new Sprite(AssetLoader.title); sprite.setColor(1, 1, 1, 0); float width = Gdx.graphics.getWidth(); float height = Gdx.graphics.getHeight(); float desiredWidth = width * .7f; float scale = desiredWidth / sprite.getWidth(); sprite.setSize(sprite.getWidth() * scale, sprite.getHeight() * scale); sprite.setPosition((width / 2) – (sprite.getWidth() / 2), (height / 2) – (sprite.getHeight() / 2)); setupTween(); batcher = new SpriteBatch(); } private void setupTween() { Tween.registerAccessor(Sprite.class, new SpriteAccessor()); manager = new TweenManager(); TweenCallback cb = new TweenCallback() { @Override public void onEvent(int type, BaseTween source) { game.setScreen(new GameScreen()); } }; Tween.to(sprite, SpriteAccessor.ALPHA, .8f).target(1) .ease(TweenEquations.easeInOutQuad).repeatYoyo(1, .4f) .setCallback(cb).setCallbackTriggers(TweenCallback.COMPLETE) .start(manager); } @Override public void render(float delta) { manager.update(delta); Gdx.gl.glClearColor(1, 1, 1, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); batcher.begin(); sprite.draw(batcher); batcher.end(); } @Override public void resize(int width, int height) { } @Override public void hide() { // TODO Auto-generated method stub } @Override public void pause() { // TODO Auto-generated method stub } @Override public void resume() { // TODO Auto-generated method stub } @Override public void dispose() { // TODO Auto-generated method stub } }

Well that does it for the libgdx game   tutorial . you can now run the game with no errors . 

​​​

If you have any questions or comments, feel free to let me know in the comments section.You can get the finished code on github .

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s