Урок 9. Игра змейка на javascript

Автор: | 21.07.2016

АЛГОРИТМ

— клеточки змейки помечаются классом «s» а еда классом «f», по наличию этих классов и определяется коллизия со змеей или с едой

— каждая новая клетка змеи помечается атрибутом «data-n» который равен number++ (постоянно увеличивается)

— ищем div’ы с классом «s» (клетки змеи) и находим клетку с минимальным значением data-n и делаем ее обычной (удаляем/перемещаем хвост змеи)

СОБЫТИЯ и МЕТОДЫ

OnKeyDown Событие, выполнение JavaScript, когда пользователь нажимает клавишу.

setInterval () Метод, вызывает функцию или вычисляет выражение через определенные промежутки времени.

Метод setInterval () будет продолжать вызов функции до вызова clearInterval (), или при закрытии окна.

getElementsByClassName () Метод, возвращает коллекцию всех элементов в документе с указанным именем класса, как NodeList объекта.

Объект NodeList представляет коллекцию узлов. Узлами могут быть номера индексов. Индекс начинается с 0.

alert () Метод, Окно оповещения, отображает окно с  предупреждением с заданным сообщением и кнопкой OK, часто используется, если вы хотите, убедиться, что информация доходит до пользователя.

SetAttribute () Метод, добавляет указанный атрибут к элементу, и придает ему определенное значение.

Если указанный атрибут уже существует, значение изменяется.

Math.round () Метод, округляет число до ближайшего целого числа.

Math.random() Метод,  Возвращает случайное число в диапазоне от 0 (включительно) и 1 (включительно)

html

<div id="main" class="main">
<div class='line'><div data-n='1' class="0_0 s"></div><div class="0_1"></div><div class="0_2"></div><div class="0_3"></div><div class="0_4"></div><div class="0_5"></div><div class="0_6"></div><div class="0_7"></div><div class="0_8"></div><div class="0_9"></div></div>
<div class="line"><div class="1_0"></div><div class="1_1"></div><div class="1_2"></div><div class="1_3"></div><div class="1_4"></div><div class="1_5"></div><div class="1_6"></div><div class="1_7"></div><div class="1_8"></div><div class="1_9"></div></div><div class="line"><div class="2_0"></div><div class="2_1"></div><div class="2_2"></div><div class="2_3"></div><div class="2_4"></div><div class="2_5"></div><div class="2_6"></div><div class="2_7"></div><div class="2_8"></div><div class="2_9"></div></div>
<div class="line"><div class="3_0"></div><div class="3_1"></div><div class="3_2"></div><div class="3_3"></div><div class="3_4"></div><div class="3_5"></div><div class="3_6"></div><div class="3_7"></div><div class="3_8"></div><div class="3_9"></div></div><div class="line"><div class="4_0"></div><div class="4_1"></div><div class="4_2"></div><div class="4_3"></div><div class="4_4"></div><div class="4_5"></div><div class="4_6"></div><div class="4_7"></div><div class="4_8"></div><div class="4_9"></div></div>
<div class="line"><div class="5_0"></div><div class="5_1"></div><div class="5_2"></div><div class="5_3"></div><div class="5_4"></div><div class="5_5"></div><div class="5_6"></div><div class="5_7"></div><div class="5_8"></div><div class="5_9"></div></div><div class="line"><div class="6_0"></div><div class="6_1"></div><div class="6_2"></div><div class="6_3"></div><div class="6_4"></div><div class="6_5"></div><div class="6_6"></div><div class="6_7"></div><div class="6_8"></div><div class="6_9"></div></div>
<div class="line"><div class="7_0"></div><div class="7_1"></div><div class="7_2"></div><div class="7_3"></div><div class="7_4"></div><div class="7_5"></div><div class="7_6"></div><div class="7_7"></div><div class="7_8"></div><div class="7_9"></div></div><div class="line"><div class="8_0"></div><div class="8_1"></div><div class="8_2"></div><div class="8_3"></div><div class="8_4"></div><div class="8_5"></div><div class="8_6"></div><div class="8_7"></div><div class="8_8"></div><div class="8_9"></div></div>
<div class="line"><div class="9_0"></div><div class="9_1"></div><div class="9_2"></div><div class="9_3"></div><div class="9_4"></div><div class="9_5"></div><div class="9_6"></div><div class="9_7"></div><div class="9_8"></div><div class="9_9"></div></div>
</div>

style

.main .line {
    clear: both;
}
.main .line div {
    width: 20px;
    height: 20px;
    float: left;
    margin: 1px;
    border: 1px solid #ddd;
    border-radius: 4px;
    background-color: #fff;
    transition: background-color .5s;
}
.main .line div.s {
    background-color: #bbb;
    transition: background-color .5s;
}
.main .line div.f {
    background-color: green;
    transition: background-color 2s;
}

script

<script>
  (function(width, height, length, current, dx, dy, x, y, hasFood, newEl){     
    
document.body.onkeydown = function(e){
    dx = (e.keyCode - 38) % 2, dy = (e.keyCode - 39) % 2; // перемещение змейки по координатам при нажатии клавиш
};
    
var timer = setInterval(function () {
    x = (x + dx) < 0 ? width - 1 : (x + dx) % width; 
    y = (y + dy) < 0 ? height - 1 : (y + dy) % height;
    newEl = document.getElementsByClassName(y + '_' + x)[0]
    if(newEl.className.indexOf('s') > 0) {
    	clearInterval(timer), alert('Game Over! Score: ' + length) // завершении игры при попадении в часть змейки
    };
    if(newEl.className.indexOf('f') > 0) {
    	newEl.className = newEl.className.replace(' f', ''), length++, hasFood = false;
    }
    newEl.className += ' s', newEl.setAttribute('data-n', current++); // увеличении змейки при съедании бонуса

    for(var i = 0, min = Infinity, item, items = document.getElementsByClassName('s'), len = items.length; i < len && len > length; i++)
    	if(+items[i].getAttribute('data-n') < min)
    		min = +items[i].getAttribute('data-n'), item = items[i];

    if(!!item) item.className = item.className.replace(' s', '');

    for(var fItem, fX, fY; !hasFood; fX = Math.round(Math.random() * 10 % width), fY = Math.round(Math.random() * 10 % height)) // появление бонуса
    	if(!!fX && !!fY && document.getElementsByClassName(fY + '_' + fX)[0].className.indexOf('s') < 0)
    		hasFood = true, document.getElementsByClassName(fY + '_' + fX)[0].className += ' f';
}, 500); // скорость движения змейки

})(10, 10, 5, 1, 1, 0, 0, 0, false, null);
    </script>