diff --git a/Games/Fly_Fighter/README.md b/Games/Fly_Fighter/README.md new file mode 100644 index 0000000000..5b46d6cf8e --- /dev/null +++ b/Games/Fly_Fighter/README.md @@ -0,0 +1,28 @@ +# Fly Fighter + +A simple game Fly Fighter building with JS. + +## Console Instruction + +| Button | Function | +|--------|----------| +| Space | Shot | +| Arrow Left| go to left | +| Arrow up| go to up | +| Arrow right| go to right | +| Arrow down| go to down | + +## Features + +- **Visual Feedback**: Images for Fly Fighter Game. +- **Attempts Counter**: Keep track of the number of attempts made to find the Fly Fighter. +- **Restart Functionality**: Easily restart the game to play again. + + +## Screenshots + +![Fly Fighter](https://github.com/TheNikhilRaj/GameZone/blob/main/assets/images/Fly_Fighter.png) + +## Try It Out + +You can try out the game by opening the `index.html` file in your web browser. \ No newline at end of file diff --git a/Games/Fly_Fighter/assets/back.jpg b/Games/Fly_Fighter/assets/back.jpg new file mode 100644 index 0000000000..78f3e3745e Binary files /dev/null and b/Games/Fly_Fighter/assets/back.jpg differ diff --git a/Games/Fly_Fighter/assets/laser.mp3 b/Games/Fly_Fighter/assets/laser.mp3 new file mode 100644 index 0000000000..9e4055946e Binary files /dev/null and b/Games/Fly_Fighter/assets/laser.mp3 differ diff --git a/Games/Fly_Fighter/assets/main.js b/Games/Fly_Fighter/assets/main.js new file mode 100644 index 0000000000..832cee7e9f --- /dev/null +++ b/Games/Fly_Fighter/assets/main.js @@ -0,0 +1,395 @@ +// Inisialisasi +var btnMulai = document.getElementById('mulai'), + btnUlangi = document.getElementById('ulangi'), + text = document.getElementById('text'), + scoreBoard = document.getElementById('score'), + livesBoard = document.getElementById('nyawa'); + +var bannerMulai = document.getElementsByClassName('banner1'), + bannerAkhir = document.getElementsByClassName('banner2'); + +var c = document.getElementById('canvas'); +let ctx = c.getContext('2d'); + +let lives = 10, + score = 0; + +let imgShip = new Image(), + imgEnemy = new Image(), + laserEffect = new Audio('/assets/laser.mp3'), + reloadEffect = new Audio('/assets/reload.mp3'), + vid = document.querySelector('video'); + +imgShip.src = '/assets/ship.png'; +imgEnemy.src = '/assets/musuh.png'; + +let batasKiri = 10, + batasKanan = 280, + batasAtas = 0, + batasBawah = 130; + +let ship = { + x: batasKanan / 2, + y: batasBawah +} + +let peluru = [], + enemy = []; + +for (i = 0; i < 4; i++) { + enemy[i] = { + x: 20 + i * 60, + y: -10, + die: false, + score: true + } +} +for (i = 0; i < 4; i++) { + peluru[i] = { + x: ship.x + 5, + y: ship.y + 5, + status: 'ready', + baca: false + } +} + + + + + +// Function Utama +function init() { + run = setInterval(function () { + draw(); + }, 1000 / 20) +} + +/** + * drawPeluru + * Berfungsi untuk menggambar peluru pada canvas + */ +function drawPeluru() { + for (i = 0; i < enemy.length; i++) { + if (peluru[i].status == "ready") { + ctx.fillStyle = 'red'; + ctx.fillRect(peluru[i].x, peluru[i].y, 2, 10); + } + if (peluru[i].status == "used") { + peluru[i].y -= 1; + ctx.fillStyle = 'red'; + ctx.fillRect(peluru[i].x, peluru[i].y, 2, 10); + } + } +} + + +/** + * crush + * function lek Pesawat nabrak musuh + */ +function crush(){ + for(i=0; i < enemy.length; i++){ + if ((enemy[i].y + 50 / 4 == ship.y || enemy[i].y == ship.y) && (ship.x >= enemy[i].x && ship.x <= enemy[i].x )) { + lives -= 1 + for (i = 0; i < enemy.length; i++){ + enemy[i].y = 0; + } + } + } +} + + + + + + +/** + * enemyDie + * Berfungsi untuk proses menembak + * apakah musuh mati karena tembakan atau tidak + */ +function enemyDie() { + for (i = 0; i < enemy.length; i++) { + for (j = 0; j < 4; j++) { + if (peluru[i].status == "used") { + if (peluru[i].x >= enemy[j].x && peluru[i].x <= enemy[j].x + 50 / 4) { + if (peluru[i].y == enemy[j].y + 10) { + // Jika musuh terkena tembakan + enemy[j].die = true; + peluru[i].y = -10; + if(enemy[j].score == true){ + score += 10; + enemy[j].y = -10 + enemy[j].score = false; + } + } + } + } + } + } +} + +/** + * updateBoard + * Melakukan update terhadap jumlah score dan juga nyawa + * sekaligus menampilkan alert menang / kalah + */ +function updateBoard() { + scoreBoard.innerHTML = score; + livesBoard.innerHTML = lives; + if (lives <= 0) { + clearInterval(run); + bannerAkhir[0].style.display = 'block'; + text.innerHTML = "Mohon Maaf
kamu gagal memenangkan permainan"; + } + if (lives >= 1 && score >= 50) { + clearInterval(run); + bannerAkhir[0].style.display = 'block'; + text.innerHTML = "Selamat
kamu telah memenangkan permainan"; + } +} + +/** + * reload + * Melakukan proses reload terhadap peluru + */ +function reload() { + reloadEffect.play(); + for (i = 0; i < peluru.length; i++) { + if (peluru[i].y <= 0) { + peluru[i] = { + x: ship.x + 6, + y: ship.y, + status: 'ready', + } + } + } +} + +/** + * drawEnemy + * Menggambar musuh pada canvas + */ +function drawEnemy() { + if (enemy[0].die == true && enemy[1].die == true && enemy[2].die == true && enemy[3].die == true) { + // Membuat musuh baru jika semua musuh telah terbunuh + for (i = 0; i < enemy.length; i++) { + enemy[i] = { + x: 20 + i * 80, + y: -10, + die: false, + score: true + } + } + } else { + for (i = 0; i < enemy.length; i++) { + if (enemy[i].die == false) { + ctx.drawImage(imgEnemy, 0, 0, 50, 38, enemy[i].x, enemy[i].y, 50 / 4, 38 / 4); + enemy[i].y += 1; + if (enemy[i].y > batasBawah + 20) { + // jika lewat nyawa berkurang satu + lives -= 1; + enemy[i].y = -10; + return + } + } + } + } +} + +/** + * drawShip + * Menggambar kapal aliansi pada canvas + */ +function drawShip() { + ctx.drawImage(imgShip, 0, 0, 50, 57, ship.x, ship.y, 50 / 4, 57 / 4); +} + +/** + * draw + * Mengatur lebar canvas & memanggil semua function yang telah dibuat + */ +function draw() { + ctx.clearRect(0, 0, 600, 600); + // Memanggil function + drawEnemy(); + drawShip(); + enemyDie(); + drawPeluru(); + crush(); + updateBoard(); +}; + + +// Menambahkan event listener click pada button mulai +btnMulai.addEventListener('click', function () { + // vid.play(); + bannerMulai[0].style.display = "none"; // hide Banner1 + init(); + document.addEventListener('keydown', function (anu) { + switch (anu.code) { + case "Space": + if (peluru[0].status == 'ready') { + laserEffect.play() + peluru[0].status = 'used'; + } else if (peluru[1].status == 'ready') { + laserEffect.play() + peluru[1].status = 'used'; + } else if (peluru[2].status == 'ready') { + laserEffect.play() + peluru[2].status = 'used'; + } else if (peluru[3].status == 'ready') { + laserEffect.play() + peluru[3].status = 'used'; + } else { + reload(); + } + break; + case "ArrowRight": + if (ship.x < batasKanan) { + ship.x += 10; + } + for (var i = 0; i < peluru.length; i++) { + if (peluru[i].status !== "used") { + if (peluru[i].x <= batasKanan) + peluru[i].x += 10; + } + } + break; + case "ArrowLeft": + if (ship.x > batasKiri) { + ship.x -= 10; + } + for (var i = 0; i < peluru.length; i++) { + if (peluru[i].status !== "used") { + if (peluru[i].x >= batasKiri + 10) + peluru[i].x -= 10; + } + } + break; + case "ArrowUp": + if (ship.y > batasAtas) { + ship.y -= 10; + } + for (var i = 0; i < peluru.length; i++) { + if (peluru[i].status !== "used") { + if (peluru[i].y > batasAtas + 10) + peluru[i].y -= 10; + } + } + break; + case "ArrowDown": + if (ship.y < batasBawah) { + ship.y += 10; + } + for (var i = 0; i < peluru.length; i++) { + if (peluru[i].status !== "used") { + if (peluru[i].y < batasBawah) + peluru[i].y += 10; + } + } + break; + default: + break; + } + }) +}) + +btnUlangi.addEventListener('click', function () { + // Re-Declare for restart game + lives = 10, + score = 0; + bannerAkhir[0].style.display = "none"; + let batasKiri = 10, + batasKanan = 280, + batasAtas = 0, + batasBawah = 130; + let ship = { + x: batasKanan / 2, + y: batasBawah + } + let peluru = [], + enemy = []; + for (i = 0; i < 4; i++) { + enemy[i] = { + x: 20 + i * 80, + y: -10, + die: false, + score: true + } + } + for (i = 0; i < 4; i++) { + peluru[i] = { + x: ship.x + 5, + y: ship.y + 5, + status: 'ready', + baca: false + } + } + init(); + document.addEventListener('keydown', function (anu) { + switch (anu.code) { + case "Space": + if (peluru[0].status == 'ready') { + laserEffect.play() + peluru[0].status = 'used'; + } else if (peluru[1].status == 'ready') { + laserEffect.play() + peluru[1].status = 'used'; + } else if (peluru[2].status == 'ready') { + laserEffect.play() + peluru[2].status = 'used'; + } else if (peluru[3].status == 'ready') { + laserEffect.play() + peluru[3].status = 'used'; + } else { + reload(); + } + break; + case "ArrowRight": + if (ship.x < batasKanan) { + ship.x += 10; + } + for (var i = 0; i < peluru.length; i++) { + if (peluru[i].status !== "used") { + if (peluru[i].x <= batasKanan) + peluru[i].x += 10; + } + } + break; + case "ArrowLeft": + if (ship.x > batasKiri) { + ship.x -= 10; + } + for (var i = 0; i < peluru.length; i++) { + if (peluru[i].status !== "used") { + if (peluru[i].x >= batasKiri + 10) + peluru[i].x -= 10; + } + } + break; + case "ArrowUp": + if (ship.y > batasAtas) { + ship.y -= 10; + } + for (var i = 0; i < peluru.length; i++) { + if (peluru[i].status !== "used") { + if (peluru[i].y > batasAtas + 10) + peluru[i].y -= 10; + } + } + break; + case "ArrowDown": + if (ship.y < batasBawah) { + ship.y += 10; + } + for (var i = 0; i < peluru.length; i++) { + if (peluru[i].status !== "used") { + if (peluru[i].y < batasBawah) + peluru[i].y += 10; + } + } + break; + } + }) +}) \ No newline at end of file diff --git a/Games/Fly_Fighter/assets/main2.js b/Games/Fly_Fighter/assets/main2.js new file mode 100644 index 0000000000..d5b77d88ac --- /dev/null +++ b/Games/Fly_Fighter/assets/main2.js @@ -0,0 +1,339 @@ +/** + * Inisialisasi Variable + */ +let btnMulai = document.getElementById('mulai'), + btnUlangi = document.getElementById('ulangi'), + c = document.getElementById('canvas'), + scoreShow = document.getElementById('score'), + livesShow = document.getElementById('nyawa'), + text = document.getElementById('text'), + banner1 = document.getElementsByClassName('banner1'), + banner2 = document.getElementsByClassName('banner2'); + + +let score = 0; +let lives = 10; + +let bAtas = 10, + bBawah = 130, + bKiri = 10, + bKanan = 280; + +let ctx = c.getContext('2d'); + +let imgShip = new Image(), + imgEnemy = new Image(), + laserAudio = new Audio(); + +imgShip.src = '/assets/ship.png'; +imgEnemy.src = '/assets/musuh.png'; +laserAudio.src = '/assets/laser.mp3'; + +let peluru = [], + enemy = []; + + +ship = { + x: bKanan / 2, + y: bBawah +} + + +/** + * Generate Enemy + */ +for (i = 0; i < 5; i++) { + enemy[i] = { + x: bKiri + i * 65, + y: bAtas, + status: "live" + } +} + + +/** + * Generate Peluru + */ +for (i = 0; i < 3; i++) { + peluru[i] = { + x: ship.x + 5, + y: ship.y + 4, + width: 2, + height: 10, + status: 'ready', + inscr: true + } +} + + +/** + * Isi ulang Peluru + */ +var reload = function () { + for (i = 0; i < 3; i++) { + peluru[i] = { + x: ship.x + 5, + y: ship.y + 4, + width: 2, + height: 10, + status: 'ready', + inscr: true + } + } +} + + +/** + * Menggambar pesawat pemain + */ +var drawShip = function () { + ctx.drawImage(imgShip, 0, 0, 50, 57, ship.x, ship.y, 50 / 4, 57 / 4); +} + + +/** + * Menggambar pesawat musuh + */ +var drawEnemy = function () { + if (enemy[0].status == "dead" && + enemy[1].status == "dead" && + enemy[2].status == "dead" && + enemy[3].status == "dead" && + enemy[4].status == "dead") { + for (i = 0; i < enemy.length; i++) { + peluru[i] = { + x: ship.x + 5, + y: ship.y + 4, + width: 2, + height: 10, + status: 'ready', + inscr: true + } + } + } else { + for (i = 0; i < enemy.length; i++) { + // menggambar musuh yang masih hidup + if (enemy[i].status == "live") { + enemy[i].y += .52; + ctx.drawImage(imgEnemy, 0, 0, 50, 38, enemy[i].x, enemy[i].y, 50 / 4, 38 / 4); + } + + if (ship.y <= enemy[i].y + 50 / 4 && ship.y >= enemy[i].y) { + if (ship.x <= enemy[i].x + 50 / 4 && ship.x >= enemy[i].x && enemy[i].status != "dead") { + lives -= 1; + for (j = 0; j < enemy.length; j++) { + enemy[j].y = -10; + } + } + } + + // mengembalikan musuh keatas , + // jika sudah melewati batas bawah + if (enemy[i].y >= bBawah + 10) { + lives -= 1; + for (j = 0; j < enemy.length; j++) { + enemy[j].y = -10; + } + return + } + } + } +} + + +/** + * Menggambar peluru + */ +var drawPeluru = function () { + if (peluru[0].status == "expired" && peluru[1].status == "expired" && peluru[2].status == "expired") { + reload(); + } else { + for (i = 0; i < peluru.length; i++) { + if (peluru[i].y < -10) { + peluru[i].status = "expired"; + } + + if (peluru[i].status == "used") { + peluru[i].y -= 1; + } + + ctx.fillStyle = 'red'; + ctx.fillRect(peluru[i].x, peluru[i].y, peluru[i].width, peluru[i].height); + } + } +} + + +/** + * Action menembak musuh + */ +var tembak = function () { + for (i = 0; i < peluru.length; i++) { + for (j = 0; j < enemy.length; j++) { + if (peluru[i].status === "used" && enemy[j].status == "live") { + if ((peluru[i].x <= enemy[j].x + 50 / 4) && (peluru[i].x >= enemy[j].x)) { + if (peluru[i].y <= enemy[j].y + 38 / 4 && peluru[i].y >= enemy[j].y) { + enemy[j].status = "dead"; + peluru[i].y = -10; + score += 10; + } + } + } + } + } +} + + +/** + * Update permainan (jumlah nyawa & Score) + */ +let update = function () { + scoreShow.innerHTML = score; + livesShow.innerHTML = lives; + + if (lives <= 0) { + clearInterval(run); + banner2[0].style.display = 'block'; + text.innerHTML = "Mohon Maaf
kamu gagal memenangkan permainan"; + } + if (lives >= 1 && score >= 50) { + clearInterval(run); + banner2[0].style.display = 'block'; + text.innerHTML = "Congratulations
You have won the game"; + } +} + + +/** + * Memanggil semua function yang telah + * dibuat , diatas + */ +function draw() { + // menggambar dicanvas sekaligus aksi + drawShip(); + drawEnemy(); + drawPeluru(); + + // aksi tembak + tembak(); + + // update score & lives board + update(); +} + + +/** + * Refresh Canvas + */ +function load() { + ctx.clearRect(0, 0, 600, 600); + draw(); +} + + +/** + * Setting Interval permainan + */ +function init() { + run = setInterval(function () { + load() + }, 50); +} + + +/** + * Aksi Keyboard + */ +var event = function () { + document.addEventListener('keydown', function (con) { + switch (con.code) { + case 'ArrowUp': + ship.y -= 2; + for (i = 0; i < 3; i++) { + if (peluru[i].status == "ready") + peluru[i].y -= 2; + } + break; + case 'ArrowDown': + ship.y += 2; + for (i = 0; i < 3; i++) { + if (peluru[i].status == "ready") + peluru[i].y += 2; + } + break; + case 'ArrowLeft': + ship.x -= 2; + for (i = 0; i < 3; i++) { + if (peluru[i].status == "ready") + peluru[i].x -= 2; + } + break; + case 'ArrowRight': + ship.x += 2; + for (i = 0; i < 3; i++) { + if (peluru[i].status == "ready") + peluru[i].x += 2; + } + break; + case 'Space': + if (peluru[0].status == "used" && peluru[1].status == "used" && peluru[2].status == "used") { + console.log("peluru habis"); + } + for (i = 0; i < 3; i++) { + if (peluru[i].status == "ready") { + peluru[i].status = "used"; + console.log("digunakan") + return; + } + } + break; + } + }) +} + + +/** + * Meng-inisialisasi permainan + * Ketika button mulai di click + */ +btnMulai.addEventListener('click', function () { + init(); + banner1[0].style.display = 'none'; + event(); +}) + + +/** + * Me re-inisialisasi permainan + * ketika button ulangi di click + */ +btnUlangi.addEventListener('click',function(){ + lives = 10; + score = 0; + ship = { + x: bKanan / 2, + y: bBawah + } + + for (i = 0; i < 5; i++) { + enemy[i] = { + x: bKiri + i * 65, + y: bAtas, + status: "live" + } + } + + for (i = 0; i < 3; i++) { + peluru[i] = { + x: ship.x + 5, + y: ship.y + 4, + width: 2, + height: 10, + status: 'ready', + inscr: true + } + } + init(); + banner2[0].style.display = 'none'; + event(); +}) diff --git a/Games/Fly_Fighter/assets/musuh.png b/Games/Fly_Fighter/assets/musuh.png new file mode 100644 index 0000000000..8e2ff44605 Binary files /dev/null and b/Games/Fly_Fighter/assets/musuh.png differ diff --git a/Games/Fly_Fighter/assets/reload.mp3 b/Games/Fly_Fighter/assets/reload.mp3 new file mode 100644 index 0000000000..91f4c0f577 Binary files /dev/null and b/Games/Fly_Fighter/assets/reload.mp3 differ diff --git a/Games/Fly_Fighter/assets/ship.png b/Games/Fly_Fighter/assets/ship.png new file mode 100644 index 0000000000..b19d785d8f Binary files /dev/null and b/Games/Fly_Fighter/assets/ship.png differ diff --git a/Games/Fly_Fighter/assets/style.css b/Games/Fly_Fighter/assets/style.css new file mode 100644 index 0000000000..1739891333 --- /dev/null +++ b/Games/Fly_Fighter/assets/style.css @@ -0,0 +1,66 @@ + +#canvas{ + width: 700px; + height: 600px; + background: url('/assets/back.jpg') 100% 100%; +} + +.banner1 { + text-align: center; + position: absolute; + top: 40vh; + left: 200px; +} +.banner1 h1{ + font-size: 32px; + padding: 0; + margin: 0; + color: red; +} +.banner1 #mulai{ + font-size:24px; + font-weight: 700; + color: blue; + cursor: pointer; + margin: 30px 0; +} +.banner1 .instruction { + color: aliceblue; + font-size: 18px; +} + +.banner2 { + text-align: center; + position: absolute; + display: none; + top: 40vh; + left: 200px; +} +.banner2 h1 { + font-size: 32px; + padding: 0; + margin: 0; + color: red; +} + +.banner2 #ulangi { + font-size: 24px; + font-weight: 700; + color: blue; + cursor: pointer; + margin: 30px 0; +} + +.banner2 .instruction { + color: aliceblue; + font-size: 18px; +} + +.board { + position: absolute; + top: 15px; + left: 15px; + color: #fff; + font-size: 15px; + +} diff --git a/Games/Fly_Fighter/index.html b/Games/Fly_Fighter/index.html new file mode 100644 index 0000000000..7df631226f --- /dev/null +++ b/Games/Fly_Fighter/index.html @@ -0,0 +1,31 @@ + + + + + + Fly Fight + + + +
+ Lives : 0
+ Score : 0 +
+
+

Fly Fighter

+
Start
+
+ Use the arrow keys to move
+ Use the spacebar to shoot
+
+
+

Fly Fighter

+
Repeat
+
+
+
+ + + + + diff --git a/Games/Fly_Fighter/manifest.json b/Games/Fly_Fighter/manifest.json new file mode 100644 index 0000000000..357c1763ed --- /dev/null +++ b/Games/Fly_Fighter/manifest.json @@ -0,0 +1,31 @@ +{ + "manifest_version": 2, + "name": "Fly Fighter", + "description": "A simple browser-based shooting game.", + "version": "1.0", + "icons": { + "128": "assets/icon_128.png" + }, + "permissions": [ + "storage", + "unlimitedStorage" + ], + "browser_action": { + "default_popup": "index.html", + "default_icon": "assets/icon_128.png" + }, + "content_scripts": [ + { + "matches": [""], + "js": ["assets/main2.js"], + "css": ["assets/style.css"] + } + ], + "web_accessible_resources": [ + "assets/back.jpg", + "assets/ship.png", + "assets/musuh.png", + "assets/laser.mp3" + ] + } + \ No newline at end of file diff --git a/Games/Fly_Fighter/modul/laser.m4a b/Games/Fly_Fighter/modul/laser.m4a new file mode 100644 index 0000000000..49010e800f Binary files /dev/null and b/Games/Fly_Fighter/modul/laser.m4a differ diff --git a/Games/Fly_Fighter/modul/reload.amr b/Games/Fly_Fighter/modul/reload.amr new file mode 100644 index 0000000000..73b30d6686 Binary files /dev/null and b/Games/Fly_Fighter/modul/reload.amr differ