Anda di halaman 1dari 114

 

2008 
 

   

Pocong Document 
http://pocong.wordpress.com/ 
 
 
 

echo.khannedy@gmail.com 
http://pocong.wordpress.com/ 
8/27/2008 
J.E.N.I.

Pemrograman
Game JAVA

Versi 1.1
February 2007
Pemrograman Game Java

Pemrograman Game Java


J.E.N.I.

Team Penyusun:
1. Eko Subiantoro, S.Pd, SST

2. Maulana Azis Asuja

3. Sajarwo Anggai

Referensi:
Harbour, S, Jonathan. 2006. Begining Java 5 Game Programing. United States
of America: Course Technology Inc

Brackeen, David@All. 2003. Developing Game in Java. United States of


America: New Riders Publishing

Davison, Andrew. 2005. Killer Game Programing. United States of America :


O’Reilly Media.

Mulholland, Andrew, dan Murphy, Glenn. 2003. Java 1.4 Game Programing.
Texas : Wordware Publishing.

Pemrograman Game Java


J.E.N.I.
BAB 1
PENGENALAN GAME

1.1 Pendahuluan

Perancangan dan pembuatan sebuah game membutuhkan imajinasi

atau wawasan yang luas. Apa yang terjadi apabila seorang programer

langsung membuat game tanpa harus mengenal seluk-beluk dari sebuah game

yang akan dibangun?, untuk itu perlu adanya penjelasan atau sosialisasi

tentang game yang nantinya cukup untuk membuka wawasan ketika seorang

programer membuat sebuah game. Sebelum melangkah lebih jauh, pada

bahasan ini kita terlebih dahulu mengenalkan seluk beluk dari sebuah game

yang akan memberikan gambaran ketika membuat sebuah game.

1.2 Tujuan

Setelah mempelajari modul ini peserta diharapkan dapat:

• Mengetahui Jenis-Jenis Game.

• Mengetahui Sejarah dari Permainan(vidio game).

• Mengetahui berbagai macam game di J2SE.

1.3 Game (Permainan)

Permainan merupakan sebuah aktivitas rekreasi dengan tujuan

bersenang-senang, mengisi waktu luang, atau berolahraga santai. Permainan

biasanya dilakukan sendiri atau bersama-sama. Permainan sendiri terbagi

menjadi 3 bagian yaitu:

1. Permainan anak-anak

Pemrograman Game Java 1


J.E.N.I.
Di lingkungan yang masih terlihat keakraban antar anggota masyarakat,

banyak permainan yang dilakukan oleh anak-anak secara beramai-ramai

dengan teman-teman mereka di halaman atau di teras rumah. Mereka

berkelompok, berlarian, atau duduk melingkar memainkan salah satu

permainan dan tercipta keakraban. Beberapa permainan ini karena tercipta di

masa yang lama berlalu disebut dengan permainan tradisional, sedangkan di

sisi lain beberapa permainan yang lebih akhir (dan biasanya menggunakan

peralatan yang canggih) disebut permainan modern.

• Bentengan • Goncang Kaleng • Main Hadang

• Boneka • Kasti • Petak Umpet

• Congkak • Layangan • Yoyo

2. Permainan Dewasa

• Kartu Remi atau Bridge • Kuis

• Catur • Sudoku

• Domino • Balap karung

3. Permainan Vidio

Permainan video (bahasa Inggris: video game) adalah permainan yang

menggunakan interaksi antarmuka pengguna melalui gambar yang dihasilkan

oleh piranti video. Permainan video umumnya menyediakan sistem

penghargaan–misalnya skor–yang dihitung berdasarkan tingkat keberhasilan

yang dicapai dalam menyelesaikan tugas-tugas yang ada di dalam permainan.

Sistem elektronik yang digunakan untuk menjalankan permainan video disebut

platform, contohnya adalah komputer pribadi dan konsol permainan.

Pemrograman Game Java 2


J.E.N.I.
a) Permainan Komputer

Permainan komputer (bahasa Inggris: computer game) adalah

permainan video yang dimainkan pada komputer pribadi, dan bukan pada

konsol permainan, maupun mesin ding-dong. Permainan komputer telah

berevolusi dari sistem grafis sederhana sampai menjadi kompleks dan

mutakhir.

Permainan online (bahasa Inggris: online game) adalah jenis permainan

video atau permainan komputer dengan menggunakan jaringan komputer,

umumnya internet, sebagai medianya. Permainan online terdiri dari dua unsur

utama, yaitu server dan client. Server adalah penyedia layanan gaming yang

merupakan basis agar client-client yang terhubung dapat memainkan

permainan dan melakukan komunikasi dengan baik. Suatu server pada

prinsipnya hanya melakukan administrasi permainan dan menghubungkan

client-client. Sedangkan client adalah pengguna permainan dan memakai

kemampuan server. Contoh permainan online adalah Ragnarok Online, Risk

Your Life, Xian dll.

Ragnarok Online adalah sebuah MMORPG (Massively Multiplayer

Online Role Playing Game) dari Korea Selatan yang dibuat berdasarkan cerita

dan latar belakang yang sama dari komik korea terkenal berjudul "Ragnarok"

yang ditulis oleh Lee Myoung-Jin.Komik ini kemudian dikembangkan menjadi

sebuah game online yang memfokuskan fitur komunitas antar pemainnya.

Game ini dibuat oleh Gravity Corporation. Hampir seluruh versi resmi (official)

RO sudah memasuki masa komersil di mana pemain harus membayar untuk

bermain (pay-to-play). Perlu dibedakan, terdapat pula private server yang

Pemrograman Game Java 3


J.E.N.I.
merupakan server tidak official ilegal dan tidak ada toleransi dari Gravity serta

penyelenggara RO di seluruh belahan dunia.

b) Konsol Permainan

Konsol permainan atau Game Console adalah sebuah mesin elektronik

yang dirancang khusus untuk memainkan permainan video. Perangkat

keluarannya biasa berupa monitor komputer atau televisi. Alat masukan

utamanya berupa sebuah pengendali. Konsol permainan yang pertama kali di

buat adalah Atari, kemudian dilanjutkan dengan Nintendo yang sukses pada

tahun 1985-1989. Konsol permainan modern sekarang ini antara lain adalah

Playstation buatan perusahaan Sony. Untuk Console yang berbentuk kecil dan

dapat dibawah kemana-mana biasa disebut Portable Console. Berikut ini

adalah Generasi dari Game Console:

 Generasi Kedua

Atari 2600

Atari 2600 adalah konsol permainan video sukses yang pertama yang

mampu mengganti kaset permainan selain daripada yang biasanya hanya

memiliki 1 atau lebih permainan yang telah ada secara permanen tertanam di

dalam konsol permainan. Pertama kali Atari 2600 dirilis bulan Oktober 1977

dan dikenal dengan nama Atari VCS (Video Computer System) dan kemudian

berganti nama menjadi Atari 2600.

Atari 5200

Atari 5200 Super System, atau biasa hanya disebut Atari 5200, adalah

konsol permainan video yang pertama kali diperkenalkan pada tahun 1982

oleh Atari, sebagai generasi penerus dari konsol permainan Atari 2600. Atari

Pemrograman Game Java 4


J.E.N.I.
5200 dibuat untuk menyaingi konsol Mattel Interlllivision, tetapi kemudian lebih

bersaing dengan Colecovision setelah perilisan Atari 5200. Konsol ini secara

teknologi lebih unggul dan pengeluaran biaya yang lebih efisien dibanding

konsol lain yang ada waktu itu. Tetapi, sejumlah cacat dan kekurangan pada

konstruksi menyebabkan dampak serius pada penggunaannya dan sistem ini

secara umum dianggap gagal.

 Generasi Ketiga

Atari 7800

Atari 7800 adalah konsol permainan video yang di rilis oleh Atari pada

bulan Juni 1986. Atari 7800 di desain untuk menggantikan konsol Atari 5200

yang kurang sukses di pasaran, dan bertujuan untuk mendirikan lagi supremasi

pasar Atari melawan Intellivision and Colecovision. Dengan sistem konsol ini,

Atari menanggapi semua kekurangan Atari 5200 memiliki joystick yang simpel,

kompatibel penuh dengan sistem konsol sebelumnya yaitu Atari 2600 dan

dapat digunakan sebagai hadiah (karena harganya pada waktu itu $140).

Nintendo Entertainment System (NES)

Nintendo Entertainment System, atau NES, adalah sebuah konsol

permainan video 8-bit yang dirilis oleh Nintendo di Amerika Utara, Brasil,

Eropa, Asia dan Australia. Versi Jepangnya dikenal dengan nama Nintendo

Family Computer atau Famicom. Di Rusia ia dinamakan Dendy. Menjadi konsol

permainan paling populer saat itu di Asia dan Amerika Utara, NES membantu

menghidupkan kembali industri permainan video setelah kerobohan permainan

video tahun 1983, dan menetapkan seluruh standar bagi konsol-konsol

Pemrograman Game Java 5


J.E.N.I.
berikutnya mulai desain permainan (permainan platform modern pertama,

Super Mario Bros, merupakan killer game pertama sistem ini) sampai ke pola

bisnis.

 Generasi Keempat

Sega Mega Drive

Sega Mega Drive adalah konsol permainan video yang dirilis oleh Sega

di Jepang pada tahun 1988 dengan kemampuan 16-bit, dan dirilis di Amerika

Utara pada tahun 1989. Sementara di Eropa dan tempat lainnya dirilis tahun

1990. Pada permulaannya di Amerika Utara, konsol ini menggunakan nama

Sega Genesis, karena Sega gagal untuk mendapat hak-hak hukum

menggunakan nama Mega Drive di wilayah itu. Sega Mega Drive adalah

saingan dari Super Famicom (Super Nintendo), walaupun Sega Mega Drive

telah dirilis 2 tahun lebih awal. Jumlah unit yang terjual adalah 29 juta, dan

perangkat lunak permainan yang paling terkenal adalah Sonic the Hedgehog.

Super Nintendo Entertainment System

Super Nintendo Entertainment System, dikenal juga dengan Super

Nintendo, Super NES or SNES, adalah konsol permainan video 16-bit yang

dirilis oleh Nintendo di Amerika Utara, Brasil, Eropa dan Australia. Di Jepang ia

dikenal dengan nama Super Famicom (Family Computer),di Korea Selatan ia

dikenal dengan nama Super Comboy dan didistribusikan oleh Hyundai

Elecronics.

 Generasi Kelima

Pemrograman Game Java 6


J.E.N.I.
3DO Interactive Multiplayer

3DO Interactive Multiplayer (umumnya disebut 3DO) adalah sebuah

konsol permainan video yang dirilis pada tahun 1993 dan 1994 oleh Panasonic,

Sanyo, dan Goldstar, disamping beberapa perusahaan lainnya. Konsol ini

dibuat menurut spesifikasi yang dibuat oleh perusahaan 3DO, dan didesain

oleh Dave Needle dan RJ Mical dari New Technology Group. Sistem konsol ini

disusun oleh pengusaha dan pemilik perusahaan EA Games. Dikarenakan

promosi peluncuran yang terlalu besar dan biaya pembuatan/teknologi yang

besar, konsol ini menjadi mahal ($699.95 dollar Amerika saat dirilis), membawa

3DO segera bangkrut dengan cepat.

Sega Saturn

Sega Saturn adalah konsol permainan video buatan Sega yang

mempunyai kemampuan 32 bit. Pertama kali diluncurkan pada 22 November

1994 di Jepang, tanggal 11 Mei 1995 di Amerika Utara dan 8 Juli 1995 di

Eropa. Konsol ini bertahan di Amerika Utara dan Eropa sampai akhir 1998, dan

di Jepang sampai akhir tahun 2000. Game terakhir yang dirilis untuk konsol ini

adalah Yukyu Gensokyoku Perpetual Collection, yang dirilis oleh Mediaworks

bulan desember 2000. Beberapa judul permainan yang terkenal adalah Sonic

the Hedgehog, Super Monkey Ball, Crazy Taxi, Virtua Fighter, Phantasy Star

Nintendo 64

Nintendo 64 atau dikenal juga N64 merupakan konsol game generasi ke

lima yang dikeluarkan oleh Nintendo, bekerja sama dengan produsen

workstation Silicon Graphics Inc.

Pemrograman Game Java 7


J.E.N.I.
Nintendo 64 sangat revolusioner di masanya dengan memperkenalkan

teknologi-teknologi baru yang kemudian diikuti oleh para pesaingnya seperti

Sony PlayStation dan Sega Saturn. Teknologi tersebut antara lain teknologi

getar Rumble Pak (yang kemudian dikenal dalam PlayStation sebagai

DualShock) serta memperkenalkan stik analog yang memungkinkan pemain

menjelajahi ruang 3-D dengan lancar. Teknologi stik analog membuka babak

baru dalam pengontrolan dari ruang 2-D ke ruang 3-D, dan sangat sukses

sehingga kompetitor lain seperti Sony PlayStation dan Sega Saturn mengikuti

Nintendo dengan menyertakan stik analog dalam konsol game buatan mereka.

Nintendo 64 juga merupakan console game pertama yang menyertakan

fungsi Anti-Aliasing dengan filter bilinear secara real-time.Selain itu, Nintendo

64 juga mendapat posisi pertama dan terpilih sebagai console game terbaik

dalam G4 baru baru ini dalam acara 10 Konsol Game Terbaik.

Nintendo 64 kurang dikenal luas di Indonesia, salah satu penyebabnya

karena Nintendo 64 menggunakan medium cartridge/kaset untuk menyimpan

data, yang lebih mahal dan lebih susah dicopy/dibajak dibandingkan dengan

medium CD yang digunakan oleh PlayStation dan Sega Saturn.Pengembangan

software Nintendo 64 berakhir pada tahun 2001 setelah rilis sekitar 350 judul

game dan 40 juta unit Nintendo 64 terjual.

PlayStation

PlayStation adalah konsol permainan grafis dari era 32-bit. Pertama kali

diproduksi oleh Sony sekitar tahun 1990. PlayStation diluncurkan perdana di

Jepang pada 3 Desember 1994, di Amerika Serikat 9 September 1995 dan

Eropa 29 September 1995. PlayStation menjadi sangat terkenal sehingga

Pemrograman Game Java 8


J.E.N.I.
membentuk "Generasi PlayStation". Dari sekian banyak game PlayStation,

beberapa yang terkenal adalah: Tomb Raider, Final Fantasy, Resident Evil,

Tekken, Winning Eleven, Ridge Racer, wipEout, Gran Turismo, Crash

Bandicoot, Spyro, dan seri Metal Gear Solid. Pada 18 Mei 2004, Sony telah

memproduksi 100 juta PlayStation dan PSOne ke seluruh dunia. Pada Maret

2004, sebanyak 7.300 judul permainan telah tersedia dengan jumlah akumulasi

949 juta.

Emulation di PC untuk PS

Saat ini hampir semua game PlayStation dapat dimainkan di PC. Hal ini

dapat dicapai dengan bantuan Emulator. Emulator yang paling terkenal adalah

ePSXe. ePSXe bekerja dengan konsep Plug-In, yang berarti user harus

pertama-tama meload Plug-In grafik atau suara ke memori. Selain itu ePSXe

juga hanya dapat bekerja menggunakan BIOS original PlayStation, yang bisa

ditransfer ke PC menggunakan kabel khusus.

 Generasi Keenam

PlayStation 2

PlayStation 2 (PS2) adalah konsol video game kedua dari Sony, setelah

PlayStation. Pengembangannya diumumkan pada April 1999, dan diedarkan

pertama kali di Jepang pada 4 Maret 2000. Versi AS dilepas pada 26 Oktober

2000. Di tahun pertama PlayStation 2 mengalami penjualan yang relatif sedikit,

namun saat ini telah tumbuh menjadi konsol game paling populer dengan

terjualnya 90 juta unit

Pemrograman Game Java 9


J.E.N.I.
Sega Dreamcast

Sega Dreamcast adalah konsol permainan buatan Sega generasi kelima

dan merupakan penerus dari konsol permainan Sega Saturn dan konsol

permainan terakhir buatan perusahaan Sega. Dengan tujuan untuk mengambil

kembali pasar konsol permainan, Dreamcast di desain untuk menggantikan

Playstation dan Nintendo 64. Dreamcast di rilis 15 bulan sebelum peluncuran

Playstation 2 (PS2) dan 3 tahun sebelum Nintendo Gamecube dan Microsoft

Xbox. Dreamcast secara umum dianggap mengungguli waktu itu dan pada

permulaannya berhasil mengembalikan reputasi Sega pada industri permainan.

Tetapi, Dreamcast gagal untuk menarik kepesatan konsumen sebelum perilisan

Playstation 2 pada bulan maret 2000 dan Sega akhirnya memutuskan untuk

menghentikan Dreamcast tahun selanjutnya, dan meninggalkan bisnis konsol

permainan video.

Nintendo GameCube

Nintendo GameCube awalnya bernama sandi Dolphin saat

pengembangan, resmi disingkat menjadi GCN oleh Nintendo Amerika) adalah

konsol permainan rumah keempat dari Nintendo, dan masuk dalam permainan

video generasi keenam—satu generasi dengan Sega Dreamcast, Sony

PlayStation 2 dan Microsoft Xbox. GameCube sendiri adalah konsol generasi

keenam yang paling kecil dan murah. GameCube dirilis pada 14 September

2001 di Jepang; 18 November 2001 di Amerika Utara; 3 Mei 2002 di Eropa;

dan 17 Mei 2002 di Australia.

Xbox

Pemrograman Game Java 10


J.E.N.I.
Xbox adalah konsol permainan video generasi ke-6 buatan Microsoft,

dan merupakan konsol permainan video pertama bagi perusahaan Microsoft.

Pertama kali dirilis tanggal 15 November 2001 di Amerika Utara, tanggal 22

Februari 2002 di Jepang, dan 14 Maret 2002 di Eropa. Xbox adalah pendahulu

dari konsol Xbox 360. Beberapa judul perangkat lunak permainan yang terkenal

untuk konsol ini adalah Halo: Combat Evolved, Amped: Freestyle

Snowboarding, Dead or Alive 3, Project Gotham Racing, dan Oddworld:

Munch's Oddysee. Sistem penyimpanan konsol Xbox adalah Harddisk dan

Memory Card.

 Generasi Ketujuh

Playstation 3

PLAYSTATION 3, disingkat PS3 adalah konsol Sony generasi ketiga.

PlayStation 3 adalah penerus dari PlayStation dan PlayStation 2 dan akan

bersaing dengan Xbox 360 dari Microsoft dan Wii dari Nintendo.

PlayStation 3 dirilis di Jepang pada tanggal 11 November 2006 tepat

pukul tujuh, dan akan dirilis pada tanggal 17 November 2006 di Amerika Utara

(Amerika Serikat dan Kanada), Hong Kong dan Taiwan, dan 1 atau 7 Maret

2007 di Eropa dan Australasia, dan wilayah PAL lainnya. PlayStation 3 akan

dirilis dengan 2 tipe, Basix dan Premium/Platinum. PlayStation 3 secara resmi

diperkenalkan kepada dunia pada tanggal 16 Mei 2005 di E3. Konfigurasi final

pertama dipertunjukkan di Tokyo Game Show 2006.

Teknologi terbaru yang digunakan adalah cell processornya, tipe

prosesor yang benar-benar dioptimalkan untuk melakukan operasi floating

point. Kemampuan cell processor untuk melakukan operasi floating point

Pemrograman Game Java 11


J.E.N.I.
sangat baik karena cell processor merupakan arsitektur vektor processor.

Selain itu GPU dibuat sendiri bekerjasama dengan NVidia.

Wii

Wii adalah konsol permainan video kelima Nintendo yang merupakan

penerus Nintendo GameCube. Inovasi utamanya adalah kontroler (joystick)

yang merespon terhadap letaknya dalam ruang fisik tiga dimensi yang terletak

di depan televisi. Pada tahap awal pengembangan, konsol ini diberi nama

Revolution.

Konsol ini diperkenalkan dalam Tokyo Game Show 2005 pada 16

September 2005. Konsol ini dirilis pada November 2006 di AS dan Desember di

Jepang dan beberapa wilayah lainnya, dan bersaing dengan PlayStation 3 dan

Xbox 360.

Berbeda dari Xbox 360 dan PlayStation3, Wii lebih menitik beratkan

pada keasyikan bermain dibandingkan tampilan grafik beresolusi tinggi seperti

yang dimiliki kedua konsol tersebut. Wiimote merupakan kontroler baru yang

unik (yang dilengkapi sebuah Nunchuk sebagai kontroler tambahan untuk

beberapa jenis game), bentuknya yang kecil, serta harga yang murah

merupakan hal-hal yang menjadi keunggulan konsol ini dibandingkan kedua

konsol saingannya.

Wii merupakan konsol game generasi baru dengan harga rilis termurah

dibandingkan para pesaingnya. Di Jepang, Wii diluncurkan dengan harga JP

¥25.000 sementara di AS seharga $249,99. Kecuali di Jepang, Wii dijual satu

paket dengan Wii Sports, sebuah game olah raga (tennis, baseball, bowling,

Pemrograman Game Java 12


J.E.N.I.
golf, boxing) yang ditujukan untuk memperkenalkan pengguna Wii kepada gaya

permainan terbarunya.

Wii mempunyai kompatibilitas lama (backward compatibility) dengan

beberapa konsol lama Nintendo dan Sega, termasuk NES, TurboGarfx-16,

SNES, Genesis, Nintendo 64 dan GameCube. Kompatibilitas dengan

GameCube dicapai dengan diadakannya slot bagi CD berukuran 8 cm seperti

yang digunakan GameCube, sementara untuk yang konsol lainnya hal ini

diperoleh melalui jasa konsol virtual (Virtual Console) yang merupakan salah

satu fitur Wii. Melalui Virtual Console, pengguna Wii dapat membeli dan

mengunduh game-game lama dan dimainkan langsung di Wii melalui channel

Wii Shop.

Semenjak peluncurannya, jumlah Wii yang terjual jauh melampaui angka

penjualan Playstation 3 dan hampir mendekati angka penjualan Xbox 360 yang

sudah diluncurkan setahun sebelumnya. Penjualan Wii mengalahkan penjualan

Playstarion 3 dengan perbandingan 2:1 di Amerika Serikat dan 4:1 di Jepang,

serta 3:1 di seluruh dunia.

Xbox 360

Xbox 360 ("tiga-enampuluh"), yang pada saat pengembangan dikenal

dengan nama Xenon atau Xbox 2, adalah penerus konsol permainan video

Xbox milik Microsoft. Microsoft secara resmi memperkenalkannya di MTV pada

12 Mei 2005, dan informasi detil mengenai peluncuran dan permainan

dibeberkan di akhir bulan yang sama dalam Expo Electronic Entertainment (E3)

yang terkenal. Saat dirilis pada 22 November 2005 di Amerika Utara dan

Puerto Rico, 2 Desember 2005 di Eropa dan 10 Desember 2005 di Jepang,

Pemrograman Game Java 13


J.E.N.I.
Xbox 360 menjadi konsol pertama yang diluncurkan berbarengan untuk tiga

daerah besar. Ia juga merupakan produk pertama konsol permainan generasi

terbaru dan akan bersaing dengan Sony PlayStation 3 dan Nintendo Wii. Xbox

360 adalah konsol pertama yang dapat memutar film HD-DVD dengan membeli

paketnya terlebih dahulu, yang akan direlease kemudian. Xbox 360 juga adalah

konsol pertama yang menggunakan stik wireless. Andalan Xbox 360 adalah

grafis dan kemampuan onlinenya. Xbox Live adalah salah satu fitur online yang

ditawarkan Microsoft selaku produsennya.

1.4 Role Playing Game

Role-Playing Game atau disingkat RPG adalah sebuah permainan di

mana para pemain memainkan peran tokoh-tokoh khayalan dan berkolaborasi

untuk merajut sebuah cerita bersama. Para pemain memilih aksi tokok-tokoh

mereka berdasarkan karakteristik tokoh tersebut, dan keberhasilan aksi mereka

tergantung dari sistem peraturan permainan yang telah ditentukan. Asal tetap

mengikuti peraturan yang ditetapkan, para pemain bisa berimprovisasi

membentuk arah dan hasil akhir permainan ini.

Pada sebuah permainan RPG, jarang ada yang "kalah" atau "menang".

Ini membuat permain RPG berbeda dari jenis permainan papan lainnya seperti

Monopoli atau Ular Tangga, permainan kartu, olah raga, dan permainan

lainnya. Seperti sebuah novel atau film, permainan RPG mempunyai daya tarik

karena permainan-permainan ini mengajak para pemain untuk menggunakan

imajinasi mereka. RPG biasa lebih mengarah ke kolaborasi sosial daripada

kompetisi. Pada umumnya dalam RPG, para pemain tergabung dalam satu

kelompok.

Pemrograman Game Java 14


J.E.N.I.
Permainan RPG rata-rata dimainkan seperti sebuah drama radio: ketika

seorang pemain "berbicara", dia berbicara sebagai tokohnya dan ketika si

pemain ingin tokohnya melakukan sesuatu yang fisik (seperti menyerang

sebuah monster atau membuka sebuah gembok) dia harus

menggambarkannya secara lisan.

Ada pula sejenis permainan RPG di mana para pemain bisa melakukan

gerakan fisik tokohnya oleh si pemain sendiri. Ini disebut Live-Action Role-

playing atau LARP. Dalam permainan LARP, biasanya para pemain memakai

kostum dan mengunakan alat-alat yang sesuai dengan tokoh, dunia dan cerita

yang dia mainkan.

Permainan PC yang mengunakan unsur-unsur dan mekanisme

permainan RPG disebut sebagai computer role-playing games atau CRPG.

Selain di PC, RPG juga banyak diadaptasikan ke mesin-mesin permainan atau

konsol, yang disebut console role-playing games, disingkat cRPG. Dengan

meningkatnya popularitas RPG elektronik, industri permainan video telah

membuat istilah RPG dikenal untuk RPG elektronik saja, dan mengakibatkan

munculnya istilah RPG "pen and paper" atau "tabletop" untuk mendeskripsikan

RPG tradisional.

Sebelum memulai sebuah permainan RPG, ada beberapa hal yang

harus dipersiapkan. Pertama, para pemain harus memilih sebuah buku

peraturan (rulebook) dan, kadang kala, sebuah buku dunia (campaign setting)

yang akan mereka gunakan. Tahap ini sangat penting karena buku-buku ini

akan menentukan jenis-jenis tokoh yang bisa dimainkan (ksatria, penyihir,

mata-mata, ninja, polisi, dan lainnya), kepandaian-kepandaian (skill) yang bisa

seseorang gunakan termasuk mantera sihir (spell), peraturan pertempuran dan

Pemrograman Game Java 15


J.E.N.I.
perincian-perincian dunia khayalan yang akan digunakan (sejarah, geografi,

nama raja-raja, negeri-negeri penting, orang-orang penting dan lainnya).

Ada pula buku-buku lain yang bisa digunakan seperti daftar-daftar

monster (contohnya adalah "Monster Manual" dari permainan Dungeons &

Dragons), buku peraturan tambahan (peraturan pertempuran yang lebih

terperinci dan kompleks, mantera-mantera baru, senjata dan jenis tokoh baru),

buku-buku dunia yang lebih terperinci (contohnya adalah buku "Silver Marches"

dari dunia Forgotten Realms yang menggambarkan sejarah, geografi, politik

negeri Silver Marches yang lebih lengkap dari buku dunia Forgotten Realms).

Tentunya, buku-buku ini tidak wajib untuk bermain, tapi bisa memberikan detil-

detil dalam permainan yang bisa membuat sebuah dunia khayalan lebih

menarik atau realistis.

1.5 Jenis-Jenis Game di JAVA

1.5.1 Game Applet

Java Game Applet adalah aplikasi yang berjalan di web browser.

keuntungannya user tidak harus menginstall apapun, tetapi pemain harus

online dan menjalankan web browser untuk memainkannya dan

keuntungannya lagi applet mempunyai batasan keaamanan untuk menangani

kode jahat yang mengakibatkan kerusakan atau kerugian. sebagai contoh

applet tidak dapat menyimpan informasi seperti menyimpan game kedalam

harddisk pengguna (client), applet juga hanya melakukan koneksi jaringan ke

dalam server dimana kode applet tersebut di letakkan.

Pemrograman Game Java 16


J.E.N.I.
1.5.2 Game Window

Java game Window tidak mempunyai batasan keamanan yang dilakukan

seperti applet, pada kenyataannya aplikasinya kelihatan seperti aplikasi biasa

dengan title bar, tombol close dll. Bagaimanapun juga bagian dari user

interface dapat membingungkan si pemain, terlebih lagi ketika para pemain

ingin lebih mendalami sebuah game.

1.5.3 Game Full-Screen

Java Game Full-Screen memberikan kontrol sepenuhnya di atas layar

atau tampilan dari sebuah game, tanpa desktop antarmuka pengguna seperti

title bar, task bar, dll. Dengan model ini para pemain akan menjadi lebih tertarik

terhadap game yang sedang dimainkan.

Pemrograman Game Java 17


J.E.N.I.
BAB 2
COLLECTION & THREAD

2.1 Pendahuluan

Pada pembuatan game di java, sering kali para programer

mendefinisikan banyak object seperti suara, gambar, dan grafik geometri yang

begitu banyak, untuk itu dibutuhkan suatu manajemen yang menangani hal

tersebut atau lebih tepatnya sebuah object untuk menangani object-object dari

gambar atau grafik yang dibuat. Java telah menyediakan sebuah container atau

collection yang digunakan untuk menangani hal tersebut. Selain itu, seiring

dengan banyaknya object gambar atau grafik geometri yang dibuat maka

proses yang dibutuhkan juga memakan waktu yang cukup lama dimana dalam

java penggambaran object itu dilakukan 1000 kali per detik yang sangat

memberatkan kinerja dari procesor, oleh sebab itu dibutuhkan thread untuk

menangani hal terebut agar komputer berjalan dengan normal sesuai dengan

keinginan.

2.2 Tujuan

Setelah mempelajari modul ini peserta diharapkan dapat:

• Memahami tentang interface Collection pada Java

• Mengerti tentang pembuatan Vector, ArrayList dan LinkedList.

• Membuat dan mengelolah Thread

• Memahami proses sinkronisasi data

• Menggunakan method Wait dan Notify

Pemrograman Game Java 1


J.E.N.I.
2.3 Collection
Collection atau sering juga disebut sebagai container adalah sebuah

object sederhana yang menampung lebih dari satu elemen di dalam satu

kesatuan. Collection digunakan untuk menyimpan,mengambil dan

memanipulasi data, juga mentransmisikan data dari satu method ke method

lain. Collection khusus merepresentasikan data item dari bentuk yang

sebenarnya seperti Poker (kumpulan dari kartu), direktori (kumpulan dari file

atau folder), kotak surat (kumpulan dari surat-surat), dll.

SDK tidak menyediakan implementasi built-in yang lain dari interface ini

tetapi mengarahkan subinterfaces, Set interfaces dan List interfaces

diperbolehkan. Sekarang, apa perbedaan dari kedua interface tersebut. Set

merupakan collection yang tidak dipesan dan tidak ada penggandaan

didalamnya. Sementara itu, list merupakan collection yang dipesan dari

elemen-elemen dimana juga diperbolehkannya penggandaan. HashSet,

LinkedHashSet dan TreeSet adalah implementasi class dari Set interfaces.

ArrayList, LinkedList dan Vector merupakan implementasi class dari List

interfaces.

<root interface>
Collection

<interface> Set <interface> List

<implementing classes> <implementing classes>

HashSet LinkedHashSet TreeSet ArrayList LinkedList Vector

Gambar 2.1 Implementasi Interface Collection

Pemrograman Game Java 2


J.E.N.I.
2.3.1 Vektor

Vektor adalah implementsi dari dinamis array, yang hampir sama

dengan ArrayList perbedaanya adalah vector mempunyai method yang bukan

turunan dari collection framework. Pada Java 2 vektor diperluas lagi dengan

mengextends AbstractList dan mengimplementasikan List interface yang

sangat mendukung collection. Dibawah ini adalah konstruktor dari Vector.

Vector();
Vector(int size);
Vector(int size,int incr);

Konstruktor pertama adalah konstruktor default yang menginialisasikan

ukuran sebanyak 10 elemen. Konstruktor kedua yaitu menentukan jumlah

elemen yang akan digunakan. Konstruktor yang ketiga yaitu menentukan

ukuran awal dan apabila ukurannya full maka akan ditambah lagi sebanyak

incr. Dibawah ini beberapa method yang disediakan oleh class Vector.

Method Keterangan
Digunakan untuk menambahkan data object ke
addElement(<object>)
dalam Vektor.
Method ini berfungsi untuk mengambil elemen
elementAt(<index>)
berdasarkan nomor index yang dimasukan.
Berfungsi untuk mengambil nilai berupa object yang
lastElement() paling terakhir di tambahkan dari sebuah object
vektor.
Berfungsi untuk mengambil nilai berupa object
firstElement() pertama yang di tambahkan dari sebuah object
vektor.
Digunakan untuk menghapus seluruh elemen yang
clear()
tersimpan dalam object vector.
Memeriksa apakah verktor yang digunakan berisi
isEmpty() elemen atau tidak. Jika ada data maka akan
mengembalikan nilai boolean berupa false.

Pemrograman Game Java 3


J.E.N.I.
2.3.2 ArrayList

ArrayList hampir mirip seperti vektor. Pada JDK 1.1 ArrayList 3-4 kali

lebih cepat dari pada Vektor, sedangkan pada JDK 1.1.4 ArrayList 40 kali lebih

cepat daripada vektor. Pembuatan Object ArrayList dapat dilihat seperti

dibawah ini.

ArrayList al=new ArrayList();

Tidak seperti array dimana untuk mengambil ukuran menggunakan

<array>.length, ArrayList menggunakan al.size(). Dibawah ini adalah beberapa

method-method yang dapat digunakan pada ArrayList.

Method Keterangan
Digunakan untuk menambahkan data object ke
add(<object>)
dalam ArrayList.
Method ini menyediakan dua parameter untuk
add(<index>,<object>) menambahkan sebuah object dengan menentukan
nomor index elemennya.
Method get adalah method yang disediakan oleh
get(<index>) ArrayList untuk mengambil sebuah object
berdasarkan nomor indexnya.
Mothod ini berfungsi untuk menghapus elemen
remove(<index>)
ArrayList berdasarkan nomor indexnya.
Digunakan untuk memeriksa apakah object ArayList
isEmpty()
yang dibuat kosong atau tidak.
Menghapus semua elemen yang ada di dalam
clear()
object ArrayList.

2.3.3 LinkedList

LinkedList mengimplementasi interface List. LinkedList juga

memperbolehkan elemennya menggunakan null. Pertama yang harus

dilakukan adalah membuat object LinkedList seperti dibawah ini:

Pemrograman Game Java 4


J.E.N.I.

LinkedList ll=new LinkedList();


Ada beberapa method yang disediakan class LinkedList antara lain

adalah sebagai berikut:

Method Keterangan
Digunakan untuk menambahkan data object ke dalam
add(<object>)
LinkedList.
size() Mengambil jumlah elemen pada object LinkedList
Mengambil nilai elemen berdasarkan nomor index yang
get(<index>)
ada pada object LinkedList
addFirst() Menambahkan object pada elemen awal
addLast() Menambahkan object pada elemen akhir
getFirst() Mengambil nilai elemen pertama
getLast() Mengambil nilai elemen terakhir
clear() Menghapus semua nilai elemen pada object LinkedList
Method remove tanpa parameter akan menghapus
remove()
elemen pertama
Parameter akan menunjukan elemen mana yang akan
remove(<index>)
dihapus

2.4 Thread

2.4.1 Membuat dan Memulai Thread

Sebuah thread dapat dengan mudah dibuat dan jalankan dengan cara

membuat instance dari object Thread dan memanggil method start().

Thread myThread= new Thread();


myThread.start();

Saat menjalankan kode diatas tentu saja tidak akan ada yang terjadi

selain aplikasi jalan dan langsung mati. Ketika menjalankannya JVM akan

membuat sebuah thread baru dan secara default akan memanggil method

run(), dalam hal ini run() kosong sehingga thread akan langsung mati. Berikut

ini adalah cara memberikan tugas kepada thread :

1) meng-extends class Thread

2) meng-implements class Runnable


Pemrograman Game Java 5
J.E.N.I.
3) menggunakan innerclass tanpa nama

2.4.2 Menurunkan Class Thread

Cara cepat memberikan tugas kepada thread adalah dengan

mengoverride method run().

public class MyThread extends Thread {


public void run(){
System.out.println(“saya adalah thread”);
}
}

Berikutnya yang perlu di lakukan adalah membuat instance dari object

Thread dan memanggil method start() sama seperti bahasan sebelumnya.

Thread myThread = new MyThread();


myThread.start();

2.4.3 Mengimplementasi Class Runnable

Meng-extends class Thread sangat mudah, tetapi tidak menutup

kemungkinan seorang programer tidak ingin menulis class baru setiap kali ingin

menggunakan thread. Contoh nya ketika sedang mengextends class JFrame

dalam aplikasi GUI dan ingin menggunakan thread, solusinya dapat

dipecahkan dengan menggunakan interface Runnable().

public class MyThread extends JFrame implements Runnable {


public MyThread(){
Thread t=new Thread(this);
t.start();
}
public void run(){
System.out.println(“saya adalah thread”);
}
}

Pemrograman Game Java 6


J.E.N.I.
Dalam kode diatas MyThread membuat instance dari object thread pada

konstruktor dengan object Runnable (dalam hal ini class MyThread sendiri),

dan selanjutnya memulainya.

2.4.4 Menggunakan Inner Class Tanpa Nama

Sebuah thread dapat dibuat tanpa harus membuat class baru ataupun

mengimplements Runnable. Pembuatannya dapat dilakukan dengan dengan

cara membuat inner class.

new Thread() {
public void run() {
System.out.println("saya adalah Thread");
}
}.start();

Cara diatas tidak lazim digunakan karena dapat beresiko terhadap sebuah
program apabila kode dalam method run() semakin besar.

2.4.5 Menggunakan Method Sleep

Suatu saat sebuah thread perlu dihentikan untuk sementara waktu untuk

keperluan tertentu, untuk itu dapat menggunakan method sleep().

try{
Thread.sleep(1000);
}catch(Exception e){}

Kode diatas akan membuat thread berhenti selama 1 detik (1000

milidetik). Selama thread dalam kondisi sleep, thread tidak memerlukan kinerja

dari cpu. Kondisi sleep pada sebuah thread akan dimanfaatkan untuk

menjalankan thread lainya.

2.4.6 Menghentikan Thread

Pemrograman Game Java 7


J.E.N.I.
Ada dua cara yang bisa dilakukan untuk menghentikan sebuah thread.

Pertama adalah menggunakan flag (tanda) dan yang kedua adalah

menggunakan method interrupt(). Apabila menggunakan method stop(), maka

bersiap-siaplah melihat program tak terkendali atau bahkan mati. Method stop()

mengakibatkan gangguan terhadap thread lain.

2.4.7 Menggunakan Flag(Tanda)

Cara yang paling banyak digunakan untuk menghentikan sebuah thread

adalah menggunakan variabel penanda. Thread dapat memeriksa variabel

tersebut secara berkala untuk memastikan kondisi berhenti.

public class MyThread extends JFrame implements Runnable {

private volatile boolean done=false;


public MyThread(){
Thread t=new Thread(this);
t.start();
}
public void run(){
while(!done){
System.out.println(“saya adalah thread”);
}
}
Public void setDone(){
done=true;
}

Dengan kode diatas secara berkala thread akan memeriksa kondisi

penanda, ketika penanda bernilai true maka thread tidak lagi dijalankan.

Pemrograman Game Java 8


J.E.N.I.
2.4.8 Menggunakan Interupsi

Cara lain yang dapat digunakan adalah dengan menginterrupsi sebuah

thread. Cara ini biasa digunakan pada sistem blocking. Sistem blocking adalah

sistem yang mem-block jalannya sistem sampai sebuah kunci di lepaskan.

Contoh sistem blocking salah satunya pola penerimaan koneksi jaringan

(pembahasan jaringan akan di jelaskan pada bab berikutnya).

Pada teknik penghentian menggunakan flag, terdapat sebuah kondisi

yang memungkinkan sistem kehilangan/terlambat menerima informasi.

Contohnya ketika sebuah thread sedang memproses suatu perintah, tiba-tiba

flag di set. Kondisi ini setidaknya membuat thread harus menyelesaikan proses

tersebut dan baru akan menghentikan proses pada loop berikutnya.

public class MyThread extends JFrame implements Runnable {


private volatile boolean done=false;
Thread t;

public MyThread(){
t=new Thread(this);
t.start();
}
public void run(){
while(!t.isInterrupted()){
System.out.println(“saya adalah thread”);
}
}
}

Dengan method interrupt(), thread akan di paksa berhenti dan

mengabaikan proses yang sedang berjalan. Penggunaan method interrupt()

dapat dengan mudah dilakukan dengan memanggil method tersebut.

Pemrograman Game Java 9


J.E.N.I.
2.4.9 Sinkronisasi Data

Apa yang terjadi ketika dua thread menggunakan variabel yang sama?

Bisa saja salah satu thread mencoba mengkases data yang telah di hapus oleh

thread lainya. Dalam hal ini kedua thread harus di sinkronisasi sehingga

masing-masing thread tidak kehilangan informasi. Sinkronisasi berfungsi

mengunci sebuah object, ketika sebuah object terkunci maka tidak ada yang

bisa dilakukan terhadap object tersebut sebelum kunci di lepas.

Asumsikan bahwa buah thread yang mengakses variabel dari object

yang sama. Suatu saat thread a mencoba mengambil data dalam variabel

tersebut , sementara thread b mencoba mengubah data tersebut .

public class GamePlayer{


public int getLives()
{ return lives; }
public void setLives(int l)
{ lives = l; }
private int lives;
}

Asumsikan kedua buah thread ingin mengakses object gamePlayer yang sama.
//Thread A
int lives=gamePlayer.getLives();
gamePlayer.setLives(lives-1);

//Thread B
int lives=gamePlayer.getLives();
gamePlayer.setLives(lives-1);

Kondisi yang diinginkan adalah variabel lives mendapatkan

pengurangan 2 kali. Namun ketika Thread A dan B mengakses variabel Lives

dalam waktu yang bersamaan kemudian menguranginya maka yang terjadi

variabel Lives hanya akan mengalami satu pengurangan. Untuk memperbaiki

kondisi tersebut dapat menggunakan kata kunci synchronized.

Pemrograman Game Java 10


J.E.N.I.
//Thread A
Synchronized(gamePlayer){
int lives=gamePlayer.getLives();
gamePlayer.setLives(lives-1);
}
//Thread B
Synchronized(gamePlayer){
int lives=gamePlayer.getLives();
gamePlayer.setLives(lives-1);
}

2.4.10 Menggunakan Method Wait dan Notify

Sebelum bahasan ini, telah dipelajari bagaimana thread bekerja secara

mandiri. Pada kenyataan suatu saat seorang programer perlu

mengkomunikasikan dua atau lebih thread. Katakanlah dua buah thread

digunakan untuk komunikasi jaringan, thread A dan thread B. Thread A akan

mengirimkan pesan ketika thread B selesai mengisi pesan.

// Thread A
public void waitForMessage() {
while (hasMessage == false) {
Thread.sleep(100);
}
}
// Thread B
public void setMessage(String message) {.....
hasMessage = true;
}

Perhatikan kode diatas. Secara berkala thread A akan mengecek kondisi

hasMessage. Jika hasMessage tidak di set pada pengecekan terkini maka

berikutnya thread akan sleep selama 100 ms. Kode tersebut memang bekerja,

tetapi apa yang terjadi jika hasMessage di set ketika Thread A dalam keadaan

sleep? Thread A akan kehilangan atau setidaknya terlambat menerima

informasi. Dengan method wait dan notify hal ini dapat di selesaikan. Thread a

Pemrograman Game Java 11


J.E.N.I.
cukup menunggu sampai dengan thread B mengirimkan sinyal bahwa pesan

telah siap.

// Thread A
public synchronized void waitForMessage() {
try {
wait();
}
catch (InterruptedException ex) { }
}
// Thread B
public synchronized void setMessage(String message) {
...
notify();
}
Seperti yang terlihat diatas apabila method waitForMessage() di panggil

maka secara otomatis program akan berhenti secara mendadak untuk

menunggu method setMessage() dipanggil atau dijalankan.

Pemrograman Game Java 12


J.E.N.I.
BAB 3
EVENT HANDLING

3.1 Pendahuluan

Sebuah game sangat membutuhkan penanganan aksi yang terjadi pada

mouse dan keyboard yang akan memberikan dampak atau perubahan kepada

suatu objek. Hampir keseluruhan game komputer menggunakan dua item ini,

dimana didalam java dikenal dengan istilah “event handling”. Sebenarnya event

handling di java tidak hanya sebatas pada mouse dan keyboard saja tetapi juga

objek-objek lain seperti item listener, componen listener dst, tetapi disini hanya

membahas tentang masalah penanganan mouse dan keyboard. Sebagai

contoh, apabila ingin mengetahui tombol apa yang ditekan maka disinilah

fungsi event handling, tidak hanya itu tetapi masih banyak lagi seperti jika

tombol space ditekan maka bom akan meledak, apabila tombol enter ditekan

maka permainan akan dimulai dan masih banyak lagi.

3.2 Tujuan

Setelah mempelajari modul ini peserta diharapkan dapat:

• Mendengarkan action dari keyboard

• Menerima input dari keyboard

• Mengetahui kode tombol-tombol keyboard pada KeyEvent.

• Membaca pergerakan mouse

• Mendeteksi tombol mouse

• Menerima input dari mouse.

Pemrograman Game Java 1


J.E.N.I.
3.3 Input dari Keyboard

Java menyediakan Interface KeyListener untuk mendengarkan aksi dari

keyboard dan mengirimkan action tersebut melalui method yang diikutsertakan

dalam program. Adapun method-methodnya adalah keyPressed,keyReleased,

dan keyTyped . Ketiga parameter dari method ini hanya mempunya satu

parameter yaitu KeyEvent.

Ketika menulis program yang menggunakan KeyListener, maka harus

menambahkan definisi dari class yang telah dibuat dengan menggunakan kata

kunci implements, sebagai contoh:

Public class TestKeyboard extends JFrame


implements Keylistener{
.......................
.......................
}

Fitur Yang paling menarik dari implements pada java adalah dapat

mengimplementasikan lebih dari satu interface didalam program dengan

menggunakan tanda koma(,) sebagai pemisah dari masing-masing interface.

3.4 Mendengarkan Action dari Keyboard

Sebuah program membutuhkan method addKeyListener untuk

mendengarkan aksi dari keyboard, agar key event akan di kirim oleh Java

Runtime Environment(JRE) kepada program yang dibuat. Parameter dari

method ini akan di turunkan pada class yang akan direpresentasikan dengan

kata kunci (this). Bisanya untuk pemanggilan addKeyListener(this) dilakukan di

dalam program dimana konstruktor akan di panggil pertama kali ketika sebuah

program dijalankan.

Pemrograman Game Java 2


J.E.N.I.
Selanjutnya, mengimplementasikan 3(tiga) aksi dari keyboard di dalam

program agar interface dari keyListener dapat bekerja.

public void keyPressed(KeyEvent e)


public void keyReleased(KeyEvent e)
public void keyTyped(KeyEvent e)

Ada tiga jalan untuk menentukan key yang telah ditekan atau dilepaskan

dengan menggunakan parameter KeyEvent. Jika ingin mengetahui karakter

tombol yang ditekan, dapat menggunakan method getKeyChar yang mana

akan mengirimkan nilai bertype char, tetapi jika ingin mengetahui kode apapun

ditekan berdasarkan kode tombol maka dapat menggunakan method

getKeyCode. Sebagai contoh ketika program mendengarkan aksi dari keyboard

dan kemudian tombol A ditekan, maka method getKeychar akan

mengembalikan hasil berupa “a”(atau “A” jika menggunakan huruf besar), tetapi

method getKeyCode akan mengembalikan nilai berupa kode tombol virtual

yaitu VK_A. Semua dari kode tombol virtual terdapat di dalam class KeyEvent.

Tabel dibawah ini menampilkan sebagian daftar dari kode tombol virtual yang

biasanya umum digunakan didalam pembuatan game.

Kode Tombol Penjelasan


VK_LEFT Panah kiri
VK_RIGHT Panah kanan
VK_UP Panah atas
VK_DOWN Panah bawah
VK_0 ..... VK_9 Tombol Numerik
VK_A .... VK_Z Tombol Alphabet
VK_F1 .. VK_F12 Tombol Fungsi
VK_KP_LEFT Numerik left
VK_KP_RIGHT Numerik right
VK_KP_UP Numerik atas
VK_KP_DOWN Numerik bawah
VK_ENTER Tombol Enter
VK_BACK_SPACE Tombol Backspace
VK_TAB Tombol Tab

Pemrograman Game Java 3


J.E.N.I.
Sekarang membuat class TestKeyboard yang mengimplementasi

interface KeyListener seperti pada kode program berikut.

import java.awt.*;
import java.awt.event.*;
import javax.swing.JFrame;

public class TestKeyboard extends JFrame implements KeyListener{

int KodeTombol;
char KarakterTombol;

public static void main(String[] args) {


TestKeyboard tk= new TestKeyboard();
}
TestKeyboard(){
setTitle("Test Keyboard");
addKeyListener(this);
setSize(300, 200);
setVisible(true);
setDefaultCloseOperation(this.EXIT_ON_CLOSE);
}
public void paint(Graphics g){
g.setColor(Color.WHITE);
g.clearRect(0, 0, 300, 200);
g.setColor(Color.BLACK);
g.drawString("Tekan sebuah tombol : ", 20, 20);
g.drawString("Kode Tombol : "+KodeTombol, 20, 50);
g.drawString("Karakter Tombol : "+KarakterTombol, 20, 70);
}

public void keyPressed(KeyEvent e) {


KodeTombol=e.getKeyCode();
KarakterTombol=e.getKeyChar();
repaint();
}
public void keyReleased(KeyEvent e) { }
public void keyTyped(KeyEvent e) { }

Kode program diatas akan menampilkan kode tombol dan karakter

tombol yang kita tekan disetiap kita menekan tombol pada keyboard. Method

clearRect() digunakan untuk menghapus tulisan ataupun gambar sebelumnya

sedangkan method repaint() dipanggil ketika ada perubahan atau ketika tombol

ditekan yang berfungsi untuk memanggil method paint().

Pemrograman Game Java 4


J.E.N.I.
3.5 Input dari Mouse

Mendengarkan action dari mouse sama prosesnya seperti

mendengarkan action dari keyboard. Java menangani masukan dari mouse

menggunakan aksi yang dihasilkan oleh Java Runtime Environment (JRE) dan

mengirimkan ke program jika mengimplementasikan MouseListener.

Langkah pertama yang harus diambil untuk menangani aksi dari mouse

di dalam program adalah memanggil kedua fungsi yang berikan oleh JRE yaitu

addMouseListener() dan addMouseMotionListener(). Kedua fungsi tersebut

harus diinialisasi, fungsi ini sama seperti yang telah dipelajari pada saat

menangani keyboard.

addMouseListener(this);
addMouseMotionListener(this);

Java menyediakan sebuah class interface untuk pergerakan mouse dan

aksi tombol yang hampir sama seperti interface pada keyboard. Class

MouseListener adalah class abstrak yang disediakan kepada program dengan

sebuah interface dengan 5(lima) method yang harus diimplementasi di dalam

walupun tidak digunakan.

public void mouseClicked(MouseEvent e)


public void mouseEntered(MouseEvent e)
public void mouseExited(MouseEvent e)
public void mousePressed(MouseEvent e)
public void mouseReleased(MouseEvent e)

Interface dari MouseListener menangani tombol mouse, posisi mouse di

dalam window, dan lokasi mouse ketika kursor mouse kedalam dan keluar dari

window.

Selain MouseListener juga terdapat class interface yang sangat

berbeda, yang digunakan untuk menangani pergerakan mouse. Posisi mouse

Pemrograman Game Java 5


J.E.N.I.
dapat dibaca melalui MouseListener, tetapi untuk menerima aksi dari

pergerakan mouse membutuhkan interface yang lain. Untuk menerima aksi

pergerakan mouse melalui jendela window harus menggunakan interface

MouseMotionListener. Ada 2(dua) aksi didalam interface ini yaitu :

public void mouseDragged(MouseEvent e)


public void mouseMoved(MouseEvent e)

3.6 Mendeteksi Tombol Mouse

Beberapa aksi akan di beritahukan oleh JRE ketika tombol mouse

diklik,ditekan, atau dilepaskan. Salah satu method yang yang tidak terhubung

dengan tombol mouse adalah mouseEntered, mouseExited, dan mouseMoved,

ketiga method itu terhubung ketika terjadi aksi terhadap posisi dan pergerakan.

Semua method dari (mouseClicked, mouseEntered, mouseExited,

mousePressed, dan mouseReleased) berjalan apabila tombol mouse ditekan.

Semua action hanya mempunyai 1 (satu) parameter yang disebut

sebagai MouseEvent. Parameter ini sebenarnya adalah sebuh class, yang

kemudian digunakan oleh JRE untuk mengirimkan action yang terjadi pada

mouse. Pada class ini terdapat mthod untuk mengetahui posisi mouse dan nilai

dari tombol mouse. Untuk nilai posisi mouse x dan y, dapat menggunakan

MouseEvent.getX() dan mouseEvent.getY(). Parameter biasanya didefinisikan

menjadi (MouseEvent e), untuk itu pada prakteknya gunakan e.getX() dan

e.getY() untuk mengetahui posisi dari mouse. Demikian juga, MouseEvent akan

memberitahu tombol mana yang telah ditekan. Pada MouseEvent ada sebuah

method getButton() yang fungsinya sama tergantung dari tombol yang telah

ditekan. Method getButton() sangat berguna ketika ingin mendeteksi satu

tombol yang ditekan.

Pemrograman Game Java 6


J.E.N.I.
public void mouseClicked(MouseEvent e) {
if(e.getButton()== MouseEvent.BUTTON1){
System.out.println("button 1");
}else if(e.getButton()== MouseEvent.BUTTON2){
System.out.println("button 2");
}else if(e.getButton()== MouseEvent.BUTTON3){
System.out.println("button 3");
}
}
Class TestMouse dibawah ini memperlihatkan semua action dari mouse

yang baru saja dipelajari. program ini menggunakan kode class Graphics,

method drawString dan rangkaian varible untuk menampilkan status dari

semua aksi mouse secara satu persatu. Gambar 3.13 dibawah ini menampilkan

hasil dari kode program TestMouse.

Gambar 3.13 Tampilan Hasil, Semua Action dari Mouse


import java.awt.Graphics;
import java.awt.event.*;
import javax.swing.JFrame;

public class TestMouse extends JFrame implements


MouseListener,MouseMotionListener{

int clickx, clicky;


int pressx, pressy;
int releasex, releasey;
int enterx, entery;
int exitx, exity;
int dragx, dragy;
int movex, movey;
int mousebutton;

Pemrograman Game Java 7


J.E.N.I.
Konstruktor adalah method pertama yang dijalankan di dalam sebuah

program ketika class tersebut dipanggil. Oleh sebab itu di method inilah dimana

variabel dan object game diinialisasi, dan disini juga dapat ditempatkan listener

untuk semua program peralatan masukan(Input Device) yang dibutuhkan.

Apabila program tidak menghiraukan keyboard atau mouse, periksalah

konstruktor utama untuk memastikan apakah listener telah ditambahkan atau

tidak.

TestMouse(){
setTitle("Test Mouse");
addMouseListener(this); // listener tombol mouse
addMouseMotionListener(this);// listener pergerakan mouse
setSize(300, 200);
setVisible(true);
setDefaultCloseOperation(this.EXIT_ON_CLOSE);
}

Method paint() adalah method yang dipanggil ketika program merefresh

jendela. Sejak paint() dengan parameter (Graphics g), object ini dapat

digunakan untuk menggambar di dalam jendela program. Untuk menampilkan

teks didalam program ini kami telah menggunakan method

Graphics.drawString().

public void paint(Graphics g){


g.setColor(Color.WHITE);
g.clearRect(0, 0, 300, 200);
g.setColor(Color.BLACK);
g.drawString("Mouse clicked : "+mousebutton+" at
"+clickx+","+clicky, 10,50);
g.drawString("Mouse Entered : "+enterx+","+entery, 10,
75);
g.drawString("Mouse Exit : "+exitx+","+exity, 10,
100);
g.drawString("Mouse Pressed : "+mousebutton+" at
"+pressx+","+pressy, 10,125);
g.drawString("Mouse Released: "+mousebutton+" at
"+releasex+","+releasey,10,150);
g.drawString("Mouse Dragged : "+dragx+","+dragy, 10,
175);
g.drawString("Mouse Moved : "+movex+","+movey, 10,
200);
}

Pemrograman Game Java 8


J.E.N.I.

Bagian kode selanjutnya adalah method checkButton(), adalah program

yang kami tulis untuk menangani aksi pada mouse. Method chekButton() ini

memeriksa tombol yang baru saja di tekan dan menyimpannya kedalam

variabel (mousebutton) sebagai nilai yang merepresentasikan tombol yang

ditekan.

public void checkButton(MouseEvent e){


switch(e.getButton()){
case MouseEvent.BUTTON1:
mousebutton=1;
break;
case MouseEvent.BUTTON2:
mousebutton=2;
break;
case MouseEvent.BUTTON3:
mousebutton=3;
break;
default:
mousebutton=0;
}
}

Method mouseClicked() adalah bagian dari interface MouseListener.

Ketika mengimplementasi interface ini, harus mengikutsertakan semua action

dari Mouse yang didefinisikan dalam interface ini atau akan mendapatkan

pesan kesalahan(error). Action ini dipanggil kapanpun ketika menekan tombol

mouse di dalam jendela window, artinya ketika menekan atau melepaskan

tombol mouse. Action ini tidak biasanya dibutuhkan didalam mousePressed()

dan mouseReleased() sendiri.

public void mouseClicked(MouseEvent e) {


// Menyimpan posisi mouse
clickx=e.getX();
clicky=e.getY();
// Mengupdate Tombol
checkButton(e);
// refresh tampilan
repaint();
}

Pemrograman Game Java 9


J.E.N.I.
Selanjutnya adalah aksi kedua method mouse, mouseEntered() dan

mouseExited() yang dipanggil ketika kursor mouse memasuki atau

meninggalkan jendela aplikasi. Kedua aksi ini tidak sering dibutuhkan dalam

pembuatan game.

public void mouseEntered(MouseEvent e) {


enterx=e.getX();
entery=e.getY();
repaint();
}
public void mouseExited(MouseEvent e) {
exitx=e.getX();
exity=e.getY();
repaint();
}

Method mousePressed() dan mouseReleased() akan dipanggil ketika

menekan dan melepaskan tombol mouse. Ketika kedua aksi tersebut terjadi,

posisi akhir dari mouse dapat diambil baik ketika ditekan atau dilepaskan.

public void mousePressed(MouseEvent e) {


pressx=e.getX();
pressy=e.getY();
repaint();
}
public void mouseReleased(MouseEvent e) {
releasex=e.getX();
releasey=e.getY();
repaint();
}

Interface MouseMotionListener mendefinisikan 2(dua) aksi yaitu

mouseDragged() dan mouseMoved(). Kedua aksi tersebut sangat membantu

ketika ingin mengetahui kapan mouse bergerak di dalam jendela window.

public void mouseDragged(MouseEvent e) {


dragx=e.getX();
dragy=e.getY();
repaint();
}

public void mouseMoved(MouseEvent e) {


movex=e.getX();
movey=e.getY();
repaint();
}

Pemrograman Game Java 10


J.E.N.I.
3.7 Membuat Class Untuk Handling Keyboard dan Mouse

Pada pokok bahasan sebelumnya penanganan aksi dari keyboard dan

mouse selalu di dalam sebuah class yang sama, sekarang akan dibuat class

sendiri untuk menangani aksi yang terjadi pada keyboard dan mouse yang

mana akan mempermudah user untuk menggunakannya. Berikut adalah

tampilan dari program yang dibuat.

Gambar 3.14 Tampilan hasil Class PercobaanKeyboardMouse

Pada Class PercobaanKeyboardMouse diatas menampilkan koor-dinat,

tombol mouse beserta kode dan karakter tombol pada keyboard dengan

menggunakan 2 buah panel, 9 buah label dan textfield.

JTextField tf[]=new JTextField[9];


JLabel l[]=new JLabel[9];
HandlingKeyboardMouse hkm;
String label[]={"Mouse clicked","Mouse Entered","Mouse Exit",
"Mouse Pressed","Mouse Released","Mouse Dragged",
"Mouse Moved","Kode Tombol","Karakter Tombol"};

....................
....................
....................

for(int i=0;i<9;i++) {
tf[i]=new JTextField(30);
tf[i].setEditable(false);
tf[i].setFocusable(false);
l[i]=new JLabel(label[i]);

p1.add(l[i]).reshape(10, i*30, 100, 25);

Pemrograman Game Java 11


J.E.N.I.
p1.add(tf[i]).reshape(120, i*30, 300, 25);
}

Kode diatas mendefinisikan array textfield dan label sebanyak 9 buah

kemudian memberikan nilai false pada method setEditable() agar tidak dapat di

edit dan method setFocusable() supaya kursor tidak terarah langsung pada

textfield ketika program di jalankan. Selanjutnya membuat object yang

digunakan untuk menangani keyboard dan mouse dengan melewatkan textfield

yang di buat tadi dari konstruktornya.

hkm=new HandlingKeyboardMouse(tf);
p2.addMouseListener(hkm);
p2.addMouseMotionListener(hkm);
addKeyListener(hkm);

Berikut ini adalah konstruktor dari class HandlingKeyboardMouse.


HandlingKeyboardMouse(JTextField a[]){
for(int i=0;i<9;i++){
tf[i]=new JTextField(30);
tf[i]=a[i];
}
}

Textfield yang dilewatkan pada konstruktor HandlingKeyboardMouse

diatas kemudian diproses sesuai kebutuhan dimana pada class ini texfield

tersebut digunakan untuk menampilkan koordinat pointer pada mouse juga

karakter dan kode tombol pada keyboard yang berada di dalam methode

update(), mothod ini selalu di panggil ketika ada aksi yang terjadi pada

keyboard ataupun mouse. Berikut adalah potongan kode programnya.

public void update(){


tf[0].setText(mousebutton+" at "+clickx+","+clicky);
tf[1].setText(enterx+","+entery);
tf[2].setText(exitx+","+exity);
tf[3].setText(mousebutton+" at "+pressx+","+pressy);
tf[4].setText(mousebutton+" at "+releasex+","+releasey);
tf[5].setText(dragx+","+dragy);
tf[6].setText(movex+","+movey);
tf[7].setText(""+KodeTombol);
tf[8].setText(""+KarakterTombol);
}

Pemrograman Game Java 12


J.E.N.I.
...........
...........
public void mouseMoved(MouseEvent e) {
movex=e.getX();
movey=e.getY();
update();
}
...........
...........
public void keyPressed(KeyEvent e) {
KodeTombol=e.getKeyCode();
KarakterTombol=e.getKeyChar();
update();
}

Pemrograman Game Java 13


J.E.N.I.
BAB 4
EFEK SUARA

4.1 Pendahuluan

Pada sebuah permainan efek suara sangat dibutuhkan untuk membuat

game yang dibangun lebih semakin hidup dan terasa nyata, hal ini juga yang

membuat para pemain lebih tertarik, bayangkan apabila di dalam suatu

permainan tidak ada suara sama sekali. Efek suara sangat diperlukan oleh

game misalnya ketika sebuah objek mengalami tabrakan, ledakan bom, suara

tembakan, dll.

4.2 Tujuan

Setelah mempelajari modul ini peserta diharapkan dapat:

• Memanggil dan Memainkan File Suara.

• Memanggil dan Memainkan File MIDI Sequence.

• Mengetahui perbedaan antara file berekstensi midi dan (Aiff, Au, Wav)

• Mengetahui cara menggunakan class File dan URL untuk meload file suara

4.3 Mengakses File Suara

API Sound pada Java mendukung 3 macam format suara yang

digunakan di Web dan Aplikasi Desktop yaitu:

1. AIFF

2. AU

3. WAV

Pemrograman Game Java 1


J.E.N.I.
Untuk memanggil dan mendengarkan suara, Java memerlukan paket

javax.sound.sampled.* untuk disertakan di baris awal program yang dapat

dituliskan seperti dibawah ini:

import javax.sound.sampled.*;

Apabila menggunakan eclipse, maka akan terlihat menu pop-up yang

menampilkan nama-nama package dalam javax. Jika mengetikan javax.sound

diikuti dengan titik maka akan terlihat package di dalamnya yaitu sampled dan

midi. Dengan menambahkan .* pada akhir statement maka compiler sudah

memberitahukan untuk meng-import semua class dalam javax.sound.sampled.

AudioSystem dan AudioInputStream adalah class yang berada di dalam

paket javax.sound.sampled dan digunakan untuk memanggil dan memainkan

sebuah suara.

Kunci utama untuk pemanggilan suara adalah class bernama

AudioInputStream. Class ini digunakan untuk memuat sebuah file suara dari file

lokal dimana program diletakkan atau dari URL lain di internet. Berikut ini

adalah pembuata sebuah obyek/instance baru dari class tersebut.

AudioInputStream suara;

Statement ini biasanya diposisikan sebagai variable global dalam class,

didefinisikan pada baris-baris awal dalam class sebelum semua method ditulis.

Selain itu juga dapat didefinisikan sebagai variable private, public, atau

protected (defaultnya adalah public). Dalam peraturan pemrograman berbasis

objek, public memposisikan variable agar dapat diakses oleh class lain diluar

variable tersebut didefinisikan, private berarti variable tersebut tidak dapat

diakses dari class lain, sedangkan protected hampir mirip dengan private hanya

Pemrograman Game Java 2


J.E.N.I.
saja class-class yang menjadi sub-classnya(melalui inheritance) bisa

menggunakannya.

Kode untuk memuat suara dari URL biasanya diletakkan dalam

konstruktor. Method yang digunakan untuk memuat sebuah file suara adalah

AudioSystem.getAudioInputStream. Method ini menerima sebuah File ,

InputStream atau URL, ada dua cara untuk membuat audio stream

(AudioFormat dan Encoding).

suara = AudioSystem.getAudioInputStream(new File(“BOOM.wav”));

Nilai balik dari method ini adalah AudioInputStream. Karena

getAudioInputStream tidak memiliki versi yang dapat di overload dan hanya

menerima input berupa string dari nama file, maka harus melewatkan sebuah

objek File kedalamnya. Cukup mudah menggunakan objek dari File, hanya

dengan memberikan nama file pada kontruktor method File. Apabila ingin

mengambil sebuah file dari sebuah URL, kode yang digunakan adalah sebagai

berikut :

URL lokasi = new URL(“http://www.vedcmalang.ac.id/suara/BOOM.wav”);


suara = AudioSystem.getAudioInputStream(lokasi);

Apabila ingin mendistribusikan program java yang telah dibuat dan ingin

mendapatkan hasil yang maksimal, sebaiknya mengganti method new File()

dan new URL() untuk memuat semua sumber (seperti sebuah file gambar atau

suara) dengan memanfaatkan this.getClass().getResource(), dimana Method

getResource() berada di instance class yang saat ini digunakan

this.getClass().. Berikut ini sebuah method yang di tulis menggunakan fungsi

tersebut :

public URL getURL(String namaFile){

Pemrograman Game Java 3


J.E.N.I.
URL url=null;
try{
url=this.getClass().getResource(namaFile);
}catch(Exception e){}
return url;
}

AudioInputStream tidak dapat langsung digunakan untuk memainkan

suara, AudioInputStream hanya dapat mengakses file audio tanpa kemampuan

untuk memainkanya. Untuk itu, perlu menggunakan class lain yang bernama

Clip (Import javax.sound.sampled.clip).

Clip klip =AudioSystem.getClip();

4.4 Memuat dan Mememainkan Klip Suara

Sebelumnya sudah mempunyai sebuah AudioInputStream dan sebuah

Clip, jadi hanya perlu untuk membuka file suara dan memainkannya. Langkah

ini dua-duanya dilakukan oleh class Clip. Pertama , bukalah file suara :

klip.open(suara);

Berikutnya, ada dua cara atau method untuk memainkan klip, dengan

menggunakan class Clip yaitu : Method start() dapat digunakan untuk

memainkan klip suara dengan kode seperti berikut:

klip.start();

Untuk yang kedua adalah method loop(), dimana method ini

menyediakan sebuah pilihan yang memperbolehkan untuk menentukan

seberapa banyak klip akan diulang. baik dengan jumlah tertentu maupun tak

hingga. Dibawah ini kode yang memungkinkan untuk memainkan klip suara

dengan method loop() :

klip.loop(0);

Pemrograman Game Java 4


J.E.N.I.
Ingat, parameter menunjukkan seberapa banyak ia akan diulang. Berikut

ini adalah bagaimana agar klip suara dapat dimainkan terus menerus :

klip.loop(Clip.LOOP_CONTINOUSLY);

Pada kenyataannya programer sering lupa untuk menghentikan suara

yang telah dimainkan padahal tidak semua suara dimainkan terus menerus

seperti suara tabrakan dll, untuk itu jika ingin menghentikan klip suara dapat

menggunakan method stop() seperti pada potongan kode dibawah ini:

klip.stop();

4.5 Memuat dan Mememainkan MIDI

MIDI adalah singkatan dari Musical Instrument Digital Interface. MIDI

adalah sebuah kumpulan format musik, bukan sebuah format sample, artinya

musik MIDI tidak direkam menggunakan konverter analog-to-digital (yang

berada pada sound card di dalam komputer).

Perlu diketahui bahwa file berekstensi (aiff,au dan wav) berukuran cukup

besar, sedangkan aplikasi tidak ingin pengguna menunggu lima menit atau

lebih (khususnya dial-up) hanya untuk menunggu sampai klip selesai

didownload(game jaringan). Hal ini terjadi ketika anda memanggil method

open(), jadi ketika anda mencoba untuk membuka sebuah file suara berukuran

besar, maka method ini akan memaksa pengguna untuk menunggu selama

waktu download klip suara. Hal ini yang dapat menjawab permasalahan

tersebut adalah MIDI sequence.

Memuat file MIDI memerlukan sedikit lebih banyak cara dari pada

memuat file berekstensi (aiff,au dan wav). Hal ini karena file MIDI dimainkan

Pemrograman Game Java 5


J.E.N.I.
melalui perangkai (sequencer) bukan melalui sound mixer. Class Sequence

digunakan untuk memuat file MIDI :

Sequence suara = MidiSystem.getSequence(new File(“contoh.mid”));

Meskipun kode tersebut disiapkan agar file MIDI dapat dimainkan

melalui sequencer, kita belum sama sekali membuat instance dari sequencer:

Sequencer ambilSuara= MidiSystem.getSequencer();

Berikutnya, Memberitahukan kepada class Sequencer bahwa kita

memiliki file midi (melalui class Sequence):

ambilSuara.setSequence(suara);

Sekarang yang perlu dilakukan adalah membuka file dan memainkannya:


ambilSuara.open();
ambilSuara.start();

Untuk memainkan MIDI secara berulang-ulang sebanyak yang

diinginkan gunakan method setLoopCount() dimana parameternya sebagai

penentu:

ambilSuara.setLoopCount(1);

Apabila ingin dimainkan secara terus menerus tanpa henti gunakan kode
berikut:
ambilSuara.setLoopCount(Sequencer.LOOP_CONTINUOUSLY);

Terakhir adalah menghentikan MIDI, prosesnya sama seperti menghentikan file


(aiff,au,wav) yaitu dengan cara memanggil method stop():
ambilSuara.stop();

Pemrograman Game Java 6


J.E.N.I.
4.6 Penanganan Error

Java menyediakan penanganan error pada class Sound, compiler secara

otomatis akan menolak atau memberikan pesan kesalahan apabila tidak

menggunakan blok try... catch. Sebagai contoh, ketika memuat sebuah file,

pertama kali akan diperiksa dengan IOException sebelum menggunakan

handler umum(Exception). Class AudioSystem, AudioInputStream dan Clip

membutuhkan handler dibawah ini :

• IOException

• LineUnavailableException

• UnsuportedAudioFileException

Cara menggunakan sebuah error handler untuk program yang akan

memainkan sebuah suara. Kode berikut ini diletakkan pada konstruktor :

KONSTRUKTOR(){
try {
//kode program
} catch (MalformedURLException e){
} catch (IOException e){
} catch (LineUnavailableException e){
} catch (UnsuportedAudioFileException e){}
}

Disamping itu class Sequence dan Sequencer juga membutuhkan

penanganan error yang tidak jauh berbeda dengan class Class AudioSystem,

AudioInputStream dan Clip. Cara penanganannya dapat dituliskan sebagai

berikut:

KONSTRUKTOR(){
try {
// kode program
} catch (InvalidMidiDataException e) {
} catch (IOException e) {
} catch (MidiUnavailableException e) { }
}

Pemrograman Game Java 7


J.E.N.I.
Penanganan error sangat diperlukan untuk mencegah program yang dijalankan

crash atau rusak.

4.7 Class OperasiSuara

Pembuatan class OperasiSuara dimaksudkan agar dapat digunakan pada

pembuatan game nanti dengan mempermudah peserta ketika mengakses dan

mendengarkan suara.

import java.io.*;
import java.net.*;
import javax.sound.sampled.*;

public class OperasiSuara{

private AudioInputStream suara;


private Clip klip;
private String namaFile = "";
private boolean looping = false;
private int repeat = 0;

public OperasiSuara(){
try{
klip = AudioSystem.getClip();
}catch(LineUnavailableException e)
{System.out.println("Terjadi kesalahan pada klip suara :
"+e.toString());}
}

public OperasiSuara(String filesuara) {


this();//memanggil default konstruktor pertama (tanpa
parameter);
load(filesuara);
}

public boolean load(String filesuara){


try{
setFilename(filesuara);
suara =
AudioSystem.getAudioInputStream(getURL(namaFile));
klip.open(suara);
return true;
}catch(IOException e){
return false;
}catch(UnsupportedAudioFileException e){
return false;
}catch(LineUnavailableException e){
return false;
}
}
public void setFilename(String nama_fail) {namaFile =
nama_fail;}
public void setLooping(boolean ulang) {looping = ulang;}

Pemrograman Game Java 8


J.E.N.I.
public void setRepeat(int ulangi) {repeat= ulangi;}
public Clip getClip() { return klip;}
public int getRepeat() {return repeat;}
public boolean getLooping() {return looping;}
public String getNamaFile() {return namaFile;}
private URL getURL(String filename){
URL url = null;
try {
url = this.getClass().getResource(filename);
System.out.println(url);
}catch(Exception e){ System.out.println("error url :
"+e.toString());}
return url;
}
public boolean isLoaded(){
return (boolean)(suara != null);
}
public void play(){
if (!isLoaded()) return;

klip.setFramePosition(0);

if(looping)
klip.loop(Clip.LOOP_CONTINUOUSLY);
else
klip.loop(repeat);
}
public void stop(){
klip.stop();
}
}

4.8 Class OperasiMIDI

Pembuatan class OperasiMIDI sangat dibutuhkan ketika peserta sudah

masuk pada pembuatan geme dimana perserta hanya mengakses method

yang disediakan di class ini dan tanpa harus menuliskannya secara berulang-

ulang.

import java.io.*;
import java.net.*;
import javax.sound.midi.*;

public class OperasiMidi{

private Sequence suara;


private Sequencer ambilSuara;
private String namaFile;
private boolean looping = false;
private int repeat = 0;

public OperasiMidi(){
try{
ambilSuara = MidiSystem.getSequencer();

Pemrograman Game Java 9


J.E.N.I.
}catch(MidiUnavailableException e){ }
}

public OperasiMidi(String fileMidi){


this();//memanggil default konstruktor pertama (tanpa
parameter);
load(fileMidi);
}
public boolean load(String fileMidi){
try{
namaFile = fileMidi;
suara = MidiSystem.getSequence(getURL(namaFile));
ambilSuara.setSequence(suara);
ambilSuara.open();
return true;
}catch(InvalidMidiDataException e){
return false;
}catch(MidiUnavailableException e){
return false;
}catch(IOException e){
return false;
}
}
public void setLooping(boolean ulang) {looping =ulang;}
public void setRepeat(int ulangi) {repeat= ulangi;}

public Sequence getSuara() { return suara;}


public String getFilename() {return namaFile;}
public boolean getLooping() {return looping;}
public int getRepeat() {return repeat;}
private URL getURL(String filename){
URL url = null;
try {
url = this.getClass().getResource(filename);
}catch(Exception e){ }
return url;
}

public boolean isLoaded(){


return (boolean)(ambilSuara.isOpen());
}

public void play(){


if(!ambilSuara.isOpen()) return;
if(looping){

ambilSuara.setLoopCount(Sequencer.LOOP_CONTINUOUSLY);
ambilSuara.start();
}else{
ambilSuara.setLoopCount(repeat);
ambilSuara.start();
}
}

public void stop(){


ambilSuara.stop();
}
}

Pemrograman Game Java 10


J.E.N.I.
BAB 5
GRAFIK VEKTOR

5.1 Pendahuluan

Grafik vektor banyak sekali digunakan pada pembuatan game-game 2

dimensi dimana terdapat banyak method yang sudah disediakan oleh Java

seperti ketika menangani pengujian tabrakan, menampilkan bound berupa

rectangle dan masih banyak lagi. Grafik vektor merupakan pelajaran dasar

yang harus dipelajari sebelum memasuki pembahasan grafik bitmap. pada

modul ini juga dibahas masalah tentang penanganan grafis full screen dimana

game yang akan dibuat dapat dimainkan dalam satu layar penuh.

5.2 Tujuan

Setelah mempelajari modul ini peserta diharapkan dapat:

• Mengetahui cara menggunakan interface Shape.

• Menggambar garis menggunakan class Graphics2D.

• Mengetahui perbedaan antara Rectangle2D dan RoundRectangle2D.

• Menggambar menggunakan Arc2D.

• Memahami fungsi dari Polygon.

• Membuat tampilan mode Full-Screen

• Menjalankan dan menutup mode Full-screen

5.3 Grafik Vektor

Java 2 Dimensi yang tepatnya terdapat pada Class Graphics2D yang

berada didalam java.awt.* menyediakan banyak fitur untuk bekerja dengan

grafik vektor 2D, yang memungkinkan pengguna untuk menggambar bentuk

Pemrograman Game Java 1


J.E.N.I.
persegi panjang, poligon dan bentuk-bentuk lain dengan mudah. Class-Class

yang ada didalam Graphics2D tidak hanya menggambar saja tetapi juga dapat

menggeser, merotasi, dan menskala bentuk.

5.4 Koordinat di Java

Berbeda dengan bahasa pemrograman lain, java mempunyai dua sistem

koordinat yang pertama user space adalah koordinat yang digunakan oleh

program java, semua yang berbentuk geometri di petakkan di koordinat ini.

Yang kedua yaitu device space adalah sistem koordinat device yang

tergantung pada output device yang digunakan.Bisanya konversi dari device

space ke user space dilakukan secara otomatis ketika proses rendering.

Gambar dibawah ini menunjukan perbeadaan antara user space dan device

space.

X=0,y=

Y
Y

X=0,y=
User Space Device Space
Gambar 5.1 Sistem Koordinat
5.5 Interface Shape

Sebelum ke pembahasan yang lebih dalam lagi sebaiknya kita

mengetahui terlebih dahulu tentang Interface Shape. Interface Shape ini

terdapat dalam package java.awt.* yang mendefinisikan tentang grafik primitif

seperti titik, garis, sudut, persegi panjang, kurva, dan elips seperti terlihat pada

Pemrograman Game Java 2


J.E.N.I.
gambar dibawah. Class-class seperti Rectangle menggunakan nilai integer,

sedangkan Rectangle2D menggunakan float dan double.

Gambar 3.16 Implementasi Interface Shape

5.6 Bekerja dengan Line2D

Tipe yang paling dasar dari shape adalah garis, dibuat dengan class

Line2D.Float, untuk membuat garis harus menuliskan secara spesifik koordinat

x dan y untuk titik awal dan akhir. Sebagai contoh:

Shape garis = new Line2D.Float(0,0,100,100);


Kode diatas, menentukan posisi garis dibuat mulai dari koordinat (0,0) sampai

dengan (100,100).

Line2D.Float adalah class mempunyai alternatif konstruktor yang dapat

menerima object Point2D sebagai parameter. Point2D juga sebuah Abstract

class dengan inner class Float dan Double untuk itu harus menggunakan

Point2D.Float atau Point2D.Double pada awal pembuatan object. Dibawah ini

adalah contoh yang sama menggambarkan garis menggunkan object point2D.


Pemrograman Game Java 3
J.E.N.I.
Point2D awal=new Point2D.Float(0,0);
Point2D akhir=new Point2D.Float(100,100);
Shape garis = new Line2D.Float(awal, akhir);

5.7 Bekerja dengan Rectangle2D & Ellipse

Rectangle membutuhkan titik awal (x, y) dan

(lebar, tinggi). Dibawah ini sebuah rectangle dimulai

pada titik (20,20) dengan lebar 50 dan tinggi 30.

Bentuk dari rectanggle dapat dilihat seperti gambar


Gambar 3.17 Rectanggle2D
disamping.

Shape rect = new Rectangle2D.Float(20,20,50,30);

Java juga menyediakan class

RoundRectangle2D yang memungkinkan

untuk menggambar dengan lengkungan pada

setiap sudut. Constructor pada class ini


Gambar 3.18 RoundRectanggle2D
menambahkan dua parameter lagi untuk menentukan lebar dan tinggi busur di

masing-masing sudut.

Shape round_rect = new RoundRectangle2D.Float(20,20,50,30,10,10);

Ellipse2D tidak jauh berbeda dengan

Rectangle2D hanya saja jika batas dari

rectangle adalah persegi maka ellipse adalah

lingkaran. Bentuk dari ellipse dapat dilihat

pada gambar disamping. Gambar 3.19 Ellipse2D

Shape ellipse = new Ellipse2D.Float(20,20,50,30);

Pemrograman Game Java 4


J.E.N.I.
5.8 Bekerja dengan Arc2D

Tipe dari shape yang sangat beguna adalah Arc2D. Yang perlu

diperhatikan dalam pembuatan Arc2D adalah: Sudut 0o dimulai dari sebelah

kanan atau dari arah jam 3. Perlu diingat bahwa penentuan sudut berlawanan

dengan arah jarum jam. Ada tiga macam parameter akhir yang digunakan pada

Arc2D yaitu:

OPEN

Konstanta ini mereperesentasikan bentuk busur terbuka yang berupa

sebuah garis kurva bagian luar dari ellipse.

PIE

Konstatanta ini merepresentasikan sebuah busur yang merupakan

potongan dari pie dimana garis kurva merupakan garis luar dari elipse dan

garis lurus dari ujung busur ke titik tengahnya.

CHORD

Konstanta ini merepresentasikan sebuah busur dimana terdapat garis

lurus yang menghubungkan antara kedua ujung busur.

Shape arc1 = new Arc2D.Float(20,20,50,30,90,90,Arc2D.OPEN);


//atau:
Shape arc1 = new Arc2D.Float(20,20,50,30,90,90,Arc2D.CHORD);
//atau:
Shape arc1 = new Arc2D.Float(20,20,50,30,90,90,Arc2D.PIE);

5.9 Bekerja dengan Polygon

Kelas polygon sedikit berbeda dengan Rectangle karena Polygon

mengijinkan untuk mendefinisikan bentuk sesuai dengan keinginan sendiri

dengan menggunakan pasangan nilai X dan Y. Untuk membuat sebuah

polygon cukup dengan sebuah titik tunggal atau sebuah polygon dengan empat

titik untuk menyalin class Rectangle.

Pemrograman Game Java 5


J.E.N.I.

int titikX[] = {200,100,130,270,300};


int titikY[] = {50,150,270,270,150};

Ketika membuat sebuah polygon dengan cara ini, perhatikan array X

dan Y harus berpasangan, maksudnya setiap nilai X harus berpasangan

dengan setiap nilai Y. Terkadang cukup membingungkan ketika anda harus

mendefinisikan bentuk polygon dengan menggunakan 2 buah array dari titik X

dan Y, jadi sebaiknya mendesain polygon pada kertas atau editor grafik terlebih

dahulu. Gambar dibawah menunjukkan desain dari polygon 5 sisi.

Gambar 5.2 Bentuk Gambar Koordinat Poligon

Melihat sebuah diagram dengan gambar akan sangat membantu,

khususnya ketika mempunyai pekerjaan membuat sebuah polygon yang

kompleks. Berikut ini adalah potongan kode pendefinisian polygone.

Polygon poligon= new Polygon(titikX, titikY, titikX.length);

Untuk menggambar sebuah bentuk, baik itu sebuah kotak, sebuah

polygon atau yang lain, ada dua method pilihan yaitu method fill() untuk

menggambar bentuk dengan warna didalamnya atau dapat menggunakan

method draw() untuk menggambar garis luar / border dari sebuah bentuk dalam

warna tertentu.

Pemrograman Game Java 6


J.E.N.I.

// Gambar Bentuk dengan didalamnya


g2d.fill(poligon);
// Gambar garis luarnya saja
g2d.draw(poligon);

Jangan lupa sebelum digambar seting warna pada Graphics2D sesuai

dengan keinginan,agar lebih mudah dalam setting warna sebaiknya

menggunakan class Color dengan pemanggilan attribut abstractnya yaitu jenis-

jenis warna.

// Setting Warna menggunakan Class Color sebagai parameter


g2d.setColor(Color.RED);

5.10 Membuat Tampilan Mode Full-Screen

Mode Full-screen berada didalam object java.awt.GraphicsDevice,

didalam singel atau multi-monitor dapat memanggil method getScreen-Devices

pada java.awt.GraphicsEnvironment dan untuk single monitor dapat

menggunakan getDefaultScreenDevices.

private GraphicsDevice device;


.........
.........
GraphicsEnvironment environment =
GraphicsEnvironment.getLocalGraphicsEnvironment();
device = environment.getDefaultScreenDevice();

5.10.1 Display Mode

DisplayMode adalah class yang disediakan oleh java untuk

mengenkapsulasi ukuran (tinggi, lebar dari monitor dengan satuan pixel),

ketajaman bit (banyaknya bit per pixel), dan refresh rate (frekwensi monitor

untuk kecepatan rata-rata dalam menampilkan citra). Untuk mengetahui

display mode pada layar cukup dengan memanggil method getDisplayMode

dan jika ingin menampilkan semua mode display yang didukung gunakan

Pemrograman Game Java 7


J.E.N.I.
method getDisplayModes. Sebelum mencoba untuk merubah display mode

sebaiknya periksa terlebih dahulu apakah sistem mendukung atau tidak

dengan memanggil method isDisplayChangeSupported jika meengembalikan

nilai true berarti sistem operasi mendukung untuk merubah display mode.

....
....
if (device.isDisplayChangeSupported())
{
device.setDisplayMode(displayMode);
}else{
System.out.println("Sistem Operasi Tidak Mendukung Mode
DisplayChange");
System.exit(0);
}
....
....

Untuk memeriksa apakah sistem operasi mendukung mode full-screen

atau tidak gunakan method isFullScreenSupported akan mengembalikan nilai

true apabila object GaphicsDevices mendukung mode Full-screen dan

mengembalikan nilai false jika tidak mendukung mode tersebut.

public void setFullScreen(DisplayMode displayMode,JFrame frame) {


if(device.isFullScreenSupported()){
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setUndecorated(true);
frame.setResizable(false);
device.setFullScreenWindow(frame);

if(displayMode != null && device.isDisplayChangeSupported()){


try {
device.setDisplayMode(displayMode);
}catch (IllegalArgumentException ex) { }
}

}else{
System.out.println("System tidak mendukung Mode Full-screen");
}

Method setUndecorated() diberi nilai true untuk menghilangkan title bar

dan bingkai pada frame, sedangkan method setResizeable() diberi nilai false

agar screen tidak dapat diubah-ubah ukurannya, kemudian untuk merubah

Pemrograman Game Java 8


J.E.N.I.
tampilan full-screen menggunkan method setFullScreenWindow() dimana

argumen yang dilewatkan adalah JFrame. Perlu diketahui bahwa JFrame yang

dilewatkan di dalam method setFullScreen(.... , ....) diatas tidak boleh di setting

setVisible(true) karena jika di setting demikian maka method FullScreen tidak

dapat berjalan sesuai dengan keinginan.

Selanjutnya mendefinisikan beberapa DisplayMode atau ukuran resolusi

yang akan digunakan untuk menentukan tinggi dan lebar layar yang diinginkan

hanya dengan menentukan array dari resolusi yang telah disediakan, listing

programnya adalah sebagai berikut.

private static final DisplayMode Mode_Pilihan[] = {


new DisplayMode(1024, 768, 32, 0),
new DisplayMode(1024, 768, 24, 0),
new DisplayMode(1024, 768, 16, 0),

new DisplayMode(800, 600, 32, 0),


new DisplayMode(800, 600, 24, 0),
new DisplayMode(800, 600, 16, 0),
new DisplayMode(640, 480, 32, 0),
new DisplayMode(640, 480, 24, 0),
new DisplayMode(640, 480, 16, 0)
};

Array Mode_Pilihan diatas akan diperiksa oleh method

periksaDisplayMode() yang melewatkan dua parameter yang bertujuan untuk

memeriksa apakah sistem yang kita gunakan mendukung resolusi yang

didefinisikan tersebut atau tidak.

public boolean perikasDisplayMode(DisplayMode mode1,DisplayMode


Mode2){
if (mode1.getWidth() != mode2.getWidth() ||
mode1.getHeight() != mode2.getHeight())
{ return false; }
if (mode1.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI &&
mode2.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI &&
mode1.getBitDepth() != mode2.getBitDepth())
{ return false; }
if (mode1.getRefreshRate() !=
DisplayMode.REFRESH_RATE_UNKNOWN &&
mode2.getRefreshRate() !=
DisplayMode.REFRESH_RATE_UNKNOWN &&
mode1.getRefreshRate() != mode2.getRefreshRate())
{ return false; }

Pemrograman Game Java 9


J.E.N.I.
return true;
}

Pada method periksaDisplayMode diatas akan mengembalikan nilai

berupa boolean yang artinya jika tidak cocok dengan kondisi yang diperiksa

diatas maka akan mengembalikan nilai false. Method ini akan dipanggil di

dalam sebuah method setResolusiLayar() dimana method ini melewatkan satu

parameter untuk menentukan index array yang akan di gunakan. Berikut ini

adalah listing programnya.

public DisplayMode setResolusiLayar(int nilai){


if(nilai >=9)nilai=0;
DisplayMode sistemMode[] = device.getDisplayModes();
for (int j = 0; j < sistemMode.length; j++) {
if (perikasDisplayMode(Mode_Pilihan[nilai],
sistemMode[j])) {
return Mode_Pilihan[nilai];
}
}
return null;
}

Seperti yang telah dijelaskan sebelumnya bahwa method

getDisplayModes() yang berada didalam class GraphicsDevice akan

memberikan nilai berupa array DisplayMode yang di dukung oleh sistem

operasi yang kita gunakan dan selanjutnya akan di cross-cek apakah sama

dengan DisplayMode yang kita tentukan pada parameter setResolusiLayar().

Setelah mendefinisikan variabel dan beberapa method diatas, sekarang

kita membuat satu method lagi yaitu tutupScreen() yang akan dipanggil apabila

user akan mengakhiri mode full-screen.

public void tutupScreen() {


Window window = device.getFullScreenWindow();
if (window != null) {
window.dispose();
}
device.setFullScreenWindow(null);
}

Pemrograman Game Java 10


J.E.N.I.
Pada class GraphicsDevice terdapat method getFullScreenWindow()

yang akan merepresentasikan jendela full-screen jika device dalam keadaan

mode full-screen dan mengembalikan nilai null apabila tidak dalam keadaan

mode full-screen. Method dispose() yang berada dalam class Window berfungsi

untuk membebaskan semua native screen yang digunakan dan akan

mengembalikan semua resource yang dipakai kepada sistem operasi. Jika

semua berjalan lancar maka method setFullScreenWindow() diberi nilai null

untuk menonaktifkan atau menutup mode full-screen.

5.10.2 Menjalankan dan Menutup Mode Full-Screen

Seperti yang kita ketahui bahwa class ScreenManager telah berhasil

dibuat sekarang mari kita mencoba untuk memanggil dan menjalankan method-

method yang ada didalam class tersebut seperti pada baris program berikut ini:

........
private ScreenManager screen;

public void () {
screen = new ScreenManager();
try {
DisplayMode displayMode = screen.setResolusiLayar(1);
screen.setFullScreen(displayMode,new PercobaanArc2d());
}
catch (Exception e){
screen.restoreScreen();
}
}
.......

Pada potongan kode diatas kita membuat object dari DisplayMode yang

digunakan untuk mengatur resolusi yang kemudian dilewatkan sebagai

argument pertama dan class yang akan ditampilkan dalam mode full-screen

yang dilewatkan pada argument kedua didalam method setFullScreen(). Untuk

method restoreScreen() dipanggil apabila terjadi eror atau jika ingin menutup

mode full-screen.

Pemrograman Game Java 11


J.E.N.I.
BAB 6
GRAFIK BITMAP

6.1 Pendahuluan

Inti dari game 2 dimensi sebenarnya terletak pada image, dimana image

yang telah dibuat ataupun diedit dari program seperti adobe photoshop, corel

draw dll, kemudian diurutkan menjadi satu bentuk. Sebagai contoh sebuah

pesawat yang untuh sampai pada pesawat yang hancur atau meledak

dikumpulkan menjadi satu kesatuan dan akan dipanggil saat dibutuhkan

(apabila terkena bom maka gambar pesawat yang ditampilkan meledak)

ilustrasinya seperti itu dan masih banyak lagi yang lain sesuai dengan game

yang akan dibuat.

6.2 Tujuan

Setelah mempelajari modul ini peserta diharapkan dapat:

• Mengetahui jenis-jenis format image

• Mengetahui cara meload file image

• Memuat gambar strip atau gambar bernomor

6.3 Pengenalan Image(Gambar)

Game sebenarnya tentu saja tidak hanya menggunakan primitive object

seperti grafik vektor melainkan juga menggunakan bitmap. Sebuah game

biasanya menggunakan format gambar GIF, JPEG, dan PNG.

Graphics Interchange Format atau gambar GIF sangat baik untuk

tampilan grafis cartoon yang menggunakan beberapa warna. Gambar GIF

menggunakan 256 elemen tabel warna untuk menyimpan informasi. Selah

Pemrograman Game Java 1


J.E.N.I.
satu dari table warna digunakan untuk representasi warna “Transparan” yang

mana tidak digambar oleh Program JAVA.

File Joint Photographic Experts Group (JPEG) menggunakan 3 byte atau

24 bit per pixel, dimana 1 byte untuk merah, hijau dan biru (komponen RGB).

File JPEG sangat bagus untuk gambar foto yang berukuran besar seperti

background game. File JPEG tidak menyediakan transparansi.

Format Portable Network Graphics (PNG) dimaksudkan untuk

menggantikan file GIF, dimana format ini menyertakan sebuah chanel Alpha

yang memungkinkan adanya area tembus cahaya(Transluccency) pada sebuah

gambar. Tembus cahaya (Transluccency) adalah bagian yang sangat berguna

untuk efek game seperti tembakan laser, asap, dll. Beberapa pengembang

lebih suka menggunakan PNG karena standarnya open source.

6.4 Memuat Gambar

Aplikasi java dapat dengan mudah memuat sebuah gambar

menggunakan class Toolkit.

Toolkit tk = new Toolkit.getDefaultTollkit();


Image = tk.getImage(“test.jpg”);

Ketika menggunakan Toolkit, class tersebut menggunakan thread untuk

memuat gambar secara terpisah. Karena class Toolkit menggunakan thread

maka program kita tidak akan pernah tahu kapan pemuatan gambar selesai

dilakukan, hasilnya gambar yang akan kita tampilkan bisa saja ditampilkan

sebagian karena belum selesai di muat atau bahkan tidak sama sekali.

Pemrograman Game Java 2


J.E.N.I.
Untuk menutupi kelamahan Toolkit, Java menyediakan class

MediaTracker, kita dapat menggunakan class ini agar aplikasi kita menunggu

sampai sebuah gambar dimuat.

Image logo = getToolkit().getImage("test.jpg");

MediaTracker mediaTracker = new MediaTracker(this);


mediaTracker.addImage(logo, 0);
try
{
mediaTracker.waitForID(0);
}
catch(InterruptedException e)
{
System.out.println(e);
}

Meskipun menggunakan MediaTracker mudah, namun akan sangat

membosankan jika harus melakukanya untuk setiap gambar yang akan dimuat

(bayangkan jika memuat 100 gambar). Ada cara yang lebih mudah yaitu

dengan menggunakan class ImageIO. Class ImageIO menyediakan cara

tercepat memuat image.

Image logo=null;
try
{
logo = ImageIO.read(new File(“test.jpg”));
}
catch(IOException e)
{
System.out.println(e);
}

Pemrograman Game Java 3


J.E.N.I.
6.5 Menggunakan BufferedImage

BufferedImage merupakan turunan dari class Image. Dengan

BufferedImage maka gambar yang akan di tampilkan akan dimuat sampai

selesai sehingga menghindari terjadinya penggambaran secara partial. Class

BufferredImage juga memiliki keunggulan dalam hal manupulasi gambar

melalui method-methodnya dan kemampuan untuk secara otomatis di ubah ke

dalam Managed Image oleh JVM. Managed Image memungkinkan adanya

akselerasi secara hardware.

BufferedImage im;

public void init( )


{
try {
im =ImageIO.read( getClass( ).getResource("ball.gif") );
}
catch(IOException e) {
System.out.println("Error Loading Image : "e.toString());
}
}

Cara termudah dan tercepat memuat image kedalam BufferedImage

adalah menggunakan class ImageIO. Menurut beberapa pengujian class

ImageIO lebih cepat 10% dari class ImageIcon, dan mungkin bisa semakin

besar jaraknya jika yang di muat adalah gambar beresolusi besar.Untuk

kepentingan lebih lanjut, BufferedImage yang akan kita buat akan di sesuaikan

dengan konfigurasi device yang kita miliki.

try {
BufferedImage im =
ImageIO.read(getClass( ).getResource(fnm));

int transparency = im.getColorModel( ).getTransparency( );


BufferedImage copy = gc.createCompatibleImage(

Pemrograman Game Java 4


J.E.N.I.
im.getWidth( ),im.getHeight( ),transparency );

Graphics2D g2d = copy.createGraphics( );

g2d.drawImage(im,0,0,null);
g2d.dispose( );
return copy;
}
catch(IOException e) {
System.out.println("Load Gambar " + fnm + " eror :\n" + e);
return null;
}

Tiga argumen dalam method createCompatibleImage adalah lebar,

tinggi dan nilai transparansi. Terdapat tiga nilai transparansi yaitu

Transparency.OPAQUE, Transparency.BITMASK, dan Transparency.

TRANSLUCENT . Opaque digunakan untuk mewakili gambar tanpa

kemampuan transparansi, contohnya gambar berekstensi JPG. Bitmask

digunakan untuk merepresentasikan area kosong (tidak digambar) yang dimiliki

gambar berformat GIF. Translucent digunakan PNG sebagai area tembus

cahaya. Tanpa adanya parameter transparansi kemungkinan besar gambar

akan di gambar tidak sesuai dengan yang diharapkan.

6.6 Membuat Image Manager

Sebelumnya telah dibahas cara memuat image kedalam aplikasi, tetapi

dalam game sebuah object nantinya tidak hanya terdiri dari gambar statis yang

bergerak hanya karena transformasi. Pada game 2 dimensi setiap object bisa

saja merupakan animasi bahkan ketika ia tidak mengalami transformasi. Untuk

mengakomodasi keperluan tersebut maka akan digunakan 2 teknik. Teknik

pertama adalah menyediakan sebuah gambar yang isinya terdiri dari

sequencial animasi suatu karakter. Dengan teknik ini gambar tidak akan di

Pemrograman Game Java 5


J.E.N.I.
tampilkan seluruhnya melainkan per frame ( setiap bagian dalam sequence

akan kita anggap sebagai frame). Teknik kedua adalah menggunakan gambar

yang berbeda untuk setiap frame namun dengan nama sama plus identitas

iterasi (contohnya : player1.png, player2.png, player3.png dst).

6.7 Mendefinisikan Aturan Pemuatan Gambar

Untuk membuat sebuah class yang akan menerima pemuatan semua

tipe gambar maka perlu mendefinisikan peraturan-peraturanya. Class

ImageManager akan memiliki method yang berbeda untuk setiap penganganan

jenis gambar yang berbeda.

Class Image Manager yang kita buat akan menggunakan sebuah object

HashMap untuk memetakan setiap object gambar dengan sebuah kunci unik.

Setiap gambar dapat diakses melalui method accessor dengan melewatkan

nama sebagai parameter. Setiap nilai yang di simpan dalam HashMap adalah

sebuah ArrayList. ArrayList digunakan karena anggota dari sebuah record

dalam HashMap bisa berisi lebih dari satu gambar. Mungkin class ini sedikit

rumit dan membingungkan, tetapi class ini akan sangat berguna untuk

keperluan game berikutnya.

Untuk keperluan pemuatan gambar kedalam class ini, kita akan

membuat 3 method. Method pertama digunakan untuk memuat gambar

tunggal, method kedua digunakan untuk memuat gambar berurutan dengan

postfiks urutan gambar, dan method terakhir digunakan untuk memuat gambar

strip (frame). Setiap method akan menggunakan sepasang method yang

berfungsi memisahkan prefix dan postfix parameter method bersangkutan dan

sebuah method untuk me-muat image (jangan bingung, sebenarnya ketiga

Pemrograman Game Java 6


J.E.N.I.
method yang disebutkan sebelumnya tidak berfungsi memuat gambar secara

langsung melainkan berfungsi me-metakan gambar yang di muat kedalam

HashMap).

private String getPrefix(String fnm)


// mengambil String sebelum '.' dari nama file
{
int posn;
if ((posn = fnm.lastIndexOf(".")) == -1) {
System.out.println("Prefix tidak ditemukan untuk nama
file: " + fnm);
return fnm;
}
else
return fnm.substring(0, posn);
}

private String getPosfix(String fnm)


// mengambil String sesudah '.' dari nama file
{
int posn;
if ((posn = fnm.lastIndexOf(".")) == -1) {
System.out.println("Posfix tidak ditemukan untuk nama
file:" + fnm);
return fnm;
}
else
return fnm.substring(posn);
}

6.8 Gambar Tunggal

Untuk meload gambar tunggal, method yang digunakan sama dengan

method pemuatan gambar yang telah dibahas. Method ini mengembalikan nilai

boolean sehingga kita bisa menggunakannya untuk memastikan gambar

berhasil dimuat.

public boolean loadSingleImage(String fnm)


{

Pemrograman Game Java 7


J.E.N.I.
String name = getPrefix(fnm);

if (imagesMap.containsKey(name)) {
System.out.println( "Error: " + name + " sudah digunakan");
return false;
}

BufferedImage bi = loadImage(fnm);
if (bi != null) {
ArrayList imsList = new ArrayList( );
imsList.add(bi);
imagesMap.put(name, imsList);
System.out.println(" disimpan " + name + "/" + fnm);
return true;
}
else
return false;
}

6.9 Gambar Ber-Nomor

Method yang menangani gambar ber-nomor bekerja dengan

memisahkan prefix dan postfix lalu menambahkan urutan gambar setelah prefix

dan menggabungkan kemabali dengan postfix menjadi argumen method

LoadImage(). Seperti halnya pemuatan gambar tunggal, nama unik yang

dugunakan sebagai kunci HashMap adalah prefix dari parameter method ini.

Dig0.gif Dig1.gif Dig2.gif Dig3.gif Dig4.gif Dig5.gif


Gambar 6.1 Gambar Bernomor

public int loadNumImages(String fnm, int number)


{
String prefix = getPrefix(fnm);
String postfix = getPosfix(fnm);

Pemrograman Game Java 8


J.E.N.I.
String imFnm;
BufferedImage bi;
ArrayList imsList = new ArrayList();
int loadCount = 0;
for(int i=0; i < number; i++) {
imFnm = prefix + i + postfix;
if ((bi = loadImage(imFnm)) != null) {
loadCount++;
imsList.add(bi);
}
}

if (loadCount == 0)
System.out.println("Tidak ada images dengan nama " +
prefix);
else
imagesMap.put(prefix, imsList);

return loadCount;
}

6.10 Gambar Strip

Seperti yang telah di singgung, gambar strip sebenarnya adalah

susunan gambar berurutan yang membentuk sebuah animasi dalam sebuah

file citra. Biasanya gambar strip digunakan untuk animasi dengan pixel yang

kecil. Gambar strip unggul dalam penggunaan waktu proses dibandingkan

gambar ber-nomor. Karena merupakan potongan gambar, maka setiap

potongan harus di pisahkan dari gambar asli sebelum di render.

Gambar 6.2 Gambar Strip 6x1

Pemrograman Game Java 9


J.E.N.I.

Gambar 6.3 Gambar Strip 8x4

Cara kerja dari method yang akan kita buat adalah memisahkan setiap

potongan gambar kedalam satu record pada ArrayList. Pemisahan akan

dilakukan oleh method loadStripImageArray().

public int loadStripImages(String fnm, int column,int row)


{
String name = getPrefix(fnm);

BufferedImage[] strip = loadStripImageArray(fnm, column, row);


if (strip == null)
return 0;

ArrayList imsList = new ArrayList();


int loadCount = 0;

for (int i=0; i < strip.length; i++) {


loadCount++;
imsList.add(strip[i]);
}

if (loadCount == 0)
System.out.println("Tidak ada image dengan prefix " +
name);
else
imagesMap.put(name, imsList);

return loadCount;
}

public BufferedImage[] loadStripImageArray(String fnm, int


column,int row)
{
if (column <= 0) {
System.out.println("column <= 0; return null");
return null;
}

BufferedImage stripIm;
if ((stripIm = loadImage(fnm)) == null) {
System.out.println("Return null");
return null;
}

Pemrograman Game Java 10


J.E.N.I.

int imWidth = (int) stripIm.getWidth() / column;


int imHeight =(int) stripIm.getHeight()/row;

int transparency = stripIm.getColorModel().getTransparency();

BufferedImage[] strip = new BufferedImage[column*row];


Graphics2D stripGC;

for (int i=0;i<row;i++)


{
for(int j=i*column;j<(i+1)*column;j++)
{
int fx=(j%column)*imWidth;
int fy=i*imHeight;
strip[j] = gc.createCompatibleImage(imWidth,
imHeight, transparency);

stripGC = strip[j].createGraphics();
stripGC.setComposite(AlphaComposite.Src);

stripGC.drawImage(stripIm,0,0, imWidth,imHeight,
fx,fy, fx+imWidth,fy+imHeight,null);
stripGC.dispose();
}
}
return strip;
}

Bagian kode yang di cetak tebal adalah fungsi utama dari method

pemuatan gambar strip. Untuk menentukan parameter pemotongan gambar

pada method drawImage digunakan dua buah variabel yaitu fx dan fy. Kedua

buah variabel tersebut menjadi titik awal pemotongan gambar.

int fx=(j%column)*imWidth;
int fy=i*imHeight;

Variabel fx menentukan titik x yang didapat dengan mendapatkan hasil

modulo nomor kolom dengan jumlah kolom di kali besar gambar per potong.

Sedangkan variabel fy menentukan titik y dengan cara mengalikan nomor baris

dengan tinggi gambar.

6.11 Mengakses Gambar

Setelah berhasil memuat gambar, selanjutnya perlu mengakses gambar

tersebut. Karena menggunakan HashMap untuk menyimpan gambar maka

Pemrograman Game Java 11


J.E.N.I.
untuk mengaksesnya baik gambar tunggal, gambar ber-nomor ataupun gambar

strip menggunakan prefix dari gambar tersebut. Ada tiga versi untuk

mengakses gambar, versi pertama menerima satu parameter berupa nama

gambar, versi kedua menerima dua parameter yaitu nama gambar dan posisi

gambar dalam ArrayList dan versi ketiga mengembalikan semua gambar yang

terdapat dalam ArrayList dalam nama tertentu.

public BufferedImage getImage(String name)


{
ArrayList imsList = (ArrayList) imagesMap.get(name);
if (imsList == null) {
System.out.println("Tidak ada gambar dengan nama " +
name);
return null;
}

return (BufferedImage) imsList.get(0);


}

public BufferedImage getImage(String name, int posn)


{
ArrayList imsList = (ArrayList) imagesMap.get(name);
if (imsList == null) {
System.out.println("Tidak ada gambar dengan nama " +
name);
return null;
}

int size = imsList.size();


if (posn < 0) {
return (BufferedImage) imsList.get(0); // return first
image
}
else if (posn >= size) {
int newPosn = posn % size; // modulo
return (BufferedImage) imsList.get(newPosn);
}
return (BufferedImage) imsList.get(posn);
}

public ArrayList getImages(String name)


{
ArrayList imsList = (ArrayList) imagesMap.get(name);
if (imsList == null) {
System.out.println("Tidak ada gambar dengan nama " +
name);
return null;
}

return imsList;
}

Pemrograman Game Java 12


J.E.N.I.

6.12 Memainkan Gambar Bernomor dan Gambar Strip

Setelah berhasil memuat dan mengakses gambar masih perlu mengatur

bagaimana gambar animasi (Bernomor dan Gambar Strip: selanjutnya disebut

gambar animasi) di tampilkan ke layar, akan dibuat sebuah class lagi yang

khusus menangani gambar animasi. Class ini akan mengatur urutan gambar

keberapa yang dapat di akses melalui getCurrentImage(). Konstruktor class

akan menerima parameter berupa nama gambar, periode animasi, panjang

animasi secara keseluruhan, boolean pengatur pengulangan dan object

ImageManager.

ImagesAnimator animator = new ImagesAnimator (imagesName,


animPeriod, seqDuration, isRepeating, imsLoader);

Proses update gambar bertumpu pada method updateTicks() yang

dipanggil pada pengendali game utama. Harus diperhatikan bahwa dalam

pemberian nilai parameter adalah besarnya nilai animPeriod dan seqDuration,

kedua parameter ini akan sangat berpengaruh jika animasi yang dijalankan

diset non-repeat. Ketika animasi di set no-repeat, maka harus menghitung

jumlah gambar yang ada dalam sebuah ArrayList. Nilai seqDuration harus

cukup besar hingga hasil bagi (showPeriod) dengan jumlah gambar masih

dibawah nilai animPeriod. Jika showPeriod kurang dari animPeriod maka

animasi tidak pernah berhenti pada saat semua urutan gambar telah

ditampilkan.

Untuk mengetahui kondisi selesai tidaknya sebuah urutan animasi perlu

mendesign sebuah interface yang berfungsi layaknya Listener seperti

ActionListener dll. Class listener ini memiliki sebuah method abstract yang

Pemrograman Game Java 13


J.E.N.I.
harus diimplementasikan. Class Listener menerima kejadian yang dikirimkan

oleh class ImageAnimator.

numbersPlayer = new ImageAnimator ("numbers", PERIOD, 1, false,


imsLoader);
numbersPlayer.addImageSequenceListener(this);

Method updateTicks() berfungsi menentukan posisi gambar dalam

ArrayList sekaligus mengirim kejadian selesainya sebuah urutan animasi

kepada ImageSequenceListener (hanya jika isReapeating tidak di set false).

public void updateTick( )


{
if (!ticksIgnored) {
// update total waktu animasi, modulo seq duration
animTotalTime = (animTotalTime + animPeriod) %
(long)(1000 * seqDuration);

// menentukan posisi gambar terkini


imPosition = (int) (animTotalTime / showPeriod);

if ((imPosition == numImages-1) && (!isRepeating)){


// menghentikan update tick pada gambar ini
ticksIgnored = true;
if (watcher != null)
watcher.sequenceEnded(imName);
}
}
}

Pengaksesan gambar terkini di lakukan melalui method

getCurrentImage() yang mengembalikan dalam gambar ArrayList pada posisi

yang ditentukan oleh imPosition.

public BufferedImage getCurrentImage( )


{
if (numImages != 0)
return imsLoader.getImage(imName, imPosition);
else
return null;
}

Pemrograman Game Java 14


J.E.N.I.
BAB 7
SKALA, ROTASI DAN TRANSLASI

7.1 Pendahuluan

Pada sebuah game skala rotasi dan translasi sangat dibutuhkan ketika

membuat sebuah game yang menggunakan grafik vektor dan grafik bitmap.

Penggunaannya seperti pemindahan sebuah object, memper-besar atau

memper kecil ukuran peta ataupun merotasi arah dari object seperti pesawat,

dll.

7.2 Tujuan

Setelah mempelajari modul ini peserta diharapkan dapat:

• Memahami fungsi-fungsi dari Skala,Rotasi dan Translasi

• Mengimplementasikan Skala pada sebuah Object

• Menerapkan Rotasi dan Translasi pada Object

7.3 Translasi
Translasi adalah bentuk yang paling sederhana dari transformasi, yaitu

metode pemindahan koordinat asal ke koordinat baru. Matriks transformasi

untuk translasi dengan vektor translasi adalah :

Maka koordinat baru dari hasil translasi adalah :

x’ = x + tx

y’ = y + ty

Sebaiknya tidak memikirkan rumus diatas karena java telah memberikan

kemudahan kepada programer untuk melakukan proses translasi, yaitu dengan

Pemrograman Game Java 1


J.E.N.I.
menggunakan method yang telah disediakan oleh Graphics2D seperti dibawah

ini:

g2d.translate(nilai1, nilai2);
g2d.fill(shape);

Dengan demikian maka object yang akan digambar dengan fill atau draw

akan dipidah dari koordinat lama ke koordinat yang baru, diamana nilai1 dan

nilai2 akan ditambahkan ke posisix dan posisiy yang pertama kali di definisikan

dan menghasilkan posisi baru hasil penjumlahan tadi yaitu (posisix+nilai1) dan

(posisiy+nilai2).

7.4 Rotasi

Rotasi adalah bentuk transformasi dengan dengan memutar sebuah

objek, ada dua macam cara atau rumus untuk merotasi object di java yaitu

berpatokan pada titik acuan (0,0) atau (p,q) dibawah ini adalah rumus yang

digunakan untuk operasi tersebut.

Rotasi dengan sudut putar dengan titik acuan (0,0) adalah:

Maka, koordinat baru hasil rotasi adalah :


x’ = x cos – y sin
y’ = x sin y + y cos

Pemrograman Game Java 2


J.E.N.I.

170
Titik
Pusat

360o
18 Object 0o

90o
Arah
Perputaran

Gambar 7.1 Arah Perputaran Object

Penggunaan sin,cos yang sangat membungungkan, di java telah

menyediakan method rotate dari class Graphics2D dengan pendefinisian

sebagai berikut:

g2d.rotate(Math.toRadians(1));
g2d.fill(shape);

Radian dan sudut adalah dua cara untuk menghitung sesuatu yang

sama. Pada sebuah lingkaran terdapat 360 derajat dan juga 2*PI radian dalam

sebuah lingkaran. Sebagai contoh:

Jika diketahui : Sudut 180o = PI = 3.141592653589793 Radian

Maka dapat dituliskan :

Radian = (Sudut/180) * PI

Untuk 90o = (90 / 180) * PI = 1.5707963267948966 Radian

Untuk 300o = (300 / 180) * PI = 5.235987755982989 Radian

Supaya parameter yang dilewatkan melalui method rotate(...) tepat

sesuai dengan sebuah lingkaran maka kita harus menggunakan nilai Radian,

Pemrograman Game Java 3


J.E.N.I.
yang dapat terlihat pada contoh diatas bahwa object akan di rotasi sebanyak 1

derajat atau = 0.017453292519943295 Radian.

Rotasi dengan sudut putar dengan titik acuan (p,q) adalah :

Dengan demikian, koordinat baru hasil rotasinya adalah:

x’ = x cos - y sin + p - p cos + q sin


y’ = x sin y + y cos + q – p sin – q cos

Untuk rotasi dengan sudut acuan parameternya ada 3 yang dapat dituliskan

sebagai berikut:

g2d.rotate(Math.toRadians(1),nilai1,nilai2);
g2d.fill(shape);

Parameter pertama digunakan untuk menentukan sudut, sedangkan

parameter yang kedua dan ketiga digunakan untuk menentukan titik pusat

perputaran berdasarkan posisix dan posisiy sebelumnya atau (posisix+nilai1)

dan (posisiy+nilai2).

7.5 Skala

Skala adalah operasi untuk membuat sebuah objek lebih besar atau

lebih kecil dari bentuk aslinya. Matriks transformasi untuk penskalaan dengan

faktor skala terhadap sumbu x dan sumbu y adalah:

Maka, koordinat baru yang dihasilkan adalah:

x’ = sx . x
Pemrograman Game Java 4
J.E.N.I.
y’ = sy . y

Jangan sekali-kali terpancing dengan rumus diatas yang sangat rumit

dan membingungkan itu hanya sebagai gambaran nyata dari operasi

matematisnya yang sebenarnya dilakukan oleh class Graphics2D. Java telah

menyediakan methodnya dimana seorang programer dipermudah tanpa harus

menghitung perkalian matriksnya.

g2d.scale(nilai1, nilai2);
g2d.fill(shape);

Perlu diingat bahwa skala digunakan untuk membuat suatu object di

perbesar atau diperkecil. Parameter nilai1 diatas dikalikan dengan lebar object

sedangkan nilai2 dikalikan dengan tinggi object.

7.6 Menggunakan Class AffineTransform

Transformasi sudah dipelajari langsung menggunakan method yang

disediakan Graphics2D. Setiap operasi transformasi hanya bisa dilakukan

sekali untuk sebuah shape. Sayangnya shape tidak digunakan dalam game

sebenarnya. Untuk keperluan tersebut maka akan menggunakan class

AffineTransform. Class AffineTransform menyediakan operasi transformasi

matrix seperti yang telah dibahas sebelumnya. Selain itu bisa menggabungkan

beberapa transformasi matrix sekaligus sebelum di terapkan pada sebuah

gambar. AffineTransform Menyediakan beberapa transformasi instant seperti

rotasi, translasi serta scalasi.

Untuk keperluan transformasi maka akan dibuat sebuah class

sederhana (class ImageEfek). Class ini menyediakan 3 buah method yaitu

getRotatedImage() untuk transformasi rotasi, getScaledImage() untuk

Pemrograman Game Java 5


J.E.N.I.
transformasi scala dan getTranslatedImage() untuk transformasi transalasi.

Masing masing method sebenarnya memiliki cara kerja yang sama kecuali

pemberian AffineTransform sesuai dengan method yang bersangkutan. Method

getRotatedImage() (dan kedua method lainya) dibawah ini bekerja dengan

membuat image penampung yang akan di gunakan sebagai tempat hasil

transformasi.

public BufferedImage getRotatedImage(BufferedImage src, int angle)


{
if (src == null) {
System.out.println("Image kosong");
return null;
}

int transparency = src.getColorModel( ).getTransparency( );


BufferedImage dest =
gc.createCompatibleImage( src.getWidth( ), src.getHeight( ),
transparency );
Graphics2D g2d = dest.createGraphics( );
AffineTransform origAT = g2d.getTransform( );
AffineTransform rot = new AffineTransform( );
rot.rotate( Math.toRadians(angle), src.getWidth( )/2,
src.getHeight( )/2);
g2d.transform(rot);
g2d.drawImage(src, 0, 0, null);
g2d.setTransform(origAT);
g2d.dispose( );

return dest;
}

Secara teknis anda hanya perlu menerapkan satu atau lebih

transformasi kedalam sebuah AffineTransform sebelum digunakan dalam

transformasi gambar. Namun satu hal yang perlu diberi perhatian lebih adalah

ketika menggunakan rotasi. Perhatikan ilustrasi berikut :

Pemrograman Game Java 6


J.E.N.I.

Gambar 7.2 Transformasi Object

Ketika menggunakan transformasi yang langsung digambarkan oleh

graphics ke layar tanpa disimpan dalam object image, maka jangan khawatir

akan terjadinya clipping gambar. Namun masalahnya tujuan sebenarnya

adalah membuat sebuah class yang menyediakan fungsi transormasi secara

langsung. Artinya perlu menggunakan sebuah image lagi untuk menampung

hasil dari transformasi. Ketika membuat object image paling tidak perlu

menentukan panjang dan lebar image tersebut. Penentuan perluasan image

penampung ini yang sedikit bermasalah, hal itu karena kita tidak tahu bentuk

citra yang terdapat pada object image yang di transformasi. Seperti ilustrasi

diatas, bagian a menunjukan proses transformasi sempurna karena luasan

image penampung sesuai dengan image yang di transformasi. Hal tersebut

berkebalikan dengan bagian b, luasan image penampung tidak sesuai

sehingga terjadi clipping.

Untuk mengantisipasi hal tersebut anda perlu memastikan besar

transparant area dari sebuah gambar yang akan ditransformasi sesuai dengan

kebutuhan. Atau anda juga bisa merubah secara langsung luasan image

Pemrograman Game Java 7


J.E.N.I.
penampung dengan nilai maximum antara panjang dan lebar image yang akan

di transformasi.

Method getRotatedImage() diatas merotasi image pada titik tengah

gambar atau dapat menambahkan beberapa method lagi seperti rotasi

terhadap sumbu tertentu dan penggabungan beberapa transformasi sekaligus.

Pemrograman Game Java 8


J.E.N.I.
BAB 8
SPRITE & COLLISION DETECTION

8.1 Pendahuluan

Sebuah game pasti tidak lepas dari karakter dan animasi. Bisa saja

karakternya berupa seekor burung gelatik yang terbang kesana kemari

memburu mangsanya. Bagaimana karakter burung gelatik berpindah tempat

atau menangkap mangsanya? modul ini akan membahas pemrograman dasar

pembentukan karakter serta bagaimana karakter tersebut berinteraksi terhadap

karakter lainya.

8.2 Tujuan

Setelah mempelajari modul ini peserta diharapkan dapat:

• Mendefinisikan dan Mengembangkan Sprite

• Mengenali jenis-jenis pengujian tabrakan

• Mengimlpementasikan pengujian tabrakan

8.3 Sprite

Sprite adalah hasil enkapsulasi object dalam sebuah game. Sebagai

contoh ketika menggunakan object shape atau gambar seperti pesawat, maka

perlu dilakukan proses transformasi seperti translasi dan rotasi,(tranformasi

pada java bekerja dengan cara menduplikasi object asli). Ketika proses

translasi dilakukan pada sebuah object, maka object yang di gambarkan pada

layar adalah duplikatnya sedangkan object asli tetap pada posisi awal oleh

sebab itu maka mustahil melakukan deteksi tabrakan atau bahkan sekedar

mengetahui lokasi object terkini.

Pemrograman Game Java 1


J.E.N.I.
Dengan metode enkapsulasi, maka setiap object sprite mempunyai

atribut dan method-method yang dibutuhkan dalam game. Selain itu sprite juga

tidak hanya menyediakan accesor dan mutator posisi object tetapi juga dapat

menyediakan arah pandang object, arah gerak object dan method lain yang

dibutuhkan. Class sprite nantinya juga dapat di gunakan sebagai parent dari

actor-actor dalam game sehingga masing-masing actor dapat memiliki behavior

tersendiri.

Sebenarnya mendefinisikan sebuah sprite untuk semua tipe game

sangat sulit karena setiap jenis game mempunyai karakteristik tersendiri.

Sebuah game arcade seperti GalaktikWar membutuhkan object yang dapat

bergerak 360°, sedangkan game isometric hanya mendefinisikan 4, 8 atau 16

arah gerak dan game side scrolling seperti MarioBros hanya butuh 3 arah

gerak. Selain itu juga pengujian benturan yang membutuhkan akurasi berbeda

untuk masing-masing game.

8.4 Mengimplementasikan Class Sprite

Seperti yang telah di singgung, class Sprite yang dibuat akan

mendefinisikan atribut-atribut dasar sebuah object dalam game. Class ini tidak

akan membuat sebuah class Sprite yang sudah lengkap dengan efek suara,

pengkondisian object dll. Sebaliknya hanya membuat class sprite sederhana

yang nantinya dapat diturunkan oleh class lainya yang lebih spesifik.

8.5 Konstruktor Sprite

Class sprite diinisialisasi dengan posisi x dan y , object ImageManager

serta nama gambar.

protected ImageManager imsMgr; // Image pool


protected int locx, locy; // Lokasi Sprite

Pemrograman Game Java 2


J.E.N.I.
protected int dx, dy; // Langkah sprite (dalam pixel)

public Sprite(int x, int y, ImageManager imsMgr, String name)


{
locx = x; locy = y;
dx=dy=0;
this.imsMgr = imsMgr;
setImage(name); // set default gambar
}

Variabel dx dan dy berfungsi menentukan nilai langkah sprite. Setiap

perpindahan tidak dilakukan dengan mengubah langsung ke variabel x dan y

namun dengan menentukan nilai lebar langkah dan selanjutnya penambahan

dilakukan setiap kali updateSprite() dipanggil.

8.6 Gambar Sprite

Sebelumnya telah dibuat sebuah ImageManager yang menangani

pemuatan gambar, jadi dalam class Sprite ini tinggal menggunakanya.

private String imageName; // nama gambar


private BufferedImage image; // Penampung gambar
private int width, height; // Dimensi gambar

private ImagesAnimator animator; // untuk memainkan strip dan


numbered
private boolean isLooping; // toogle image berulang

public void setImage(String name)


{
imageName = name;
image = imsMgr.getImage(imageName);
if (image == null) {
System.out.println("Tidak ada gambar dengan nama " +
imageName);
}

Pemrograman Game Java 3


J.E.N.I.
else {
width = image.getWidth();
height = image.getHeight();
}
// gambar diasumsikan gambar tunggal
animator = null;
isLooping = false;
}

Selain menyediakan akses ke gambar tunggal, sprite juga

memungkinkan menggunakan gambar ber-nomor atau gambar strip.

Penggunaan gambar strip dapat dilakukan dengan memanfaatkan class

ImageAnimator melalui method loopImage().

public void loopImage(int animPeriod, double seqDuration,boolean


isRepeating)
{
if (imsManager.numImages(imageName) > 1) {
animator = null; // untuk garbage collection
animator = new ImageAnimator(imageName, animPeriod,
seqDuration,isRepeating, imsManager);
isLooping = true;
}
else
System.out.println(imageName + " bukan gambar berurutan");
}

8.7 Bounding Box

Meskipun pengujian trabrakan akan lebih di utamakan untuk di turunkan,

kelas sprite akan menyediakan sebuah Rectangle dengan besar sesuai dengan

besar gambar untuk pengujian tabrakan.

public Rectangle getBoundingBox() {


return new Rectangle(locx, locy, width, height);
}

Pemrograman Game Java 4


J.E.N.I.
8.8 Update Sprite

Sprite memiliki atribut dx dan dy yang merupakan besar velocity sprite

tersebut. Kedua atribut tersebut menentukan kecepatan dan arah gerak dari

sprite tersebut. Atribut velocity akan digunakan sebagai increment posisi sprite

setiap kali sprite di update. Selain perubahan posisi sprite, update pada sprite

juga akan mengirimkan pesan ke object ImageAnimator jika sprite tersebut

memiliki lebih dari satu gambar.

public void updateSprite() {


if (isActive()) {
locx += dx;
locy += dy;
if (isLooping)
// update posisi gambar pada animator
animator.updateTick();
}
}

Kecepatan gerak sprite akan sangat dipengaruhi banaknya pemanggilan

method update. Sebuah sprite dengan dx=5 yang di-update sebanyak 40 kali

dalam satu detik berarti sprite tersebut akan berpindah 5 x 40 pixel, nilai yang

berbeda akan diperoleh jika kecepatan update berubah.

8.9 Menggambar Sprite

Method ini memiliki input berupa object Graphics untuk menampilkan

gambar. Jika sprite memiliki lebih dari satu gambar, method ini akan meminta

gambar terkini pada object ImageAnimator.

public void drawSprite(Graphics g) {


if (isActive()) {
if (isLooping)
image = animator.getCurrentImage();
g.drawImage(image, locx, locy, null);

Pemrograman Game Java 5


J.E.N.I.
}
}

8.10 Collision Detection

Pada bahasan sprite terdapat method getBound(), method tersebut

menyediakan rectangle yang akan digunakan dalam proses pendeteksian

tabrakan antar sprite. Perhatikan visualisasi beberapa cara pendeteksian

berikut ini:

Gambar 8.1 Mendeteksi Tabrakan

Gambar pertama menunjukan visualisasi yang digunakan dalam class

sprite. Cara ini adalah cara paling mudah dan tercepat, namun seperti yang

terlihat diatas cara ini kurang bagus secara akurasi. Program akan mendeteksi

terjadinya tabrakan ketika bound kedua sprite bersinggungan meskipun secara

kasat mata sprite tersebut sama sekali tidak bersinggungan. Cara ini ideal

untuk game yang tidak terlalu memperhatikan akurasi deteksi tabrakan atau

game yang menggunakan sprite mendekati kotak.

Cara kedua adalah menggunakan apa yang disebut reduzed size

bounding box ( kotak batas yang diperkecil). Cara ini cukup mudah, hanya

perlu mengurangi beberapa pixel dari ukuran sebenarnya dari image sprite

sehingga pendeteksian masuk lebih dalam seperti terlihat pada gambar cara

diatas lebih akurat dari pada cara pertama.

Pemrograman Game Java 6


J.E.N.I.
Cara ketiga bisa dikatakan cara paling akurat dari ketiga cara diatas.

Idenya adalah menyediakan beberapa bounding box sekaligus untuk keperluan

pendeteksian tabrakan. Karena menggunakan banyak bounding box, maka di

munkinkan penyesuaian bounding box dengan bentuk gambar pada sprite.

Dengan cara ini bisa menggunakan sebanyak mungkin bounding box agar

lebih akurat dengan catatan semakin banyak bounding box maka akan semakin

banyak waktu yang diperlukan untuk mendeteksi tabrakan antar sprite.

Pemrograman Game Java 7


J.E.N.I.
BAB 9
PEMROGRAMAN SOCKET

9.1 Pendahuluan

Seiring dengan pesatnya perkembangan networking di dunia ternyata

juga sangat memberi dampak positif yang besar terhadap industri-industri

pembuat game seperti yang kita rasakan saat ini dimana banyak game online

yang bermunculan di internet diantarannya seperti xian, ragnarok, warcraf dan

masih banyak lagi. Bagi para pembuat, pengembang game ataupun yang

tertarik untuk membuat game, tentunya sangat menginginkan game yang

dihasilkan tidak hanya berjalan secara stand alone tetapi juga di dalam jaringan

(multi player). Dalam hal ini, Java dapat menjawab dan memberi solusi kepada

para developer untuk membuat game baik di jaringan local maupun global

dengan menyertakan pemrograman socket agar permasalahan-permasalahan

tersebut dapat teratasi.

9.2 Tujuan:

Setelah mempelajari modul ini peserta diharapkan dapat:

• Memahami konsep jaringan menggunakan socket.

• Membuat program client-server sederhana.

• Memahami dan mampu mengolah data disisi client maupun server

9.3 Socket

Socket adalah salah satu cara untuk komunikasi antar komputer,

umumnya lewat network atau internet. Socket biasa digunakan untuk

Pemrograman Game Java 1


J.E.N.I.
pemrograman berbasis client-server yang dapat menggunakan socket TCP/IP

atau socket UDP

9.3.1 Socket Client

Socket adalah sebuah penghubung antara dua host, yang dapat

dibangun dengan tujuh dasar operasi yaitu:

 Menghubungkan untuk mengendalikan mesin atau perangkat

 Mengirim data

 Menerima data

 Menutup koneksi

 Bergantung pada port

 Mendengarkan data yang masuk

 menerima koneksi dari mesin yang dikendalikan berdasarkan sebuah port

Class Socket pada Java,digunakan oleh client dan server yang

mempunyai method yang menangani keempat operasi diatas.Tiga operasi

berikutnya hanya dibutuhkan untuk server yang menunggu client untuk koneksi

ke server cukup dengan mengimplementasikan class ServerSocket.

Data yang dikirimkan melalui internet di dalam sebuah paket disebut

datagra. Setiap datagram berisi header dan payload. header berisi alamat dan

port untuk setiap paket, addres dan port untuk tiap paket yang masuk,

sedangkan payload berisi data, sejak datagram mempunyai batasan jarak,

memungkinkan sebuah paket hilang atau corupted ketika dikirimkan dan

membutuhkan pegiriman lagi, untungnya socket memberikan kesempatan

kepada programer untuk melakukan koneksi ke jaringan, sebagai contoh

Pemrograman Game Java 2


J.E.N.I.
stream di dalam byte dapat dituliskan dan dapat dibaca. Socket melindungi

programer dari low-level yang detail dari sebuah jaringan, seperti deteksi

kesalahan (error detection), ukuran paket, pengiriman kembali sebuah paket,

alamat jaringan dan masih banyak lagi.

Java.net.Socket adalah JFC yang digunakan untuk melakukan operasi

TCP client-side. Untuk mendefinisikan host dapat menggunakan InetAddress

atau String sedangkan untuk definisi port menggunakan int mulai dari 0 sampai

65.535. Definisi constructornya dapat dilihat sperti dibawah ini:

try {
Socket koneksi = new Socket(“192.168.12.138”, 80);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

Jika host tidak ditemukan atau tidak berfungsi maka konstructor akan

melemparkan UnknownHostException tetapi jika socket tidak dapat dibuka

maka akan dilemparkan ke IOException ada beberapa hal yang

menyebabkan permintaan koneksi gagal misalnya host tujuan mungkin tidak

menerima koneksi, koneksi dial-up terputus atau permasalahan routing

menolak host tujuan(rejected).Selain metode diatas definisi socket dapat

dilakukan dengan menggunakan class InetAddress.

9.3.2 Socket Server

Socket Server digunakan untuk menangani seluruh request dari jaringan

yang disebut dengan socket client. Berikut ini adalah cara pendefinisian

konstruktor dari class ServerSocket yang akan digunakan untuk menangani

koneksi dari Client.

Pemrograman Game Java 3


J.E.N.I.
try {
ServerSocket s=new ServerSocket(90);
s.accept();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

Konstruktor dari ServerSocket diatas akan membuka atau menerima

koneksi melalui port 90, kemudian method accept() yang dipanggil untuk

menunggu koneksi dari client. Konstruktor akan melemparkan exception

apabila port yang didefinisikan diatas telah dibuaat sebelumnya. Potongan

kode berikut digunakan untuk memeriksa port yang telah digunakan(terbuka).

for(int i=0;i<1024;i++){
try {
ServerSocket s=new ServerSocket(i);
}catch (IOException e) {
System.out.println("Port ini telah digunakan : "+i);
}
}

Selain metode diatas class ServerSocket juga menyediakan pilihan

untuk membatasi jumlah koneksi dari client menggunakan dua parameter

dimana parameter pertama adalah nomor port dan parameter kedua adalah

jumlah koneksi yang akan diterima, potongan kodenya dapat dilihat sebagai

berikut.

try {
ServerSocket s=new ServerSocket(90,10);
}catch (IOException e) {

Kebanyakan server yang dipakai sekarang menggunakan lebih dari satu

IP Address untuk itu class ServerSocket juga menyediakan konstruktor yang

digunakan untuk memilih IP mana yang akan digunakan, cotohnya sebagai

berikut:

Pemrograman Game Java 4


J.E.N.I.
try {
ServerSocket s=new ServerSocket(100,10,
InetAddress.getByName("192.168.12.138"));

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

Konstruktor diatas melewatkan tiga parameter yang pertama adalah

nomor port kemudian parameter, kedua adalah banyaknya koneksi yang akan

diterima dan yang terakhir yaitu ip addres yang akan menerima permintaan

koneksi dari client dimana parameter ketiga ini menggunakan class

InetAddress untuk melewatkan IP Address yang akan digunakan.

3.4 Membuat Server Sederhana

Setelah memahami tentang konstruktor dari ServerSocket yang terdapat

pada bab II, sekarang kita akan membuat server sederhana yang akan

digunakan untuk menangani koneksi dari client. Berikut ini adalah kode

program dari class Server.

import java.net.*;
import java.io.*;
import java.util.*;

public class Server implements Runnable


{
private ServerSocket server;

public Server(int port)


{
try
{
server = new ServerSocket(port);
}
catch(IOException e)
{
System.out.println("Port : "+port+ " telah digunakan");
System.exit(1);
}
System.out.println("-> Server berhasil dibuat dengan port
"+port);
}

Pemrograman Game Java 5


J.E.N.I.

public void run()


{
while(true)
{
try
{
System.out.println("Menunggu konesi dari
client...");
new ProsesClient(server.accept());
}
catch(IOException e){}
}
}
public static void main(String args[])
{
Server server = new Server(5000);
new Thread(server).start();
}
}
Konstruktor dari class Server diatas melewatkan parameter berupa nilai

integer yang akan dugunakan sebagai nomor port dari server. Jika port yang

kita masukan telah digunakan maka program akan melemparkan exception.

Kemudian program kita akan menunggu koneksi dari client dengan

menggunakan bantuan dari thread yang akan kita bahas nanti. Method

server.accept() dari object ServerSocket yang kita buat akan menunggu

koneksi yang kemudian dilewatkan lagi atau ditangani pada konstruktor dari

class ProsesClient.

Ada beberapa peraturan yang harus kita gunakan untuk menangani data

data yang diterima oleh server agar program dapat berjalan sesuai dengan

keinginan. Untuk itu kita harus membuat interface Protocol yang akan kita

implementasikan pada class yang mmbutuhkan peraturan-peraturan yang

diinialisasikan pada interface Protocol tersebut. Berikut ini adalah listing

programnya.

public interface Protocol {


public static final int CHAT_USER_BARU = 0;
public static final int CHAT_HAPUS_USER = 1;
public static final int CHAT_PESAN_USER = 2;
public static final int SET_USER = 3;
}

Pemrograman Game Java 6


J.E.N.I.

Interface Protocol diatas menetapkan beberapa peraturan yang bertype

integer dan nilainya tidak dapat diubah ataupun dioverride. Ada beberapa

variable diatas antara lain CHAT_USER_BARU dalam program yang akan kita

buat nanti digunakan untuk pengecekan user yang yang baru terkoneksi dan

datanya akan dikirimkan ke seluruh client yang online dalam hal ini data yang

dikirimkan berupa nama user(“nick ???? telah bergabung di room ini”),

CHAT_HAPUS_USER digunakan sebagai validasi untuk memberitahu kepada

seluruh client yang terkoneksi bahwa user telah putus koneksinya dari server (“

nick ???? keluar dari room”), CHAT_PESAN_USER digunakan sebagai validasi

dimana datanya juga dikirimkan keseluruh client yang aktif dan akan

ditampilkan berupa pesan, SET_USER diginakan untuk memberikan nama dari

client disisi server (setiap object yang dibuat oleh class server melalui class

ProsesClient).

Semua penjelasan tentang peraturan-peraturan yang dibuat pada

inteface Protocol akan diterapkan pada class ProsesClient yang potongan kode

programnya adalah sebagai berikut.

import java.io.*;
import java.net.*;
import java.util.*;

public class ProsesClient implements Protocol{


Socket client;
boolean koneksi;
private TerimaData terimadata;
private KirimData kirimdata;
public static ArrayList clientList = new ArrayList();
String nama;

Class ProsesClient diatas mengimplementasi Protocol yang akan

digunakan sebagai rule dari data yang akan diproses, kemudian ada beberapa

variable yaitu antara lain client yang digunakan sebagai referensi dari socket

Pemrograman Game Java 7


J.E.N.I.
yang diterima oleh server melalui socket.accept() yeng dilewatkan melalui

konstruktor ProcesClient, koneksi bertype boolean dimana akan di set true

apabila client berhasil terkoneksi, terimadata adalah inner class yang

digunakan untuk menghandle data yang masuk dari server, kirimdata juga

berupa inner class yang digunakan untuk mengirim data, clientList digunakan

untuk menambpung setiap client yang terkoneksi ke server, nama digunakan

sebagai nama dari setiap client yang terkoneksi.

ProsesClient(Socket client){
try{
this.client = client;

DataInputStream in = new DataInputStream


(client.getInputStream());
DataOutputStream out = new DataOutputStream
(client.getOutputStream());

terimadata = new TerimaData(in);


kirimdata = new KirimData(out);

koneksi = true;

synchronized(clientList)
{
clientList.add(this);
}

}catch(IOException e){
System.out.println("Tidak dapat terkoneksi: "+e);
}
}

Program diatas merupakan konstruktor untama dari class ProsesClient

yang melewatkan data berupa object Socket. Didalam konstruktor tersebut juga

ada DataInputStream yang akan digunakan untuk menerima data dan

DataOuputStream untuk mengirimkan data dimana kedua-duanya di lewatkan

melalui konstruktor dari inner class TerimaData(in) dan KirimData(out). Apabila

terjadi kesalahan maka akan melemparkan exception. Selanjutnya adalah inner

class TerimaData yang potongan kodenya seperti dibawah ini.

public class TerimaData implements Runnable


{

Pemrograman Game Java 8


J.E.N.I.
Thread loop;
private DataInputStream in;
public TerimaData(DataInputStream in)
{
this.in = in;
loop = new Thread(this);
loop.start();
}

public void run()


{
Thread thisThread = Thread.currentThread();
while(loop==thisThread)
{
try
{
String data = in.readUTF();
prosesData(data);
}

catch(IOException e)
{
disconnect();
}
}
}

public void destroy()


{
loop = null;
}
}

Inner class TerimaData diatas melewatkan object DataInputStream dari

konstruktornya dan juga dithread untuk membaca data yang dikirimkan oleh

client dengan in.readUTF() yang kemudian diolah melalui method prosesData().

Jika terjadi kesalahan maka akan memanggil method disconnect(). Method

prosesData() dibawah ini mempunyai satu parameter bertype String dimana

parameter ini adalah data yang ditangkap dari client yang kemudian diproses

dengan bantuan dari StringTokenizer yang digunakan untuk memecah data

dengan pemisah “ | “ kemudian datanya yang pertama dikonversi menjadi

Integer dan kemudian diolah berdasarkan peraturan-peraturan yang kita buat

pada interface Protocol diatas.

public void prosesData(String data){


StringTokenizer st = new StringTokenizer(data, "|");
int kode = Integer.parseInt(st.nextToken());

Pemrograman Game Java 9


J.E.N.I.

switch(kode)
{
case SET_USER:{
nama=st.nextToken();
break;
}
case CHAT_USER_BARU :{
broadcastToClient(data);
break;
}
case CHAT_HAPUS_USER :{
broadcast(data);
break;
}
case CHAT_PESAN_USER :{
broadcast(data);
break;
}
}
}

Seperti yang terlihat pada program diatas terdapat method

broadcastToClint() yang brfungsi untuk mengirimkan data keseluruh client

kecuali client yang mengirim data sedangkan broadcast() mengirimkan data

keseluruh client termasuk client yang mengirimkan data.

public static void broadcast(String data)


{
synchronized(clientList)
{
ProsesClient user;
for(int i=0; i<clientList.size(); i++)
{
user = (ProsesClient)clientList.get(i);
user.kirimData(data);
}
}
}
public void broadcastToClient(String data)
{
synchronized(clientList)
{
ProsesClient user;

for(int i=0; i<clientList.size(); i++)


{
user = (ProsesClient)clientList.get(i);
if(user!=this)
user.kirimData(data);
}
}
}

Pemrograman Game Java 10


J.E.N.I.
Sekarang kita akan membahas tentang pengiriman data dari server

dengan inner class KirimData seperti dibawah ini.

public class KirimData implements Runnable {


Thread loop;
LinkedList tampungData;
DataOutputStream out;
public KirimData(DataOutputStream out)
{
this.out = out;
tampungData = new LinkedList();
loop = new Thread(this);
loop.start();
}
public void tambahData(String data)
{
synchronized(tampungData)
{
tampungData.add(data);
tampungData.notify();
}
}

public void run()


{
String data;

Thread thisThread = Thread.currentThread();


while(loop==thisThread)
{
synchronized(tampungData)
{
if(tampungData.isEmpty() && loop!=null)
{
try
{
tampungData.wait();
}
catch(InterruptedException e) { }
}
}
while(tampungData.size()>0)
{
synchronized(tampungData)
{
data = (String)tampungData.removeFirst();
}

try
{
out.writeUTF(data);
}
catch(IOException e)
{
disconnect();
}
}
}
}

Pemrograman Game Java 11


J.E.N.I.

public void destroy()


{
loop = null;
synchronized(tampungData)
{
tampungData.notify();
}
}
}

Inner class KirmData diatas menggunakan thread agar pengiriman data

dapat dilakukan setiap saat dimana data yang dikirimkan tidak langsung dikirim

dengan DataOutputStream tetapi masih di tambahkan kedalam LinkedList

sebagai antrian kemudian dikirimkan dengan out.WriteUTF() dimana apabila

data di object tampungData kosong maka program akan menunggu dengan

menggunakan method tampungData.wait(), dimana method ini akan diinterupsi

apabila terjadi penambahan data melalui method tambahData() karena disana

method tampungData.notify() dipanggil. Walaupun pada inner class KirimData

menyediakan method tambahData() yang melewatkan parameter berupa String

tetapi dalam kenyataanya kita tidak langsung mengakses kesana tetapi masih

membuat method lagi yaitu

public void kirimData(String data)


{
kirimdata.tambahData(data);
}

Kita membuat satu method lagi yaitu disconnect() yang akan digunakan

untuk mengirimkan keseluruh client yang aktif yang memberitahukan bahwa

koneksi dari client telah terputus. Berikut potongan kode programnya.

public synchronized void disconnect(){


if(koneksi){
synchronized(clientList){
clientList.remove(this);
}

broadcast(CHAT_HAPUS_USER+"|"+nama);
koneksi = false;
kirimdata.destroy();

Pemrograman Game Java 12


J.E.N.I.
terimadata.destroy();
try{ client.close(); }
catch(Exception e) {}
client = null;
}
System.out.println("Client Disconnected");
}

3.5 Membuat Client Sederhana

Sebagai lanjutan dari sisi server dimana pusatnya seluruh data diolah,

sekarang kita akan membuat aplikasi Client yang melakukan koneksi ke server

yang baru saja dibuat tadi. Disini kita hanya membuat dua class dan sebuah

interface yaitu class NetworkData, Client dan interface NetworkDataListener.

Program yang akan dibangun dititikberatkan pada pengiriman, penerimaan dan

pemrosesan data yang di ilustrasikan dalam aplikasi berupa chatting.

Program yang akan kita buat juga akan mengimplementasi interface

Protocol yang telah dibuat pada pembahasan server diatas. Sekarang mari kita

mulai dengan membuat interface NetworkDataListener sebagai berikut.

public interface NetworkDataListener {


public void menerimaData(String data);
public void networkDisconnected(String data);
}

Intrface NetworkDataListener akan diimplementasikan pada class utama

yaitu Client dimana fungsinya untuk menerima data yang dikirimkan oleh

server. NetworkDataListener akan kita gunakan sebagai parameter dari class

NetworkData seperti berikut ini.

import java.io.*;
import java.net.*;
import java.util.*;

public class NetworkData implements Protocol{


NetworkDataListener NDL;
Socket client;
boolean koneksi;
private TerimaData terimadata;
private KirimData kirimdata;
NetworkData(String host,int port,NetworkDataListener NDL){

Pemrograman Game Java 13


J.E.N.I.
try {
this.NDL=NDL;
client=new Socket(host,port);
DataInputStream in = new
DataInputStream(client.getInputStream());
DataOutputStream out = new
DataOutputStream(client.getOutputStream());
terimadata = new TerimaData(in);
kirimdata = new KirimData(out);
koneksi = true;
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

Class NetworkData akan mengimplementasi interface Protocol sebagai

aturan yang diberlakukan untuk metode pengiriman data, adapun

konstruktornya melewatkan tiga parameter yaitu host, port dan

NetworkDataListener, didalam class ini terdapat dua inner class yang isinya

tidak jauh berbeda dengan inner class yeng berada di sisi server pada bahasan

di atas. Apabila koneksi gagal dilakukan maka akan melemparkan exception.

Berikut ini adalah program inner class TerimaData.

public class TerimaData implements Runnable{


Thread loop;
private DataInputStream in;
public TerimaData(DataInputStream in)
{
this.in = in;
loop = new Thread(this);
loop.start();
}

public void run()


{
Thread thisThread = Thread.currentThread();
while(loop==thisThread)
{
try
{
String data = in.readUTF();
NDL.menerimaData(data);
}
catch(IOException e)
{
disconnect();
}
}
}

Pemrograman Game Java 14


J.E.N.I.

public void destroy()


{
loop = null;
}
}

Seperti yang terlihat object bernama NDL yang dibuat dari

NetworkDataListener digunakan ketika data diterima menggunakan

in.readUTF() dan kemudian memanggil dan melewatkan data yang dibaca tadi

pada method yang ada didalam interface tersebut yaitu NDL.menerimaData(...).

Perlu diketahui bahwa semua program yang mengimplementasikan interface

NetworkDataListener akan secara otomatis memanggil method

menerimaData(...) maka disinilah kesempatan kita untuk memproses data.

Untuk inner class KirimData tidak ada perbedaan dengan KirimData yang ada

di server. Berikut adalah listing programnnya.

public class KirimData implements Runnable{


Thread loop;
LinkedList tampungData;
DataOutputStream out;
public KirimData(DataOutputStream out){
this.out = out;
tampungData = new LinkedList();
loop = new Thread(this);
loop.start();
}
public void tambahData(String data){
synchronized(tampungData)
{
tampungData.add(data);
tampungData.notify();
}
}
public void run()
{
String data;
Thread thisThread = Thread.currentThread();
while(loop==thisThread)
{
synchronized(tampungData)
{
if(tampungData.isEmpty() && loop!=null)
{
try{
tampungData.wait();
}catch(InterruptedException e) { }
}

Pemrograman Game Java 15


J.E.N.I.
}
while(tampungData.size()>0)
{
synchronized(tampungData)
{
data =
(String)tampungData.removeFirst();
}
try{
out.writeUTF(data);
}
catch(IOException e){
disconnect();
}
}
}
}
public void destroy()
{
loop = null;
synchronized(tampungData)
{
tampungData.notify();
}
}
}

Method disconnect juga sama dengan yang ada di server, potongan

kodenya adalah sebagai berikut.

public synchronized void disconnect(){


if(koneksi)
{
NDL.networkDisconnected("disconnected..");

koneksi = false;

kirimdata.destroy();
terimadata.destroy();

try
{
client.close();
}
catch(Exception e) {}
client = null;
}

System.out.println("Client Disconnected");
}
public void kirimData(String data){
kirimdata.tambahData(data);
}

Method disconnect diatas juga akan memanggil NDL.network

Disconnected(...) dimana seluruh class yang mengimplementasi

Pemrograman Game Java 16


J.E.N.I.
NetworkDataListener akan memanggil secara otomatis method

networkDisconnected(...).

Sekarang membuat satu class lagi yaitu class Client yang akan

digunakan sebagai GUI dan sekaligus akhir dari program chating yang akan

kita bangun. Program ini menggunakan dua panel yaitu panel pertama

menampung nama, host dan port dan tombol connect kemudian panel yang

kedua yaitu isi, pesan dan tombol send. Pertama kali dijalanan adalah panel

pertama jika tombol connect ditekan maka panel pertama akan dihapus dan

digantikan dengan panel kedua sebagai tampilan GUInya. Program ini

mengimplementasi NetworkDataListener, Protocol dan ActionListener. Layout

dari container diset null oleh sebab itu semua letak dari componen

menggunakan bentuk koordinat dengan menggunakan method reshape(posisi

x, posisi y, panjang, tinggi) . Berikut ini adalah listing program dari class Client.

public class Client extends JFrame implements


NetworkDataListener,Protocol, ActionListener {

public static void main(String[] args) {


new Client();
}

private String host;


private String nama;
private int port;
NetworkDataListener NDL=this;
NetworkData ND;

JPanel p1=new JPanel();


JLabel l1=new JLabel("Nama :");
JLabel l2=new JLabel("Host :");
JLabel l3=new JLabel("Port :");
JTextField NAMA=new JTextField("anonymouse");
JTextField HOST=new JTextField("127.0.0.1");
JTextField PORT=new JTextField("5000");
JButton connect=new JButton("Connect");

JPanel p2=new JPanel();


JButton send=new JButton("SEND");
JTextArea pesan=new JTextArea(15,2);
JTextArea isi=new JTextArea(2,2);

Container c;

Pemrograman Game Java 17


J.E.N.I.

Client(){
c=getContentPane();
c.setLayout(null);
p1.setLayout(null);
p1.add(l1).reshape(0, 0, 100, 25);
p1.add(l2).reshape(0, 40, 100, 25);
p1.add(l3).reshape(0, 80, 100, 25);
p1.add(NAMA).reshape(50, 0, 100, 25);
p1.add(HOST).reshape(50, 40, 100, 25);
p1.add(PORT).reshape(50, 80, 100, 25);
p1.add(connect).reshape(30, 120, 100, 25);

p2.setLayout(null);
isi.setEditable(false);
p2.add(new JScrollPane(isi)).reshape(0, 0, 470, 200);
p2.add(new JScrollPane(pesan)).reshape(0, 220, 350, 55);
p2.add(send).reshape(370, 220, 100, 25);

c.add(p1).reshape(150, 50, 200, 200);

connect.addActionListener(this);
send.addActionListener(this);

setDefaultCloseOperation(this.EXIT_ON_CLOSE);
setSize(500,500);
setVisible(true);
setResizable(false);
}

Jika tombol connect ditekan maka instance dari NetworkData yaitu ND

akan dibuat dimana akan menangani pesan yang diterima ataupun yang

dikirimkan. Selain itu juga mengirimkan data keserver untuk memberi nama

pada object ProsesClient yang menangani data yang masuk atau keluar

dengan menggunakan ND.kirimData (SET_USER+”|”+nama), juga

mengirimkan ND.kirimData (CHAT_USER_BARU+”|”+ nama), dimana jika data

ini diterima oleh server maka akan langsung mengirimkan ke seluruh client

yang aktif bahwa user telah bergabung ke room.

public void actionPerformed(ActionEvent e) {

if(e.getSource() == connect){
this.host=HOST.getText();
this.port=Integer.parseInt(PORT.getText());
this.nama=NAMA.getText();

ND=new NetworkData(host,port,NDL);
ND.kirimData(SET_USER+"|"+nama);

Pemrograman Game Java 18


J.E.N.I.
ND.kirimData(CHAT_USER_BARU+"|"+nama);
c.remove(p1);
c.add(p2).reshape(10, 10, 500, 500);
setTitle(nama);
this.validate();
}
if(e.getSource()== send){
ND.kirimData(CHAT_PESAN_USER+"|"+nama+" :
pesan.getText());
}
}
Ketika tombol send ditekan maka program akan mengirimkan data

melalui method ND.kirimData(CHAT_PESAN_USER+”|”+nama” :

“+pesan.getText()); dimana ketika data sampai diserver maka akan di periksa

menggunakan Protocol yang telah ditetapkan dan kemudian mengirimkan data

ke seluruh client.

Method menerimaData(...) yang dioverride dari interface

NetworkDataListener akan digunakan untuk memeriksa data yang diterima oleh

client, dimana data-data tersebut akan diproses sesuai dengan Protocol yang

telah ditetapkan, pengolahan datanya juga menggunakan StringTokennizer

dengan tanda pemisah adalah “ | “ sama seperti yang dilakukan pada sisi

server. Apabila ternyata pesannya berupa CHAT_USER_BARU maka object

TextArea(isi) akan ditambahkan isi.append(“nick : “+nick+” telah bergabung di

channel ini\n”); jika ternyata pesannya berupa CHAR_HAPUS_USER maka

yang akan ditambahkan kedalam object TextArea(isi) isi.append(“nick : “+nick+”

telah keluar dari channel ini!\n”); tetapi apabila pesannya berupa

CHAT_PESAN_USER maka object TextArea(isi) akan ditambahkan

isi.append(st.nextToken()+”\n”). Apabila terjadi disconnect disisi client maka

class NetworkData yang ada disisi client akan mengirimkan pesan

“disconnect”.

Pemrograman Game Java 19