Friday, January 9, 2009

JAVA 2D Graphics dan Animation (Part 1) - Games Engineering

Key topics pada pembahasan:
  • Full-screen Graphics
  • Images
  • Getting Rid of Flicker and Tearing
  • Simple Effects
  • Summary
Full-screen Graphics
Pembuatan games akan lebih interaktif dan menarik ketika kita menambahkan adanya user interface(graphic) dan animation. Tetapi dalam pembuatannya kita perlu membuat spesifikasi2 seperti berapa resolusi yang digunakan dan juga jangan sampai mengabaikan masalah refresh rate pada monitor.
Oke sekarang kita akan langsung melihat bagaimana hardware displai bekerja sebelum menginjak ke masalah programming. Secara garis besar ada dua bagian pada display hardware : video card dan monitor. Video card merepresentasikan apa yang ada di memorinya dan mempunyai fungsi2 untuk melakukan modifikasi pada apa yang ditampilkan. Memori card juga bekerja dibackground untuk mempush memorinya ke monitor. Sedangkan monitor akan menampilkan informasi yang diberikan oleh video card.

Screen Layout
Screen pada monitor sebenarnya akan dibagi dalan pixel warna kecil2 yang mempunyai ukuran sama. Perkalian dari pixel horizontal dan vertikal akan membuat sebuah ukuran screen yang kita sebut sebagai resolusi.
Screen akan dimulai dari pojok kiri atas, yang diperlihatkan pada gambar 1 dibawah ini. Pixel akan dimasukkan mulai dari pojok kiri atas, kemudian ke kanan dan seterusnya samapi ke pojok paling kiri bawah. Area pada screen bisa kita akses perdasarkan posisi koordinat (x, y), x merepresentasikan horizontal pixel dan y merepresentasikan vertical pixel.

gambar 1 ilustrasi pixel dalam screen 800x600.

Resolusi yang kita manipulasi sangat bergantung pada kemampuan video card dan monitor. Umumnya resolusi yang sering di pakai adalah 640x480, 800x600, 1024x768, 1280x1024.
Secara umum monitor dan televisi mempunyai size ratio 4:3. Yang berarti tinggi dari monitor adalah 3/4 dari ukuran lebarnya. Beberapa monitor yang baru dibuat dalam wides creen dengan display size retio 3:2 atau 16:10 dan 16:9(untuk wide screen movie).

Warna Pixel dan Kedalaman Bit
Warna primer ada tiga merah, kuning, dan biru. Mungkin kita masih ingat dengan percampuran warna, "kuning + biru = hijau." Idenya adalah kita bisa memanipulasi warna-warna tersebut menjadi warna yang lain yang kita inginkan. Model semacam ini sering disebut sebagai subtractive color model, dan percampuran semua warna akan mejadi putih.
Ini sama sebagaimana monitor komputer dan televisi bekerja. Monitor mengkombinasikan merah, biru dan hijau untuk membuat banyak warna lain.
Warna2 pada monitor dapat ditampilkan tergantung pada kedalaman bit-nya. Secara umum kedalaman bit yang sering digunakan adalah 8,15, 16, 24, dan 32 bit.
  • Warna 8-bit mempunyai 2^8=256 warna. Hanya 256 warna yang bisa ditampilkan pada suatu waktu.
  • Warna 15-bit mempunyai 5 bit untuk merah, biru dan hijau, totalnya ada 2^15=32,768 warna.
  • Warna 16-bit mempunyai 5 bit untuk merah dan biru, dan 6 bit untuk hijau, totalnya ada 2^16=65,536 warna.
  • Waran 24-bit mempunyai 8 bit untuk merah, hijau dan biru, total ada 2^24=16,777,216 warna.
  • Warna 32-bit mempunyai warna sama dengan 24 bit, tetapi ditambah dengan extra 8 bit sebagai padding.
Video card saat ini sudah mendukung 8-, 16-, dan 32-bit. Karena disesuikan dengan mata manusia dapat melihat sampai 10 miliar warna, 24-bit ideal digunakan. 16-bit sedikit lebih cepat dari pada 24-bit karena data yang ditransfer juga lebih sedikit, tetapi kualitas warnanya tidak akurat.

Refresh Rate
Bagaimana monitor bisa menampilkan pixel seperti gambar beneran ?, sebenarnya setiap pixel akan menghilang setelah beberapa milisecond. Untuk tetap menjaga agar bisa tetap ditampilkan, maka monitor akan secara berkelanjutan melakukan refresh pada display biar tidak menghilang. Kecepatan melakukan refresh ini yang disebut sebagai refresh rate. Refresh rate mempunyai satuan Hertz (Hz), yang berarti cycles per second. Refresh rate antara 75Hz dan 85Hz sesuai untuk mata manusia.

Switching Display ke Mode Full-Screen
Sekarang kita sudah mengetahui tentang konsep resolusi, kedalaman warna, dan refresh rate, sekarang tinggal masuk koding. Di dalam java kita membutuhkan beberapa object untuk merubah ke mode full-screen, sebagai berikut:
  • Window object. Window object adalah abstraksi dari apa yang ditampilkan ke layar, anggaplah sebuah kanvas untuk menggambar. Kita akan memanfaatkan JFrame, yang merupakan subclass dari Windows class dan dapat juga digunakan untuk membuat applikasi windowed.
  • DisplayMode object. DisplayMode object digunakan untuk spesifikasi resolusi, kedalaman bit, dan refresh rate untuk switch display.
  • GraphicsDisplay object. GraphicsDislay object digunakan untuk merubah display mode dan melihat display properti. Bayangkan saja ini sebagai video card. GraphicsDisplay object diperoleh dari GraphicsEnvironment object.

Berikut adalah contoh untuk melakukan switch ke mode full-screen:
JFrame window = new JFrame();
DisplayMode displayMode = new DisplayMode(800, 600, 16, 75);

// mendapatkan GraphicsDevice
GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice device = environment.getDefaultScreenDevice();
// menggunakan JFrame untuk full screen window
device.setFullScreenWindow(window);
// mengubah display mode
device.setDisplayMode(displayMode);
Setelah itu jika ingin mengembalikan pada resolusi semula, set full-screen window dengan nilai null:
device.setFullScreenWindow(null);
Kadang pada sistem tertentu tidak mengijinkan kita untuk mengubah mode display, dan saat kita melakukan pemanggilan pada setDisplayMode() akan menampilakan IllegalArgumentException.

Oke sekarang kita akan membuat class wrapper untuk memudahkan dalam pembuatan mode full-screen simpan dengan nama SimpleScreenManager.java, listing programmnya sebagai berikut:
import java.awt.*;
import javax.swing.JFrame;
/**
SimpleScreenManager class menangani inisialisasi dan
menampilkan mode full-screen.
*/
public class SimpleScreenManager {
private GraphicsDevice device;
/**
Membuat SimpleScreenManager object.
*/
public SimpleScreenManager() {
GraphicsEnvironment environment =
GraphicsEnvironment.getLocalGraphicsEnvironment();
device = environment.getDefaultScreenDevice();
}
/**
Memasukkan full screen mode and mengubah display mode.
*/
public void setFullScreen(DisplayMode displayMode,
JFrame window)
{
window.setUndecorated(true); // menghilangkan border
window.setResizable(false);
device.setFullScreenWindow(window);
if (displayMode != null &&
device.isDisplayChangeSupported())
{
try {
device.setDisplayMode(displayMode);
}
catch (IllegalArgumentException ex) {
// illegal mode untuk device
}
}
}
/**
Mengembalikan window yang sedang digunakan pada full screen mode.
*/
public Window getFullScreenWindow() {
return device.getFullScreenWindow();
}
/**
Mengembalikan display mode semula.
*/
public void restoreScreen() {
Window window = device.getFullScreenWindow();
if (window != null) {
window.dispose();
}
device.setFullScreenWindow(null);
}
}
Selanjutnya kita akan membuat kode untuk melakukan test menggunakan SimpleScreenManager, yang menerima parameter berupa ukuran resolusi yang digunakan dan kedalaman bit. Untuk menjalankannya dengan cara sebagai berikut :
java FullScreenTest 1024 768 32 ------> berarti merubah ke fullscreen mode menjadi 1024x768 dengan kedalaman bit 32-bit.

Perlu diingat jangan menggunakan resolusi yang tidak disupport oleh system, karen program tidak akan jalan. Berikut adalah kode program untuk melakukan test FullScreenTest.java :
import java.awt.*;
import javax.swing.JFrame;
public class FullScreenTest extends JFrame {
public static void main(String[] args) {
DisplayMode displayMode;
if (args.length == 3) {
displayMode = new DisplayMode(
Integer.parseInt(args[0]),
Integer.parseInt(args[1]),
Integer.parseInt(args[2]),
DisplayMode.REFRESH_RATE_UNKNOWN);
}
else {
displayMode = new DisplayMode(800, 600, 16,
DisplayMode.REFRESH_RATE_UNKNOWN);
}
FullScreenTest test = new FullScreenTest();
test.run(displayMode);
}
private static final long DEMO_TIME = 5000;
public void run(DisplayMode displayMode) {
setBackground(Color.blue);
setForeground(Color.white);
setFont(new Font("Dialog", Font.PLAIN, 24));
SimpleScreenManager screen = new SimpleScreenManager();
try {
screen.setFullScreen(displayMode, this);
try {
Thread.sleep(DEMO_TIME);
}
catch (InterruptedException ex) { }
}
finally {
screen.restoreScreen();
}
}
public void paint(Graphics g) {
g.drawString("Hello World!", 20, 50);
}
}
Berikut adalah hasil screenshot running programnya :


Anti Aliasing
Kita bisa memanfaatkan anti aliasing untuk membuat tulisan "Hello World!" menjadi lebih smooth, karena dengan anti aliasing kita bisa melakukan blending antara text dengan background. Ubah kode menjadi sebagai berikut:
public void paint(Graphics g) {
if (g instanceof Graphics2D) {
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(
RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
}
g.drawString("Hello World!", 20, 50);
}
Mode Mana yang Sebaiknya digunakan?
Banyak pilihan resolusi yang dapat digunakan, tetapi yang mana yang seharusnya digunakan untuk running game yang kita buat?
Oke, sebaiknya game yang kita develop berjalan minimal pada dua resolusi, sehingga player akan menentukan sendiri resolusi mana yang cocok digunakan.
Jika memungkinkan, inisialisasi game yang kita develop sesuai dengan resolusi monitor yang digunakan, sehingga game display akan ditampilkan dengan bagus. Penggunaan kedalaman warna 16-, 24-, atau 32-bit warna adalah ide yang bagus. 16-bit warna akan berjalan sedikit lebih cepat, tetapi gunakanlah resolusi yang lebih besar jika menginginkan representasi warna yang akurat. Gunakan refresh rate antara 75Hz dan 85Hz karena sesuai dengan mata manusia.

Reference :
  • http://java.sun.com
  • David Brackeen, Bret Barker, Laurence Vanhelsuwé, Developing Games in Java, 2003, New Riders Publishing

No comments:

Post a Comment