diff --git a/index.html b/index.html
index e198b29..0bfb650 100644
--- a/index.html
+++ b/index.html
@@ -21,6 +21,9 @@
diff --git a/script.js b/script.js
index 7df65f1..2da34b6 100644
--- a/script.js
+++ b/script.js
@@ -1,19 +1,23 @@
/* Задание
*
- * 1. Добавить управление
- * 2. Каждая из сторон при пресечении должна перемещать на противоположенную
- * 3. Добавить рандомное появление еды (подсказка: надо навешивать на ячейки класс food)
- * 4. Размер змейки должен увеличиваться
- * 5*. Научиться увеличивать сокрость игры при увеличении количества очков
+ * 1. Добавить управление +
+ * 2. Каждая из сторон при пресечении должна перемещать на противоположенную +
+ * 3. Добавить рандомное появление еды (подсказка: надо навешивать на ячейки класс food) +
+ * 3,5. Добавить поедание змейкой еды. +
+ * 4. Размер змейки должен увеличиваться
+ * 5*. Научиться увеличивать сокрость игры при увеличении количества очков
* 6**. Придумать новую фичу и реализовать
*
*/
-var snakeGame = (function () {
+var snakeGame = (function() {
//Константы оформляются в особом стиле
const WIDTH = 10;
const HEIGHT = 10;
+ let isFoodEaten = true;
+ let scores = 0;
+
let headX = 0;
let headY = 0;
let dx = 1;
@@ -23,19 +27,61 @@ var snakeGame = (function () {
let playStep = () => {
headX += dx;
headY += dy;
+ checkCoords(headX, headY);
let newHeadCell = getCell(headX, headY);
- removeSnakeCells();
- addSnakeToCell(newHeadCell);
+ removeSnakeCells();
+
+ checkForFood(newHeadCell);
+ addObjToCell(newHeadCell, " snake");
setCellStep(newHeadCell, currentStep);
+ if (isFoodEaten) {
+ refreshScore(scores);
+ spawnFood();
+ isFoodEaten = false;
+ }
+
currentStep++;
return true;
}
+ let getScore = () => {
+ return scores;
+ }
+
+ let checkForFood = headCell => {
+ if (isFood(headCell)) {
+ removeObjFromCell(headCell, "food");
+ isFoodEaten = true;
+ scores++;
+ }
+ }
+
+ //При пересечении стороны перемещает на противоположную
+ let checkCoords = (hX, hY) => {
+ if (hX >= WIDTH) {
+ headX = 0;
+ }
+ if (hX < 0) {
+ headX = WIDTH - 1;
+ }
+ if (hY >= HEIGHT) {
+ headY = 0;
+ }
+ if (hY < 0) {
+ headY = HEIGHT - 1;
+ }
+ }
+
let removeSnakeCells = () => {
for (let snakeCell of getSnakeCells())
- removeSnakeFromCell(snakeCell);
+ removeObjFromCell(snakeCell, "snake");
+ }
+
+ let isFood = cell => {
+ //indexOf возвращает -1, если входжений строки нет
+ return cell.className.indexOf("food") != -1;
}
let getCell = (x, y) => {
@@ -48,14 +94,14 @@ var snakeGame = (function () {
return document.getElementsByClassName('snake');
}
- let addSnakeToCell = cell => {
+ let addObjToCell = (cell, obj) => {
// Строчка className может включать несколько классов, например "class1 class2".
// Поэтому добавляем пробел.
- cell.className += ' snake';
+ cell.className += ' ' + obj;
}
- let removeSnakeFromCell = cell => {
- cell.className = cell.className.replace('snake', '');
+ let removeObjFromCell = (cell, obj) => {
+ cell.className = cell.className.replace(obj, '');
}
let setCellStep = (cell, step) => {
@@ -63,32 +109,70 @@ var snakeGame = (function () {
cell.setAttribute('data-step', step);
}
- let getCellStep = cell => {
+ let getCellStep = cell => {
// Явное преобразование строки к числу через объект-обертку.
return new Number(cell.getAttribute('data-step'));
}
+ let setDirection = (x, y) => {
+ //Меняет направление, если аргументами не передается противоположное текущему
+ dx = (x == -dx) ? dx : x;
+ dy = (y == -dy) ? dy : y;
+ }
+
+ let getRandomNumber = (min, max) => {
+ return Math.random() * (max - min) + min;
+ }
+
+ let spawnFood = () => {
+ let x = Math.round(getRandomNumber(0, WIDTH - 1));
+ let y = Math.round(getRandomNumber(0, HEIGHT - 1));
+
+ let foodCell = getCell(x, y);
+ addObjToCell(foodCell, " food");
+ }
+
// Только этот объект будет доступен извне.
return {
- getScore: 0,
- playStep: playStep
+ getScore: getScore,
+ playStep: playStep,
+ setDirection: setDirection
}
})(); // Используем IIFE (Immediately Invoked Function Expression) для изоляции.
// Главный цикл игры.
-let timer = setInterval(function () {
- if (!snakeGame.playStep())
- {
+let timer = setInterval(function() {
+ if (!snakeGame.playStep()) {
// Игра закончена - останавливаем цикл.
clearInterval(timer);
alert('Game Over! Score: ' + snakeGame.getScore());
}
-}, 500);
+}, 300);
+
+
+let refreshScore = scores => {
+ let scoreDiv = document.getElementById('scores');
+ scoreDiv.innerHTML = scores;
+}
// Обработка действий пользователя.
document.onkeydown = e => {
- switch (e.keyCode)
- {
- // http://keycode.info/
+ switch (e.keyCode) {
+ //w
+ case (87):
+ snakeGame.setDirection(0, -1);
+ break;
+ //a
+ case (65):
+ snakeGame.setDirection(-1, 0);
+ break;
+ //s
+ case (83):
+ snakeGame.setDirection(0, 1);
+ break;
+ //d
+ case (68):
+ snakeGame.setDirection(1, 0);
+ break;
}
}
\ No newline at end of file
diff --git a/style.css b/style.css
index 2239811..019e423 100644
--- a/style.css
+++ b/style.css
@@ -18,6 +18,20 @@
transition: background-color .5s;
}
+.main div.scores {
+ width: 40px;
+ height: 20px;
+ float: left;
+ margin: 1px;
+ border: 1px solid green;
+ border-radius: 4px;
+ background-color: #fff;
+ text-align: right;
+ color: #666;
+ font-family: sans-serif;
+ font-weight: bold;
+}
+
.main .line div.food {
background-color: green;
transition: background-color 2s;