Tic-tac-toe game. How to move between cells using arrows?

  • 0
    How to navigate in the game Tic Tac Toe using the arrow keyboard? Now the game is implemented by mouse click.
    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);
    });
    JavaScript Anonymous, May 26, 2020

  • 0 Answers
Your Answer
To place the code, please use CodePen or similar tool. Thanks you!