Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 21.04.2022, 21:37
Интересующийся
Отправить личное сообщение для borzik2h Посмотреть профиль Найти все сообщения от borzik2h
 
Регистрация: 12.03.2022
Сообщений: 15

Змейка. Говно-код
Здравствуйте. Нужен совет. Как сделать подобие ООП? На данный момент навоял следующее:
<!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 будет отвечать за создание, движение змейки. Или здесь ООП вообще не уместно?
Ответить с цитированием
  #2 (permalink)  
Старый 22.04.2022, 07:53
Аватар для micscr
Профессор
Отправить личное сообщение для micscr Посмотреть профиль Найти все сообщения от micscr
 
Регистрация: 10.09.2009
Сообщений: 1,576

ООП уместно - это о связности кода, потому что у вас сейчас перемешано все.

Вот можете посмотреть мою реализацию.

Как минимум, чтобы отделить бизнес логику игры и работу с "представлением" - html, события
Ответить с цитированием
  #3 (permalink)  
Старый 22.04.2022, 19:21
Интересующийся
Отправить личное сообщение для borzik2h Посмотреть профиль Найти все сообщения от borzik2h
 
Регистрация: 12.03.2022
Сообщений: 15

micscr,
спасибо за ответ. Ознакомлюсь с вашей реализацией.
Ответить с цитированием
  #4 (permalink)  
Старый 23.04.2022, 12:08
Профессор
Отправить личное сообщение для Rise Посмотреть профиль Найти все сообщения от Rise
 
Регистрация: 07.11.2013
Сообщений: 4,672

Сообщение от borzik2h
Как сделать подобие ООП?
Напиши правила игры. В них найди существительные. Это будут классы.
Ответить с цитированием
  #5 (permalink)  
Старый 23.04.2022, 21:25
Интересующийся
Отправить личное сообщение для borzik2h Посмотреть профиль Найти все сообщения от borzik2h
 
Регистрация: 12.03.2022
Сообщений: 15

Rise,
спасибо, интересный подход.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Сортировка массива с объектами на javascript sergiu920 Элементы интерфейса 2 07.12.2018 09:47
как получить исходный код страницы после ajax lerneree AJAX и COMET 4 28.05.2018 13:53
Как найти и заменить код скрипта на странице на другой код? smls Общие вопросы Javascript 2 18.07.2016 22:01
"Оживите" код с хабра - https://habrahabr.ru/sandbox/51453/ Daniil2206 Node.JS 0 11.05.2016 18:09
Требуется выводить код рекламного блока Adsense из файла JavaScript??? speedflow Элементы интерфейса 0 26.05.2012 15:50