J2ME Game Dev #2: Graphics dan Moving Object

Materi kali ini tentang fungsi Graphics dan Moving Object. Setelah sebelumnya kita melakukan setting pada eclipse kita dan mencoba MIDlet pertama kita, sekarang kita coba untuk membuat gambar dan membuat gambar tersebut bergerak.

Sekarang mari kita mencoba membuat sebuah bola berwarna putih, di atas layar berwarna hitam. Kita akan membuat 2 file, yang pertama adalah MainMidlet.java yang berfungsi sebagai MIDlet utama yang dijalankan dan MainCanvas.java berfungsi untuk menampung kode-kode kita untuk menggambar objek. Mari kita bedah file satu persatu, dimulai dari MainCanvas.java.

1. Pertama buatlah sebuah kelas Java Me Midlet baru dengan nama MainCanvas.java. Ganti import kita menjadi seperti ini

import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.midlet.MIDlet;

file java kita nanti akan mengimport Graphics , GameCanvas, dan MIDlet agar kita dapat membuat gambar. Lalu kita buat main class kita inherit dari GameCanvas dan implements Runnable.

public class MainCanvas extends GameCanvas implements Runnable {

. Kita buat beberapa variabel global seperti ini

public MIDlet mainMidlet;
public Graphics g;
public static int SLEEP_TIME = 1000/30;

mainMidlet kita butuhkan untuk konstruktor, g digunakan untuk menggambar objeknya, sedangkan SLEEP_TIME berguna untuk mendefinisikan waktu sleep thread kita. Secara keseluruhan, kita memiliki 4 fungsi, yaitu:
1. Fungsi MainCanvas(), MainCanvas merupakan konstruktor, sekarang kita isi dengan kode berikut. Pertama-tama kita tulis parameter masukkan ini,

(MIDlet midlet)

Lalu isi dari konstruktor, kita isikan dengan ini,

super(false);
mainMidlet = midlet;
this.setFullScreenMode(true);

Kode di atas membuat aplikasi yang kita buat akan menjadi fullscreen mode. “mainMidlet = midlet” untuk membuat kita bisa mengakses fungsi yang ada di MainMidlet.

2. Fungsi mulai()
Pada fungsi mulai, kita tambahkan baris kode berikut,

	Thread runner = new Thread(this);
	runner.start();

Kode di atas merupakan fungsi untuk membuat thread baru untuk menjalankan canvas, runner merupakan instansiasi dari class Thread, sehingga runner bisa memanggil fungsi start().

3. Fungsi run()
Buat fungsi run(), fungsi ini merupakan hasil implements dari Runnable

public void run() {
	//isi kode...
}

Pada , kita instansiasikan dulu getGraphics ke g

g = getGraphics();

Dengan begini, g akan memiliki fungsi dari getGraphics(), seperti g.setColor(), g.fillRect(), dan lain-lain, lalu kita buat game loop di dalam fungsi run(),

while(true){
	//kode-kode....
}

semua kode-kode yang berada didalam loop tersebut akan di ulang terus menerus, untuk saat ini tidak ada kondisi yang membuat game ini berhenti, karena while(true). Coba kita masukkan

System.out.print("Testing dulu yah...")

Run emulator, maka akan terlihat di console seperti ini,

Game Loop

Lalu kita tambahkan kode berikut didalam game loop kita agar dapat menampilkan latar belakang hitam seperti ini,

g.setColor(0x000000);
g.fillRect(0, 0, getWidth(), getHeight());

Kode tersebut akan membuat sebuah kotak berwarna hitam, dimulai dari koordinat (0,0) sampai koordinat (getWidth(), getHeight()) (getWidth dan getHeight merupakan turunan dari GameCanvas).

drawCircle(50, 50, 40, 0xff0000);

Kode ini akan membuat game kita menggambar sebuah lingkaran, drawCircle merupakan fungsi yang kita buat sendiri, nanti kita akan bahas isi dari fungsi drawCircle(). Lalu kita tambah

flushGraphics();
try {
	Thread.sleep(SLEEP_TIME);
} catch (InterruptedException e) {
	e.printStackTrace();
}

flushGraphics() berguna agar ketika terjadi game loop, gambar akan terhapus dan tergambar ulang. Sedangkan fungsi Thread.sleep() berfungsi untuk memperlambat proses update gambar agar device tidak terlalu berat.

4. drawCircle()

public void drawCircle(int x, int y, int diameter, int color){
	g.setColor(color);
	g.fillArc(x-diameter/2, y-diameter/2, diameter, diameter, 0, 360);
}

Ini merupakan fungsi yang kita panggil sebelumnya, sebenarnya untuk membuat gambar lingkaran bisa dilakukan dengan memanggil fungsi fillArc dengan parameter masukan (int x, int y, int width, int height, int startAngle, int arcAngle)

x - koordinat x sudut kiri atas lingkaran yang akan di isi.
y - koordinat y sudut kiri atas lingkaran yang akan di isi.
width - lebar dari lingkaran yang akan di isi.
height - tinggi dari lingkaran yang akan di isi.
startAngle - awal dari sudut.
arcAngle - akhir dari sudut, misalkan startAngle 0 dan arcAngle 360 maka akan terbentuk lingkaran sempurna.

referenced

Setelah kita buat MainCanvas.java, sekarang mari kita rubah file MainMidlet.java. Yang kita butuhkan hanya menambahkan import ini,

import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.game.GameCanvas;

Lalu tambahkan ini di variable global

public MainCanvas canvas;

Masukkan ini di konstruktor

canvas = new MainCanvas(this);

Terakhir tambahkan ini di fungsi startApp()

Display display = Display.getDisplay(this);
display.setCurrent(canvas);
canvas.mulai();

Mari kita coba run aplikasi kita :D Kalau tidak ada masalah, harusnya keluar seperti di gambar,

Nah sekarang kita coba agar bola yang telah kita buat ini bisa bergerak :D , secara logika kita harus meng-update posisi dari bola kita secara dinamis. Kita tadi membuat drawCircle() dengan parameter masukan yang statis, yaitu 50. Sekarang kita modif file MainCanvas.java agar bola kita bisa bergerak,

public int ballX;
public int ballY;
public int speed_ballX;
public int speed_ballY;

masukan kode di atas sebagai variable global, lalu masukan kode berikut di fungsi run()

ballX = 60;
ballY = 60;
speed_ballX = 3;
speed_ballY = 3;

ballX dan ballY merupakan posisi awal dari sang bola, speed_ballX dan speed_ballY adalah kecepatan awal dari si bola. Lalu kita rubah drawCircle kita menjadi

drawCircle(ballX, ballY, 10, 0xffffff);

Dengan begitu, maka posisi awal dari bola adalah (60,60). Posisi bola sekarang sudah dinamis, kita bisa dengan mudah merubah posisi bola dengan merubah nilai dari ballX dan ballY. Karena kita ingin bola bergerak dengan kecepatan konstan maka kita gunakan kecepatan yang konstan juga yaitu speed_ballX dan speed_ballY.

ballX+=speed_ballX;
ballY+=speed_ballY;

Mari kita coba run aplikasi kita, pasti bola kita bergerak :D . Eh tapi kenapa bolanya malah meluncur keluar batas? Hilang tidak muncul lagi… :( Ya, itu karena kita belum memberikan collision detection, collision detection memungkinkan merubah arah bola ketika dia menabrak batas device kita, simpel saja sebenarnya hanya dengan menambah conditional saja,

if(ballX>getWidth()){
	speed_ballX*=-1;
}else if(ballX<0){
	speed_ballX*=-1;
}
if(ballY>getHeight()){
	speed_ballY*=-1;
}else if(ballY<0){
	speed_ballY*=-1;
}

Pada kode di atas, terlihat bahwa ada conditional yang mengecek apakah ballX > getWidth() , kalau hasilnya true berarti ballX sudah mencapai ujung kanan dari device kita, maka nilai dari speed_ballX yang awalnya positif (bergerak ke kanan) harus kita jadikan negatif (bergerak ke kiri), yaitu dikali -1. Jika ballX < 0 berarti ballX sudah mencapai batas kiri dari device kita, maka kita rubah lagi speed_ballX menjadi positif kembali dengan mengalikannya dengan -1 lagi. Begitu pula dengan ballY :D .

Yap itu adalah akhir dari sesi ini, selamat mencoba :D

Download Source Code: Project part 2

2 comments

Leave a Reply

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