Здравствуйте. Нужен совет. Как сделать подобие ООП? На данный момент навоял следующее:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title></title>
<style>
html, body {
margin: 0;
padding: 0;
height: 100%;
}
body {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
table {
border: 1px solid #00bfff;
border-collapse: collapse;
}
td {
border: 1px solid #00bfff;
width: 10px;
height: 10px;
}
</style>
</head>
<body>
<script>
let snake = [];
const field = document.createElement('table');
let tr, td;
let timerID;
let direction = 'ArrowRight';
let prev;
let eaten;
let score = 0;
let generated;
let reverseDirections = {
'ArrowRight': 'ArrowLeft',
'ArrowLeft': 'ArrowRight',
'ArrowUp': 'ArrowDown',
'ArrowDown': 'ArrowUp'
};
let snakeInitWidth = 3;
let snakeInitHeight = 1;
let scoreElem = `<section id="score">Score: <span>0</span></section>`;
document.body.insertAdjacentHTML('afterbegin', scoreElem);
let fieldWidth = 41;
let fieldHeight = 21;
for (let i = 0; i < fieldHeight; i++) {
tr = document.createElement('tr');
for (let j = 0; j < fieldWidth; j++) {
td = document.createElement('td');
if (i == (fieldHeight - snakeInitHeight) / 2 && j >= (fieldWidth - snakeInitWidth) / 2 && j < (fieldWidth - snakeInitWidth) / 2 + snakeInitWidth) {
snake.unshift({x: j, y: i});
td.style.backgroundColor = '#00bfff'
}
tr.append(td);
}
field.append(tr);
}
document.body.append(field);
let fieldX = fieldWidth - 1;
let fieldY = fieldHeight - 1;
document.addEventListener('keydown', function(e) {
if (e.code == 'ArrowRight' || e.code == 'ArrowLeft' || e.code == 'ArrowUp' || e.code == 'ArrowDown') {
if (e.code != direction && direction != reverseDirections[e.code]) {
direction = e.code;
if (timerID) clearTimeout(timerID)
move(e.code);
}
}
});
function move(keyName) {
if (checkLoss()) {
clearTimeout(timerID);
blink();
return;
}
for (let i = 0; i < snake.length; i++) {
field.rows[snake[i].y].cells[snake[i].x].style.backgroundColor = '';
if (i == 0) {
prev = Object.assign({}, snake[i]);
if (keyName == 'ArrowUp') {
if (snake[i].y - 1 >= 0 && field.rows[snake[i].y - 1].cells[snake[i].x].style.backgroundColor == 'black' ||
snake[i].y - 1 < 0 && field.rows[fieldY].cells[snake[i].x].style.backgroundColor == 'black') {
eaten = true;
}
snake[i].y = (snake[i].y == 0) ? fieldY : snake[i].y - 1;
}
if (keyName == 'ArrowDown') {
if (snake[i].y + 1 <= fieldY && field.rows[snake[i].y + 1].cells[snake[i].x].style.backgroundColor == 'black' ||
snake[i].y + 1 > fieldY && field.rows[0].cells[snake[i].x].style.backgroundColor == 'black') {
eaten = true;
}
snake[i].y = (snake[i].y == fieldY) ? 0 : snake[i].y + 1;
}
if (keyName == 'ArrowRight') {
if (snake[i].x + 1 <= fieldX && field.rows[snake[i].y].cells[snake[i].x + 1].style.backgroundColor == 'black' ||
snake[i].x + 1 > fieldX && field.rows[snake[i].y].cells[0].style.backgroundColor == 'black') {
eaten = true;
}
snake[i].x = (snake[i].x == fieldX) ? 0 : snake[i].x + 1;
}
if (keyName == 'ArrowLeft') {
if (snake[i].x - 1 >= 0 && field.rows[snake[i].y].cells[snake[i].x - 1].style.backgroundColor == 'black' ||
snake[i].x - 1 < 0 && field.rows[snake[i].y].cells[fieldX].style.backgroundColor == 'black') {
eaten = true;
}
snake[i].x = (snake[i].x == 0) ? fieldX : snake[i].x - 1;
}
if (eaten) {
score += 10;
document.querySelector('#score > span').innerHTML = score;
let lastCell = Object.assign({}, prev);
snake.splice(1, 0, lastCell);
field.rows[prev.y].cells[prev.x].style.backgroundColor = '#00bfff';
eaten = false;
generateFood();
i = 0;
continue;
}
} else {
let temp = snake[i];
snake[i] = prev;
prev = temp;
}
field.rows[snake[i].y].cells[snake[i].x].style.backgroundColor = '#00bfff';
}
timerID = setTimeout(() => move(keyName), 100);
}
move('ArrowRight');
function checkLoss() {
for (let i = 1; i < snake.length; i++) {
if (snake[0].x == snake[i].x && snake[0].y == snake[i].y) return true;
}
return false;
}
function blink() {
debugger;
let count = 0;
function tick() {
if (count == 6)
return;
for (let i = 0; i < snake.length; i++) {
if (count % 2 == 0) {
field.rows[snake[i].y].cells[snake[i].x].style.backgroundColor = '';
} else {
field.rows[snake[i].y].cells[snake[i].x].style.backgroundColor = '#00bfff';
}
}
count++;
setTimeout(tick, 500);
}
tick();
}
function generateFood() {
let emptyCells = Array.from(field.querySelectorAll('td')).filter((td) => td.style.backgroundColor == '');
generated = Math.floor(Math.random() * emptyCells.length);
emptyCells[generated].style.backgroundColor = 'black';
}
generateFood();
</script>
</body>
</html>
Думаю сделать два класса - Field и Snake. Класс Field будет создавать поле для игры, генерировать еду и некоторые другие методы. Класс Snake будет отвечать за создание, движение змейки. Или здесь ООП вообще не уместно?