- vừa được xem lúc

[Phần 1] Trò chơi Audition - Xây dựng chức năng cơ bản với JavaScript

0 0 24

Người đăng: Nguyen Van Tuan

Theo Viblo Asia

1. Giới thiệu

Audition - Một tựa game online mỗi khi nhắc tới thì đại đa số thế hệ 8x9x đời đầu sẽ bất chợt có cảm giác bồi hồi, xao xuyến với bao nhiêu kỉ niệm ùa về 😊😊😊 Là thế hệ giữa 9x nhưng may sao ngày bé, mình được các ông anh dẫn đi NET cỏ đưa mình vào con đường nghiện game online ngày ấy... 😃

image.png

Mình chơi Audition từ hè 2006 ( lớp 5, lớp 6 ) với biết bao kỉ niệm đẹp về tựa game này. Lên 2009 thì quen em - hai đứa cùng chơi Audition và quen tại quán net. Em - top xinh trong trường lúc bấy giờ. Biết bao kỉ niệm đạp xe đi chơi tối, trốn học ra net nhảy Audition. Lần nào trốn tiết ra xong đến lúc vào lớp, mình cũng phải hôn 1 cái khiến bọn lớp lớn hơn nhìn choáng 😄 Yêu 5,6 năm thì chia tay. Quá nhiều kỉ niệm từ kênh itv, đến Ola, Avatar... kể ra thì cả quyển. Giá mà có thể yêu nhau đến cuối thì đẹp... 😢

Vì để thoả mãn cái kỉ niệm đẹp đẽ, ngây ngô ngày ấy của tuổi trẻ, mình sẽ ra một series xây dựng các chức năng của tựa game này 😃 Ở bài viết phần 1 này mình sẽ làm các chức năng cơ bản của game để có thể chơi: Nhảy 4K, 4K có del, load nhạc, tính điểm... Dự định mình sẽ dùng JavaScript ( not NodeJS nha 😆) để build game. Mình hi vọng sẽ được sự đón nhận, phản hồi từ mọi người để game được tốt và nhiều chức năng hơn 😘

2. Cấu trúc project

image.png

  • images: Thư mục sẽ lưu các hình ảnh của trò chơi : Phím bấm, ảnh nền,...
  • js: Thư mục chứa các file JavaScript để xử lý các chức năng của game.
  • musics: Thư mục lưu các bài hát của trò chơi. Người chơi sẽ được lựa chọn trong list này.

3. Xử lý trò chơi cho chức năng nhảy 4K

  • audition.html: File này chứa giao diện của trò chơi ( Mình không phải dân chuyên Front-end nên html, css không tốt lắm nên các bạn cố gắng bỏ qua nha 😃😃😃 ) Cấu trúc cũng tương tự như các html bình thường: Có Html, Css và nhúng JavaScript để xử lý.

image.png

  • constants.js: File này lưu các biến hằng số trong trò chơi: Ví dụ danh sách các key nhảy, level max,...
// Const variable
const MAX_LEVEL = 11
const MIN_COUNT_TO_PLAY = 5
const LIST_KEY_HAS_REVERSE = ["right", "up", "down", "left", "right-reverse", "up-reverse", "down-reverse", "left-reverse"]
const LIST_KEY = ["right", "up", "down", "left"]
const MAP_KEY = new Map([["right", "right"], ["up", "up"], ["down", "down"], ["left", "left"], ["right-reverse", "left"], ["up-reverse", "down"], ["down-reverse", "up"], ["left-reverse", "right"],])
  • main.js: File xử lý chính các tác vụ, chức năng trong game. Hiện tại, trò chơi chỉ có vài chức năng nên mình sẽ viết gộp vào đây 😃😃😃 khi nào đi qua từng chức năng mà file to quá mình sẽ refactor tách nhỏ dần. Nào xem file này chúng ta sẽ phải xử lý logic gì nào. Gét gô...

Variable các biến cần có

let audio = new Audio() // Khởi tạo audio để xử lý nhạc
let isReverse = false // Kiểm tra xem người chơi có bật nhảy ngược phím hay không?
let isSpaced = false // Kiểm tra người chơi đã ấn space để nhảy chưa?
let increase = 1 // Tốc độ chạy của box trên thanh progress bar
let pos = 0 // Vị trí của box trên thanh progress bar
let count = 0 // Số lần box vượt quá thanh progress bar
let countToIncreaseLevel = 0 // Số lần count để tăng level chơi
let score = 0 // Điểm người chơi
let level = 1 // Level hiện tại
let listKeyRandom = [] // Danh sách key generate random
let listKeyPress = [] // Danh sách key người chơi nhập
const boxElement = document.getElementById("box") // Box element trong html
let picElement = document.getElementById("pic") // Ảnh trong html
let scoreElement = document.getElementById("score") // Điểm trong html
let intervalID = setInterval(move, 0) // Id interval

Show, hide, set key theo id element

// Hiện phần tử trên html theo id
function show(id) { document.getElementById(id).style.display = 'block'
} // Ẩn phần tử trên html theo id
function hide(id) { document.getElementById(id).style.display = 'none'
} // Hiển thị ảnh phím bấm theo key và id element
function setKey(key, id) { document.getElementById(id).src = "images/" + key + ".png"
}

compareKeyPressAndRandom: So sánh danh sách key người chơi bấm có bằng với danh sách key random theo từng level không?

function compareKeyPressAndRandom(key) { if (listKeyPress.length === listKeyRandom.length) { return } if (MAP_KEY.get(listKeyRandom[listKeyPress.length]) === key && !isReverse) { listKeyPress.push(key + "-success") setKey(key + "-success", listKeyPress.length) } else if (MAP_KEY.get(listKeyRandom[listKeyPress.length]) === key && isReverse) { listKeyPress.push(key + "-success") setKey(key + "-success", listKeyPress.length) } else { listKeyPress = [] for (let i = 0; i < listKeyRandom.length; i++) { setKey(listKeyRandom[i], i + 1) } }
}

getListKey: Lấy ra danh sách key theo level được random theo list key. Ví dụ 4K thì listRandom = ["right", "up", "down", "left"]

function getListKey(level, listRandom) { let list = [] Array.prototype.random = function () { return this[Math.floor((Math.random() * this.length))]; } for (let i = 0; i < level; i++) { list.push(listRandom.random()) } return list
}

resetKeyRandom, resetListKeyPress: Tạo lại danh sách key random và key mà người chơi bấm

function resetKeyRandom() { for (let i = 1; i <= 11; i++) { document.getElementById(i.toString()).src = "" }
} function resetListKeyPress() { listKeyPress = []
}

setScore: Set lại điểm mỗi khi người chơi bấm phím và sau đó căn box để space -> Có các kiểu : Perfect, Great, Cool, Bad, Miss có các vị trí trên thanh bar và giảm dần điểm theo thứ tự.

function setScore(pos) { if (listKeyPress.length !== listKeyRandom.length) { picElement.src = "images/Miss.png" return } if (840 <= pos && pos <= 860) { picElement.src = "images/Perfect.png" score += isReverse ? 1200 : 800 } else if ((790 <= pos && pos < 840) || (860 < pos && pos <= 910)) { picElement.src = "images/Great.png" score += isReverse ? 600 : 350 } else if ((760 <= pos && pos < 790) || (910 < pos && pos <= 940)) { picElement.src = "images/Cool.png" score += isReverse ? 350 : 150 } else if ((750 <= pos && pos < 760) || (940 < pos && pos <= 950)) { picElement.src = "images/Bad.png" score += isReverse ? 200 : 50 } else { picElement.src = "images/Miss.png" } scoreElement.textContent = score
}

move: Function này xử lý sự kiện cho khối box di chuyển

function move() { if (pos > 1150) { pos = 0 count++ if (count >= MIN_COUNT_TO_PLAY) { resetKeyRandom() setTimeout(function () { listKeyRandom = isReverse ? getListKey(level, LIST_KEY_HAS_REVERSE) : getListKey(level, LIST_KEY) console.log(listKeyRandom) for (let i = 0; i < listKeyRandom.length; i++) { setKey(listKeyRandom[i], i + 1) } }, 1000) } if (count >= MIN_COUNT_TO_PLAY && countToIncreaseLevel % 1 === 0) { level++ } if (level > MAX_LEVEL) { level = 1; } if (count > MIN_COUNT_TO_PLAY && !isSpaced) { countToIncreaseLevel++ picElement.src = "images/Miss.png" resetListKeyPress() hide("box") setTimeout(function () { show("box") pos = 0 }, 3000) } } pos += increase boxElement.style.left = pos + "px"
}

Xử lý sự kiện mỗi khi người chơi bấm phím

document.body.onkeyup = function (e) { if (e.code === "Space" && count >= MIN_COUNT_TO_PLAY) { isSpaced = true setScore(pos) hide("box") resetListKeyPress() setTimeout(function () { show("box") pos = 0 isSpaced = false }, 3000) countToIncreaseLevel++ } // Key dance if (e.code === "ArrowUp") { compareKeyPressAndRandom("up") } if (e.code === "ArrowDown") { compareKeyPressAndRandom("down") } if (e.code === "ArrowRight") { compareKeyPressAndRandom("right") } if (e.code === "ArrowLeft") { compareKeyPressAndRandom("left") } // Key turn on, turn off reverse if (e.code === "NumpadDecimal") { isReverse = !isReverse if (isReverse) { document.getElementById("reverse").textContent = "Reverse" show("reverse") } else { hide("reverse") } }
}

initAudio: Khởi tạo đối tượng audio để xử lý nhạc trong game và xử lý phát nhạc mỗi khi người chơi thay đổi trên list.

function initAudio() { clearInterval(intervalID) let ext, plist ext = ".mp3" plist = document.getElementById("list-music") plist.addEventListener("change", changeTrack) function changeTrack(event) { audio.src = "musics/" + event.target.value + ext audio.play() intervalID = setInterval(move, 0) initVariable() }
} window.addEventListener("load", initAudio)

Bắt sự kiện mỗi khi bài nhạc kết thúc: Khi đó chúng ta sẽ thông báo điểm cho người chơi và init lại các variable lại từ đầu

audio.onended = function () { clearInterval(intervalID) alert("Chúc mừng bạn đã đạt: " + score + " điểm") initVariable() scoreElement.textContent = "0"
}

4. Kết luận

Để làm 1 con game audition có các chức năng cơ bản cũng không khó lắm phải không các bạn 😃😃😃 Hãy cũng tận hưởng thành quả nào -> Video dưới đây là demo chỗ đoạn code này 😄

Bình luận

Bài viết tương tự

- vừa được xem lúc

Giới thiệu Typescript - Sự khác nhau giữa Typescript và Javascript

Typescript là gì. TypeScript là một ngôn ngữ giúp cung cấp quy mô lớn hơn so với JavaScript.

0 0 528

- vừa được xem lúc

Bạn đã biết các tips này khi làm việc với chuỗi trong JavaScript chưa ?

Hi xin chào các bạn, tiếp tục chuỗi chủ đề về cái thằng JavaScript này, hôm nay mình sẽ giới thiệu cho các bạn một số thủ thuật hay ho khi làm việc với chuỗi trong JavaScript có thể bạn đã hoặc chưa từng dùng. Cụ thể như nào thì hãy cùng mình tìm hiểu trong bài viết này nhé (go).

0 0 436

- vừa được xem lúc

Một số phương thức với object trong Javascript

Trong Javascript có hỗ trợ các loại dữ liệu cơ bản là giống với hầu hết những ngôn ngữ lập trình khác. Bài viết này mình sẽ giới thiệu về Object và một số phương thức thường dùng với nó.

0 0 158

- vừa được xem lúc

Tìm hiểu về thư viện axios

Giới thiệu. Axios là gì? Axios là một thư viện HTTP Client dựa trên Promise.

0 0 149

- vừa được xem lúc

Imports và Exports trong JavaScript ES6

. Giới thiệu. ES6 cung cấp cho chúng ta import (nhập), export (xuất) các functions, biến từ module này sang module khác và sử dụng nó trong các file khác.

0 0 113

- vừa được xem lúc

Bài toán đọc số thành chữ (phần 2) - Hoàn chỉnh chương trình dưới 100 dòng code

Tiếp tục bài viết còn dang dở ở phần trước Phân tích bài toán đọc số thành chữ (phần 1) - Phân tích đề và những mảnh ghép đầu tiên. Bạn nào chưa đọc thì có thể xem ở link trên trước nhé.

0 0 249