Anda di halaman 1dari 49

s

KATA PENGANTAR Video game. Sudah banyak sekali orang di dunia ini yang tergila-gila dengan benda yang satu ini. Seiring dengan semakin canggihnya teknologi komputer, semakin menggila juga teknologi game. Impian masa kecil kita tentang game, sekarang sudah menjadi barang yang umum di sekitar kita. Banyaknya game juga sudah tak terhitung lagi jumlahnya, sehingga semakin banyak pula pemain game di dunia ini. Hampir semua orang yang termasuk ke dalam usia produktif sekarang, pasti pernah bermain game. Di antara para pemain game itu (mungkin termasuk Anda), pasti banyak di antaranya yang ingin menjadi seorang game developer agar ia dapat membuat game impiannya sendiri. Namun, banyak yang merasa tidak mampu karena tidak mempunyai latar belakang pendidikan yang memadai atau yang berhubungan dengan game development. Bahkan, seseorang dengan latar pendidikan TI (teknologi informasi) yang pasti mempunyai pengetahuan pemrograman dasar, mungkin merasa tidak mampu untuk masuk ke dunia impiannya, dunia game development, karena tidak pernah sama sekali mendapat kesempatan untuk membuat game. Oleh karena itu, dengan adanya framework canggih yang sangat membantu seseorang untuk memprogram game seperti XNA Framework, kami tergerak untuk mendokumentasikan pengetahuan dasar XNA Framework dan langkah awal pembuatan game dengan menggunakan XNA Framework. Ucapan terima kasih sebesar-besarnya dari kami untuk Ronald Rajagukguk dan Narenda Wicaksono, yang telah menjadi inspirasi kami dalam membuat e-book ini ^^; Vincentius Hening W. Ismawan (Wiwied), yang telah membuatkan kami cover e-book yang oke punya ^^; dan semua crew Agate Studio yang senantiasa mendukung kami dalam pembuatan e-book ini. Kami harap melalui e-book ini, semakin banyak orang yang menggali kembali mimpi masa kecilnya untuk menjadi seorang game developer! Happy game developing, everyone! ^^

Shieny Aprilia & Arief Widhiyasa

ii

DAFTAR ISI Kata Pengantar................................................................................................................................................................ ii Daftar Isi ......................................................................................................................................................................... iii 1. 2. 3. Sekilas Tentang Dunia Game Development ............................................................................................................ 1 Pengantar XNA Game Studio .................................................................................................................................. 3 Persiapan Penggunaan XNA Game Studio .............................................................................................................. 5 3.1. 3.2. 3.3. 3.4. 3.5. 4. 5. Kebutuhan Perangkat Keras............................................................................................................................ 5 Kebutuhan Perangkat Lunak ........................................................................................................................... 5 Instalasi XNA Game Studio 3.0 ........................................................................................................................ 5 Menguji Hasil Instalasi XNA Game Studio 3.0 ................................................................................................. 5 Membuat Game dengan Project Starter kit .................................................................................................... 6

Lets Start Making Game .................................................................................................................................... 8 The First Step ........................................................................................................................................................ 9 5.1. 5.2. 5.3. 5.4. 5.5. Membuat Project Game PC dengan XNA Game Studio 3.0 ............................................................................ 9 Komponen-komponen Project...................................................................................................................... 10 Menambahkan Aset Game ........................................................................................................................... 11 Menentukan Resolusi Game ......................................................................................................................... 12 Menampilkan Background Game ................................................................................................................. 13

6.

Objek-objek game ................................................................................................................................................. 15 6.1. 6.2. Membuat Kapal ............................................................................................................................................. 15 Menambahkan Kapal ke Game ..................................................................................................................... 17

iii

6.3. 6.4. 6.5. 7.

Menggerakkan Kapal dengan Input Device................................................................................................... 19 Membuat Peluru ........................................................................................................................................... 21 Membuat Kapal yang Dapat Menembakkan Peluru ..................................................................................... 23

Interaksi antar objek ............................................................................................................................................. 28 7.1. 7.2. 7.3. Deteksi Tabrakan antara Peluru dan Kapal ................................................................................................... 28 Membuat Tambahan Objek Penghalang (Obstacle) ..................................................................................... 29 Menambahkan Objek Penghalang ke Game ................................................................................................. 32

8. 9.

Menampilkan Graphical User Interface Score ...................................................................................................... 34 Sound & Music ...................................................................................................................................................... 38 9.1. 9.2. Membungkus File Audio menjadi File Aset Game dengan Microsoft XACT ................................................. 38 Menambahkan Suara ke Game ..................................................................................................................... 40 The Game is Done! ........................................................................................................................................ 43

10.

Penutup......................................................................................................................................................................... 44 Referensi ......................................................................................................................................................................... v

iv

1. SEKILAS TENTANG DUNIA GAME DEVELOPMENT Game development adalah sebuah proses pembuatan perangkat lunak yang keluarannya berupa video game. Orang yang terlibat dalam proses game development disebut game developer. Peran-peran yang ada pada sebuah proses game development antara lain, producer (yang bertugas mengelola tim, jadwal, progress, alokasi anggota tim, dsb.), designer (yang bertugas merancang konsep game, gameplay, struktur game, dan aturan dalam game), artist (yang bertugas membuat aset visual game dan bertanggung jawab terhadap aspek visual game), programmer (yang bertugas membuat perangkat lunak dari konsep dan aset yang telah dibuat oleh designer dan artist), level designer (yang bertugas membuat atau merancang level, tantangan, atau misi pada game), sound engineer (yang bertugas membuat aset audio game dan bertanggung jawab terhadap aspek audio game), dan tester (yang bertugas mencari kecacatan pada game sebagai sebuah perangkat lunak). Sebuah proses game development melibatkan tahap-tahap sebagai berikut: 1. Pre-production Tahap ini adalah tahap perencanaan proyek yang fokus pada ide dan konsep dan pembuatan game design document (dokumen perancangan game). Tujuan dari pengembangan konsep adalah untuk menghasilkan dokumen yang jelas dan mudah dimengerti. Game design document inilah yang menjadi pedoman dalam proses produksi game sampai akhir. 2. Production Tahap ini adalah tahap utama pada proses game development, di mana hasil akhirnya berupa aset dan source code game. Secara umum, tahap ini dapat dibagi menjadi 3: a. Design : tahap merancang isi dan aturan game

b. Programming : tahap memprogram game sehingga menghasilkan source code game c. Art Production : tahap membuat aset visual game sehingga siap dipakai untuk game Di antara tahap-tahap pada game development, tahap yang memiliki aspek reusability 1 yang paling tinggi, adalah tahap programming. Sehingga, tahap programming yang paling mungkin untuk ditingkatkan produktivitasnya, antara lain dengan penggunaan game engine, library, atau framework yang sudah membungkus kegiatan-kegiatan umum yang dilakukan oleh programmer game ketika membuat game. Salah satu game framework yang fiturnya paling banyak dan sudah banyak digunakan oleh para game developer dunia adalah Microsoft XNA Framework. Selain fiturnya yang sudah cukup lengkap dan sangat membantu para game programmer, XNA juga cross-platform framework, sehingga game untuk PC hanya cukup dikompilasi ulang

Reusability : penggunaan ulang apa yang telah dibuat sebelumnya, misalnya kode tertentu di game A, digunakan kembali di game B

untuk ditaruh di platform lain, misalnya Xbox360 dan Zune. Microsoft XNA Framework adalah bagian dari XNA Game Studio, yaitu tools tambahan pada Microsoft Visual Studio untuk membuat game menggunakan XNA. Mari kita lihat XNA Game Studio lebih dekat di bagian selanjutnya

2. PENGANTAR XNA GAME STUDIO Seperti yang telah dijelaskan pada bagian sebelumnya, XNA Game Studio adalah tools tambahan pada Microsoft Visual Studio yang menyediakan kerangka game XNA untuk para developer, sehingga para developer hanya tinggal melakukan kustomisasi dan mengembangkan kerangka tersebut untuk membuat game mereka sendiri dengan menggunakan XNA. Kerangka game XNA yang dihasilkan secara otomatis ketika kita membuat proyek game XNA baru di Visual Studio yang sudah ter-install dengan XNA Game Studio adalah sebuah kelas Game1 yang merupakan turunan dari kelas Microsoft.Xna.Framework.Game dan memiliki atribut dan fungsifungsi sebagai berikut: 1. graphics Atribut bertipe GraphicsDeviceManager yang memungkinkan developer untuk mengakses kartu grafis PC, Xbox360, atau Zune (tergantung pada platform apakah game kita akan ditaruh). Kelas GraphicsDeviceManager memiliki properti GraphicsDevice yang merepresentasikan kartu grafis mesin kita yang sebenarnya. Karena properti ini adalah perantara game XNA kita dengan GPU (Graphics Processing Unit) pada kartu grafis kita, apapun yang kita lakukan pada layar game XNA kita, akan melalui properti ini. 2. spriteBatch Atribut ini merupakan instansiasi dari kelas SpriteBatch. Ini adalah objek utama yang digunakan untuk menggambar sprite. Sprite adalah gambar 2D atau 3D yang diintegrasi dengan suatu adegan (scene). Dengan demikian, sebuah game 2D dibuat dengan menggambar sejumlah sprite pada suatu scene (sprite pemain, sprite musuh, sprite background, dsb.) 3. Initialize() Fungsi ini digunakan untuk melakukan inisialisasi semua variabel dan objek yang ada pada Game1. 4. LoadContent() Fungsi ini akan dipanggil setelah fungsi Initialize() dipanggil. Fungsi ini adalah di mana kita akan me-load semua elemen grafis dan semua aset yang dibutuhkan oleh game, misalnya gambar, model 3D, suara, dsb. Setelah fungsi LoadContent() selesai dipanggil, Game1 akan memasuki fase apa yang disebut dengan game loop. Hampir semua game, bukan hanya game XNA, mempunyai game

loop. Inilah yang membedakan game development dengan software development biasa. Sebuah game loop terdiri dari sekumpulan fungsi yang dipanggil terus menerus sampai game berakhir. Di XNA, sebuah game loop hanya terdiri dari 2 fungsi : Update() dan Draw(). 5. UnloadContent() Fungsi ini digunakan untuk unload semua aset yang di-load pada fungsi LoadContent() dan membutuhkan penanganan unload khusus. Biasanya XNA akan menangani proses unload aset ini, tetapi jika kita melakukan perubahan manajemen memori pada beberapa objek yang di-load pada fungsi LoadContent(), maka kita dapat melakukan proses unload-nya pada fungsi ini. 6. Update() Semua algoritma yang mempengaruhi gameplay, selain yang berhubungan dengan penggambaran objek, berada pada fungsi ini. Instruksi yang biasanya ada pada fungsi ini adalah menggeser objek, collision detection (deteksi tabrakan), melakukan update score, dsb. 7. Draw() Seperti namanya, fungsi ini digunakan untuk menggambar semua objek pada game. Kita harus memastikan sesedikit mungkin instruksi pada fungsi ini, selain instruksi penggambaran objek, karena seharusnya instruksi-instruksi tersebut ada pada fungsi Update(). Diagram alir pemanggilan fungsi-fungsi di atas dapat dilihat pada Gambar 1.

Initialize()

LoadContent()

Game Over Update() UnloadContent ()

Draw()

Gambar 1 Diagram Alir Fungsi-fungsi Kelas Game1

3. PERSIAPAN PENGGUNAAN XNA GAME STUDIO Sekarang kita akan melakukan instalasi XNA Game Studio. Jika Anda sudah mempunyai XNA Game Studio 3.0 di komputer Anda, Anda dapat melewati bagian ini. 3.1. KEBUTUHAN PERANGKAT KERAS Kebutuhan perangkat keras untuk melakukan instalasi XNA Game Studio 3.0 adalah sebagai berikut: Minimum : Komputer x86 / x64 dengan CPU 1.6 GHz, 384 MB RAM, monitor 1024x768, dan hard disk 5400 RPM Disarankan : Komputer x86 / x64 dengan CPU 2.2 GHz atau lebih, 1024 MB atau lebih RAM, monitor 1280x1024, dan hard disk 7200 RPM Jika sistem operasi yang digunakan adalah Windows Vista, CPU 2.4 GHz, 768 RAM

3.2. KEBUTUHAN PERANGKAT LUNAK Kebutuhan perangkat lunak untuk melakukan instalasi XNA Game Studio 3.0 adalah sebagai berikut: Sistem operasi : Windows XP Service Pack 3, Windows Vista Service Pack 1, Windows 7 IDE : Microsoft Visual Studio 2008 Express atau Team System, dengan C#

3.3. INSTALASI XNA GAME STUDIO 3.0 Kita akan melakukan instalasi XNA Game Studio 3.0 dengan langkah-langkah sebagai berikut: 1. Download installer XNA Game Studio 3.0 di http://www.microsoft.com/downloads/details.aspx?FamilyId=7D70D6ED-1EDD-4852-98839A33C0AD8FEE&displaylang=en 2. Ikuti petunjuk instalasi sampai XNA Game Studio 3.0 selesai di-install pada komputer Anda 3.4. MENGUJI HASIL INSTALASI XNA GAME STUDIO 3.0 Kita akan menguji apakah XNA Game Studio 3.0 sudah ter-install dengan baik pada komputer kita, dengan langkah-langkah sebagai berikut: 1. Buka Visual Studio 2008, pilih menu File New Project

2. Pada kotak dialog New Project, lihat apakah pada kotak Project Types, sudah ada pilihan XNA Game Studio 3.0 dan sudah ada pilihan template untuk project XNA Game Studio 3.0 pada Templates

Gambar 2 Pilihan Project Type dan Templates pada Kotak Dialog New Project

3. Masih pada kotak dialog New Project, klik OK. Jika project XNA baru telah berhasil dibuat, maka itu artinya instalasi XNA Game Studio 3.0 pada komputer Anda berhasil dengan baik! 3.5. MEMBUAT GAME DENGAN PROJECT STARTER KIT Kita akan mencoba membuat sebuah game utuh menggunakan project starter kit yang disediakan oleh XNA Game Studio 3.0 dengan langkah-langkah sebagai berikut: 1. Pilih File New Project

2. Pada kotak dialog New Project, pilih XNA Game Studio 3.0 pada Project Types dan Platformer Starter Kit (3.0) pada Templates 3. Klik OK 4. Setelah project selesai dibuat, tekan F5 untuk melakukan kompilasi dan pembentukan file executable game dan menampilkan game, maka sebuah game akan muncul seperti pada Gambar 3, dan kita bisa langsung memainkannya!

Gambar 3 Game Platformer Starter Kit

4. LETS START MAKING GAME Sekarang kita akan membuat game kita sendiri, yang ber-genre shooting. Game ini akan melibatkan dua buah kapal yang saling menembak, di mana satu kapal terletak di bawah dan kapal yang lain terletak di atas. Di antara kedua kapal akan ada objek-objek penghalang yang dapat menghalangi datangnya peluru, sehingga akan menyulitkan kedua kapal untuk menembakkan pelurunya ke kapal lawannya. Kita akan membuat game ini dalam beberapa tahap kecil, yaitu sebagai berikut: 1. Menambahkan aset ke game 2. Menentukan resolusi game 3. Menampilkan background game 4. Membuat kapal 5. Menambahkan kapal ke game 6. Menggerakkan kapal dengan input device 7. Membuat peluru 8. Membuat kapal yang dapat menembakkan peluru 9. Deteksi tabrakan antara peluru dan kapal 10. Membuat tambahan objek penghalang 11. Menambahkan objek penghalang ke game 12. Menampilkan user interface score 13. Membungkus file audio menjadi file aset game dengan Microsoft XACT 14. Menambahkan suara ke game Setiap tahap yang dijabarkan di atas akan dijelaskan lebih detil pada bagian-bagian selanjutnya. Selamat menikmati!

5. THE FIRST STEP Sebelum memulai pembuatan game, ada baiknya kita menyiapkan sebuah folder tertentu, misalnya di D:\Documents\My Games\ untuk menaruh semua file yang dibutuhkan dalam pembuatan game kita nantinya. Lalu, kita juga perlu men-download file aset yang dibutuhkan untuk game kita di http://agategames.com/xnabooks/asetgamexna.zip. Extract file asetgamexna.zip dan simpanlah hasil ekstraksi tersebut di dalam folder Content dalam folder yang telah kita siapkan tadi. Sehingga lokasi file aset kita adalah D:\Documents\My Games\Content. 5.1. MEMBUAT PROJECT GAME PC DENGAN XNA GAME STUDIO 3.0 Untuk membuat game PC menggunakan XNA Game Studio 3.0, kita terlebih dahulu harus melakukan instalasi XNA Game Studio 3.0. Sebagai IDE, kita dapat menggunakan Visual Studio Team System 2008 atau Visual C# 2008 Express. Berikut adalah langkah-langkah untuk membuat project game PC XNA pada Visual Studio Team System 2008: 1. Pilih File New Project

2. Pilih template Windows Game (3.0) 3. Isilah nama proyek dan lokasi proyek sesuai dengan yang Anda inginkan, misalnya : Name Location : ShootingGameXNA : D:\Documents\My Games

Solution Name : ShootingGameXNA

Gambar 4 Membuat Project Game PC pada XNA Game Studio 3.0

4. Pilih OK

5.2. KOMPONEN-KOMPONEN PROJECT Setelah project ShootingGameXNA berhasil dibuat, pada project tersebut terdapat beberapa komponen antara lain sebagai berikut :

Gambar 5 Komponen-komponen Project Game PC XNA Game Studio 3.0

1. Properties

: elemen proyek yang berisi informasi penting terkait proyek, misalnya

tipe hasil kompilasi proyek (library, aplikasi Windows, dsb.), lokasi tempat hasil kompilasi berada, dan lain sebagainya 2. References : library referensi yang diperlukan game

10

3. Content 4. Game.ico 5. Game1.cs 6. GameThumbnail.png 7. Program.cs

: content pipeline yang berguna untuk load aset-aset game : file image yang akan ditampilkan sebagai icon game : kelas utama yang memodelkan game yang akan kita buat : file image yang akan ditampilkan sebagai thumbnail game : kelas main program tempat instansiasi dari Game1.cs akan dijalankan

5.3. MENAMBAHKAN ASET GAME Kita menambahkan file aset game ke dalam content pipeline, dengan cara sebagai berikut : 1. Pada Solution Explorer, klik kanan pada Content, pilih Add 2. Pilihlah semua file yang akan ditambahkan sebagai aset game Existing Item

Gambar 6 Pilih Semua File Aset Game

3. Pilih Add 4. Semua file yang telah ditambahkan ke content pipeline dapat dilihat pada Solution Explorer

Gambar 7 Semua File Aset Tampil pada Solution Explorer

11

5.4. MENENTUKAN RESOLUSI GAME Kita akan membuat game yang resolusinya 800x600. Oleh karena itu, pada Game1.cs, kita harus melakukan hal-hal sebagai berikut pada kelas Game1: 1. Menambahkan atribut konstanta GAME_WIDTH (800) dan GAME_HEIGHT (600) 2. Pada konstruktor kelas Game1, kita masukkan nilai PreferredBackBufferWidth dan PreferredBackBufferHeight dengan konstanta yang telah dideklarasi pada poin 1
public readonly static int GAME_WIDTH = 800; public readonly static int GAME_HEIGHT = 600; public Game1() { graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; // Menentukan resolusi layar game graphics.PreferredBackBufferWidth = GAME_WIDTH; graphics.PreferredBackBufferHeight = GAME_HEIGHT; }

Jika kita menekan F5 sekarang, maka akan tampak layar game kita yang masih kosong. Jadi dengan menggunakan XNA, game kita telah dibuat hanya dengan cara membuat project XNA baru.

Gambar 8 Game XNA yang Masih Kosong

12

5.5. MENAMPILKAN BACKGROUND GAME Tambahkan atribut dan properti berikut dalam kelas Game1: 1. BG_POS 2. SpriteBatch 3. BgTexture : atribut konstanta posisi background digambar : getter atribut spriteBatch : data tekstur 2D yang akan dijadikan background game

public readonly static Vector2 BG_POS = Vector2.Zero; public SpriteBatch SpriteBatch { get { return spriteBatch; } } public Texture2D BgTexture;

Tekstur 2D adalah representasi file gambar (.jpg, .png) yang berupa kumpulan (array) data warna.

Pada fungsi LoadContent(), kita harus melakukan langkah-langkah sebagai berikut: 1. Inisialisasi spriteBatch yang digunakan untuk menggambar tekstur 2. Load tekstur background 3. Inisialisasi bujur sangkar tempat data tekstur 2D background akan digambar
protected override void LoadContent() { // Inisialisasi spriteBatch yang digunakan untuk menggambar tekstur spriteBatch = new SpriteBatch(GraphicsDevice); BgTexture = Content.Load<Texture2D>("bg"); }

Sprite Batch adalah kelas pada XNA yang memungkinkan sejumlah gambar 2D digambar dengan menggunakan pengaturan kartu grafis yang sama.

13

Terakhir, kita menggambar data tekstur background pada fungsi Draw() dengan menggunakan spriteBatch. Perlu diingat, bahwa sebelum spriteBatch digunakan untuk menggambar, fungsi spriteBatch.Begin() dan spriteBatch.End() harus dipanggil terlebih dahulu :
protected override void Draw(GameTime gameTime) { // Menggambar semua objek setiap gameTime spriteBatch.Begin(); spriteBatch.Draw(BgTexture, BG_POS, Color.White); spriteBatch.End(); base.Draw(gameTime); }

Tekan F5 untuk melihat hasilnya. Sekarang game kita sudah mempunyai background! Mudah sekali bukan?

Gambar 9 Game yang Sudah Memiliki Background

14

6. OBJEK-OBJEK GAME Pada game ini, ada 2 objek utama yang berperan, yaitu kapal dan peluru. Kapal adalah pemeran utama game kita, jadi pemain akan menggerakkan kapal ini di game. Peluru adalah objek yang ditembakkan oleh kapal. 6.1. MEMBUAT KAPAL Sekarang kita membuat kapal yang nantinya dapat digerakkan oleh pemain. Pertama-tama kita membuat kelas Ship yang memodelkan kapal pada game: 1. Klik kanan pada project ShootingGameXNA pada Solution Explorer, pilih Add New Item

Gambar 10 Menambahkan file Kelas Ship.cs pada Game

2. Kita membuat kelas Ship menjadi turunan dari kelas Microsoft.Xna.Framework.DrawableGameComponent


using using using using using using using using using using System; System.Collections.Generic; Microsoft.Xna.Framework; Microsoft.Xna.Framework.Audio; Microsoft.Xna.Framework.Content; Microsoft.Xna.Framework.GamerServices; Microsoft.Xna.Framework.Graphics; Microsoft.Xna.Framework.Input; Microsoft.Xna.Framework.Net; Microsoft.Xna.Framework.Storage;

namespace ShootingGameXNA

15

{ public class Ship : DrawableGameComponent { } }

DrawableGameComponent adalah kelas dari XNA Framework yang merepresentasikan komponen game XNA yang dapat digambar pada game

Lalu kita menambahkan atribut berikut dalam kelas Ship: 1. shipTexture 2. Position 3. Direction menghadap ke bawah
private Texture2D shipTexture; public Vector2 Position; public int Direction; // 0 : menghadap atas, 1 : menghadap bawah public int Score;

: data tekstur 2D kapal : posisi kapal (dalam Vector2) : arah hadap kapal, 0 berarti kapal menghadap ke atas, 1 berarti kapal

Vector2 pada XNA adalah tipe bentukan yang merupakan representasi dari vektor 2 dimensi, dengan demikian mempunyai X dan Y, dan juga fungsi-fungsi operasi vektor, seperti operasi dot vektor, cross vektor, dan sebagainya Setelah atribut dideklarasi, saatnya melakukan inisialisasi atribut tersebut dalam konstruktor kelas Ship :
public Ship(Game1 game, Texture2D texture, Vector2 position, int direction) : base(game) { shipTexture = texture; Position = position; Direction = direction; Score = 0; }

Kita membuat kapal ini bisa digambar dengan melakukan menambahkan fungsi Draw():
public override void Draw(GameTime gameTime) { ((Game1)Game).SpriteBatch.Draw(shipTexture, Position, Color.White);

16

base.Draw(gameTime); }

6.2. MENAMBAHKAN KAPAL KE GAME Setelah kita membuat kelas yang memodelkan sebuah kapal pada game, kita akan menambahkan kapal tersebut ke game kita. Pertama-tama, tambahkan atribut berikut pada kelas Game1: 1. NUM_SHIPS 2. SHIP_TEXTURE_PATHS kapal relatif terhadap Content 3. SHIP_INIT_POS game 4. ShipTextures 5. Ships 6. i
public readonly static public readonly static { "ship1", "ship2" }; public readonly static { new Vector2(350, new Vector2(350, };

: array jumlah kapal yang ada di game : array path dan nama file (tanpa ekstensi) semua tekstur 2D

: array posisi inisial semua kapal ketika pertama kali muncul di

: array data tekstur 2D untuk semua kapal : array berisi semua kapal yang terdapat di game : iterator bertipe integer serba guna
int NUM_SHIPS = 2; string[] SHIP_TEXTURE_PATHS = new string[]

Vector2[] SHIP_INIT_POS = new Vector2[] 500), 0)

public Texture2D[] ShipTextures; public Ship[] Ships; private int i;

Atribut ShipTextures dan Ships harus diinisialisasi pada fungsi LoadContent(), dan setiap instansiasi dari kapal harus ditambahkan ke list of components Components yang diturunkan dari base class Game1, yaitu Microsoft.Xna.Framework.Game agar fungsi Update() dan Draw() kelas Ship ikut dipanggil ketika fungsi Update() dan Draw() pada Game1 dipanggil. Kita tambahkan potongan kode berikut ke dalam fungsi LoadContent().
ShipTextures = new Texture2D[NUM_SHIPS]; for (i = 0; i < NUM_SHIPS; i++)

17

{ ShipTextures[i] = Content.Load<Texture2D>(SHIP_TEXTURE_PATHS[i]); } Ships = new Ship[NUM_SHIPS]; for (i = 0; i < NUM_SHIPS; i++) { Ships[i] = new Ship(this, ShipTextures[i], SHIP_INIT_POS[i], i); Components.Add(Ships[i]); }

Fungsi Draw() untuk semua objek turunan DrawableGameComponent yang telah di-add pada Game.Components, akan dipanggil pada base.Draw() yang dipanggil di dalam fungsi Game1.Draw(). Karena fungsi Ship.Draw() tidak memanggil fungsi SpriteBatch.Begin() dan SpriteBatch.End(), kita harus memastikan bahwa base.Draw() dipanggil di dalam lingkup SpriteBatch.Begin() dan SpriteBatch.End() yang dipanggil di dalam fungsi Game1.Draw(), agar tidak muncul exception ketika game dijalankan. Dengan demikian fungsi Game1.Draw() akan menjadi seperti di bawah ini.
protected override void Draw(GameTime gameTime) { // Menggambar semua objek setiap gameTime spriteBatch.Begin(); spriteBatch.Draw(BgTexture, BG_POS, Color.White); base.Draw(gameTime); spriteBatch.End(); }

Sekarang tekan F5 untuk melihat 2 kapal kita sudah berdiri kokoh di posisinya masing-masing

18

Gambar 11 Dua Buah Kapal pada Game

6.3. MENGGERAKKAN KAPAL DENGAN INPUT DEVICE Kita akan membuat kedua kapal yang telah kita buat pada tahap sebelumnya dapat digerakkan ke kiri dan ke kanan dengan menggunakan keyboard. Pertama-tama, tambahkan atribut konstanta SPEED yang menyatakan kecepatan gerak kapal pada kelas Ship. Nilai SPEED sama dengan 100 berarti kapal akan bergerak sejauh 100 pixel setiap 1 detik.
readonly static int SPEED = 100;

Lalu, mari kita tambahkan fungsi MoveLeft() dan MoveRight() pada kelas Ship agar kapal kita dapat bergerak ke kiri dan ke kanan. Posisi kapal akan bergeser sejauh SPEED dikalikan dengan jumlah detik yang dilewati sejak fungsi Game1.Update() dipanggil sebelumnya. Dengan demikian, posisi kapal akan bergeser sejauh SPEED setiap elapsed telah berjumlah 1 detik.
float elapsed; public void MoveLeft(GameTime gameTime) { elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds; Position.X -= SPEED * elapsed; }

19

public void MoveRight(GameTime gameTime) { elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds; Position.X += SPEED * elapsed; }

Di manakah fungsi MoveLeft() dan MoveRight() dipanggil? Fungsi ini akan dipanggil di Game1.Update(). Tapi kita akan membuat kedua fungsi ini tidak dipanggil secara langsung di Game1.Update(), melainkan kita akan membuat suatu fungsi pada Game1 yang khusus untuk menangani semua input untuk game. Tambahkan fungsi playingHandleInput() pada Game1.cs. Fungsi ini menggunakan fungsi pada kelas Keyboard XNA yang dapat mengecek status dari setiap tombol pada keyboard, dengan memanggil fungsi Keyboard.GetState() yang mengembalikan nilai bertipe KeyboardState. Karena kita melakukan suatu aksi ketika tombol pada keyboard ditekan, kita menggunakan fungsi KeyboardState.IsKeyDown() untuk mengecek apakah suatu tombol sedang dalam keadaan ditekan atau tidak.
private void playingHandleInput(GameTime gameTime) { // Menangani input untuk player 1 : // A : gerak ke kiri // D : gerak ke kanan if (Keyboard.GetState().IsKeyDown(Keys.A)) { // Menggeser persegi kapal player 1 ke kiri Ships[0].MoveLeft(gameTime); } else if (Keyboard.GetState().IsKeyDown(Keys.D)) { // Menggeser persegi kapal player 1 ke kanan Ships[0].MoveRight(gameTime); } // // // if { Menangani input untuk player 2 : Panah Kiri : gerak ke kiri Panah Kanan : gerak ke kanan (Keyboard.GetState().IsKeyDown(Keys.Left)) // Menggeser persegi kapal player 2 ke kiri Ships[1].MoveLeft(gameTime); } else if (Keyboard.GetState().IsKeyDown(Keys.Right)) { // Menggeser persegi kapal player 2 ke kanan Ships[1].MoveRight(gameTime); }

20

// Menangani input keluar dari permainan if (Keyboard.GetState().IsKeyDown(Keys.Escape)) { Exit(); } }

Lalu panggilah fungsi playingHandleInput() pada Game1.Update():


protected override void Update(GameTime gameTime) { playingHandleInput(gameTime); base.Update(gameTime); }

Jika kita tekan F5, maka kita dapat menggerakan kapal yang di atas dengan menggunakan tombol panah kiri dan kanan, dan kapal yang di bawah dengan menggunakan tombol A dan D. 6.4. MEMBUAT PELURU Sekarang kita akan membuat peluru yang dapat ditembakkan oleh kedua kapal kita. Peluru untuk kedua kapal akan menggunakan tekstur yang sama. Tambahkan file kelas Bullet.cs pada project kita, lalu seperti pada kelas Ship, buatlah kelas Bullet menjadi turunan kelas Microsoft.Xna.Framework.DrawableGameComponent.
using using using using using using using using using using System; System.Collections.Generic; Microsoft.Xna.Framework; Microsoft.Xna.Framework.Audio; Microsoft.Xna.Framework.Content; Microsoft.Xna.Framework.GamerServices; Microsoft.Xna.Framework.Graphics; Microsoft.Xna.Framework.Input; Microsoft.Xna.Framework.Net; Microsoft.Xna.Framework.Storage;

namespace ShootingGameXNA { public class Bullet : DrawableGameComponent { } }

Tambahkan atribut berikut di kelas Bullet: 1. ParentShip : kapal yang menembakkan peluru

21

2. bulletTexture 3. Position 4. Direction gerak peluru ke bawah

: data tekstur 2D peluru : posisi peluru : arah gerak peluru, 0 berarti arah gerak peluru ke atas, 1 berarti arah

readonly static float BULLET_POS_OFFSET_SHIP_X = 35; readonly static float BULLET_POS_OFFSET_SHIP_Y = 80; readonly static float SPEED = 400; public Ship ParentShip; private Texture2D bulletTexture; public Vector2 Position; public int Direction; // 0 : tembak ke atas, 1 : tembak ke bawah

Setelah kita melakukan deklarasi atribut di atas, kita harus melakukan inisialisasi atribut tersebut di konstruktor kelas Bullet, sehingga konstruktor kelas Bullet akan menjadi sebagai berikut:
public Bullet(Game1 game, Ship ship, Texture2D texture) : base(game) { ParentShip = ship; bulletTexture = texture; Direction = ship.Direction; Position = new Vector2(); Position.X = ship.Position.X + BULLET_POS_OFFSET_SHIP_X; if (Direction == 0) { Position.Y = ship.Position.Y; } else { Position.Y = ship.Position.Y + BULLET_POS_OFFSET_SHIP_Y; } }

Setelah ditembakkan, peluru pasti bergerak maju sesuai dengan arah geraknya dan tidak akan di-update ataupun digambar lagi (dihapus dari Game.Components) ketika peluru telah berada di luar area game. Untuk mewujudkan hal itu, mari kita mengimplementasi behavior ini dengan menambahkan fungsi Update() pada kelas Bullet. Semua fungsi Update() yang terdapat pada semua objek turunan dari DrawableGameComponent akan dipanggil secara otomatis ketika fungsi Game1.Update() dipanggil, asalkan objek tersebut telah ditambahkan pada list DrawableGameComponent Game.Components.

22

float elapsed; public override void Update(GameTime gameTime) { elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds; if (Direction == 0) // menembak ke atas { Position.Y -= SPEED * elapsed; } else //menembak ke bawah { Position.Y += SPEED * elapsed; } if (Position.Y <= 0 ||Position.Y >= Game1.GAME_HEIGHT) { Game.Components.Remove(this); } base.Update(gameTime); }

Untuk menggambar peluru, kita gunakan cara yang sama seperti menggambar kapal, yaitu dengan menambahkan fungsi Draw() dan memanggil fungsi SpriteBatch.Draw() di dalamnya.
public override void Draw(GameTime gameTime) { ((Game1)Game).SpriteBatch.Draw(bulletTexture, Position, Color.White); base.Draw(gameTime); }

6.5. MEMBUAT KAPAL YANG DAPAT MENEMBAKKAN PELURU Sekarang kita sudah mempunyai kelas Bullet yang memodelkan peluru pada game, sehingga kita dapat membuat kapal kita menembakkan peluru. Pertama-tama, kita harus menambahkan atribut BulletTexture di kelas Game1 yang menyimpan data tekstur peluru yang akan kita gunakan untuk mengambarkan peluru pada game. Atribut ini harus bersifat public karena kita akan membuat peluru baru di kelas Ship, bukan di kelas Game1.
public Texture2D BulletTexture;

Lalu kita load data tekstur ini pada fungsi Game1.LoadContent().


BulletTexture = Content.Load<Texture2D>("bullet");

23

Setelah kita mempunyai data tekstur peluru pada Game1, kita menambahkan sebuah atribut pada kelas Ship, yaitu sebuah list of Bullet yang berisi peluru-peluru yang ditembakkan oleh kapal tersebut.
public List<Bullet> Bullets;

Lalu atribut Bullets ini akan diinisialisasi pada konstruktor kelas Ship.
Bullets = new List<Bullet>();

Terakhir, kita menambahkan fungsionalitas menembak pada kapal kita dengan membuat fungsi Ship.Shoot() yang akan membuat sebuah peluru baru dengan menggunakan data tekstur peluru yang telah kita load pada Game1, lalu menambahkannya ke Ship.Bullets dan Game.Components.
public void Shoot() { Bullet bullet = new Bullet((Game1)Game, this, ((Game1)Game).BulletTexture); Bullets.Add(bullet); Game.Components.Add(bullet); }

Lalu di manakah fungsi Ship.Shoot() ini dipanggil? Ya, tepat sekali! Kita harus menambahkan sesuatu pada fungsi Game1.playingHandleInput(), sehingga kedua kapal kita dapat menembakkan peluru setiap kali ada trigger dari input device. Oleh karena itu, kita tambahkan potongan kode berikut pada fungsi Game1.playingHandleInput() agar ketika tombol W ditekan, kapal yang di bawah akan menembakkan peluru ke atas, dan agar ketika tombol panah bawah ditekan, kapal yang di atas akan menembakkan peluru ke bawah. Tetapi, kita tidak ingin setiap kali tombol W atau tombol panah atas ditekan, sebuah peluru ditembakkan, karena ketika sebuah tombol keyboard ditekan sambil ditahan, tombol tersebut dapat terdeteksi dalam keadaan ditekan berkali-kali dalam selang waktu sepersekian detik saja. Dengan demikian jika peluru ditembakkan setiap kali tombol tersebut terdeteksi sedang dalam keadaan ditekan, maka akan terjadi hujan peluru yang sama sekali tidak bagus untuk game kita. Oleh karena itu, kita harus memastikan peluru baru akan ditembakkan setelah selang waktu minimum antara 2 buah peluru yang ditembakkan secara berurutan telah dipenuhi. Caranya adalah dengan menambahkan beberapa atribut pada kelas Game1.

24

public readonly static TimeSpan UPDATE_INTERVAL = new TimeSpan(0, 0, 0, 0, 330); private TimeSpan timeSinceLastUpdate1; private TimeSpan timeSinceLastUpdate2;

Pada Game1.Update(), nilai atribut timeSinceLastUpdate1 dan timeSinceLastUpdate2 akan ditambahkan dengan selang waktu antara pemanggilan fungsi Game1.Update() yang sekarang dengan pemanggilan yang sebelumnya. Kita lakukan ini di awal fungsi Game1.Update().
protected override void Update(GameTime gameTime) { timeSinceLastUpdate1 += gameTime.ElapsedGameTime; timeSinceLastUpdate2 += gameTime.ElapsedGameTime; playingHandleInput(gameTime); base.Update(gameTime); }

Sekarang kita dapat menambahkan potongan kode berikut pada fungsi Game1.playingHandleInput(), untuk membuat kapal menembakkan peluru ketika suatu tombol pada keyboard ditekan. Tetapi peluru baru akan ditembakkan jika total waktu yang telah berlalu telah lebih dari selang waktu minimum yang diperlukan untuk sebuah peluru ditembakkan (UPDATE_INTERVAL). Setiap peluru baru ditembakkan, timeSinceLastUpdate1 dan timeSinceLastUpdate2 di-assign dengan nilai TimeSpan.Zero.
if (Keyboard.GetState().IsKeyDown(Keys.W) && (timeSinceLastUpdate1 > UPDATE_INTERVAL)) { // Menembakkan peluru dari ship1 Ships[0].Shoot(); timeSinceLastUpdate1 = TimeSpan.Zero; } if (Keyboard.GetState().IsKeyDown(Keys.Down) && (timeSinceLastUpdate2 > UPDATE_INTERVAL)) { // Menembakkan peluru dari ship2 Ships[1].Shoot(); timeSinceLastUpdate2 = TimeSpan.Zero; }

25

Pada fungsi Bullet.Update(), kita sudah membuat sedemikian rupa sehingga ketika peluru sampai di luar area game, peluru tersebut akan dihapuskan dari Game1.Components. Sekarang, karena kita mempunyai atribut baru pada kelas Ship, yaitu Bullets, list of peluru yang ditembakkan oleh kapal tersebut, kita pun harus menghapuskan peluru yang sampai di luar area game dari Bullets. Sehingga fungsi Bullet.Update() kita sekarang akan menjadi seperti berikut ini:
float elapsed; public override void Update(GameTime gameTime) { elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds; if (Direction == 0) // menembak ke atas { Position.Y -= SPEED * elapsed; } else //menembak ke bawah { Position.Y += SPEED * elapsed; } if (Position.Y <= 0 || Position.Y >= Game1.GAME_HEIGHT) { ParentShip.Bullets.Remove(this); Game.Components.Remove(this); } base.Update(gameTime); }

Untuk melihat bagaimana kedua kapal kita sekarang sudah dapat menembakkan peluru, tekan F5

26

Gambar 12 Kedua Kapal Sudah Dapat Menembakkan Peluru Merah

27

7. INTERAKSI ANTAR OBJEK 7.1. DETEKSI TABRAKAN ANTARA PELURU DAN KAPAL Deteksi tabrakan (collision detection) adalah suatu teknik yang digunakan untuk menentukan apakah sebuah objek bertabrakan/berhimpitan dengan objek lain. Kita akan menambahkan fungsi deteksi tabrakan sederhana pada kelas Bullet. Fungsi ini bernama IsCollide() yang mengembalikan true jika peluru bertabrakan dengan sebuah objek dengan posisi dan radius tertentu. Fungsi ini menggunakan rumus untuk menentukan apakah sebuah titik ada di dalam lingkarang atau tidak. Jika jarak titik dan pusat lingkaran lebih kecil dari hasil kuadrat radius lingkaran, maka titik tersebut berada di dalam lingkaran. Kita merepresentasikan peluru menjadi sebuah titik, dan kapal menjadi sebuah lingkaran. Sehingga jika titik berada di dalam lingkaran, maka peluru bertabrakan dengan kapal.
public bool IsCollide(Vector2 position, float radius) { if (Vector2.DistanceSquared(this.Position, position) <= radius*radius) { return true; } else { return false; } }

Kita membutuhkan fungsi Bullet.IsCollide() untuk menentukan apakah peluru dari kapal yang satu berhasil mengenai kapal yang lainnya. Oleh karena itu, kita akan menambah sebuah atribut pada kelas Ship yang menyatakan radius dari kapal dan sebuah fungsi lagi, juga pada kelas Ship, yaitu fungsi yang bertugas untuk mengecek apakah peluru dari kapal lainnya berhimpitan dengan kapal tersebut.
readonly static float RADIUS = 50; int i, j; private void CheckCollisionWithBullets() { for (i = 0; i < ((Game1)Game).Ships.Length; i++) { if (((Game1)Game).Ships[i] != this) { for (j = 0; j < ((Game1)Game).Ships[i].Bullets.Count; j++) { if (((Game1)Game).Ships[i].Bullets[j].IsCollide(Position, RADIUS)) {

28

((Game1)Game).Ships[i].Score++; Game.Components.Remove(((Game1)Game).Ships[i].Bullets[j]); ((Game1)Game).Ships[i].Bullets.RemoveAt(j); } } } } }

Pada kelas Ship, kita harus menambahkan fungsi Update(), sehingga kita akan memanggil fungsi Ship.CheckCollisionWithBullets() di dalam fungsi tersebut.
public override void Update(GameTime gameTime) { CheckCollisionWithBullets(); base.Update(gameTime); }

Sekarang jika kita tekan F5 untuk melihat hasilnya, kita akan mendapatkan bahwa peluru yang kita tembakkan akan menghilang ketika mengenai kapal yang lain. Game kita sudah mulai terlihat seperti game sungguhan kan! ^^ 7.2. MEMBUAT TAMBAHAN OBJEK PENGHALANG (OBSTACLE) Untuk membuat game kita semakin menarik, mari kita membuat objek-objek penghalang yang bergerak-gerak di antara kedua kapal. Seperti membuat kelas Bullet, kita membuat kelas Obstacle, menambahkannya ke project kita, dan membuatnya menjadi kelas turunan dari Microsoft.Xna.Framework.DrawableGameComponent.
using using using using using using using using using using System; System.Collections.Generic; Microsoft.Xna.Framework; Microsoft.Xna.Framework.Audio; Microsoft.Xna.Framework.Content; Microsoft.Xna.Framework.GamerServices; Microsoft.Xna.Framework.Graphics; Microsoft.Xna.Framework.Input; Microsoft.Xna.Framework.Net; Microsoft.Xna.Framework.Storage;

namespace ShootingGameXNA { public class Obstacle : DrawableGameComponent { } }

29

Kita tambahkan atribut berikut ke kelas Obstacle: 1. LEFT_MARGIN : atribut konstanta yang nilainya menyatakan batas kiri yang dapat

dicapai oleh objek penghalang 2. RIGHT_MARGIN : atribut konstanta yang nilainya menyatakan batas kanan yang dapat

dicapai oleh objek penghalang 3. obstacleTexture : data tekstur 2D objek penghalang 4. Position 5. Radius 6. Speed : posisi objek penghalang : radius objek penghalang : kecepatan gerak objek penghalang

readonly static float LEFT_MARGIN = 100; readonly static float RIGHT_MARGIN = 100; public public public public Texture2D obstacleTexture; Vector2 Position; float Radius; float Speed;

Inisialisasi atribut-atribut ini dilakukan di konstruktor kelas Obstacle. Oleh karena itu, mari kita buat konstuktor kelas Obstacle sebagai berikut :
public Obstacle(Game1 game, Texture2D texture, Vector2 position, float speed) : base(game) { obstacleTexture = texture; Position = position; Radius = obstacleTexture.Width / 2; Speed = speed; }

Kita akan membuat objek penghalang yang bergerak-gerak secara horizontal di antara kedua kapal, dengan kecepatan berdasarkan atribut Speed. Dan ketika objek penghalang mencapai batas kiri atau kanan (LEFT_MARGIN atau RIGHT_MARGIN), objek akan bergerak ke arah sebaliknya. Selain behavior yang berhubungan dengan pergerakan, objek penghalang ini juga tidak bisa ditembus oleh peluru. Dengan kata lain, peluru akan menghilang ketika bertabrakan dengan objek penghalang. Semua behavior peluru ini akan kita implementasi dengan menambahkan fungsi Update() pada kelas Obstacle.
float elapsed; int i, j;

30

public override void Update(GameTime gameTime) { elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds; // Menggerakan obstacle if (Speed < 0) { if (Position.X < LEFT_MARGIN) { Speed = -Speed; } else { Position.X += Speed * elapsed; } } else { if (Position.X > Game1.GAME_WIDTH - RIGHT_MARGIN) { Speed = -Speed; } else { Position.X += Speed * elapsed; } } // Apakah obstacle bertabrakan dengan peluru? for (i = 0; i < ((Game1)Game).Ships.Length; i++) { for (j = 0; j < ((Game1)Game).Ships[i].Bullets.Count; j++) { if (((Game1)Game).Ships[i].Bullets[j].IsCollide(Position, Radius)) { Game.Components.Remove(((Game1)Game).Ships[i].Bullets [j]); ((Game1)Game).Ships[i].Bullets.RemoveAt(j); } } } base.Update(gameTime); }

Dan seperti kelas-kelas turunan DrawableGameComponent yang telah kita buat sebelumnya, kita harus melakukan membuat fungsi Draw() pada kelas Obstacle.
public override void Draw(GameTime gameTime) { ((Game1)Game).SpriteBatch.Draw(obstacleTexture, Position, Color.White); base.Draw(gameTime); }

31

7.3. MENAMBAHKAN OBJEK PENGHALANG KE GAME Pada kelas Game1, kita harus menambahkan beberapa atribut yang diperlukan untuk menambahkan objek penghalang pada game kita. 1. OBSTACLE_TEXTURE_PATH : array path dan nama file (tanpa ekstensi) semua tekstur 2D objek penghalang relatif terhadap Content 2. OBSTACLE_INIT_POS muncul di game 3. OBSTACLE_SPEED 4. ObstacleTextures 5. Obstacles : array kecepatan gerak semua objek penghalang : array data tekstur 2D objek penghalang : array objek penghalang yang ada di game : array posisi inisial semua objek penghalang ketika pertama kali

public readonly static int NUM_OBSTACLES = 3; public readonly static string[] OBSTACLE_TEXTURE_PATH = new string[] { "obstacle1", "obstacle2", "obstacle3" }; public readonly static Vector2[] OBSTACLE_INIT_POS = new Vector2[] { new Vector2(300, 200), new Vector2(170, 300), new Vector2(120, 400) }; public readonly static float[] OBSTACLE_SPEED = new float[] { 200, 300, -400 }; public Texture2D[] ObstacleTextures; public Obstacle[] Obstacles;

Kita melakukan load data tekstur objek penghalang dan membuat objek penghalang di dalam fungsi Game1.LoadContent().
ObstacleTextures = new Texture2D[NUM_OBSTACLES]; for (i = 0; i < NUM_OBSTACLES; i++) { ObstacleTextures[i] = Content.Load<Texture2D>(OBSTACLE_TEXTURE_PATH[i]); }

32

Obstacles = new Obstacle[NUM_OBSTACLES]; for (i = 0; i < NUM_OBSTACLES; i++) { Obstacles[i] = new Obstacle(this, ObstacleTextures[i], OBSTACLE_INIT_POS[i], OBSTACLE_SPEED[i]); Components.Add(Obstacles[i]); }

Kita tekan F5, dan Voila! Sekarang game kita semakin lengkap dan semakin menarik dengan adanya objek-objek penghalang yang menyulitkan pemain untuk menembakkan peluru ke kapal yang ada di seberang

Gambar 13 Objek Penghalang pada Game

33

8. MENAMPILKAN GRAPHICAL USER INTERFACE SCORE Game yang bagus tidak lepas dari Graphical User Interface (GUI) atau tampilan antar muka yang baik. GUI berfungsi untuk menampilkan informasi penting yang dibutuhkan oleh pemain, misalnya : nyawa pemain, score pemain, waktu tersisa, dan lain sebagainya. GUI yang baik merupakan hal wajib untuk sebuah game. Definisi GUI yang baik adalah GUI yang mudah dimengerti dan tidak merepotkan pemain untuk memperoleh informasi dari game. Sekarang kita akan membuat GUI sederhana agar pemain dapat melihat score untuk masing-masing kapal. Sebenarnya kita sudah membuat sistem scoring sederhana untuk kapal kita, sehingga setiap kapal berhasil menembakkan peluru ke kapal lain di seberang, score kapal tersebut akan bertambah. Sistem scoring sederhana ini ada pada fungsi Ship.CheckCollisionWithBullets():
((Game1)Game).Ships[i].Score++;

Kita akan menambahkan Graphical User Interface (UI) score yang berfungsi untuk menampilkan score setiap kapal. Karena score yang ditampilkan itu berupa teks, maka kita harus menggambarkan nilai score kapal berupa teks juga. Untuk menggambar teks pada XNA,kita memerlukan font yang direpresentasikan dalam bentuk Sprite Font. Sprite Font ini berupa file aset XML yang mempunyai extension .spritefont. Untuk UI score, kita akan menggunakan font Arial, sehingga kita membuat Sprite Font Arial dengan cara sebagai berikut : 1. Pada Solution Explorer, klik kanan pada Content, pilih Add New Item

2. Pada kotak dialog Add New Item, pilih Sprite Font pada kotak Templates. 3. Beri nama Arial.spritefont

34

Gambar 14 Menambahkan Sprite Font Arial ke Game

4. Klik Add Sekarang kita sudah mempunyai Arial.spritefont pada Content game kita. Namun default font yang digunakan pada Sprite Font biasanya bukan Arial, sehingga kita harus mengubahnya secara manual seperti di bawah ini: 1. Buka file Arial.spritefont 2. Ganti nilai elemen FontName menjadi Arial dan nilai element Size menjadi 26
<FontName>Arial</FontName> <Size>26</Size>

3. Save file Arial.spritefont Seperti tipe file aset lainnya, kita harus melakukan load Sprite Font pada fungsi Game1.LoadContent(). Tetapi terlebih dahulu kita harus menambahkan atribut yang akan menyimpan hasil load Sprite Font pada kelas Game1.
public SpriteFont ArialSpriteFont;

Pada fungsi Game1.LoadContent(), tambahkan potongan kode berikut untuk load file Arial.spritefont.
ArialSpriteFont = Content.Load<SpriteFont>("Arial");

35

Setelah kita mempunyai Sprite Font, kita dapat menggambar teks yang menyatakan score untuk masingmasing kapal dengan menggunakan fungsi SpriteBatch.DrawString(). Kita melakukannya di dalam fungsi Game1.Draw(), di dalam lingkup SpriteBatch.Begin() dan SpriteBatch.End(). Sebelumnya, kita akan menambahkan atribut konstanta pada kelas Game1, untuk menentukan posisi dan warna teks score yang kita gambar.
public readonly static { new Vector2(310, new Vector2(310, }; public readonly static { Color.Red, Color.Green }; Vector2[] SCORE_UI_POS = new Vector2[] 535), 25) Color[] SCORE_UI_COLOR = new Color[]

protected override void Draw(GameTime gameTime) { // Menggambar semua objek setiap gameTime spriteBatch.Begin(); spriteBatch.Draw(BgTexture, BG_POS, Color.White); for (i = 0; i < NUM_SHIPS; i++) { spriteBatch.DrawString(ArialSpriteFont, Ships[i].Score.ToString(), SCORE_UI_POS[i], SCORE_UI_COLOR[i]); } base.Draw(gameTime); spriteBatch.End(); }

Tekan F5, dan kita akan dapat melihat UI score yang telah kita bikin ada di samping masing-masing kapal

36

Gambar 15 Game yang Sudah Mempunyai UI Score

37

9. SOUND & MUSIC Game tanpa suara tentu saja kurang menarik. Oleh karena itu, kita akan menambahkan suara pada game kita, agar pemain dapat memperoleh pengalaman audio dari game, selain pengalaman visual. 9.1. MEMBUNGKUS FILE AUDIO MENJADI FILE ASET GAME DENGAN MICROSOFT XACT Pada XNA, semua file audio dibungkus terlebih dahulu dalam suatu file .xap. File .xap ini dibuat dengan menggunakan tools yang disediakan oleh XNA, yang bernama Microsoft Cross-Platform Audio Creation Tool (XACT). Kita ikuti langkah-langkah di bawah ini untuk membuat file .xap dari semua file audio yang akan kita tambahkan ke game kita: 1. Buka Microsoft Cross-Platform Audio Creation Tool (XACT). Jika XNA di-install di C:\Program Files\ maka program ini dapat ditemukan di C:\Program Files\Microsoft XNA\XNA Game Studio\v3.0\Tools\ dengan executable file bernama Xact.exe 2. Buat project baru dengan memilih pada menu bar File New Project

3. Tentukan lokasi penyimpanan project pada folder Content project kita, beri nama project ShootingGameXNAAudio, lalu klik Save 4. Pada window di kiri atas, terdapat Wave Banks dan Sound Banks. Klik kanan pada Wave Banks, pilih New Wave Bank, lalu klik kanan pada Sound Banks, pilih New Sound Bank Wave Banks adalah kumpulan file wave (.wav), sedangkan Sound Banks adalah kumpulan suara yang sudah dapat langsung dimainkan di dalam game.

38

Gambar 16 Tampilan Microsoft XACT

5. Tambahkan file audio untuk game kita pada Wave Bank, dengan cara klik kanan pada window Wave Bank, pilih Insert Wave File(s) Kita akan menambahkan file missilelaunch.wav dan explosion.wav yang terdapat pada folder yang sama dengan folder project XACT, yaitu folder Content 6. Drag missilelaunch dan explosion dari window Wave Bank ke Cue List yang ada pada window Sound Bank (bagian bawah dari Sound Bank)

39

Gambar 17 Menambahkan Wave dan Cue pada Microsoft XACT

9.2. MENAMBAHKAN SUARA KE GAME Setelah kita mempunyai file .xap yang merupakan kumpulan dari file audio, kita dapat menambahkan suara ke dalam game kita seperti di bawah ini: 1. Tambahkan file ShootingGameXNAAudio.xap, missilelaunch.wav, dan explosion.wav ke Content project kita, dengan klik kanan pada Content, lalu Add Existing Item

2. Tambahkan atribut yang diperlukan untuk audio pada game berikut: a. AudioEngine b. SoundBank c. WaveBank : engine yang digunakan XNA untuk mengelola suara pada game : objek representasi dari sound bank yang di-load dari file aset audio : objek representasi dari wave bank yang di-load dari file aset audio

public AudioEngine AudioEngine; public SoundBank SoundBank; public WaveBank WaveBank;

3. Inisialisasi ketiga atribut di atas pada fungsi Game1.LoadContent()


AudioEngine = new AudioEngine("Content/ShootingGameXNAAudio.xgs"); WaveBank = new WaveBank(AudioEngine, "Content/Wave Bank.xwb");

40

SoundBank = new SoundBank(AudioEngine, "Content/Sound Bank.xsb");

Sekarang kita sudah dapat menggunakan suara yang sudah kita bungkus menjadi file .xap tadi untuk dijadikan sound effect ketika terjadi sesuatu pada game kita dengan menggunakan fungsi SoundBank.PlayCue(). Kita tambahkan potongan kode ini ke dalam fungsi Ship.Shoot() untuk memberikan sound effect missilelaunch ketika sebuah peluru ditembakkan.
((Game1)Game).SoundBank.PlayCue("missilelaunch");

Dan kita tambahkan potongan kode ini ke dalam fungsi Ship.CheckCollisionWithBullets() untuk memberikan sound effect ledakan ketika peluru mengenai kapal, sehingga fungsi Ship.CheckCollisionWithBullets() menjadi seperti di bawah ini:
int i, j; private void CheckCollisionWithBullets() { for (i = 0; i < ((Game1)Game).Ships.Length; i++) { if (((Game1)Game).Ships[i] != this) { for (j = 0; j < ((Game1)Game).Ships[i].Bullets.Count; j++) { if (((Game1)Game).Ships[i].Bullets[j].IsCollide(Position, RADIUS)) { ((Game1)Game).Ships[i].Score++; Game.Components.Remove(((Game1)Game).Ships[i].Bullets[j]); ((Game1)Game).Ships[i].Bullets.RemoveAt(j); ((Game1)Game).SoundBank.PlayCue("explosion"); } } } } }

Lalu kita tambahkan potongan kode yang sama seperti di atas dalam fungsi Obstacle.Update() untuk memberikan sound effect ledakan juga ketika peluru mengenai objek penghalang, sehingga bagian pengecekan tabrakan dengan peluru pada Obstacle.Update() akan menjadi seperti di bawah ini:
// Apakah obstacle bertabrakan dengan peluru? for (i = 0; i < ((Game1)Game).Ships.Length; i++) { for (j = 0; j < ((Game1)Game).Ships[i].Bullets.Count; j++) { if (((Game1)Game).Ships[i].Bullets[j].IsCollide(Position,Radius)) { Game.Components.Remove(((Game1)Game).Ships[i].Bullets[j]);

41

((Game1)Game).Ships[i].Bullets.RemoveAt(j); ((Game1)Game).SoundBank.PlayCue("explosion"); } } }

Tekan F5 dan kita akan mendapatkan pengalaman yang lebih ketika bermain game ini dengan adanya sound effect ketika kita menembak dan mengenai objek pada game :D

42

10. THE GAME IS DONE! Selamat! Game kita sudah selesai, dengan demikian Anda sudah menjadi seorang game developer! Sebenarnya masih banyak pengembangan selanjutnya yang dapat dilakukan untuk game tadi, misalnya: 1. Menambahkan efek partikel ledakan ketika peluru menabrak kapal 2. Membuat kapal dikendalikan dengan artificial intelligence (AI), sehingga pemain bisa bermain sendirian, tanpa harus mengendalikan kedua kapal sekaligus 3. Menambahkan layar main menu, game over, dan sebagainya Anda dapat mengembangkan sesuka hati Anda, karena ini adalah game yang sepenuhnya milik Anda! Selamat berkreasi!

43

PENUTUP Sampailah juga kita di bagian akhir e-book ini dan telah muncullah seorang game developer baru di dunia, yaitu Anda! Dari perjalanan kita dari awal sampai akhir e-book ini, kita dapat menyimpulkan bahwa XNA sangat memudahkan kita untuk membuat sebuah game. Cukup dengan pengetahuan pemrograman dasar, kita dapat membuat game dengan mudah. Jika Anda tertarik untuk mendalami XNA lebih lanjut, Anda dapat mencari sumber online yang terpercaya di XNA Creators Club Online, XNA Framework Class Library Reference, atau Riemers XNA Tutorial. Selamat belajar dan sampai jumpa di e-book game development berikutnya!

44

REFERENSI XNA 3.0 Game Programming Recipes: A Problem-Solution Approach (Expert's Voice in XNA) Beginning XNA 3.0 Game Programming: From Novice to Professional Game Development and Production Learning XNA 3.0: XNA 3.0 Game Development for the PC, Xbox 360, and Zune Microsoft XNA Unleashed: Graphics and Game Programming for Xbox 360 and Windows Microsoft XNA Game Studio 3.0 Unleashed XNA Creators Club Online XNA Framework Class Library Reference