Upgrade to Pro — share decks privately, control downloads, hide ads and more …

LibGDX: User Input and Frame by Frame Animation

LibGDX: User Input and Frame by Frame Animation

Jussi Pohjolainen

January 22, 2016
Tweet

More Decks by Jussi Pohjolainen

Other Decks in Technology

Transcript

  1. Event vs Polling • Polling – Do something on each

    frame, really fast • Was mouse clicked? Was mouse clicked? Was mouse clicked? – Good for arcade games • Event – Do something when event handles • Notify when mouse was clicked • Mouse / touch / keyboard can be received either in 1) polling or 2) event handling
  2. Polling Touch / Keyboard • For most arcade games, polling

    is good • Multitouch is supported! – boolean first = Gdx.input.isTouched(0); – boolean second = Gdx.input.isTouched(1); – int firstX = Gdx.input.getX(); – int firstY = Gdx.input.getY(); – int secondX = Gdx.input.getX(1); – int secondY = Gdx.input.getY(1); • Keyboard – boolean isAPressed = Gdx.input.isKeyPressed(Keys.A);
  3. Event: InputProcessor • An InputProcessor (Interface) is used to receive

    input events from the keyboard and the touch screen • It has to be registered – Input.setInputProcessor(InputProcessor); • When registered the methods from InputProcessor interface are called.
  4. Using InputProcessor public class InputDemo extends ApplicationAdapter implements InputProcessor {

    @Override public void create () { Gdx.input.setInputProcessor(this); } @Override public void render () { } @Override public boolean keyDown(int keycode) { return false; } @Override public boolean keyUp(int keycode) { return false; } ...
  5. Using InputAdapter and Inner Class public class InputDemo extends ApplicationAdapter

    { @Override public void create () { Gdx.input.setInputProcessor(new Listener()); } private class Listener extends InputAdapter { @Override public boolean touchDragged(int screenX, int screenY, int pointer) { // implementation here return true; } } }
  6. GestureDetector • TouchDown – User touches screen • LongPress –

    User touches screen for some time • Tap – User touches screen and lifts the finger again • Pan – User drags a finger across the screen. Useful for implementing Camera panning in 2D • PanStop – Called when no longer panning • Fling – User dragged a finger across the screen, then lifted up. Useful for swipe gestures • Zoom – User places two fingers on the screen and moves them together/apart. Useful for Camera zooming • Pinch – Zooming + rotation
  7. Starting to Listen to Gestures • Really easy – Gdx.input.setInputProcessor(new

    GestureDetector(GestureListener)); • GestureListener is an interface • GestureAdapter also available
  8. GestureListener public class MyGestureListener implements GestureListener { @Override public boolean

    touchDown(float x, float y, int pointer, int button) {} @Override public boolean tap(float x, float y, int count, int button) {} @Override public boolean longPress(float x, float y) {} @Override public boolean fling(float velocityX, float velocityY, int button) {} @Override public boolean pan(float x, float y, float deltaX, float deltaY) {} @Override public boolean panStop(float x, float y, int pointer, int button) {} @Override public boolean zoom (float originalDistance, float currentDistance){} @Override public boolean pinch (Vector2 initialFirstPointer, Vector2 initialSecondPointer, Vector2 firstPointer, Vector2 secondPointer){} }
  9. Accelerometer • An accelerometer measures the acceleration of a device

    on three axes • From this acceleration one can derive the tilt or orientation of the device. – Phones: portrait default – Tablet: landscape default • LibGDX shows accelerometer readings always as in the image
  10. Accelerometer Readings • Accelerometer readings can be accessed – float

    accelX = Gdx.input.getAccelerometerX(); – float accelY = Gdx.input.getAccelerometerY(); – float accelZ = Gdx.input.getAccelerometerZ(); • When moving and if in landscape mode in android, notice X vs Y! – speedX += Gdx.input.getAccelerometerY();
  11. User input • Desktop – Swing dialog • Android –

    Android dialog • Use TextInputListener
  12. public class InputDemo extends ApplicationAdapter { @Override public void create

    () { MyTextInputListener listener = new MyTextInputListener(); Gdx.input.setInputProcessor(new GestureDetector(new GestureDetector.GestureAdapter() { @Override public boolean tap(float x, float y, int count, int button) { Gdx.input.getTextInput(new MyTextInputListener(), "title", "test", "hint"); return true; } })); } private class MyTextInputListener implements Input.TextInputListener { @Override public void input (String text) { Gdx.app.log("InputDemo", text); } @Override public void canceled () { Gdx.app.log("InputDemo", "canceled"); } } }
  13. Game Object • Game object may hold information about –

    Texture – Geometry • width • height • x, y – Color • You could create a class for your game object that capsulates all of these • But even better, libGDX has already this class, it's called Sprite
  14. Sprite - class • Holds geometry, color and texture information

    • Has a position and a size given as width and height • Sprite is always rectangular • Sprite has also origin for rotation and scaling – origin is in bottom left
  15. public class SpriteDemo extends ApplicationAdapter { private Sprite player; private

    Texture alienTexture; private OrthographicCamera camera; private SpriteBatch batch; public final static float WIDTH = 1280; public final static float HEIGHT = 720; @Override public void create () { player = new Sprite( alienTexture = new Texture("alien-displeased-icon.png") ); camera = new OrthographicCamera(); camera.setToOrtho(false, WIDTH, HEIGHT); batch = new SpriteBatch(); } @Override public void render() { batch.setProjectionMatrix(camera.combined); Gdx.gl.glClearColor(1, 1, 1, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); batch.begin(); player.draw(batch); batch.end(); } @Override public void dispose() { alienTexture.dispose(); } }
  16. Animation • Use Animation class – Animation walkAnimation = new

    Animation(frameDuration, frames); • Frame duration? Time between frames in seconds: 1 / 60 fps • Frames? – TextureRegionarray • TextureRegion? – Part of texture
  17. Split .png into TextureRegions walkSheet = new Texture(Gdx.files.internal(”image.png")); // Method

    for splitting one texture to TextureRegions TextureRegion[][] tmp = TextureRegion.split( walkSheet, walkSheet.getWidth() / FRAME_COLS, walkSheet.getHeight() / FRAME_ROWS );
  18. 2D array -> 1D private TextureRegion[] transformTo1D(TextureRegion[][] tmp) { TextureRegion

    [] walkFrames = new TextureRegion[FRAME_COLS * FRAME_ROWS]; int index = 0; for (int i = 0; i < FRAME_ROWS; i++) { for (int j = 0; j < FRAME_COLS; j++) { walkFrames[index++] = tmp[i][j]; } } return walkFrames; }
  19. Split .png into TextureRegions walkSheet = new Texture(Gdx.files.internal(”image.png")); // Method

    for splitting one texture to TextureRegions TextureRegion[][] tmp = TextureRegion.split( walkSheet, walkSheet.getWidth() / FRAME_COLS, walkSheet.getHeight() / FRAME_ROWS ); TextureRegion [] frames = transformTo1D(tmp); Animation walkAnimation = new Animation(1 / 60f, frames);
  20. Rendering float stateTime = 1.0f; TextureRegion currentFrame; public void render()

    { // stateTime was initialized to 0.0f stateTime += Gdx.graphics.getDeltaTime(); // stateTime is used to calculate the next frame // frameDuration! // true = it's a looping anim // false = it's not a looping anim currentFrame = walkAnimation.getKeyFrame(stateTime, true); spriteBatch.begin(); spriteBatch.draw(currentFrame, 150, 150); spriteBatch.end(); }
  21. Creating Game Objects • For each Game Object, create own

    class • The class may have – Inheritance relationship with Sprite / Texture(is – a) or – Composition relationship with Sprite / Texture (has – a) • Add attributes like – speedX, speedY, sounds, animations • See example from course homepage!