LibGDX Video Tutorial: Gestures–Panning, Zooming, Pinch, Tapping and more

16. December 2014

 

This video tutorial covers handling gestures in LibGDX, this includes:

  • pinch
  • zoom
  • tap
  • pan
  • long press

 

You can view the video in full resolution on Youtube here.  The source is included below.

 

Source from this tutorial example:

package com.gamefromscratch;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.input.GestureDetector;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;

public class GestureDemo extends ApplicationAdapter implements GestureDetector.GestureListener {
   SpriteBatch batch;
   Sprite sprite;
   OrthographicCamera camera;
   GestureDetector gestureDetector;
   
   @Override
   public void create () {
      batch = new SpriteBatch();
      sprite = new Sprite(new Texture(Gdx.files.internal("storm_trooper.png")));
      sprite.setPosition(-sprite.getWidth()/2,-sprite.getHeight()/2);
      sprite.setCenter(0.5f,0.5f);

      camera = new OrthographicCamera(1280,720);
      camera.update();

      gestureDetector = new GestureDetector(this);
      Gdx.input.setInputProcessor(gestureDetector);
   }

   @Override
   public void render () {
      Gdx.gl.glClearColor(0, 0, 0, 1);
      Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
      batch.setProjectionMatrix(camera.combined);
      batch.begin();
      sprite.draw(batch);
      batch.end();
   }

   @Override
   public boolean touchDown(float x, float y, int pointer, int button) {
      return false;
   }

   @Override
   public boolean tap(float x, float y, int count, int button) {
      if(count > 1){
         sprite.setPosition(-sprite.getWidth()/2,-sprite.getHeight()/2);
         sprite.setSize(256f,256f);
         sprite.setRotation(0f);
      }
      else {
         Vector3 touchPos = new Vector3(x, y, 0);
         camera.unproject(touchPos);
         sprite.setPosition(touchPos.x, touchPos.y);
      }
      return true;
   }

   @Override
   public boolean longPress(float x, float y) {

      Vector3 touchPos = new Vector3(x,y,0);
      camera.unproject(touchPos);

      if(sprite.getBoundingRectangle().contains(touchPos.x,touchPos.y)) {
         float alpha = sprite.getColor().a;

         if (alpha >= 0.f)
            sprite.setAlpha(alpha - 0.25f);
         else
            sprite.setAlpha(1f);
      }
      return true;
   }

   @Override
   public boolean fling(float velocityX, float velocityY, int button) {
      return false;
   }

   @Override
   public boolean pan(float x, float y, float deltaX, float deltaY) {
      Vector3 touchPos = new Vector3(x,y,0);
      camera.unproject(touchPos);

      sprite.setPosition(touchPos.x - sprite.getWidth()/2,touchPos.y - sprite.getHeight()/2);

      return true;
   }

   @Override
   public boolean panStop(float x, float y, int pointer, int button) {
      return false;
   }

   @Override
   public boolean zoom(float initialDistance, float distance) {
      sprite.setSize(distance,distance);
      return true;
   }

   @Override
   public boolean pinch(Vector2 initialPointer1, Vector2 initialPointer2, Vector2 pointer1, Vector2 pointer2)
{
float deltaX = pointer2.x - pointer1.x; float deltaY = pointer2.y - pointer1.y; float angle = (float)Math.atan2((double)deltaY,(double)deltaX) * MathUtils.radiansToDegrees; angle += 90f; if(angle < 0) angle = 360f - (-angle); sprite.setRotation(-angle); return true; } }

Programming , ,




LibGDX Video Tutorial: Cameras and Viewports. Handling multiple resolutions and aspect ratios

9. December 2014

 

In this video tutorial we look at using the different types of Cameras available, using a Camera to position your world in a device independent way.  Next we discuss the various Viewport options available for making your render results look best across a number of devices.  Since this video was released at the same time as the text version of the tutorial, I will be linking to those tutorials for code examples.

 

You can see the full 1080p video directly on YouTube or embedded below.

 

 

For the text tutorials, or for the code or assets used in this tutorial, check this tutorial on Cameras and this tutorial on Viewports.

 

Additionally, the text only tutorial also covers converting coordinates too and from your world coordinates, something I forgot to do in the video tutorial.

Programming , , ,




LibGDX Video Tutorial: Handling Keyboard, Mouse and Touch Input

24. November 2014

 

In this video tutorial, we look at handling Keyboard, Mouse and Touch input in LibGDX.  We look at both handling input via polling as well as an event driven approach.

 

You can see the video in full 1080p definition here.  Once again, all the code included in the video is available below:

 

 

Polled Input Sample

package com.gamefromscratch;

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

public class PolledInputDemo extends ApplicationAdapter {
   SpriteBatch batch;
   Texture img;
   Sprite sprite;
   
   @Override
   public void create () {
      batch = new SpriteBatch();
      img = new Texture("badlogic.jpg");
      sprite = new Sprite(img);
      sprite.setPosition(Gdx.graphics.getWidth()/2 - sprite.getWidth()/2,
            Gdx.graphics.getHeight()/2 - sprite.getHeight()/2);
   }

   @Override
   public void render () {

      // Keyboard events
      if(Gdx.input.isKeyPressed(Input.Keys.LEFT))
         sprite.translateX(-1f);
      if(Gdx.input.isKeyPressed(Input.Keys.RIGHT))
         sprite.translateX(1f);
      if(Gdx.input.isKeyPressed(Input.Keys.SPACE))
         sprite.setPosition(Gdx.graphics.getWidth()/2 - sprite.getWidth()/2,
               Gdx.graphics.getHeight()/2 - sprite.getHeight()/2);

      if(Gdx.input.isButtonPressed(Input.Buttons.RIGHT))
         sprite.setPosition(Gdx.input.getX(),Gdx.graphics.getHeight() - Gdx.input.getY());


      Gdx.gl.glClearColor(0, 0, 0, 1);
      Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
      batch.begin();
      batch.draw(sprite, sprite.getX(), sprite.getY());
      batch.end();
   }

   @Override
   public void dispose(){
      img.dispose();
   }
}

Event Driven Input Sample

package com.gamefromscratch;

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

public class EventDrivenInputDemo extends ApplicationAdapter implements InputProcessor {
   SpriteBatch batch;
   Texture img;
   Sprite sprite;
   boolean movingRight = false;
   
   @Override
   public void create () {
      batch = new SpriteBatch();
      img = new Texture("badlogic.jpg");
      sprite = new Sprite(img);
      sprite.setPosition(Gdx.graphics.getWidth()/2-sprite.getWidth()/2,
            Gdx.graphics.getHeight()/2 - sprite.getHeight()/2);

      Gdx.input.setInputProcessor(this);
   }

   @Override
   public void render () {

      if(movingRight)
         sprite.translateX(1f);
      Gdx.gl.glClearColor(0, 0, 0, 1);
      Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
      batch.begin();
      batch.draw(sprite, sprite.getX(),sprite.getY());
      batch.end();
   }

   @Override
   public boolean keyDown(int keycode) {
      if(keycode == Input.Keys.RIGHT)
         movingRight = true;
      return true;
   }

   @Override
   public boolean keyUp(int keycode) {
      if(keycode == Input.Keys.LEFT)
         sprite.translateX(-1f);
      if(keycode == Input.Keys.RIGHT)
         movingRight = false;
      return true;
   }

   @Override
   public boolean keyTyped(char character) {
      return false;
   }

   @Override
   public boolean touchDown(int screenX, int screenY, int pointer, int button) {
      return false;
   }

   @Override
   public boolean touchUp(int screenX, int screenY, int pointer, int button) {
      return false;
   }

   @Override
   public boolean touchDragged(int screenX, int screenY, int pointer) {
      // If the user is holding down ( or was holding down, and hasnt released ) three fingers, move the sprite
      if(pointer ==2)
         sprite.setPosition(screenX,Gdx.graphics.getHeight()-screenY);
      return true;
   }

   @Override
   public boolean mouseMoved(int screenX, int screenY) {
      sprite.setPosition(screenX,Gdx.graphics.getHeight()-screenY);
      return true;
   }

   @Override
   public boolean scrolled(int amount) {
      if(amount > 0)
         sprite.translateY(1f);
      if(amount < 0)
         sprite.translateY(-1f);

      return true;
   }
}

Programming , , ,




LibGDX Video Tutorial: Creating and Using Fonts and Text

21. November 2014

 

In the last video tutorial we used a graphic instead of text to create a Hello World.  This is because drawing text is actually a multi step process in LibGDX and not really appropriate for a first tutorial.  It is however perfect for a second tutorial, so here we are! ;)

 

In this video we explore the difference between TTF and Bitmap fonts, show how to run the Hiero font generation tool in both Eclipse and IntelliJ IDEA then create and save a bitmap font.  We then explore the code needed to show a bitmap font on screen, including how to measure the results, apply color and text justification.

 

The video is available in up to 1080P on YouTube by clicking here.

 

The source code:

Initial Example – Loading a font and drawing text:

package com.gamefromscratch;

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

public class gdxtext extends ApplicationAdapter {
   SpriteBatch batch;
    BitmapFont font;

   @Override
   public void create () {
      batch = new SpriteBatch();
        font = new BitmapFont(Gdx.files.internal("Papy.fnt"));
   }

   @Override
   public void render () {
      Gdx.gl.glClearColor(0, 0, 0, 1);
      Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
      batch.begin();

        //Example One -- Drawing Text
        font.draw(batch,"Hello World",Gdx.graphics.getWidth()/2,Gdx.graphics.getHeight()/2);

        batch.end();
   }
}

 

Example 2 – Measuring and centering text:

BitmapFont.TextBounds bounds = font.getBounds("Hello World");
font.draw(batch,"Hello World",
       Gdx.graphics.getWidth()/2 - bounds.width/2,
       Gdx.graphics.getHeight()/2 + bounds.height/2);

Example 3 – Multi-line Text

String debugString = "I took one, one cause you left me\n"
           + "Two, two for my family\n"
           + "Three, three for my heartache\n"
           + "Four, four for my headaches\n"
           + "Five, five for my sorrow\n";
   BitmapFont.TextBounds bounds = font.getMultiLineBounds(debugString);

 

Example 4 -- Center justified text in the colour purple

    font.setColor(Color.PURPLE);
    font.drawMultiLine(batch,
            debugString,
            0,
            Gdx.graphics.getHeight()/2 + bounds.height/2,
            Gdx.graphics.getWidth(),
            BitmapFont.HAlignment.CENTER
            );

Programming , , ,




LibGDX Video Tutorial: Hello World!

18. November 2014

 

In this video tutorial, we create our first LibGDX project.  This tutorial covers that basic layout of a LibGDX application, adding new assets to a project and looks at how the initial project is composed and how multiple platforms are supported.  We then go through the initial code, then look in depth at coordinate systems, then move on to creating a sprite.  Finally we look at positioning, scaling and rotating a sprite with a SpriteBatch.

 

This tutorial assumes you already have your development environment setup and know how to run a LibGDX application in your chosen IDE.  If you do no, please watch these videos first.

 

The following is the video tutorial.  It was recorded in 1080p and the complete version can be viewed here.

 

 

The following is the final code generated:

 

package com.gamefromscratch;

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.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;

public class HelloWorld extends ApplicationAdapter {
   SpriteBatch batch;
   Texture img;
   Sprite sprite;
   
   @Override
   public void create () {
      batch = new SpriteBatch();
      img = new Texture("HelloWorld.png");
      sprite = new Sprite(img);
      sprite.setPosition(
            Gdx.graphics.getWidth()/2 - sprite.getWidth()/2,
            Gdx.graphics.getHeight()/2 - sprite.getHeight()/2);
      sprite.setScale(1.0f,2.0f);
   }

   @Override
   public void render () {
      Gdx.gl.glClearColor(0, 0, 0, 1);
      Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
      batch.begin();
      batch.draw(sprite, sprite.getX(),sprite.getY(),sprite.getWidth()/2,
            sprite.getHeight()/2,sprite.getWidth(),
            sprite.getHeight(),sprite.getScaleX(),
            sprite.getScaleY(),sprite.getRotation());
      batch.end();
   }
}

 

Here is the image that was used in this tutorial:

HelloWorld

Programming , , ,