Лабиринт на JavaScript и canvas | В паутине

Лабиринт на JavaScript и canvas

Создание игры-лабиринта на языке JavaScript с помощью HTML5 Canvas.

Разметка

<canvas id="canvas"></canvas>
<img id="face" src="face.png">
img{display:none;}
canvas{border:5px double black;}

Создается холст и картинка-маркер.

Код

После загрузки документа, находим холст и создаем контекст рисования.

window.onload = function(){
    var canvas = document.getElementById("canvas");
    var context = canvas.getContext("2d");
    
    var x = 0;
    var y = 0;
    var timer;

    drawMaze("maze.png", 268, 5);
    window.onkeydown = processKey;
}

Создаем переменные x и y для хранения положения маркера, timer для перерисовки холста.
Запускаем функцию drawMaze, рисующую лабиринт (с указанием изображения лабиринта и начальных координат маркера).
Устанавливаем прослушку на событие нажатия клавиши с функцией-обработчиком processKey.

Код этих функций:

function drawMaze(mazeFile, startingX, startingY){

    // Остановить таймер (если запущен)
    clearTimeout(timer);

    // Остановить перемещение значка
    dx = 0;
    dy = 0;

    // Загружаем изображение лабиринта
    var imgMaze = new Image();
    imgMaze.onload = function() {
        // Изменяем размер холста в соответствии 
        // с размером изображения лабиринта
        canvas.width = imgMaze.width;
        canvas.height = imgMaze.height;

        // Рисуем лабиринт
        context.drawImage(imgMaze, 0,0);

        // Рисуем значок
        x = startingX;
        y = startingY;

        var imgFace = document.getElementById("face");
        context.drawImage(imgFace, x, y);
        context.stroke();

        // Рисуем следующий кадр через 10 миллисекунд
        timer = setTimeout(drawFrame, 10);
    };
    imgMaze.src = mazeFile;
}
function processKey(e) {
    // Если значок находится в движении, останавливаем его
    dx = 0;
    dy = 0;

    // Если нажата стрелка вверх, начинаем двигаться вверх
    if (e.keyCode == 38) {
        dy = -1;
    }

    // Если нажата стрелка вниз, начинаем двигаться вниз
    if (e.keyCode == 40) {
        dy = 1;
    }

    // Если нажата стрелка влево, начинаем двигаться влево
    if (e.keyCode == 37) {
        dx = -1;
    }

    // Если нажата стрелка вправо, начинаем двигаться вправо
    if (e.keyCode == 39) {
        dx = 1;
    }
}

После того, как лабиринт нарисован, через 10 миллисекунд запускается функция drawFrame, которая должна перерисовать лабиринт.

function drawFrame() {
   
    // Обновляем кадр только если значок движется
    if (dx != 0 || dy != 0) {
        // Закрашиваем перемещение значка желтым цветом
        context.beginPath();
        context.fillStyle = "rgb(254,244,207)";
        context.rect(x, y, 15, 15);
        context.fill()

        // Обновляем координаты значка, создавая перемещение
        x += dx;
        y += dy;

        // Проверка столкновения со стенками лабиринта
        // (вызывается доп. функция)
        if (checkForCollision()) {
            x -= dx;
            y -= dy;
            dx = 0;
            dy = 0;
        }

        // Перерисовываем значок
        var imgFace = document.getElementById("face");
        context.drawImage(imgFace, x, y);

        // Проверяем дошел ли пользователь до финиша.
        // Если дошел, то выводим сообщение
        if (y > (canvas.height - 17)) {
            alert("Ты победил!");
            return;
        }
    }

    // Рисуем следующий кадр через 10 миллисекунд
    timer = setTimeout(drawFrame, 10);
}

Эта функция проверяет, двигается ли маркер, и при необходимости перерисовывает весь лабиринт. При этом она отмечает пройденный путь желтым цветом. Получая новые координаты маркера, функция проверяет, нет ли столкновения со стенами, вызывая функцию checkForCollision. Для обеспечения цикла перерисовки, функция drawFrame сама себя вызывает с интервалом в 10 миллисекунд.

function checkForCollision() {
    // Перебираем все пикселы и инвертируем их цвет
    var imgData = context.getImageData(x-1, y-1, 15+2, 15+2);
    var pixels = imgData.data;

    // Получаем данные для одного пиксела
    for (var i = 0; n = pixels.length, i < n; i += 4) {
        var red = pixels[i];
        var green = pixels[i+1];
        var blue = pixels[i+2];
        var alpha = pixels[i+3];

        // Смотрим на наличие черного цвета стены, что указывает на столкновение
        if (red == 0 && green == 0 && blue == 0) {
          return true;
        }
        // Смотрим на наличие серого цвета краев, что указывает на столкновение
        if (red == 169 && green == 169 && blue == 169) {
          return true;
        }
    }
    // Столкновения не было
    return false;
}

Проверка столкновения со стенами лабиринта основана на анализе цвета пикселей.

Полный код файла script.js

window.onload = function(){
    var canvas = document.getElementById("canvas");
    var context = canvas.getContext("2d");
    drawMaze("maze.png", 268, 5);
    window.onkeydown = processKey;
    var x = 0;
    var y = 0;
    var timer;

    function drawMaze(mazeFile, startingX, startingY){
        clearTimeout(timer);
        dx = 0;
        dy = 0;
        var imgMaze = new Image();
        imgMaze.onload = function() {
            canvas.width = imgMaze.width;
            canvas.height = imgMaze.height;
            context.drawImage(imgMaze, 0,0);
            x = startingX;
            y = startingY;
            var imgFace = document.getElementById("face");
            context.drawImage(imgFace, x, y);
            context.stroke();
            timer = setTimeout(drawFrame, 10);
        };
        imgMaze.src = mazeFile;
    }
    function processKey(e) {
        dx = 0;
        dy = 0;
        if (e.keyCode == 38) {dy = -1;}
        if (e.keyCode == 40) {dy = 1;}
        if (e.keyCode == 37) {dx = -1;}
        if (e.keyCode == 39) {dx = 1;}
    }
    function drawFrame() {
        if (dx != 0 || dy != 0) {
            context.beginPath();
            context.fillStyle = "rgb(254,244,207)";
            context.rect(x, y, 15, 15);
            context.fill()
            x += dx;
            y += dy;
            if (checkForCollision()) {
                x -= dx;
                y -= dy;
                dx = 0;
                dy = 0;
            }
            var imgFace = document.getElementById("face");
            context.drawImage(imgFace, x, y);
            if (y > (canvas.height - 17)) {
                alert("Ты победил!");
                return;
            }
        }
        timer = setTimeout(drawFrame, 10);
    }

    function checkForCollision() {
        var imgData = context.getImageData(x-1, y-1, 15+2, 15+2);
        var pixels = imgData.data;
        for (var i = 0; n = pixels.length, i < n; i += 4) {
            var red = pixels[i];
            var green = pixels[i+1];
            var blue = pixels[i+2];
            var alpha = pixels[i+3];
            if (red == 0 && green == 0 && blue == 0) {return true;}
            if (red == 169 && green == 169 && blue == 169) {return true;}
        }
        return false;
    }
}

Открыть в новой вкладке



Источник professorweb.ru


Вам будет интересно:

Пятнашки на JavaScript и Canvas
Простой платформер на Flash

Комментарии (0)

Ваш email не будет опубликован. Все поля обязательны