Cách tạo trò chơi rắn bằng HTML, CSS và JavaScript
Tạo lại trò chơi trường học cũ này trong trình duyệt của bạn và tìm hiểu về nhà phát triển trò chơi JavaScript trên đường đi.
Trò chơi con rắn là một bài tập lập trình cổ điển mà bạn có thể sử dụng để cải thiện kỹ năng lập trình và giải quyết vấn đề của mình. Bạn có thể tạo trò chơi trong trình duyệt web bằng HTML, CSS và JavaScript.
Trong trò chơi, bạn điều khiển một con rắn di chuyển xung quanh một tấm ván. Con rắn tăng kích thước khi bạn thu thập thức ăn. Trò chơi sẽ kết thúc nếu bạn va vào đuôi của chính mình hoặc bất kỳ bức tường nào.
Mục Lục
Cách tạo giao diện người dùng cho Canvas
Sử dụng HTML và CSS để thêm canvas cho con rắn di chuyển. Có nhiều dự án HTML và CSS khác mà bạn có thể thực hành nếu bạn cần sửa lại bất kỳ khái niệm cơ bản nào.
Bạn có thể tham khảo kho lưu trữ GitHub của dự án này để biết mã nguồn đầy đủ.
- Tạo một tệp mới có tên “index.html”.
- Mở tệp bằng bất kỳ trình soạn thảo văn bản nào như Visual Code hoặc Atom. Thêm cấu trúc mã HTML cơ bản:
<!doctype html>
<html lang="en-US">
<head>
<title>Snake Game</title>
</head>
<body></body>
</html> - Bên trong thẻ body, thêm canvas để đại diện cho bảng trò chơi rắn.
<h2>Snake Game</h2>
<div id="game">
<canvas id="snake"></canvas>
</div> - Trong cùng thư mục với tệp HTML của bạn, hãy tạo một tệp mới có tên “styles.css”.
- Bên trong, thêm một số CSS cho trang web tổng thể. Bạn cũng có thể tạo kiểu cho trang web của mình bằng cách sử dụng các mẹo và thủ thuật CSS cần thiết khác.
#game {
width:400px;
height:400px;
margin:0 auto;
background-color:#eee;
}
h2 {
text-align:center;
font-family:Arial;
font-size:36px;
} - Bên trong tệp HTML của bạn, hãy thêm một liên kết đến CSS trong thẻ đầu:
<link rel="stylesheet" type="text/css" href="styles.css"> - Để xem canvas, hãy mở tệp “index.html” của bạn trong trình duyệt web.
Cách vẽ con rắn
Trong ví dụ dưới đây, đường màu đen đại diện cho con rắn:
Nhiều ô vuông hoặc “phân đoạn” tạo nên con rắn. Khi con rắn lớn lên, số ô vuông cũng tăng lên. Khi bắt đầu trò chơi, chiều dài của con rắn là một mảnh.
- Bên trong tệp HTML của bạn, hãy liên kết tới một tệp JavaScript mới ở cuối thẻ body:
<body>
<script src="script.js"></script>
</body> - Tạo script.js và bắt đầu bằng cách lấy phần tử DOM của canvas:
var canvas = document.getElementById("snake"); - Đặt ngữ cảnh cho phần tử canvas HTML. Trong trường hợp này, bạn muốn trò chơi hiển thị canvas 2d. Điều này sẽ cho phép bạn vẽ nhiều hình dạng hoặc hình ảnh lên phần tử HTML.
var canvas2d = canvas.getContext("2d"); - Đặt các biến khác trong trò chơi, chẳng hạn như trò chơi đã kết thúc hay chưa, chiều cao và chiều rộng của canvas:
var gameEnded = false;
canvas.width = 400;
canvas.height = 400; - Khai báo một biến gọi là “snakeSegments”. Điều này sẽ giữ số “ô vuông” mà con rắn sẽ chiếm. Bạn cũng có thể tạo một biến để theo dõi độ dài của con rắn:
var snakeSegments = [];
var snakeLength = 1; - Khai báo vị trí X và Y ban đầu của con rắn:
var snakeX = 0;
var snakeY = 0; - Tạo một chức năng mới. Bên trong, thêm mảnh rắn bắt đầu vào mảng solidSegments, với tọa độ X và Y bắt đầu của nó:
function moveSnake() {
snakeSegments.unshift({ x: snakeX, y: snakeY });
} - Tạo một chức năng mới. Bên trong, đặt kiểu tô thành màu đen. Đây là màu nó sẽ sử dụng để vẽ con rắn:
function drawSnake() {
canvas2d.fillStyle = "black";
} - Đối với mỗi đoạn tạo nên kích thước của con rắn, hãy vẽ một hình vuông có chiều rộng và chiều cao là 10 pixel:
for (var i = 0; i < snakeSegments.length; i++) {
canvas2d.fillRect(snakeSegments[i].x, snakeSegments[i].y, 10, 10);
} - Tạo một vòng lặp trò chơi sẽ chạy cứ sau 100 mili giây. Điều này sẽ khiến trò chơi liên tục kéo con rắn vào vị trí mới, điều này sẽ rất quan trọng khi con rắn bắt đầu di chuyển:
function gameLoop() {
moveSnake();
drawSnake(); - Mở tệp “index.html” trong trình duyệt web để xem con rắn ở kích thước nhỏ nhất ở vị trí bắt đầu.
Làm thế nào để làm cho con rắn di chuyển
Thêm một số logic để di chuyển con rắn theo các hướng khác nhau, tùy thuộc vào nút mà người chơi nhấn trên bàn phím.
- Ở đầu tệp, khai báo hướng ban đầu của con rắn:
var directionX = 10;
var directionY = 0; - Thêm trình xử lý sự kiện kích hoạt khi người chơi nhấn phím:
document.onkeydown = function(event) {};
- Bên trong trình xử lý sự kiện, thay đổi hướng mà con rắn đang di chuyển, dựa trên phím được nhấn:
switch (event.keyCode) {
case 37:
directionX = -10;
directionY = 0;
break;
case 38:
directionX = 0;
directionY = -10;
break;
case 39:
directionX = 10;
directionY = 0;
break;
case 40:
directionX = 0;
directionY = 10;
break;
} - Trong hàm moveSnake(), sử dụng hướng để cập nhật tọa độ X và Y của con rắn. Ví dụ: nếu con rắn cần di chuyển sang trái, hướng X sẽ là “-10”. Thao tác này sẽ cập nhật tọa độ X để xóa 10 pixel cho mọi khung hình của trò chơi:
function moveSnake() {
snakeSegments.unshift({ x: snakeX, y: snakeY });
snakeX += directionX;
snakeY += directionY;
} - Trò chơi hiện không xóa các phân đoạn trước đó trong khi con rắn đang di chuyển. Điều này sẽ làm cho con rắn trông như thế này:
-
Để khắc phục điều này, hãy xóa canvas trước khi vẽ con rắn mới trong mỗi khung, khi bắt đầu hàm drawSnake():
canvas2d.clearRect(0, 0, canvas.width, canvas.height); - Bạn cũng sẽ cần xóa phần tử cuối cùng của mảng SnakeSegments, bên trong hàm moveSnake():
while (snakeSegments.length > snakeLength) {
snakeSegments.pop();
} - Mở tệp “index.html” và nhấn các phím trái, phải, lên hoặc xuống để di chuyển con rắn.
Cách thêm thức ăn lên canvas
Thêm dấu chấm vào trò chơi cờ để đại diện cho miếng thức ăn cho rắn.
- Khai báo một biến mới ở đầu tệp để lưu trữ một mảng các miếng thức ăn:
var dots = []; - Tạo một chức năng mới. Bên trong, tạo tọa độ X và Y ngẫu nhiên cho các dấu chấm. Bạn cũng có thể đảm bảo rằng chỉ có 10 dấu chấm trên bảng bất cứ lúc nào:
function spawnDots() {
if(dots.length < 10) {
var dotX = Math.floor(Math.random() * canvas.width);
var dotY = Math.floor(Math.random() * canvas.height);
dots.push({ x: dotX, y: dotY });
}
} - Sau khi tạo tọa độ X và Y cho thực phẩm, hãy vẽ chúng lên canvas bằng màu đỏ:
for (var i = 0; i < dots.length; i++) {
canvas2d.fillStyle = "red";
canvas2d.fillRect(dots[i].x, dots[i].y, 10, 10);
} - Gọi hàm spawnDots() mới bên trong vòng lặp trò chơi:
function gameLoop() {
moveSnake();
drawSnake();
spawnDots();
if(!gameEnded) {
setTimeout(gameLoop, 100);
}
} - Mở tệp “index.html” để xem thức ăn trên bàn trò chơi.
Làm thế nào để làm cho con rắn lớn lên
Bạn có thể làm cho con rắn lớn lên bằng cách tăng chiều dài của nó khi nó va chạm với chấm thức ăn.
- Tạo một chức năng mới. Bên trong nó, lặp qua mọi phần tử trong mảng dấu chấm:
function checkCollision() {
for (var i = 0; i < dots.length; i++) {
}
} - Nếu vị trí của con rắn khớp với tọa độ của bất kỳ dấu chấm nào, hãy tăng chiều dài của con rắn và xóa dấu chấm:
if (snakeX < dots[i].x + 10 &&
snakeX + 10 > dots[i].x &&
snakeY < dots[i].y + 10 &&
snakeY + 10 > dots[i].y) {
snakeLength++;
dots.splice(i, 1);
} - Gọi hàm checkCollision() mới trong vòng lặp trò chơi:
function gameLoop() {
moveSnake();
drawSnake();
spawnDots();
checkCollision();
if(!gameEnded) {
setTimeout(gameLoop, 100);
}
} - Mở tệp “index.html” trong trình duyệt web. Di chuyển con rắn bằng bàn phím để thu thập các miếng thức ăn và nuôi rắn.
Làm thế nào để kết thúc trò chơi
Để kết thúc trò chơi, hãy kiểm tra xem con rắn có va chạm với đuôi của chính nó hoặc bất kỳ bức tường nào không.
- Tạo một chức năng mới để in cảnh báo “Trò chơi kết thúc”.
function gameOver() {
setTimeout(function() {
alert("Game over!");
}, 500);
gameEnded = true
} - Bên trong hàm checkCollision(), kiểm tra xem con rắn có va vào bất kỳ bức tường nào của canvas không. Nếu vậy, hãy gọi hàm gameOver():
if (snakeX < -10 ||
snakeY < -10 ||
snakeX > canvas.width+10 ||
snakeY > canvas.height+10) {
gameOver();
} - Để kiểm tra xem đầu rắn có va chạm với bất kỳ đoạn đuôi nào không, hãy luồn qua từng đoạn rắn:
for (var i = 1; i < snakeSegments.length; i++) {}
- Bên trong vòng lặp for, hãy kiểm tra xem vị trí của đầu rắn có khớp với bất kỳ đoạn đuôi nào không. Nếu vậy, điều này có nghĩa là đầu va chạm với đuôi, vì vậy hãy kết thúc trò chơi:
if (snakeX === snakeSegments[i].x && snakeY === snakeSegments[i].y) {
gameOver();
} - Mở tệp “index.html” trong trình duyệt web. Cố gắng đâm vào tường hoặc vào đuôi của chính bạn để kết thúc trò chơi.
Học các khái niệm JavaScript thông qua các trò chơi
Tạo trò chơi có thể là một cách tuyệt vời để làm cho trải nghiệm học tập của bạn thú vị hơn. Hãy tiếp tục tạo nhiều trò chơi hơn để tiếp tục nâng cao kiến thức JavaScript của bạn.