pemrograman java game
TRANSCRIPT
Pocong Document http://pocong.wordpress.com/
2008
[email protected] http://pocong.wordpress.com/
8/27/2008
J.E.N.I.
PemrogramanGame JAVA
Versi 1.1February 2007Pemrograman 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 1PENGENALAN 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
• Boneka
• Congkak
• Goncang Kaleng
• Kasti
• Layangan
• Main Hadang
• Petak Umpet
• Yoyo
2. Permainan Dewasa
• Kartu Remi atau Bridge
• Catur
• Domino
• Kuis
• Sudoku
• 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 2COLLECTION & 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.
Gambar 2.1 Implementasi Interface Collection
Pemrograman Game Java 2
<root interface>Collection
<interface> Set <interface> List
<implementing classes> <implementing classes>
HashSet LinkedHashSet TreeSet ArrayList LinkedList Vector
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
addElement(<object>)Digunakan untuk menambahkan data object ke
dalam Vektor.
elementAt(<index>)Method ini berfungsi untuk mengambil elemen
berdasarkan nomor index yang dimasukan.
lastElement()
Berfungsi untuk mengambil nilai berupa object yang
paling terakhir di tambahkan dari sebuah object
vektor.
firstElement()
Berfungsi untuk mengambil nilai berupa object
pertama yang di tambahkan dari sebuah object
vektor.
clear()Digunakan untuk menghapus seluruh elemen yang
tersimpan dalam object vector.
isEmpty()
Memeriksa apakah verktor yang digunakan berisi
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
add(<object>)Digunakan untuk menambahkan data object ke
dalam ArrayList.
add(<index>,<object>)
Method ini menyediakan dua parameter untuk
menambahkan sebuah object dengan menentukan
nomor index elemennya.
get(<index>)
Method get adalah method yang disediakan oleh
ArrayList untuk mengambil sebuah object
berdasarkan nomor indexnya.
remove(<index>)Mothod ini berfungsi untuk menghapus elemen
ArrayList berdasarkan nomor indexnya.
isEmpty()Digunakan untuk memeriksa apakah object ArayList
yang dibuat kosong atau tidak.
clear()Menghapus semua elemen yang ada di dalam
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
add(<object>)Digunakan untuk menambahkan data object ke dalam
LinkedList.size() Mengambil jumlah elemen pada object LinkedList
get(<index>)Mengambil nilai elemen berdasarkan nomor index yang
ada pada object LinkedListaddFirst() Menambahkan object pada elemen awal addLast() Menambahkan object pada elemen akhirgetFirst() Mengambil nilai elemen pertamagetLast() Mengambil nilai elemen terakhir clear() Menghapus semua nilai elemen pada object LinkedList
remove()Method remove tanpa parameter akan menghapus
elemen pertama
remove(<index>)Parameter akan menunjukan elemen mana yang akan
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 Aint lives=gamePlayer.getLives();gamePlayer.setLives(lives-1);
//Thread Bint 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 ASynchronized(gamePlayer){
int lives=gamePlayer.getLives();gamePlayer.setLives(lives-1);
}//Thread BSynchronized(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 Apublic void waitForMessage() { while (hasMessage == false) { Thread.sleep(100); }}// Thread Bpublic 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 Apublic synchronized void waitForMessage() { try { wait(); } catch (InterruptedException ex) { }}// Thread Bpublic 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 3EVENT 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 kiriVK_RIGHT Panah kananVK_UP Panah atasVK_DOWN Panah bawahVK_0 ..... VK_9 Tombol NumerikVK_A .... VK_Z Tombol AlphabetVK_F1 .. VK_F12 Tombol FungsiVK_KP_LEFT Numerik leftVK_KP_RIGHT Numerik rightVK_KP_UP Numerik atasVK_KP_DOWN Numerik bawahVK_ENTER Tombol EnterVK_BACK_SPACE Tombol BackspaceVK_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 Mouseimport 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 mouseaddMouseMotionListener(this);// listener pergerakan mousesetSize(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 mouseclickx=e.getX();clicky=e.getY();// Mengupdate TombolcheckButton(e);// refresh tampilanrepaint();
}
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 4EFEK 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);
elseklip.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 5GRAFIK 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.
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
X=0,y=
x
Y
X=0,y=
x
Y
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
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
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.
Shape ellipse = new Ellipse2D.Float(20,20,50,30);
Pemrograman Game Java 4
Gambar 3.17 Rectanggle2D
Gambar 3.18 RoundRectanggle2D
Gambar 3.19 Ellipse2D
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 didalamnyag2d.fill(poligon);// Gambar garis luarnya sajag2d.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 6GRAFIK 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 7SKALA, 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 TranslasiTranslasi 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.
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 :
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
Radian = (Sudut/180) * PI
Object
Arah Perputaran
Titik Pusat
0o
90o
18
170
360o
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 siny’ = 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 poolprotected 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 animatoranimator.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 9PEMROGRAMAN 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 blocke.printStackTrace();
} catch (IOException e) {// TODO Auto-generated catch blocke.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 blocke.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 blocke.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