Pac-man Game with Vanilla JS, HTML, CSS(Christmas Theme)๐ŸŽ…๐Ÿป๐ŸŽ„๐ŸŽ

emilysconeยท2021๋…„ 1์›” 9์ผ
4

SideProject

๋ชฉ๋ก ๋ณด๊ธฐ
2/2
post-thumbnail

ํ‚ค๋ณด๋“œ๋กœ ํ”Œ๋ ˆ์ด, ๋ฌผ๋ก  ๋ชจ๋ฐ”์ผ๋กœ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

Vanilla Javascript, CSS, HTML ์„ ์‚ฌ์šฉํ•ด์„œ ๋งŒ๋“  ํŒฉ๋งจ.
ํฌ๋ฆฌ์Šค๋งˆ์Šค๊ฐ€ ๋‹ค๊ฐ€์˜ฌ๋•Œ์ฏค ๋งŒ๋“ค์–ด์„œ ํŒฉ๋งจ ๋กœ๊ณ ์— ํฌ๋ฆฌ์Šค๋งˆ์Šค ๋ชจ์ž๋ฅผ ์”Œ์˜€๊ณ 
๋กœ๊ณ ๋ฅผ ๋ˆ„๋ฅด๋ฉด ์Œ์•…์žฌ์ƒ, arrow key๋กœ ํ”Œ๋ ˆ์ด, ๊ฒŒ์ž„์‹œ์ž‘ ๋ฒ„ํŠผ, ๊ฒŒ์ž„, ์ตœ๊ณ ๊ธฐ๋ก, ๊ฒŒ์ž„์˜ค๋ฒ„, ์„ฑ๊ณต, ๋จน์ด ๋จน์œผ๋ฉด ๋ฌด์ ์œผ๋กœ ๋ณ€ํ•˜๋Š” ๊ฒƒ์„ ๊ตฌํ˜„ํ–ˆ๋‹ค.

๐Ÿ‘ฉโ€๐Ÿ’ปCan you JavaScript it?

After 2 months of learning JS, CSS and HTML(before knowing the existance of REACT) I wanted to push myself to see if I can Javascript games. Here I present my most proud achievement of all :)

Breaking-down codes

์ฃผ์†Œ : https://emilyoun.github.io/pacman-christmas/
Github ๋ ˆํฌ : https://github.com/emilyoun/pacman-christmas

CLick logo to turn on || off music

์ด๊ฑฐ ํ•œ๋ฒˆ ๋งŒ๋“ค์–ด๋‘๊ณ  ์ด๊ณณ์ €๊ณณ ์ž˜ ์“ฐ๊ณ  ์žˆ๋‹ค css ๊ผญ ๋„ฃ์–ด์ค˜์•ผ ๊ท€์—ฌ์›€

HTML

 <audio id="audio" style="display:none;" src="Fun Christmas - AShamaluevMusic.mp3" controls autoplay loop onloadeddata="setHalfVolume()">

JavaScript

let on_off = document.querySelector(".musicOn");

on_off.onclick = function () {
	if (audio.paused) {
		audio.play();
	}
	else {
		audio.pause();
	}
}

CSS ๋กœ๊ณ  ๋ˆ„๋ฅด๋ฉด ๊ท€์—ฝ๊ฒŒ ๋“ค์–ด๊ฐ€๋Š” ํšจ๊ณผ

#logo{
	width: 700px;
}

#logo:active{
    transform: scale(1, 0.9);
    transition: transform 0.2s color 0.2s;
    }

Creating a map

**0 = ๋จน์ด, 1 = ๋ฒฝ, 2 = ๊ณ ์ŠคํŠธ ๋ถ€ํ™œ ์žฅ์†Œ, 3 = ๋ถ€์ŠคํŠธ, 4 = ๋นˆ๊ณต๊ฐ„ **์„ ์žก๊ณ  array ํ•˜๋‚˜ ๋งŒ๋“ค์–ด์„œ(layout) ํ•˜๋‚˜ํ•˜๋‚˜ ๊ทธ๋ ค์ค€๋‹ค

document.getElementById("play").addEventListener("click", function game() {
	const scoreDisplay = document.getElementById("score");
	const width = 28; // 28*28 = 784 squares
	const grid = document.querySelector(".grid")
	const layout = [
		1,1,1,1,1,1,1,1,4,4,1,1,1,4,4,1,1,1,1,1,1,1,1,1,1,1,1,1,
		1,0,0,0,0,0,0,1,4,4,1,3,1,4,4,1,0,0,0,0,0,0,0,0,0,0,3,1,
		1,0,1,1,1,1,0,1,1,1,1,0,1,4,4,1,1,1,1,0,1,0,1,1,1,0,1,1,
		1,3,1,4,4,1,0,0,0,0,0,0,1,4,4,4,4,4,1,0,0,0,1,4,1,0,1,4,
		1,0,1,4,4,1,0,1,1,0,1,0,1,4,4,4,4,4,1,0,1,0,1,4,1,0,1,4,
		1,0,1,1,1,1,0,0,0,0,1,0,1,1,1,1,1,1,1,0,1,0,1,1,1,0,1,1,
		1,0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,
		1,0,1,1,1,1,0,3,1,0,1,1,1,0,1,0,1,1,1,0,1,0,1,1,1,1,0,1,
		1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,1,
		1,1,1,1,1,1,0,1,0,1,0,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,
		4,4,4,4,4,1,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,1,4,4,4,4,4,
		4,4,4,4,4,1,0,0,0,0,0,1,1,4,4,1,1,0,0,0,0,0,1,4,4,4,4,4,
		1,1,1,1,1,1,0,1,1,1,0,1,2,2,2,2,1,0,1,1,1,0,1,1,1,1,1,1,
		4,0,0,0,0,0,0,1,4,1,0,2,2,2,2,2,2,0,1,4,1,0,0,0,0,0,0,4,
		1,1,1,1,1,1,0,1,1,1,0,1,2,2,2,2,1,0,1,1,1,0,1,1,1,1,1,1,
		4,4,4,4,4,1,0,0,0,0,0,1,1,4,4,1,1,0,0,0,0,0,1,4,4,4,4,4,
		4,4,4,4,4,1,0,1,1,1,0,0,0,0,0,0,0,0,1,0,1,0,1,4,4,4,4,4,
		1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,0,1,3,1,0,1,1,1,1,1,1,
		1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,3,1,
		1,0,1,1,1,1,0,3,1,0,0,1,1,1,1,1,1,0,0,0,0,0,1,0,1,1,1,1,
		1,0,0,0,0,0,0,0,0,0,1,1,4,4,4,4,1,1,0,1,1,0,1,0,1,4,4,4,
		1,1,1,0,1,1,1,1,1,0,1,4,4,4,4,4,4,1,0,0,0,0,1,0,1,4,4,4,
		4,4,1,0,1,4,4,4,1,0,1,4,4,4,4,4,4,1,0,1,1,1,1,0,1,1,1,1,
		1,1,1,0,1,1,1,1,1,0,1,1,1,4,4,1,1,1,0,0,0,0,0,0,0,0,0,1,
		1,0,0,0,0,0,0,0,0,0,0,0,1,4,4,1,0,0,0,1,1,1,1,0,1,1,0,1,
		1,3,1,1,1,1,1,1,1,1,1,0,1,4,4,1,0,1,0,1,4,4,1,0,1,3,0,1,
		1,0,0,0,0,0,0,0,0,0,0,0,1,4,4,1,0,0,0,1,4,4,1,0,0,0,0,1,
		1,1,1,1,1,1,1,1,1,1,1,1,1,4,4,1,1,1,1,1,4,4,1,1,1,1,1,1]; 
	const squares = [];

and traverse a for loop to place each element in the right place.

// Draw the grid
	function createBoard() {
		for (let i = 0; i < layout.length ; i++){
			const square = document.createElement("div");
			grid.appendChild(square);
			squares.push(square);

		// Add layout to the board
			if (layout[i] === 0) {
				squares[i].classList.add("pac-dot");
			} else if (layout[i] === 1) {
				squares[i].classList.add("wall");
			} else if (layout[i] === 2) {
				squares[i].classList.add("ghost-lair");
			} else if (layout[i] === 3) {
				squares[i].classList.add("power-pellet");
			} else if (layout[i] === 4) {
				squares[i].classList.add("empty");
			}
		}
	}
	createBoard();

Best Score

function bestScoreCount () {
		let higher;
		let bestScore = window.localStorage.getItem(higher);
		window.localStorage.setItem(bestScore, higher);
		const bestScoreDisplay = document.getElementById("bestScore");
		if (bestScore == null) {
			bestScore = score;
			window.localStorage.setItem(higher, bestScore);
		} else if (score < Number(window.localStorage.getItem(higher))) {
			bestScore = score;	
		} else if (score > Number(window.localStorage.getItem(higher))) {
			window.localStorage.clear();
			bestScore = score;
			window.localStorage.setItem(higher, bestScore);
		}
		bestScoreDisplay.innerHTML = window.localStorage.getItem(higher);
	}
	bestScoreCount();

Starting position of Pac man

	let pacmanCurrentIndex = 518;
	squares[pacmanCurrentIndex].classList.add("pac-man");

move pac man

	function movePacman (e) {
		squares[pacmanCurrentIndex].classList.remove("pac-man");
		switch(e.keyCode){
			case 37:
				if (pacmanCurrentIndex % width !== 0 && !squares[pacmanCurrentIndex -1].classList.contains("wall") && !squares[pacmanCurrentIndex -1].classList.contains("ghost-lair")) {
					pacmanCurrentIndex -=1;
					squares[pacmanCurrentIndex].style.transform = "scaleX(-1) rotate(95deg)";
					// If Pac-Man is on the left exit
					if (pacmanCurrentIndex - 1 === 363) {
						pacmanCurrentIndex = 391;
				}}
				break;
			case 38:
				if (pacmanCurrentIndex - width >= 0 && !squares[pacmanCurrentIndex - width].classList.contains("wall") && !squares[pacmanCurrentIndex - width].classList.contains("ghost-lair")) { pacmanCurrentIndex -= width;
					squares[pacmanCurrentIndex].style.transform = "scaleY(1)";
				}
				break;
			case 39:
				if (pacmanCurrentIndex % width < width - 1 && !squares[pacmanCurrentIndex +1].classList.contains("wall") && !squares[pacmanCurrentIndex +1].classList.contains("ghost-lair")){ pacmanCurrentIndex += 1;
					squares[pacmanCurrentIndex].style.transform = "scaleY(1) rotate(95deg)";
					// If Pac-Man is on the right exit
					if(pacmanCurrentIndex + 1 === 392) {
						pacmanCurrentIndex = 364;
				}}
				break;
			case 40:
				if (pacmanCurrentIndex + width < width * width && !squares[pacmanCurrentIndex + width].classList.contains("wall") && !squares[pacmanCurrentIndex + width].classList.contains("ghost-lair")) {
					pacmanCurrentIndex += width;
					squares[pacmanCurrentIndex].style.transform = "rotate(190deg)";
				}
				break;
		}

		squares[pacmanCurrentIndex].classList.add("pac-man");

		pacDotEaten();
		powerPelletEaten();
		checkForGameOver();
		checkForWin();
	}

	document.addEventListener("keydown", movePacman);

Move on mobile phone

e.touches ๋ฅผ ์ฃผ์—ˆ๋Š”๋ฐ ์ž์„ธํ•œ๊ฑด ๊นƒํ—™ ๋ ˆํฌ์— app.js์—์„œ ํ™•์ธ ๊ฐ€๋Šฅํ•˜๋‹ค.

์ €๋…์— ์‹œ์ž‘ํ•ด์„œ ์ž๊ธฐ์ „์— ๋๋‚ด๋ ค ํ–ˆ๋Š”๋ฐ ์š•์‹ฌ์ด ์ƒ๊ฒจ์„œ ์˜คํ›„ 8์‹œ์ฏค ์‹œ์ž‘ํ•ด์„œ ์ƒˆ๋ฒฝ 4์‹œ์ฏค ๋๋‚ฌ๋‹ค. ๋Œ€๋žต 8์‹œ๊ฐ„์ •๋„ ๊ฑธ๋ ธ์ง€๋งŒ ๊ฒฐ๊ณผ๋ฌผ์ด ๋งˆ์Œ์— ๋“ค์—ˆ๋˜ ํ”„๋กœ์ ํŠธ. ํ• ๋•Œ๋งˆ๋‹ค ๋ฟŒ๋“ฏํ•ด์„œ ์•„์ง๋„ ๊ฐ€๋” ํ”Œ๋ ˆ์ดํ•œ๋‹ค ๐Ÿ˜Š
์ด๋ ‡๊ฒŒ ํด๋”์•ˆ์— ์ž ์ž๊ณ ์žˆ๋Š” Side Project๋“ค์ด ๋งŽ์€๋ฐ(blogging materials) ์ฐจ๊ทผ์ฐจ๊ทผ ์—…๋ฐ์ดํŠธ ํ•  ์˜ˆ์ •.

profile
Hello world

4๊ฐœ์˜ ๋Œ“๊ธ€

comment-user-thumbnail
2021๋…„ 1์›” 11์ผ

๋Œ€ํ•™๊ต์—์„œ ๊ณผ์ œ๋กœ JS๋กœ ํŒฉ๋งจ ๋งŒ๋“ค์—ˆ๋˜ ๊ฒฝํ—˜์ด ์žˆ๋Š”๋ฐ.. ์ถ”์–ต์ด๋„ค์š”.
์ €๋Š” ๊ทธ๋•Œ Canvas๋ฅผ ์‚ฌ์šฉํ–ˆ์—ˆ์–ด์š”.

๊ทธ๋•Œ ์ž‘์„ฑํ–ˆ๋˜ ์ฝ”๋“œ, ๋‹ค์‹œ ํ•œ๋ฒˆ ๋ณด๊ณ  ์‹ถ์€๋ฐ ์ฐพ์„์ˆ˜๊ฐ€ ์—†๊ตฐ์š” ใ…  ๊ทธ๋•Œ๋Š” GitHub์„ ์“ธ ์ค„ ๋ชฐ๋ž์–ด์„œ ใ…‹ใ…‹ใ…‹ ์•„์‰ฌ์›Œ์š”.

์ฐธ, ๋งํฌ๊ฐ€ ์ž˜๋ชป ๋‹ฌ๋ ธ์–ด์š”~

1๊ฐœ์˜ ๋‹ต๊ธ€
comment-user-thumbnail
2021๋…„ 1์›” 11์ผ

์™€...! ์—„์ฒญ ๊ณ ํ€„๋ฆฌํ‹ฐ๋„ค์š”!ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹

์ž˜ ์ฝ์—ˆ์Šต๋‹ˆ๋‹ค๐Ÿ˜Š

๋‹ต๊ธ€ ๋‹ฌ๊ธฐ
comment-user-thumbnail
4์ผ ์ „

Wow!!! ๋ฉ‹์ ธ์š” ํ•œ๋ฒˆ ์ €๋„ ๋„์ „ํ•ด ๋ณด๊ณ  ์‹ถ๋„ค์š” ใ…Žใ…Ž

๋‹ต๊ธ€ ๋‹ฌ๊ธฐ