forked from trpomoais2017/snake
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
127 lines (106 loc) · 4.33 KB
/
Copy pathscript.js
File metadata and controls
127 lines (106 loc) · 4.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/* Задание
*
* 1. Добавить управление
* 2. Каждая из сторон при пресечении должна перемещать на противоположенную
* 3. Добавить рандомное появление еды (подсказка: надо навешивать на ячейки класс food)
* 4. Размер змейки должен увеличиваться
* 5*. Научиться увеличивать сокрость игры при увеличении количества очков
* 6**. Придумать новую фичу и реализовать
*
*/
var snakeGame = (function () {
//Константы оформляются в особом стиле
const WIDTH = 10;
const HEIGHT = 10;
let headX = 0;
let headY = 0;
let dx = 1;
let dy = 0;
let currentStep = 1;
let foodCounter = 0;
let playStep = (direction) => {
dx = (direction - 38) % 2;
dy = (direction - 39) % 2;
headX = (WIDTH - 1) * (WIDTH - (headX + dx)) % WIDTH;
headY = (HEIGHT - 1) * (HEIGHT - (headY + dy)) % HEIGHT;
let newHeadCell = getCell(headX, headY);
let newFoodCell = getCell(Math.ceil(Math.random() * WIDTH), Math.ceil(Math.random() * HEIGHT));
removeSnakeCells();
addSnakeToCell(newHeadCell);
removeFoodCells();
addFoodToCell(newFoodCell);
setCellStep(newHeadCell, currentStep);
currentStep++;
return true;
}
let removeFoodCells = () => {
for (let foodCell of document.getElementsByClassName('food snake')) {
removeFoodFromCell(foodCell);
foodCounter--;
}
}
let getCellClass = (cell) => {
return cell.className;
}
let removeFoodFromCell = cell => {
cell.className = cell.className.replace('food', '');
}
let getFoodCells = () => {
// Можно находить элементы DOM по классу
return document.getElementsByClassName('food');
}
let addFoodToCell = cell => {
if (foodCounter == 0 && cell.className == '') {
cell.className += ' food';
foodCounter++;
}
}
let removeSnakeCells = () => {
for (let snakeCell of getSnakeCells())
removeSnakeFromCell(snakeCell);
}
let getCell = (x, y) => {
// Можно находить элементы DOM по id
return document.getElementById(y + '_' + x);
}
let getSnakeCells = () => {
// Можно находить элементы DOM по классу
return document.getElementsByClassName('snake');
}
let addSnakeToCell = cell => {
// Строчка className может включать несколько классов, например "class1 class2".
// Поэтому добавляем пробел.
cell.className += ' snake';
}
let removeSnakeFromCell = cell => {
cell.className = cell.className.replace('snake', '');
}
let setCellStep = (cell, step) => {
// Есть соглашение, что пользовательские атрибуты называются с префикса "data-".
cell.setAttribute('data-step', step);
}
let getCellStep = cell => {
// Явное преобразование строки к числу через объект-обертку.
return new Number(cell.getAttribute('data-step'));
}
// Только этот объект будет доступен извне.
return {
getScore: 0,
playStep: playStep
}
})(); // Используем IIFE (Immediately Invoked Function Expression) для изоляции.
// Главный цикл игры.
let timer = setInterval(function () {
if (!snakeGame.playStep(direction)) {
// Игра закончена - останавливаем цикл.
clearInterval(timer);
alert('Game Over! Score: ' + snakeGame.getScore());
}
}, 500);
var direction = 39;
// Обработка действий пользователя.
document.onkeydown = e => {
if (e.keyCode < 41 && e.keyCode > 36) {
direction = e.keyCode;
}
}