Membuat Permainan Space Shooter Sederhana di HTML5 dengan EaselJS
Indonesian (Bahasa Indonesia) translation by ⚡ Rova Rindrata (you can also view the original English article)
Tahun lalu, saya menunjukkan cara membuat permainan shoot-'em-up dengan Flash dan AS3. Dengan meningkatnya popularitas (dan kemampuan) HTML5, mari kita lihat cara melakukan hal yang sama dengan HTML5, JavaScript, dan EaselJS.
Pratinjau Hasil Akhir
Mari kita lihat hasil akhir yang akan kita jalani:
Langkah 1: Ringkasan Singkat
Menggunakan sprite yang dibuat sebelumnya kita akan mengkode permainan Space Shooter yang menghibur di HTML5 menggunakan perpustakaan EaselJS.
Pemain akan dapat mengontrol pesawat ruang angkasa dan menembak beberapa musuh saat bepergian di luar angkasa.
Langkah 2: Antarmuka
Antarmuka yang sederhana dan futuristik akan digunakan, ini melibatkan bitmap dan banyak lagi. Saya telah menggunakan perpustakaan sprite yang sangat bagus dalam demo tutorial ini, ini adalah bagian dari Sinistar Clone Graphics yang gratis.
Sumber daya antarmuka yang diperlukan untuk tutorial ini dapat ditemukan di unduhan terlampir.
Langkah 3: Mendapatkan EaselJS
Perpustakaan EaselJS akan digunakan untuk membangun permainan kita, pastikan Anda membaca tutorial Getting Started jika Anda baru mengenal perpustakaan ini.
Anda dapat mengunduh EaselJS dari situs resminya.
Langkah 4: Struktur HTML
Mari siapkan dokumen HTML kita, ini adalah struktur HTML sederhana untuk mulai menulis aplikasi kita. Simpan ini sebagai Shooter.html
.
<!DOCTYPE html> <html> <head> <title>Shooter</title> </head> <body> </body> </html>
Langkah 5: Menyembunyikan Sorotan Mobile
Mari tambahkan sedikit CSS juga, baris ini akan menghapus sorotan default saat Anda mengetuk elemen menggunakan browser mobile; tanpa ini, pengalaman mobile akan menurun drastis.
<!DOCTYPE html> <html> <head> <title>Shooter</title> <style>*{-webkit-tap-highlight-color: rgba(0, 0, 0, 0);}</style> </head> <body> </body> </html>
Langkah 6: Perpustakaan JavaScript
Kode berikut menambahkan perpustakaan JavaScript yang diperlukan agar aplikasi kita berfungsi.
<!DOCTYPE html> <html> <head> <title>Shooter</title> <style>*{-webkit-tap-highlight-color: rgba(0, 0, 0, 0);}</style> <script src="easel.js"></script> <script src="Tween.js"></script> <script src="sound.js"></script> <script src="Main.js"></script> </head> <body> </body> </html>
Main.js
adalah file yang akan kita gunakan untuk menyimpan semua fungsi kita sendiri untuk permainannya. Buat sekarang dan simpan di folder yang sama dengan Shooter.html
. Anda juga harus mengunduh perpustakaan EaselJS yang terdaftar.
Langkah 7: Memanggil Fungsi Utama
Di baris berikutnya kita panggil fungsi utama kita; ini adalah fungsi yang akan memulai aplikasi kita, itu akan dibuat nanti di kode JavaScript kita.
<!DOCTYPE html> <html> <head> <title>Shooter</title> <style>*{-webkit-tap-highlight-color: rgba(0, 0, 0, 0);}</style> <script src="easel.js"></script> <script src="Tween.js"></script> <script src="sound.js"></script> <script src="Main.js"></script> </head> <body onload="Main();"> </body> </html>
Langkah 8: Elemen Canvas
Canvas ditambahkan di baris ini. Kita menetapkan ID untuk referensi nanti dan juga mengatur lebar dan tingginya.
<!DOCTYPE html> <html> <head> <title>Shooter</title> <style>*{-webkit-tap-highlight-color: rgba(0, 0, 0, 0);}</style> <script src="easel.js"></script> <script src="Tween.js"></script> <script src="sound.js"></script> <script src="Main.js"></script> </head> <body onload="Main();"> <canvas id="Shooter" width="320" height="480"></canvas> </body> </html>
Langkah 9: Memulai JavaScript
Mari kita mulai pembuatan permainan kita!
Buka editor JavaScript pilihan Anda (editor teks apa pun akan berfungsi, tetapi Anda tidak akan memiliki penyorotan sintaks) dan bersiap untuk menulis permainan Anda yang luar biasa. Buka file Main.js
yang Anda buat sebelumnya.
Langkah 10: Mendefinisikan Canvas
Kita akan mulai dengan mendefinisikan semua variabel grafis dan logika.
Variabel berikutnya mewakili elemen canvas HTML dan tahap yang akan dikaitkan dengannya. (Variabel stage akan berperilaku dengan cara yang mirip dengan stage dalam proyek AS3 Flash.)
/* Define Canvas */ var canvas; var stage;
Langkah 11: Latar Belakang
Variabel berikutnya menyimpan gambar latar belakang. Dua ubin gambar digunakan untuk membuat latar belakang pengguliran yang tak terbatas.
/* Background */ var bgImg = new Image(); var bg; var bg2Img = new Image(); var bg2;
Langkah 12: Pesawat
Ini adalah Pesawat yang akan digunakan sebagai karakter pemain atau pahlawan.
/* Ship */ var sImg = new Image(); var ship;
Langkah 13: Musuh
Beberapa musuh akan berada di panggung; mereka akan menggunakan ini sebagai grafik sumber.
/* Enemy */ var eImg = new Image();
Step 14: Bos
Seorang bos akan hadir dalam permainan, lebih besar dan dengan health yang lebih banyak daripada musuh lainnya. Variabel-variabel ini digunakan untuk instansiasi itu.
/* Boss */ var bImg = new Image(); var boss;
Langkah 15: Nyawa
Ikon "life". Tiga nyawa diberikan di awal, dan Anda kehilangan satu ketika terkena musuh.
/* Lives */ var lImg = new Image();
Langkah 16: Peluru
Ini adalah senjata Anda: tembakkan peluru pada musuh untuk membunuh mereka. Variabel ini menyimpan gambar sumber.
/* Bullets */ var bltImg = new Image();
Langkah 17: Grafik Peringatan
Dua peringatan digunakan dalam permainan, satu untuk saat Anda menang dan satu untuk saat Anda kalah. Kita akan melihat bagaimana menentukan kemenangan atau kekalahan nanti dalam tutorial ini.
/* Alert */ var winImg = new Image(); var loseImg = new Image(); var win; var lose;
Langkah 16: Variabel-variabel
Ini adalah variabel yang akan kita gunakan, baca komentar di kode untuk mengetahui lebih banyak tentang mereka. Beberapa nama mereka cukup jelas dan tidak memiliki komentar.
var lives = new Container(); //stores the lives gfx var bullets = new Container(); //stores the bullets gfx var enemies = new Container(); //stores the enemies gfx var bossHealth = 20; var score; var gfxLoaded = 0; //used as a preloader, counts the already loaded items var centerX = 160; var centerY = 240; var tkr = new Object(); //used as a Ticker listener var timerSource; //references a setInterval method
Langkah 17: Suara-suara
Kita akan menggunakan efek suara untuk meningkatkan rasa permainan. Anda dapat menemukan suara-suara yang digunakan dalam contoh ini di Soungle.com menggunakan kata kunci space, explosion dan laser.
Langkah 18: Fungsi Main
Fungsi Main()
akan menjadi yang pertama dijalankan saat halaman web dimuat, karena dirujuk ke atribut onload
dari dokumen HTML (lihat Langkah 7).
Ini memanggil fungsi yang diperlukan untuk memulai permainan. Kita akan membuat fungsi-fungsi itu di langkah selanjutnya - semuanya dari Langkah 19 hingga Langkah 23 harus masuk ke dalam fungsi ini.
function Main() { //code... }
Langkah 19: Tautan Canvas
Kode ini mendapatkan ID canvas HTML dan menghubungkannya ke kelas Stage EaselJS. Ini akan membuat variabel stage berperilaku seperti kelas stage di AS3.
/* Link Canvas */ canvas = document.getElementById('Shooter'); stage = new Stage(canvas);
Langkah 20: Mengaktifkan Event Mouse
Event Mouse dinonaktifkan secara default di EaselJS untuk meningkatkan kinerja; seperti yang kita butuhkan dalam permainan kita tambahkan baris berikut.
stage.mouseEventsEnabled = true;
Langkah 21: Memuat Suara-suara
Kita akan menggunakan SoundJS untuk menambahkan suara ke permainan kita. Metode addBatch
SoundJS menggunakan array tiga parameter untuk setiap panggilan:
-
name
: Nama instance yang Anda inginkan untuk suaranya - ini akan digunakan untuk memainkan suara nanti. -
src
: URL file suara. -
instances
: Jumlah instance yang dapat diputar pada waktu yang sama.
/* Sound */ SoundJS.addBatch([ {name:'boss', src:'boss.mp3', instances:1}, {name:'explo', src:'explo.mp3', instances:10}, {name:'shot', src:'shot.mp3', instances:10}]);
Langkah 22: Memuat Grafis
Kode ini digunakan untuk melakukan pramuat grafik dengan bantuan fungsi yang akan kita tulis nanti. Ini menunjuk setiap objek Image yang kita buat sebelumnya ke file sumber PNG di folder dokumen kita. Sebuah nama diberikan untuk mendeteksi gambar mana yang dimuat, dan terakhir fungsi yang menangani gambar yang dimuat dipanggil.
/* Load GFX */ bgImg.src = 'bg.png'; bgImg.name = 'bg'; bgImg.onload = loadGfx; bg2Img.src = 'bg2.png'; bg2Img.name = 'bg2'; bg2Img.onload = loadGfx; sImg.src = 'ship.png'; sImg.name = 'ship'; sImg.onload = loadGfx; eImg.src = 'enemy1.png'; eImg.name = 'enemy'; eImg.onload = loadGfx; bImg.src = 'boss.png'; bImg.name = 'boss'; bImg.onload = loadGfx; lImg.src = 'live.png'; lImg.name = 'live'; lImg.onload = loadGfx; bltImg.src = 'bullet.png'; bltImg.name = 'bullet'; bltImg.onload = loadGfx; winImg.src = 'win.png'; winImg.name = 'win'; winImg.onload = loadGfx; loseImg.src = 'lose.png'; loseImg.name = 'lose'; loseImg.onload = loadGfx;
Langkah 23: Menetapkan Ticker
Kelas Ticker menyediakan "tick" yang terpusat, disiarkan pada interval yang ditetapkan. Kita dapat menggunakan fungsi tick()
untuk menjalankan kode tertentu pada frekuensi reguler.
Kode berikut menetapkan frame rate menjadi 30 dan mendefinisikan stage sebagai listener untuk ticks.
Kelas TweenJS akan melakukan listen kepada tick ini untuk melakukan animasi.
/* Ticker */ Ticker.setFPS(30); Ticker.addListener(stage);
Langkah 24: Fungsi Preload
Setiap kali grafik dimuat fungsi ini akan berjalan. Ini akan menetapkan setiap gambar ke objek bitmap dan memeriksa bahwa semua elemen dimuat sebelum melanjutkan untuk memanggil addGameView
.
function loadGfx(e) { if(e.target.name = 'bg'){bg = new Bitmap(bgImg);} if(e.target.name = 'bg2'){bg2 = new Bitmap(bg2Img);} if(e.target.name = 'ship'){ship = new Bitmap(sImg);} gfxLoaded++; if(gfxLoaded == 9) { addGameView(); } }
Langkah 25: Menambahkan Tampilan Permainan
Ketika semua grafik dimuat, fungsi addGameView
dipanggil. Fungsi ini akan menambahkan pesawat, penghitung nyawa, skor, dan latar belakang ke panggung.
function addGameView() { ship.x = centerX - 18.5; ship.y = 480 + 34; /* Add Lives */ for(var i = 0; i < 3; i++) { var l = new Bitmap(lImg); l.x = 248 + (25 * i); l.y = 463; lives.addChild(l); stage.update(); } /* Score Text */ score = new Text('0', 'bold 14px Courier New', '#FFFFFF'); score.maxWidth = 1000; //fix for Chrome 17 score.x = 2; score.y = 476; /* Second Background */ bg2.y = -480; /* Add gfx to stage and Tween Ship */ stage.addChild(bg, bg2, ship, enemies, bullets, lives, score); Tween.get(ship).to({y:425}, 1000).call(startGame); }
Langkah 26: Memindahkan Pesawat
Pesawat pemain akan dikontrol dengan mouse, dan kita menggunakan fungsi ini untuk menanganinya:
function moveShip(e) { ship.x = e.stageX - 18.5; }
e.stageX
mengacu pada koordinat x dari mouse, dan fungsi ini dipanggil setiap kali mouse dipindahkan.
Langkah 27: Menembak
Pesawat kita akan dapat menembakkan peluru untuk menghancurkan dan melindungi diri dari musuh. Fungsi ini akan berjalan setiap kali pengguna mengklik panggung dan akan menempatkan peluru di depan pesawat yang nantinya akan dipindahkan oleh fungsi update()
. Ini juga memainkan suara tembakan.
function shoot() { var b = new Bitmap(bltImg); b.x = ship.x + 13; b.y = ship.y - 20; bullets.addChild(b); stage.update(); SoundJS.play('shot'); }
Langkah 28: Menambahkan Fungsi Musuh
Itu bukan penembak tanpa sesuatu untuk ditembak. Di sini, sebuah setInterval()
digunakan untuk membuat musuh setiap 1000 milidetik (Anda dapat mengubah nilai itu di langkah berikutnya) yang kemudian dipindahkan oleh fungsi update()
.
function addEnemy() { var e = new Bitmap(eImg); e.x = Math.floor(Math.random() * (320 - 50)) e.y = -50 enemies.addChild(e); stage.update(); }
Langkah 29: Mulai Permainan
Baris-baris ini akan menambahkan listener yang diperlukan ke panggung dan pengatur waktu; ini termasuk event mouse, event yang dibatasi waktu (melalui setInterval
) dan event Ticker yang akan memperbarui permainan setiap frame.
function startGame() { stage.onMouseMove = moveShip; bg.onPress = shoot; bg2.onPress = shoot; Ticker.addListener(tkr, false); tkr.tick = update; timerSource = setInterval('addEnemy()', 1000); }
Langkah 30: Memindahkan Latar Belakang
Latar belakang dipindahkan setiap frame untuk mensimulasikan perjalanan ruang angkasa; ketika sprite latar belakang yang lebih rendah mencapai batas panggung ia dipindahkan kembali ke atas, menciptakan perulangan tak terbatas.
function update() { /* Move Background */ bg.y += 5; bg2.y += 5; if(bg.y >= 480) { bg.y = -480; } else if(bg2.y >= 480) { bg2.y = -480; }
Langkah 31: Memindahkan Peluru
Baris kode berikutnya memeriksa apakah ada peluru di panggung; jika demikian, peluru akan bergerak ke atas.
/* Move Bullets */ for(var i = 0; i < bullets.children.length; i++) { bullets.children[i].y -= 10; }
Langkah 32: Menghapus Peluru di Luar Panggung
Mari tambahkan beberapa baris untuk mendeteksi posisi peluru, dan gunakan ini untuk menghancurkan peluru ketika tidak lagi terlihat.
/* Move Bullets */ for(var i = 0; i < bullets.children.length; i++) { bullets.children[i].y -= 10; /* Remove Offstage Bullets */ if(bullets.children[i].y < - 20) { bullets.removeChildAt(i); } }
Langkah 33: Menunjukkan Bos
Kita akan menambahkan bos besar yang buruk ke dalam permainan. Ketika pengguna mencapai skor tertentu, bos akan muncul:
/* Show Boss */ if(parseInt(score.text) >= 500 && boss == null) { boss = new Bitmap(bImg); SoundJS.play('boss'); boss.x = centerX - 90; boss.y = -183; stage.addChild(boss); Tween.get(boss).to({y:40}, 2000) //tween the boss onto the play area }
Langkah 34: Memindahkan Musuh-musuh
Musuh-musuh, seperti peluru, juga dipindahkan setiap frame. Kode ini menemukan semua musuh di panggung menggunakan kontainer enemies
, dan menggerakkan mereka masing-masing 5px ke bawah.
/* Move Enemies */ for(var j = 0; j < enemies.children.length; j++) { enemies.children[j].y += 5;
Langkah 35: Menghapus Musuh di Luar Panggung
Kita juga memeriksa posisi musuh untuk menghancurkan mereka ketika tidak lagi terlihat.
/* Move Enemies */ for(var j = 0; j < enemies.children.length; j++) { enemies.children[j].y += 5; /* Remove Offstage Enemies */ if(enemies.children[j].y > 480 + 50) { enemies.removeChildAt(j); }
Langkah 36: Tabrakan Peluru - Musuh
Peluru di kontainer diuji untuk bertabrakan dengan musuh; ketika ini terjadi, keduanya dihapus dari panggung, suara dimainkan dan skor diperbarui.
for(var k = 0; k < bullets.children.length; k++) { /* Bullet - Enemy Collision */ if(bullets.children[k].x >= enemies.children[j].x && bullets.children[k].x + 11 < enemies.children[j].x + 49 && bullets.children[k].y < enemies.children[j].y + 40) { bullets.removeChildAt(k); enemies.removeChildAt(j); stage.update(); SoundJS.play('explo'); score.text = parseFloat(score.text + 50); }
Langkah 37: Tabrakan Peluru - Bos
Kode berikut menangani tabrakan bos, itu menggunakan metode yang sama yang digunakan dalam perulangan tabrakan peluru-musuh. Di sini kita menggunakan variabel bossHealth
untuk menentukan kapan bos sudah dikalahkan.
/* Bullet - Boss Collision */ if(boss != null && bullets.children[k].x >= boss.x && bullets.children[k].x + 11 < boss.x + 183 && bullets.children[k].y < boss.y + 162) { bullets.removeChildAt(k); bossHealth--; stage.update(); SoundJS.play('explo'); score.text = parseInt(score.text + 50); } }
Langkah 38: Tabrakan Pesawat - Musuh
Di sini kita memeriksa apakah musuh bertabrakan dengan kapal pemain; jika itu terjadi, suara dimainkan, nyawa dihapus, dan pesawat itu dianimasikan.
/* Ship - Enemy Collision */ if(enemies.hitTest(ship.x, ship.y) || enemies.hitTest(ship.x + 37, ship.y)) { enemies.removeChildAt(j); lives.removeChildAt(lives.length); ship.y = 480 + 34; Tween.get(ship).to({y:425}, 500) SoundJS.play('explo'); } }
Langkah 39: Periksa untuk Menang atau Kalah
Pemain menang ketika bos kehilangan semua health dan kalah jika semua nyawa mereka hilang. Baris berikutnya mendeteksi situasi tersebut dan memanggil fungsi peringatan menggunakan parameter yang benar.
/* Check for win */ if(boss != null && bossHealth <= 0) { alert('win'); } /* Check for lose */ if(lives.children.length <= 0) { alert('lose'); } }
Langkah 40: Peringatan
Peringatan menunjukkan informasi pemain tentang status permainan; ini ditunjukkan saat tercapai event permainan. Ini menghapus listener permainan dan menunjukkan pesan yang sesuai.
function alert(e) { /* Remove Listeners */ stage.onMouseMove = null; bg.onPress = null; bg2.onPress = null; Ticker.removeListener(tkr); tkr = null; timerSource = null; /* Display Correct Message */ if(e == 'win') { win = new Bitmap(winImg); win.x = centerX - 64; win.y = centerY - 23; stage.addChild(win); stage.removeChild(enemies, boss); } else { lose = new Bitmap(loseImg); lose.x = centerX - 64; lose.y = centerY - 23; stage.addChild(lose); stage.removeChild(enemies, ship); } bg.onPress = function(){window.location.reload();}; bg2.onPress = function(){window.location.reload();}; stage.update(); }
Langkah 41: Pengujian



Simpan pekerjaan Anda (jika Anda belum) dan buka file HTML di browser untuk melihat permainan HTML5 Anda berfungsi!
Kesimpulan
Anda telah belajar cara membuat permainan Space Shooter dengan semua fitur dasarnya, cobalah untuk memperluasnya menggunakan apa yang sudah Anda ketahui. Awal yang baik adalah membuat musuh atau bos membalas tembakan pemain.
Saya harap Anda menyukai tutorial ini, terima kasih telah membaca!