Cách xây dựng bản sao Wordle bằng JavaScript
Worlde là một trò chơi nổi tiếng đã gây bão trên toàn thế giới vào đầu năm 2022. Việc tạo lại trò chơi Wordle hoặc ít nhất là xây dựng một phiên bản đơn giản hơn của nó là điều mà các nhà phát triển mới sử dụng JavaScript nên cân nhắc.
Mục Lục
Wordle hoạt động như thế nào
Trong Wordle, có một từ gồm năm chữ cái bí mật. Người chơi có sáu lần thử và phải đoán các từ có năm chữ cái khác nhau để xem mức độ gần gũi của chúng với từ bí mật.
Sau khi người chơi gửi dự đoán, Wordle sử dụng màu sắc để cho người chơi biết mức độ gần gũi của họ với từ bí mật. Nếu một chữ cái có màu vàng, điều đó có nghĩa là chữ cái đó nằm trong từ bí mật, nhưng sai vị trí.
Màu xanh lá cây cho người dùng biết rằng chữ cái nằm trong từ bí mật và ở đúng vị trí, trong khi màu xám cho người chơi biết rằng chữ cái đó không có trong từ.
Thiết lập máy chủ phát triển
Mã được sử dụng trong dự án này có sẵn trong kho lưu trữ GitHub và bạn được sử dụng miễn phí theo giấy phép MIT. Nếu bạn muốn xem phiên bản trực tiếp của dự án này, bạn có thể xem bản demo này.
Dự án sử dụng công cụ xây dựng Vite thông qua Giao diện dòng lệnh (CLI) cho giàn giáo. Đảm bảo rằng bạn đã cài đặt Sợi trên máy tính của mình vì nó thường nhanh hơn Trình quản lý gói nút (NPM). Mở terminal của bạn và chạy lệnh sau:
yarn create vite
Thao tác này sẽ tạo một dự án Vite mới. khuôn khổ nên được Vanilla và biến thể nên được đặt thành JavaScript. Bây giờ hãy chạy:
yarn
Điều này sẽ cài đặt tất cả các phụ thuộc cần thiết để làm cho dự án hoạt động. Sau khi cài đặt này, hãy chạy lệnh sau để khởi động máy chủ phát triển:
yarn dev
Thiết lập trò chơi và thiết kế bàn phím
Mở dự án trong trình chỉnh sửa mã của bạn, xóa nội dung của chính.js tệp và đảm bảo thư mục dự án của bạn trông như thế này:
Bây giờ, thay thế nội dung của index.html tệp với mã soạn sẵn sau:
<!DOCTYPE html>
<html lang="en"><head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>JS Wordle</title>
</head>
<body>
<div id="app">
<div>
<h1>Wordle Clone</h1>
<div id="controls">
<button id="restart-btn">Replay</button>
<button id="show-btn">Show Answer</button>
</div>
<div id="message">Please wait. The Game is loading...</div>
</div>
<div id="interface">
<div id="board"></div>
<div class="keyboard"></div>
</div>
</div>
<script type="module" src="/main.js"></script>
</body>
</html>
Đối với CSS, hãy truy cập Kho lưu trữ GitHub của dự án này và sao chép nội dung của phong cách.css tập tin vào của riêng bạn phong cách.css tài liệu.
Bây giờ, trong thiết bị đầu cuối, hãy cài đặt gói Toastify NPM bằng cách chạy lệnh sau:
yarn add toastify -S
Toastify là gói JavaScript phổ biến cho phép bạn hiển thị cảnh báo cho người dùng. Tiếp theo, trong chính.js tệp, nhập tệp phong cách.css tập tin và nâng cốc chúc mừng tính thiết thực.
import "./style.css"
import Toastify from 'toastify-js'
Xác định các biến sau để tương tác với các phần tử DOM dễ dàng hơn:
let board = document.querySelector("#board");
let message = document.querySelector("#message");
let keys = "QWERTYUIOPASDFGHJKLZXCVBNM".split("");
let restartBtn = document.querySelector("#restart-btn");
let showBtn = document.querySelector("#show-btn");
showBtn.setAttribute("disabled", "true");
keys.push("Backspace");
let keyboard = document.querySelector(".keyboard");
Thiết lập bảng trò chơi
Vì Wordle là một trò chơi mà người dùng phải đoán một từ có năm chữ cái trong sáu lần thử, hãy xác định một biến có tên bảngNội dung chứa một mảng gồm sáu mảng. Sau đó xác định các biến hàng hiện tại Và hộp hiện tại để làm cho nó dễ dàng hơn để đi qua bảngNội dung.
let boardContent = [
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
];
let currentRow = 0;
let currentBox = 0;
let secretWord;
Để hiển thị bảng với năm hộp trong mỗi sáu hàng bằng cách sử dụng các phần tử HTML, hãy sử dụng các vòng lặp lồng nhau để lặp lại và tạo các phần tử. Cuối cùng, nối chúng vào bảng.
for (let i = 0; i <= 5; i++) {
let row = document.createElement('div')
for (let y = 0; y <= 4; y++) {
let box = document.createElement('span');
row.appendChild(box);
row.className = `row-${i + 1}`
}
board.appendChild(row);
}
Thêm bàn phím và nghe đầu vào bàn phím
Để tạo bàn phím, lặp qua các phím bằng cách sử dụng cho mỗi, tạo phần tử nút cho mỗi mục nhập. Đặt văn bản của nút thành xóa lùi nếu mục là *nếu không thì đặt nó thành giá trị mục nhập.
chỉ định chìa khóa class vào nút và đặt khóa dữ liệu thuộc tính cho giá trị mục nhập chữ hoa. Tiếp theo, thêm trình xử lý sự kiện nhấp chuột vào nút gọi hàm đút chìa khóa vào với giá trị nhập chữ hoa.
keys.forEach(entry => {
let key = document.createElement("button");
if (entry === "*") {
key.innerText = "Backspace";
} else {
key.innerText = entry;
}
key.className = "key";
key.setAttribute("data-key", entry.toUpperCase());
key.addEventListener("click", () => {
insertKey(entry.toUpperCase())
setTimeout(() => {
document.querySelector(`button[data-key=${entry.toUpperCase()}]`).blur();
}, 250)
})
keyboard.append(key);
})
Nhận một từ mới từ một API
Khi người dùng tải trò chơi lần đầu tiên, trò chơi sẽ tìm nạp một từ gồm năm chữ cái mới từ API từ ngẫu nhiên. Từ này sau đó được lưu trữ trong từ bí mật Biến đổi.
function getNewWord() {
async function fetchWord() {
try {
const response = await fetch("https://random-word-api.herokuapp.com/word?length=5");
if (response.ok) {
const data = await response.json();
return data;
} else {
throw new Error("Something went wrong!")
}
} catch (error) {
message.innerText = `Something went wrong. n${error}nCheck your internet connection.`;
}
}
fetchWord().then(data => {
secretWord = data[0].toUpperCase();
main();
})}
Trong khối mã ở trên, chủ yếu chức năng chạy nếu từ ngẫu nhiên được tìm nạp thành công. xác định một chủ yếu chức năng ngay bên dưới getNewWord chức năng:
function main(){}
Để tạo kiểu cho từng hộp trên bảng, bạn sẽ cần một danh sách tất cả các hộp trong mỗi hàng. Khai báo một biến, hàng ngang lấy tất cả các hàng trong DOM. Ngoài ra, đặt tin nhắn phong cách hiển thị để không có:
rows.forEach(row => [...row.children].forEach(child => boxes.push(child)))
boxes.forEach((box) => {
box.classList.add("empty");
})
message.style.display = "none";
Tiếp theo, thêm một bàn phím trình lắng nghe sự kiện cho đối tượng cửa sổ và kiểm tra xem khóa đã phát hành có hợp lệ hay không. Nếu hợp lệ, hãy tập trung vào nút tương ứng, mô phỏng nhấp chuột và làm mờ nút đó sau độ trễ 250 mili giây:
window.addEventListener('keyup', (e) => {
if (isValidCharacter(e.key)) {
document.querySelector(`button[data-key=${e.key.toUpperCase()}]`).focus();
document.querySelector(`button[data-key=${e.key.toUpperCase()}]`).click();
setTimeout(() => {
document.querySelector(`button[data-key=${e.key.toUpperCase()}]`).blur();
}, 250)
}
})
Bên dưới bàn phím trình nghe sự kiện, hãy thiết lập trình nghe sự kiện cho hai nút: showBtn Và khởi động lạiBtn. Khi người chơi nhấp vào showBtnhiển thị thông báo chúc mừng với giá trị của từ bí mật Biến đổi.
nhấp chuột khởi động lạiBtn tải lại trang. Ngoài ra, hãy chắc chắn rằng bạn bao gồm một isValid Character chức năng kiểm tra xem một khóa có phải là một ký tự hợp lệ hay không.
showBtn.addEventListener('click', () => {
Toastify({
text: `Alright fine! the answer is ${secretWord}`,
duration: 2500,
className: "alert",
}).showToast();
}) restartBtn.addEventListener('click', () => {
location.reload();
})
function isValidCharacter(val) {
return (val.match(/^[a-zA-Z]+$/) && (val.length === 1 || val === "Backspace"))
}
bên ngoài chủ yếu chức năng, tạo một kết xuấtHộp chức năng và cung cấp ba tham số: hàng ngang (số hàng), hộp (chỉ mục hộp trong hàng) và dữ liệu (nội dung văn bản cần cập nhật).
function renderBox(row, box, data) {
[...document.querySelector(`.row-${row}`).children][box].innerText = data;
}
Xử lý đầu vào bàn phím với một chức năng
Để xử lý các đầu vào chính và để cập nhật bảng, hãy tạo một đút chìa khóa vào chức năng với một chìa khóa tham số. Hàm sẽ hoạt động theo tham số được truyền.
function insertKey(key) {
if (key === "Backspace".toUpperCase() && currentRow < boardContent.length) {
boardContent[currentRow][currentBox] = 0;
if (currentBox !== 0) {
currentBox--;
renderBox(currentRow + 1, currentBox, "");
}
} else {
if (currentRow < boardContent.length) {
boardContent[currentRow][currentBox] = key;
renderBox(currentRow + 1, currentBox, key);
currentBox++;
}
if (currentRow < boardContent.length && boardContent[currentRow][currentBox] !== 0) {
evaluate(currentRow, key);
currentBox = 0;
currentRow++;
}
}
}
Đánh giá dự đoán của người chơi
Tạo ra một đánh giá chức năng chấp nhận một tham số hàng. Chức năng này có nhiệm vụ đánh giá dự đoán của người chơi.
function evaluate(row){}
Mỗi trò chơi có một Hiển thị câu trả lời nút chỉ xuất hiện sau khi người dùng đã thực hiện bốn lần đoán. Vì vậy, trong chức năng, hãy triển khai chức năng thực hiện điều đó:
if (currentRow === 4) {
showBtn.removeAttribute('disabled')
}
Sau đó xác định biến đoán và biến trả lời để kiểm tra xem các chữ cái có ở đúng vị trí hay không.
let guess = boardContent[row].join('').toUpperCase();
let answer = secretWord.split("");
Thuật toán tô màu gạch sẽ có ích ở đây. Nhớ lại rằng một ô hoặc chữ cái phải có màu xanh lá cây nếu nó nằm trong từ và ở đúng vị trí.
Nếu ô nằm trong từ nhưng ở vị trí sai, ô có màu vàng và cuối cùng là màu xám dành cho ô không có trong từ.
let colors = guess
.split("")
.map((letter, idx) => letter == answer[idx] ? (answer[idx] = false) : letter)
.map((letter, idx) =>
letter
? (idx = answer.indexOf(letter)) < 0
? "grey"
: (answer[idx] = "yellow")
: "green"
);
Khối mã đã cho ở trên thực hiện so sánh từng phần tử giữa đoán mảng và trả lời mảng. Dựa trên kết quả so sánh này, mã cập nhật màu sắc mảng.
Tiếp theo, xác định một setColors chức năng có thể đảm nhận trong màu sắc mảng làm tham số và tô màu các ô thích hợp:
function setColor(colors) {
colors.forEach((color, index) => {
document.querySelector(`button[data-key=${guess[index].toUpperCase()}]`).style.backgroundColor = color;
document.querySelector(`button[data-key=${guess[index].toUpperCase()}]`).style.color= "black";
[...document.querySelector(`.row-${row + 1}`).children][index].style.backgroundColor = color;
})
}
Trò chơi hiện đã hoàn tất. Tất cả những gì bạn phải làm bây giờ là gọi getNewWord chức năng, và bạn tốt để đi.
getNewWord();
Xin chúc mừng, bạn vừa tạo lại Wordle.
Đưa kỹ năng JavaScript của bạn lên một tầm cao mới bằng cách tạo lại trò chơi
Học một ngôn ngữ mới khi mới bắt đầu không hề dễ dàng. Tái tạo các trò chơi như Tic-tac-toe, Hangman và Wordle bằng ngôn ngữ như JavaScript có thể giúp người mới bắt đầu nắm vững các khái niệm của ngôn ngữ bằng cách áp dụng chúng vào thực tế.