Belajar Pemrograman Java Dari Dasar

Belajar Membuat Game 2D Dengan Java dan Netbeans Bagian 4: Thread dan Game Loop

Pada tutorial belajar membuat game 2D dengan java bagian 4 ini anda akan mempelajari tentang thread dan juga game loop.

Jadi, apa itu thread pada Java?

Di sini tidak akan dijelaskan penjelasan mengenai thread secara teknis, karena begitu banyak artikel dan tutorial di luar sana yang membahas mengenai topik tersebut.

Saya hanya akan menjelaskan sesimpel mungkin mengenai thread ini dalam tujuan pembuatan game sederhana ini.

Thread adalah program mini.

Maksudnya?

Pada program game ini terdapat beberapa class. Dan misalkan ketika anda hanya ingin program class Game yang dijalankan saja, ini di sebut dengan thread. Jadi thread ini adalah program mini yang terdapat di dalam program besar, dalam hal ini program game 2D yang anda buat. Hanya inilah poin penting yang harus anda pahami di sini sebenarnya.

Tapi berikut ini adalah pengetahuan lebih lanjut mengenai thread.

Setiap thread  kendalikan dan dibuat  oleh class java.lang.Thread. Ketika sebuah thread di buat maka itu menjadi prioritas. Thread dengan prioritas paling tinggi akan dieksekusi lebih dulu, baru kemudian diikuti oleh thread lain yang prioritasnya lebih rendah.

Setiap program Java memiliki setidaknya satu thread yang dikenal sebagai thread utama. Thread ini dibuat oleh JVM pada saat program dijalankan, ketika method main dipanggil oleh thread utama.

Thread dapat dihentikan oleh JVM ketika salah satu kondisi di bawah ini terpenuhi:

  • Method exit dipanggil dan disahkan
  • Tidak ada lagi thread yang berjalan di belakang layar (daemon thread) 

Membuat Thread Pada Class Game

Sekarang anda akan membuat thread pada class Game. 

Apa artinya?

Artinya adalah segala sesuatnya yang terdapat di class Game akan dijalankan secara terpisah dari semua kode lainnya yang terdapat dalam aplikasi. Atau dengan kata lain menjalankan class Game secara terpisah dari keseluruhan kode program.

Untuk melakukannya anda harus mengimplementasikan interface Runnable dan mengimplementasikan method abstrak run() dengan mengoverride-nya pada class Game. 

Berikut ini adalah update kode program class Game dengan thread:

package com.bahasajava.gamejava;

import com.bahasajava.gamejava.gamedisplay.GameDisplay;
import java.util.logging.Level;
import java.util.logging.Logger;

//Mnegimplementasikan interface Runnable untuk thread
public class Game implements Runnable {
   private GameDisplay gameDisplay;
   
   public int lebar, tinggi;
   
   private Thread thread;//thread yang dijalankan
   
   public Game(String judul, int lebar, int tinggi){
       this.lebar = lebar;
       this.tinggi = tinggi;
       //objek gameDisplay memiliki konstruktor dengan parameter
       //judul, lebar, dan tinggi, jadi semua parameter ini harus terpenuhi
       gameDisplay = new GameDisplay(judul, lebar, tinggi);
   }
   
   //Method ini akan menginisialisasi semua graphic
   //dan akan memastikan semuanya siap sebelum game dijalankan
   private void inisialisasi(){
       
   }

    //run() adalah method abstract yang harus diimplentasikan
    //ketika class mengimplementasikan Runnable
    @Override
    public void run() {
        inisialisasi();//Memanggil method inisialisasi()
        
        //Di sini kita akan menjalankan loop game
    }
    
    //synchronized digunakan ketika langsung berhubungan dengan thread
    //startThread() akan menjalankan thread
    public synchronized void startThread(){
        //Konstruktor Thread mengambil parameter class mana yang 
        //akan di jalankan, dalam hal ini adalah class Game
        //oleh karena itu menggunakan keyword this
        thread = new Thread(this);
        thread.start();//Method start() ini akan menjalankan method run()
    }
    
    //stopThread akan menghentikan thread
    public synchronized void stopThread(){
       //Method join() melemparkan checked exception sehingga
       //akan memaksa anda untuk menggunakan blok try-catch
       //atau bisa juga dengan menggunakan clausa Throws
       try {
           thread.join();//Method join() akan menunggu thread untuk "mati"
       } catch (InterruptedException ex) {
           Logger.getLogger(Game.class.getName()).log(Level.SEVERE, null, ex);
       }
    }  
    
}

Membuat Loop Pada Game

Secara garis besarnya, setiap game apapun memiliki diagram loop seperti berikut ini:
java game loop


Dari diagram di atas kita bisa menyimpulkan:

  • Pertama ketika program dijalankan, apakah program tersebut di close? Jika ya program dihentikan. Tapi bila tidak, maka input dari user akan didapatkan.
  • Setelah itu, semua variabel, posisi objek, grafik, dan lainnya akan diupdate.
  • Kemudian, proses render atau menggambar akan dilakukan
  • Proses akan kembali lagi ke tahap awal dan loop atau perulangan akan terus berjalan sampai dengan program di hentikan.

Berikut ini adalah update koding dari class Game yang telah diberi loop dan juga ada beberapa method tambahan yaitu inisialisasi(), updateGame, dan render().

package com.bahasajava.gamejava;

import com.bahasajava.gamejava.gamedisplay.GameDisplay;
import java.util.logging.Level;
import java.util.logging.Logger;

//Mnegimplementasikan interface Runnable untuk thread
public class Game implements Runnable {
   private GameDisplay gameDisplay;
   
   public int lebar, tinggi;
   public String judul;
   
   private Thread thread;//thread yang dijalankan
   
   private boolean gameRunning = false;//Untuk mengontrol while loop
   
   public Game(String judul, int lebar, int tinggi){
       this.lebar = lebar;
       this.tinggi = tinggi;
       this.judul= judul;
       
   }
   
   //Method inisialisasi() akan menginisialisasi semua graphic
   //dan akan memastikan semuanya siap sebelum game dijalankan
   private void inisialisasi(){
       //objek gameDisplay memiliki konstruktor dengan parameter
       //judul, lebar, dan tinggi, jadi semua parameter ini harus terpenuhi
       gameDisplay = new GameDisplay(judul, lebar, tinggi);
   }
   
   //Method updateGame() akan terus melakukan update game
   private void updateGame(){
       
   }
   
   //Method render() untuk merender 
   private void render(){
       
   }

    //run() adalah method abstract yang harus diimplentasikan
    //ketika class mengimplementasikan Runnable
    @Override
    public void run() {
        inisialisasi();
        
        //Di sini kita akan menjalankan loop game
        while(gameRunning){
            updateGame();
            render();
        }
        stopThread();
    }
    
    //synchronized digunakan ketika langsung berhubungan dengan thread
    //startThread() akan menjalankan thread
    public synchronized void startThread(){
        
        if(gameRunning)
            return;
        
        gameRunning = true;
        
        //Konstruktor Thread mengambil parameter class mana yang 
        //akan di jalankan, dalam hal ini adalah class Game
        //oleh karena itu menggunakan keyword this
        thread = new Thread(this);
        thread.start();//Method start() ini akan menjalankan method run()
    }
    
    //stopThread akan menghentikan thread
    public synchronized void stopThread(){
       if(!gameRunning)
           return;
       
       gameRunning = false;
        
       //Method join() melemparkan checked exception sehingga
       //akan memaksa anda untuk menggunakan blok try-catch
       //atau bisa juga dengan menggunakan clausa Throws
       try {
           thread.join();//Method join() akan menunggu thread untuk "mati"
       } catch (InterruptedException ex) {
           Logger.getLogger(Game.class.getName()).log(Level.SEVERE, null, ex);
       }
    }  
    
}

Penjelasan kode


Sekarang fokus ke method startThread() pada line 59. Di body method terdapat pernyataan if, pada line 61 - 62 yaitu:

if(gameRunning)
            return;

Ini artinya,jika game sudah berjalan maka jangan eksekusi kode berikutnya, yaitu kode di line 64 - 70. Dan jika game belum berjalan, maka gameRunning akan di set ke nilai true (line 64 di eksekusi) dan tentu saja kode di line 69 - 70 juga akan dieksekusi.

Perhatikan, kode di line 70, yaitu thread.start() akan memanggil method run().

Nah, apa yang dilakukan oleh method run() tersebut?

  • Pertama, method tersebut akan memanggil method inisialisasi yang akan menampilkan window game (line 47)
  • Kedua, method ini akan menjalankan loop ketika game berjalan, jadi method updateGame() dan render() akan terus dipanggil, selama parameter gameRunning bernilai true,(line 50-53). Secara default anda sudah mengatur nilai gameRunning bernilai false, lihat line 16.
  • Ketiga, ketika game berhenti atau gameRunning bernilai false maka method stopThread() akan dipanggil, lihat line 54.

Selanjutnya, anda bisa melihat body method stopThread(),line 75 - 88.

Perhatikan di line 75 - 76 ada pernyatan if:

if(!gameRunning)
           return;

Artinya adalah jika game tidak berjalan (false) maka kode di bawahnya tidak perlu dieksekusi, yaitu kode line 78 - 87. Sebaliknya,jika gameRunning itu bernilai true, maka gameRunning akan di set menjadi false, kemudian kode di bawahnya dieksekusi.

Menjalankan thread

Untuk menjalankan thread ini kita kembali ke class Main, yang memiliki main method.

Berikut ini adalah kode class Main tersebut dari tutorial sebelumnya:

package com.bahasajava.gamejava;

public class Main {
    //main method
    public static void main(String[] args) {
       new Game("My Java Game", 640, 360);
    }
    
}

Cobalah untuk menjalankan program dan anda tidak akan melihat window game tersebut.

Apa yang terjadi?

Ini dikarenakan anda tidak memanggil method startThread().

Dan method start ini adalah method objek. Jadi anda harus membuat objek Game terlebih dahulu untuk memanggil method tersebut.

Lihat kode di bawah ini untuk memanggil method startThread().

package com.bahasajava.gamejava;

public class Main {
    //main method
    public static void main(String[] args) {
       Game game = new Game("My Java Game", 640, 360);
       game.startThread();//objek Game memanggil method start thread
    }
    
}

Sekarang coba jalankan aplikasi lagi, anda akan melihat window game ditampilkan di layar. Namun sekarang anda sudah menggunakan thread.

Admin harap penjelasan in masuk akal dan mudah diterima oleh teman-teman meskipun agak rumit. Sampai di sini dulu ya. Pada tutorial berikutnya kita akan masuk ke BufferStrategy dan juga dasar grafik.

Baca juga:
Bagian 3

Share on Facebook
Share on Twitter
Share on Google+

Artikel Menarik Lainnya :