GRAFIKA GAME Aditya Wikan Mahastama mahas@ukdw.ac.id Implementasi Grid dan Animasi Sederhana 7 UNIV KRISTEN DUTA WACANA TEKNIK INFORMATIKA GENAP 1213
Apa saja yang dibutuhkan untuk melakukan implementasi pemrograman game menggunakan grid? Sebuah grid map/tile map Sebuah sprite sheet/tile sheet Implementasi Grid
Grid Map Grid Map adalah gambaran dari papan permainan yang akan kita gunakan (background) Berbentuk struktur data berisi representasi objek yang akan diletakkan di papan permainan sebagai objek statis Objek pada umumnya diwakili dengan sebuah ID yang nantinya akan digunakan untuk mendeteksi sifat objek dan menampilkan sprite yang sesuai dengan objek tersebut
Grid Map Sifat objek misalnya: halangan, makanan, jalan, dsb., yang tentunya akan berkorelasi dengan sprite yang akan ditampilkan Pemberian ID akan lebih mudah jika menggunakan bilangan, contoh: 31 = tembok pojok 30 = tembok biasa 0 = jalan 25 = halangan, dsb
Grid Map Sehingga untuk sebuah peta papan permainan berikut, kita bisa mendefinisikannya dalam stuktur data array dua dimensi seperti ini: var tilemap = [ var tilemap = [ [32,31,31,31,1,31,31,31,31,32], [1,1,1,1,1,1,1,1,1,1], [32,1,26,1,26,1,26,1,1,32], [32,26,1,1,26,1,1,26,1,32], [32,1,1,1,26,26,1,26,1,32], [32,1,1,26,1,1,1,26,1,32], [32,1,1,1,1,1,1,26,1,32], [1,1,26,1,26,1,26,1,1,1], [32,1,1,1,1,1,1,1,1,32], [32,31,31,31,1,31,31,31,31,32] ];
Tile Sheet Tile sheet (disebut juga sprite sheet) adalah sebuah citra yang berisi beberapa frame citra individual yang akan digunakan untuk menggambarkan sebuah objek pada game Setiap frame pada tile sheet akan diasosiasikan pada sebuah ID, melalui script pemrograman yang digunakan Mengapa tidak menggunakan citra yang terpisahpisah? Secara teknis memang memungkinkan, tetapi tidak efisien karena melakukan loading citra secara berulang-ulang ke memori
Tile Sheet Berikut contoh tile sheet yang diperlukan untuk menggambarkan peta permainan pada slide sebelumnya, yang sebagai contoh diasosiasikan dengan ID berikut: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 Courtesy: http://my.safaribooksonline.com/9781449308032/advanced_cell-based_animation#example_tile_sheet
Menggambar Papan Permainan Untuk dapat menggambarkan sebuah citra ke layar, kita membutuhkan instruksi untuk me-load sebuah citra ke memori, dan sebuah event handler untuk menangkap event load, kemudian melakukan sesuatu: var tilesheet = new Image(); tilesheet.src = tanks_sheet.png ; tilesheet.addeventlistener('load', eventsheetloaded, false); +
Menggambar Papan Permainan Kemudian tentukan variabel-variabel untuk membantu loop saat rendering, serta tile mapnya var maprows = 10; var mapcols = 10; var tilemap = [ [31,30,30,30,0,30,30,30,30,31], [0,0,0,0,0,0,0,0,0,0], [31,0,25,0,25,0,25,0,0,31], [31,25,0,0,25,0,0,25,0,31], [31,0,0,0,25,26,0,25,0,31], [31,0,0,25,0,0,0,25,0,31], [31,0,0,0,0,0,0,25,0,31], [0,0,25,0,25,0,25,0,0,0], [31,0,0,0,0,0,0,0,0,31], [31,30,30,30,0,30,30,30,30,31] ];
Menggambar Papan Permainan Terakhir, event handler dan function penggambarnya function eventsheetloaded() { drawscreen() //jika ingin diulang2 gunakan setinterval(drawscreen,100) } function drawscreen() { for (var rowctr=0;rowctr<maprows;rowctr++) { for (var colctr=0;colctr<mapcols;colctr++){ var tileid = tilemap[rowctr][colctr]+mapindexoffset; var sourcex = Math.floor(tileId % 8) *32; var sourcey = Math.floor(tileId / 8) *32; context.drawimage(tilesheet, sourcex, sourcey,32,32,colctr*32,rowctr*32,32,32); } } }
The Key context.drawimage(tilesheet, sourcex, sourcey, 32, 32, colctr*32, rowctr*32, 32, 32); Courtesy: http://www.w3schools.com/tags/canvas_drawimage.asp
Menganimasikan Sprite Menganimasikan sprite menggunakan prinsip yang sama dengan penggambaran peta permainan, hanya saja penggambaran diletakkan pada koordinat yang sama Pada contoh berikut kita akan menganimasikan gambar tank dari tile sheet yang ada sebelumnya 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
Menganimasikan Sprite Kita tentukan dulu frame-frame yang akan dianimasikan var animationframes = [1,2,3,4,5,6,7,8]; var frameindex = 0; Mengapa tidak menggunakan sekedar counter? Jika menggunakan counter, maka akan butuh dua variabel maksimum dan minimum, serta tidak memungkinkan adanya loncatan frame
Kemudian gambarkan kumpulan frame tersebut ke sebuah koordinat yang sama function eventsheetloaded() { } setinterval(drawscreen, 100 ); Menganimasikan Sprite function drawscreen() { //draw a background so we can see the Canvas edges context.fillstyle = "#aaaaaa"; context.fillrect(0,0,500,500); var sourcex = Math.floor(animationFrames[frameIndex] % 8) *32; var sourcey = Math.floor(animationFrames[frameIndex] / 8) *32; context.drawimage(tilesheet, sourcex, sourcey,32,32,50,50,32,32); frameindex++; if (frameindex ==animationframes.length) { frameindex=0; } }
Menggerakkan Sprite? Tinggal geser koordinat penggambarannya di kanvas
Menggabungkan Peta dan Objek Beri nama tersendiri untuk fungsi penggambaran peta dan penggambaran sprite, misal drawmap() dan drawsprite(); Pada event handler, fungsi yang dipanggil adalah fungsi induk untuk penggambaran dengan interval terhadap kedua fungsi tersebut function eventsheetloaded() { } setinterval(drawall, 100 ); function drawall(){ drawmap(); drawsprite(); }
Sprite Tidak Menyatu Dengan Peta Solusi sementara (non grafika) dan lebih efisien adalah dengan memberikan warna yang sama untuk background objek dinamis dengan warna peta yang akan dilaluinya, atau Memberikan warna background objek yang transparan, jika menggunakan citra GIF atau PNG
Question: Translation SPEED How to move two objects along with different speeds at the same delay interval? Integer speeds caused unnatural multiplication problem. Any solution?
Extra: Mendeteksi Event Keyboard Event keyboard bisa dideteksi oleh browser secara keseluruhan, maupun oleh objek di dalam browser, misalnya kanvas. Jenis event ada dua, yaitu keypress untuk menangkap penekanan tombol apapun, dan keydown untuk menangkap penekanan tombol tertentu window.addeventlistener( "keypress", dokeydown, false); canvas.addeventlistener( "keydown", dokeydown, true);
Extra: Mendeteksi Event Keyboard Jika memilih untuk menggunakan event keydown, maka EventListener akan mengembalikan sebuah parameter yang berisi kode keyboard, misal untuk A adalah 65. Parameter ini diakses melalui atribut keycode Kode keyboard bisa dicari sepenuhnya di Internet, atau dicetak sendiri melalui script berikut: window.addeventlistener( "keydown", dokeydown, true); //tampilkan function dokeydown(e) { alert( e.keycode ); }
Extra: Mendeteksi Event Mouse Sama dengan mendeteksi event keyboard, kita gunakan kembali EventListener, hanya sekarang event yang kita handle adalah mousedown, yang mengembalikan parameter dengan method pagex dan pagey canvas.addeventlistener( mousedown", dokeydown, true); //tampilkan function dokeydown(e) { alert( e.pagex ); alert( e.pagey ); }
Tips pemrograman: Extra: Mendeteksi Event Mouse By common sense saja: jika ada mousedown, biasanya ada mouseup, dan mousemove Gunakan common sense untuk mencoba menemukan event lain dari event yang sudah anda ketahui, misalnya keydown
SELESAI UNTUK MATERI INI Materi berikutnya: Gerak bebas dan deteksi tumbukan sederhana Sumber: 1. http://my.safaribooksonline.com/book/web-development/html/9781449308032/images-on-the-canvas/creating_a_grid_of_tiles 2. http://my.safaribooksonline.com/9781449308032/advanced_cell-based_animation#example_tile_sheet 3. http://my.safaribooksonline.com/9781449308032/combining_bitmaps_and_sound#combining_bitmaps_and_sound 4. http://http://www.w3schools.com/tags/canvas_drawimage.asp 5. http://www.homeandlearn.co.uk/js/html5_canvas_keyboard_keys.html 6. http://www.homeandlearn.co.uk/js/html5_canvas_mouse_events.html