it Новини Создание игры "Змейка" на чистом JavaScript и HTML5
Создание игры

Создание игры "Змейка" на чистом JavaScript и HTML5

125 401
17 липня 2019 в 16:46

Змейка - классическая игра, которую мы знаем еще с давних времен. Мы представляем вам статью, в ходе которой мы создадим полноценную игру «Змейка» на чистом JavaScript и HTML5.

Для создания веб игр на языке JavaScript используется технология Canvas, которая позволяет выполнять JavaScript код в HTML5 документе. Вы можете более детально ознакомиться с этой технологией посмотрев видео ниже:



HTML страница может содержать классическую разметку, в которую необходимо вписать canvas для отображения игры внутри него. Пример кода:

<!DOCTYPE html>
<html lang="ru">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title>Игра на JavaScript</title>
	<link rel="stylesheet" href="css/style.css">
</head>
<body>
	<canvas id="game" width="608" height="608"></canvas>
	<script src="js/game.js"></script>
</body>
</html>

Внутри этого файла мы подключаем скрипт "game.js", который будет описывать весь функционал нашей игры.

JavaScript файл

Внутри JavaScript файла добавьте выборку канваса, а также укажите контекст игры.

var cvs = document.getElementById("canvas");
var ctx = cvs.getContext("2d");

Добавление изображений и аудио

Далее необходимо загрузить все основные изображения, которые будут использоваться в игре. Для этого используйте класс Image. Ниже вы можете скачать все необходимые картинки к игре.




Код добавления изображений и аудио в игру:

const ground = new Image(); // Создание объекта
ground.src = "img/ground.png"; // Указываем нужное изображение

const foodImg = new Image(); // Создание объекта
foodImg.src = "img/food.png"; // Указываем нужное изображение

Рисование объектов

Чтобы нарисовать объекты, а также добавить функционал к игре необходимо прописать функцию, которая будет постоянно вызываться. Такую функцию вы можете назвать как вам будет угодно. Чтобы функция работала постоянно, вы можете запустите её выполнение через setInterval().

function draw() {
	// Какой-либо код
}

let game = setInterval(draw, 100); // Вызов функции из вне

Весь код игры стоит помещать в этот метод, ведь в нем он будет постоянно обрабатываться и игра будет выглядеть живой и анимированной.


Чтобы отследить нажатие игрока на какую-либо клавишу, необходимо использовать отслеживание событий - addEventListener. К примеру, чтобы отследить нажатие на любую клавишу на клавиатуре надо прописать следующий код:

// При нажатии на какую-либо кнопку
document.addEventListener("keydown", someMethod);
// Вызывается метод someMethod
function someMethod() {
	// Изменяем что-то в коде
}

Видео урок

Это были лишь небольшие азы перед созданием самой игры. Предлагаем вам ознакомиться с большим видео уроком, в ходе которого вы создадите 2D игру "Змейка" на чистом JavaScript'е



Полезные ссылки из видео:

  • Текстовый редактор Atom.io;
  • Подбор иконок IconFinder;
  • Хостинг компания Reg.ru.

Весь JS код игры

Ниже вы можете посмотреть на полностью весь код JavaScript файла, который был создан в ходе видео урока выше:

const canvas = document.getElementById("game");
const ctx = canvas.getContext("2d");

const ground = new Image();
ground.src = "img/ground.png";

const foodImg = new Image();
foodImg.src = "img/food.png";

let box = 32;

let score = 0;

let food = {
	x: Math.floor((Math.random() * 17 + 1)) * box,
	y: Math.floor((Math.random() * 15 + 3)) * box,
};

let snake = [];
snake[0] = {
	x: 9 * box,
	y: 10 * box
};

document.addEventListener("keydown", direction);

let dir;

function direction(event) {
	if(event.keyCode == 37 && dir != "right")
		dir = "left";
	else if(event.keyCode == 38 && dir != "down")
		dir = "up";
	else if(event.keyCode == 39 && dir != "left")
		dir = "right";
	else if(event.keyCode == 40 && dir != "up")
		dir = "down";
}

function eatTail(head, arr) {
	for(let i = 0; i < arr.length; i++) {
		if(head.x == arr[i].x && head.y == arr[i].y)
			clearInterval(game);
	}
}

function drawGame() {
	ctx.drawImage(ground, 0, 0);

	ctx.drawImage(foodImg, food.x, food.y);

	for(let i = 0; i < snake.length; i++) {
		ctx.fillStyle = i == 0 ? "green" : "red";
		ctx.fillRect(snake[i].x, snake[i].y, box, box);
	}

	ctx.fillStyle = "white";
	ctx.font = "50px Arial";
	ctx.fillText(score, box * 2.5, box * 1.7);

	let snakeX = snake[0].x;
	let snakeY = snake[0].y;

	if(snakeX == food.x && snakeY == food.y) {
		score++;
		food = {
			x: Math.floor((Math.random() * 17 + 1)) * box,
			y: Math.floor((Math.random() * 15 + 3)) * box,
		};
	} else
		snake.pop();

	if(snakeX < box || snakeX > box * 17
		|| snakeY < 3 * box || snakeY > box * 17)
		clearInterval(game);

	if(dir == "left") snakeX -= box;
	if(dir == "right") snakeX += box;
	if(dir == "up") snakeY -= box;
	if(dir == "down") snakeY += box;

	let newHead = {
		x: snakeX,
		y: snakeY
	};

	eatTail(newHead, snake);

	snake.unshift(newHead);
}

let game = setInterval(drawGame, 100);


Также вы можете скачать весь проект целиком по этой ссылке.
Telegram group

Підписуйтесь на нашу групу в Телеграмі 🇺🇦

Більше цікавих новин

Коментарі (1)
Додати коментар

Віталій 04 лютого 2024 в 14:31

const field = document.getElementById("field")
const context = field.getContext("2d")

const fieldImg = new Image()
fieldImg.src = "img/field.png"

const foodImg = new Image()
foodImg.src = "img/food.png"

const box = 32

let food = {
    x: Math.floor((Math.random()*17)+1)*box,
    y: Math.floor((Math.random()*15)+3)*box
}

const snakeArr = []

snakeArr[0]={
    x: box*9,
    y: box*10
}


let dir;

document.addEventListener("keydown", direction)

function direction(e){
    if(e.keyCode==38 && dir!="down"){
        dir = "up"
    }else if(e.keyCode==39 && dir!="left"){
        dir = "right"
    }else if(e.keyCode==40 && dir!="up"){
        dir = "down"
    }else if(e.keyCode==37 && dir!="right"){
        dir = "left"
    }
}

let score = 0

function drawGame(){
    const snakeHead = {
        x: snakeArr[0].x,
        y: snakeArr[0].y
    }
    context.drawImage(fieldImg, 0, 0)
    if(snakeArr[0].x==food.x && snakeArr[0].y==food.y){
        food = {
            x: Math.floor((Math.random()*17)+1)*box,
            y: Math.floor((Math.random()*15)+3)*box
        }
        score++
    }else{snakeArr.pop()}
    
    for(let i=0; i<snakeArr.length; i++){
        context.fillStyle = i==0?"green":"red"
        context.fillRect(snakeArr[i].x, snakeArr[i].y, box, box)
    }

    if(food.x!=snakeArr.y && food.y!=snakeArr.y){
        context.drawImage(foodImg, food.x, food.y)
    }

    if(dir=="left") snakeArr[0].x-=box
    if(dir=="right") snakeArr[0].x+=box
    if(dir=="up") snakeArr[0].y-=box
    if(dir=="down") snakeArr[0].y+=box

    

    if(snakeArr[0].x==-1*box){
        // snakeArr[0].x=17*box
        clearInterval(game)
    }else if(snakeArr[0].x==19*box){
        // snakeArr[0].x=1*box
        clearInterval(game)
    }else if(snakeArr[0].y==1*box){
        // snakeArr[0].y=15*box
        clearInterval(game)
    }else if(snakeArr[0].y==19*box){
        // snakeArr[0].y=3*box
        clearInterval(game)
    }

    
    
    let newHead = {
        x: snakeArr[0].x,
        y: snakeArr[0].y
    }
    

    let scoreXY = {
        x: 2.5*box,
        y: 1.7*box
    }

    context.fillStyle = "white"
    context.font = "50px Arial"
    context.fillText(score, scoreXY.x, scoreXY.y)

    snakeArr.unshift({snakeHead})
}
 


let game = setInterval(drawGame, 100)


Я коли використовую pop(), то воно відразу забирай голову
Відповісти