Animasi sederhana pada LibGDX

Menggunakan program dari tutorial sebelumnya kita akan membuat kotak tersebut bergerak dari kanan ke kiri.

Dari source sebelumnya, terdapat method render() yang digunakan untuk menggambar layar. Method ini dipanggil secara otomatis 30 sampai dengan 80 kali dalam satu detik. Semakin bagus hardware, semakin banyak render akan dipanggil. Satuan pemanggilan render ini sering disebut FPS = frame per second.   Kita akan memanfaatkan method render ini untuk mengupdate posisi kotak. Setiap render() dipanggil, posisi kotak akan ditambah agar bergeser ke kanan.

 

package edu.upi.cs.yudiwbs.libgdx;

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

public class Coba1 extends ApplicationAdapter {
	SpriteBatch batch;
	Texture img;

    //resoulsi nexus 1794 x 885
    private float wWorld = 1794;
    private float hWorld = 885;

    //ukuran kotak
    private int  wBox = 200;
    private int  hBox = 200;
    private Pixmap pm;
    private Sprite sp;
    private OrthographicCamera camera;

    //posisi
    private float posX;

	@Override
	public void create () {
        camera = new OrthographicCamera(wWorld, hWorld);
       	batch = new SpriteBatch();

        //siapkan gambar kotak berwarna merah dengan line hitam
        pm  = new Pixmap(wBox,hBox,Pixmap.Format.RGBA8888);
        pm.setColor(Color.RED);
        pm.fill();
        pm.setColor(Color.BLACK);
        pm.drawRectangle(0,0, pm.getWidth(), pm.getHeight());

        //jadikan sprite
        img = new Texture(pm);
        pm.dispose(); //!! harus ada
        sp = new Sprite(img);
        sp.setSize(wBox,hBox);

        //init lokasi awal di ujung kiri layar
        sp.setPosition(-wWorld*0.5f, -(hBox/2f));
	}

    private void updatePosisi() {
        //update posisi, geser sepuluh pixel
        posX = posX + 10;
        sp.setPosition(posX, 200f-sp.getHeight());
        
        //lewat dari batas kanan, kembalikan ke kiri
        if (posX>wWorld*0.5) {
            posX = -wWorld*0.5f;
        }
    }

	@Override
	public void render () {
        //update posisi dipanggil setiap render dipanggil
        updatePosisi();
        Gdx.gl.glClearColor(1, 1, 1, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        batch.setProjectionMatrix(camera.combined);
        batch.begin();
        sp.draw(batch);
        batch.end();
	}
}

Masalah utama dari code di atas adalah render tidak dipanggil dalam jumlah yang konstant dan sangat bergantung pada hardware. Untuk device berkinerja rendah, render bisa dipanggil 30 kali per detik bahkan kurang, sedangkan untuk device terbaru mencapai 80 kali. Efeknya, kecepatan kotak bergerak akan berbeda.

Untuk mengatasi hal ini dapat digunakan method Gdx.graphics.getDeltaTime(). Method ini menghasikan detik selisih sejak frame terakhir dipanggil. Jadi nilainya ada di kisaran 1/FPS. Semakin lambat device, semakin besar nilai getDelta. Berbekal variabel ini, kita bisa membuat kecepatan animasi menjadi konsisten. Ingat pelajaran SMP? jika kita punya kecepatan dan waktu, maka kita bisa menghitung jarak (jarak = kecepatan * waktu). Jadi untuk device yang lambat, jarak yang harus ditambah akan semakin besar dibandingkan device yang cepat. Bahkan kalau terlalu lambat, mungkin akan terlihat kotaknya meloncat-loncat karena jaraknya yang ditambah terlalu besar, tapi ini lebih baik daripada menjadi film slow motion 🙂

Isi updateposisi() dan render() adalah sebagai berikut (yang lainnya sama)

    private void updatePosisi(float delta) {
        //update posisi
        //kecepatan posisi bergeser adalah 500 pixel per detik
        posX = posX + (500*delta); //jarak = kecepatan * waktu
        sp.setPosition(posX, 200f-sp.getHeight());
        //lewat dari batas kanan, kembalikan ke kiri
        if (posX>wWorld*0.5) {
            posX = -wWorld*0.5f;
        }
    }

    @Override
    public void render () {
        //delta = selisih dalam detik sejak frame terkahir digambar
        float delta = Gdx.graphics.getDeltaTime();
        updatePosisi(delta);

        Gdx.gl.glClearColor(1, 1, 1, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        batch.setProjectionMatrix(camera.combined);
        batch.begin();
        sp.draw(batch);
        batch.end();
     }

  

Coba jalankan diberbagai device, kecepatan kotak akan tetap sama.

0 comments on “Animasi sederhana pada LibGDX

1 Pings/Trackbacks for "Animasi sederhana pada LibGDX"

Leave a Reply

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

Time limit is exhausted. Please reload CAPTCHA.