Qurel
@Qurel

Игра Крестики-нолики. Как перемещаться между ячейками с помощью стрелок?

Как в игре Крестики-нолики перемещаться с помощью клавиатуры стрелок? Сейчас игра реализована по клику мышки.
GitHubPages

spoiler
<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<link rel="stylesheet" href="style.css">
	<title>Tic Tac Toe</title>
</head>

<body>

	<div class="wrapper">
		<div id="game-menu-container">
			<div class="game-menu__background">
				<h2 class="game-menu__title">Press Enter to start the game</h2>
				<button id="on" class="game-menu__btn js-game-menu-btn">Start Game</button>
			</div>
		</div>

		<div class="result" id="result"></div>
		<div class="game" id="game">
			<div class="game__field js-game-field"></div>
			<div class="game__field js-game-field"></div>
			<div class="game__field js-game-field"></div>
			<div class="game__field js-game-field"></div>
			<div class="game__field js-game-field"></div>
			<div class="game__field js-game-field"></div>
			<div class="game__field js-game-field"></div>
			<div class="game__field js-game-field"></div>
			<div class="game__field js-game-field"></div>
		</div>
		<div class="game-menu__container">
			<button class="game-menu__btn scale" id="play-again">Play Again</button>
			<button class="game-menu__btn scale" id="exit-game">Exit Game</button>
		</div>
	</div>

	<script src="app.js"></script>
</body>

</html>

@import url("https://fonts.googleapis.com/css?family=Arbutus");
*,
*::before,
*::after {
	box-sizing: border-box;
}

body {
	padding: 0;
	margin: 0;
	font-family: Arbutus;
}

.wrapper {
	min-height: 100vh;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	background: url("img/bg.jpg") no-repeat center;
	background-size: cover;
	/* position: relative; */
}

/* *** Game menu *** */
#game-menu-container {
	position: fixed;
	display: table;
	height: 100%;
	width: 100%;
	top: 0;
	left: 0;
	transform: scale(1);
	z-index: 1;
}
#game-menu-container.on {
	transform: scale(1);
	animation: unfoldOut 1s 0.3s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
}
#game-menu-container.on.out {
	transform: scaleY(0.01) scaleX(0);
	animation: unfoldIn 1s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
}
#game-menu-container .game-menu__background {
	display: table-cell;
	background: rgba(0, 0, 0, 0.9);
	text-align: center;
	vertical-align: middle;
}

.game-menu__title {
	margin-bottom: 30px;
	font-weight: 400;
	font-size: 65px;
	line-height: 65px;
	color: #fff;
}

@keyframes unfoldIn {
	0% {
		transform: scaleY(0.005) scaleX(0);
	}
	50% {
		transform: scaleY(0.005) scaleX(1);
	}
	100% {
		transform: scaleY(1) scaleX(1);
	}
}
@keyframes unfoldOut {
	0% {
		transform: scaleY(1) scaleX(1);
	}
	50% {
		transform: scaleY(0.005) scaleX(1);
	}
	100% {
		transform: scaleY(0.005) scaleX(0);
	}
}

/* *** Game *** */
.game-menu {
	position: absolute;
	z-index: 1;
	left: 0;
	top: 0;
	width: 100%;
	height: 100%;
	display: flex;
	justify-content: center;
	align-items: center;
}

.game-menu__container {
	height: 64px;
}

.game-menu__btn {
	width: 162px;
	margin: 5px;
	cursor: pointer;
	border: none;
	padding: 15px;
	background-color: #ffffff;
	font-size: 20px;
	text-transform: uppercase;
	font-weight: 700;
	letter-spacing: 1px;
	border-radius: 2px;
}

.game-menu__btn.scale {
	transform: scale(0);
	transition: transform 0.3s;
}

.game-menu__btn.scale.active {
	transform: scale(1.1);
}

.game {
	margin: 30px 0;
	width: 360px;
	height: 360px;
	display: flex;
	flex-wrap: wrap;
	outline: 3px solid #000;
}

.game__field {
	width: 120px;
	height: 120px;
	border: 2px solid #000;
	background-color: #ffffff;
	cursor: pointer;
}

.game__field.active {
	background-color: rgba(0, 255, 0, 0.95);
}

.new-game {
	padding: 10px 16px;
	border: none;
	background-color: green;
	color: #ffffff;
	font-size: 20px;
	border-radius: 5px;
	cursor: pointer;
}

.zero,
.cross {
	width: 100%;
	height: 100%;
}

.zero {
	stroke-dasharray: 283;
	stroke-dashoffset: 283;
	animation: draw 0.5s forwards;
}

.cross__first,
.cross__last {
	stroke-dasharray: 121;
	stroke-dashoffset: 121;
	animation: draw 0.5s forwards;
}

.cross__last {
	animation-delay: 0.5s;
}

.result {
	height: 50px;
	color: lime;
	font-size: 55px;
}

@keyframes draw {
	100% {
		stroke-dashoffset: 0;
	}
}

//1.Написать игру крестики-нолики на чистом js +
//2.Управление через клавиатуру - стрелки для перемещения и Enter -
//3.Запуск приложения - появляется окно с кнопками Играть или Выйти
//4.Если нажато Играть - загружаем игру
//5.Заходим на страницу - игровое поле 3*3 человек с компьютером +
//6.Состояние игры: 1.Выигрыш, 2.Проигрыш, 3.Ничья +
//7.Выбор: сыграете еще или выйти
//8.При выборе "Сыграть еще" показывать видео-рекламу тестовую от гугл google ima sdk
//9.Разрешение 1280*720, не адаптировать, дизайн на свое усмотрение
//10.url на тестовое и архив с исходниками

// let zero = document.querySelector('circle');
// console.log(zero.getTotalLength());
document.addEventListener('DOMContentLoaded', () => {
	let
		startGameBtn = document.querySelector('.js-game-menu-btn'),
		game = document.querySelector('#game'),
		result = document.querySelector('#result'),
		playAgain = document.querySelector('#play-again'),
		exitGame = document.querySelector('#exit-game'),
		fields = Array.from(document.querySelectorAll(".js-game-field")),
		count = 0,
		zero = `<svg class="zero"><circle r="45" cx="58" cy="58" stroke="red" stroke-width="10" fill="none" stroke-linecap="round"/></svg>`,
		cross = `<svg class="cross"><line class="cross__first" x1="15" y1="15" x2="100" y2="100" stroke="blue" stroke-width="10" fill="none" stroke-linecap="round"/><line class="cross__last" x1="100" y1="15" x2="15" y2="100" stroke="blue" stroke-width="10" fill="none" stroke-linecap="round"/></svg>`;

	function startGame() {
		let buttonId = startGameBtn.getAttribute('id');
		let gameMenuContainer = document.querySelector('#game-menu-container');

		gameMenuContainer.removeAttribute('class');
		gameMenuContainer.classList.add(buttonId);
		document.body.classList.remove('modal-active');
	}

	function exit() {
		let gameMenuContainer = document.querySelector('#game-menu-container');

		gameMenuContainer.classList.add('out');
		document.body.classList.remove('modal-active');
	}

	function AIPlay() {
		let emptyFields = fields.filter(el => el.innerHTML === '');
		let random_index = Math.floor(Math.random() * emptyFields.length);

		setTimeout(() => {
			if (count !== 9) {
				emptyFields[random_index].innerHTML = zero;
				emptyFields[random_index].classList.add('o');
				let zeroAudio = new Audio('audio/zero.mp3');
				zeroAudio.play();
				count++;
			}
		}, 1000)

	};

	function stepCross(target) {
		target.innerHTML = cross;
		target.classList.add('x');
		let crossAudio = new Audio('audio/cross.mp3');
		crossAudio.play();
		count++;
	}

	function win() {
		let comb = [
			[0, 1, 2],
			[3, 4, 5],
			[6, 7, 8],
			[0, 3, 6],
			[1, 4, 7],
			[2, 5, 8],
			[0, 4, 8],
			[2, 4, 6]
		];

		for (let i = 0; i < comb.length; i++) {
			setTimeout(() => {
				if (fields[comb[i][0]].classList.contains('x') && fields[comb[i][1]].classList.contains('x') && fields[comb[i][2]].classList.contains('x')) {
					fields[comb[i][0]].classList.add('active');
					fields[comb[i][1]].classList.add('active');
					fields[comb[i][2]].classList.add('active');
					result.innerText = 'You won';
					game.removeEventListener('click', init);
				}
				else if (fields[comb[i][0]].classList.contains('o') && fields[comb[i][1]].classList.contains('o') && fields[comb[i][2]].classList.contains('o')) {
					fields[comb[i][0]].classList.add('active');
					fields[comb[i][1]].classList.add('active');
					fields[comb[i][2]].classList.add('active');
					result.innerText = 'You lose';
					game.removeEventListener('click', init);
				}
				else if (count == 9) {
					result.innerText = 'Noone is winner';
					game.removeEventListener('click', init);
				}
			}, 5000);
		}
	}

	function init(e) {
		stepCross(e.target);
		AIPlay();
		win();
	}

	function newGame() {
		count = 0;
		result.innerText = '';
		fields.forEach(el => {
			el.innerHTML = '';
			el.classList.remove('x', 'o', 'active');
		});
		game.addEventListener('click', init);
	}

	document.body.addEventListener('keydown', (e) => {
		if (e.key == "Enter") {
			startGame();
		}
	});
	startGameBtn.addEventListener('click', startGame);
	game.addEventListener('click', init);
	playAgain.addEventListener('click', newGame);
	exitGame.addEventListener('click', exit);
});
  • Вопрос задан
  • 132 просмотра
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
28 нояб. 2024, в 11:20
50000 руб./за проект
28 нояб. 2024, в 10:57
50000 руб./за проект
28 нояб. 2024, в 10:52
10000 руб./за проект