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

Emily SconeΒ·2021λ…„ 1μ›” 9일
7

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

8개의 λŒ“κΈ€

comment-user-thumbnail
2021λ…„ 1μ›” 11일

λŒ€ν•™κ΅μ—μ„œ 과제둜 JS둜 팩맨 λ§Œλ“€μ—ˆλ˜ κ²½ν—˜μ΄ μžˆλŠ”λ°.. μΆ”μ–΅μ΄λ„€μš”.
μ €λŠ” κ·Έλ•Œ Canvasλ₯Ό μ‚¬μš©ν–ˆμ—ˆμ–΄μš”.

κ·Έλ•Œ μž‘μ„±ν–ˆλ˜ μ½”λ“œ, λ‹€μ‹œ ν•œλ²ˆ 보고 싢은데 μ°Ύμ„μˆ˜κ°€ μ—†κ΅°μš” γ…  κ·Έλ•ŒλŠ” GitHub을 μ“Έ 쀄 λͺ°λžμ–΄μ„œ γ…‹γ…‹γ…‹ μ•„μ‰¬μ›Œμš”.

μ°Έ, 링크가 잘λͺ» λ‹¬λ Έμ–΄μš”~

1개의 λ‹΅κΈ€
comment-user-thumbnail
2021λ…„ 1μ›” 11일

와...! μ—„μ²­ κ³ ν€„λ¦¬ν‹°λ„€μš”!γ…‹γ…‹γ…‹γ…‹γ…‹

잘 μ½μ—ˆμŠ΅λ‹ˆλ‹€πŸ˜Š

λ‹΅κΈ€ 달기
comment-user-thumbnail
2024λ…„ 5μ›” 22일

Keep up the great work, and continue exploring JavaScript game development! If you have specific questions or need further assistance with any part of your code, slope feel free to ask.

λ‹΅κΈ€ 달기
comment-user-thumbnail
2025λ…„ 2μ›” 13일

겉보기에 ν‰λ²”ν•œ 주제λ₯Ό 가져와 μ‹ μ„ ν•˜κ³  ν₯λ―Έμ§„μ§„ν•œ 관점을 가져와 λ§€λ ₯적으둜 λ§Œλ“­λ‹ˆλ‹€. 정보λ₯Ό μœ μ΅ν•˜κ³  즐겁게 읽을 수 μžˆλŠ” κ²ƒμœΌλ‘œ λ°”κΎΈλŠ” λŠ₯λ ₯은 μ§„μ •ν•œ κΈ°μˆ μž…λ‹ˆλ‹€. ꡐ윑적일 뿐만 μ•„λ‹ˆλΌ 즐거움을 μ£ΌλŠ” μ½˜ν…μΈ λ₯Ό λ³΄λŠ” 것은 항상 μƒμΎŒν•©λ‹ˆλ‹€. https://littletotheleftgame.com

1개의 λ‹΅κΈ€
comment-user-thumbnail
2025λ…„ 3μ›” 25일

Keep up the great work, and continue exploring JavaScript game development! If you have specific questions or need further assistance with any part of your code https://repomod.com

λ‹΅κΈ€ 달기
comment-user-thumbnail
2025λ…„ 6μ›” 18일

μ–΄λ¨Έ! Vanilla JS둜 μ΄λ ‡κ²Œ κ·€μ—¬μš΄ 팩맨 κ²Œμž„μ„ λ§Œλ“€λ‹€λ‹ˆ λŒ€λ‹¨ν•΄μš”! 크리슀마슀 ν…Œλ§ˆλ„ λ„ˆλ¬΄ κΉœμ°ν•˜κ³ , BearClicker 같은 κ°„λ‹¨ν•œ κ²Œμž„λ„ μ’‹μ§€λ§Œ 이런 퀄리티 λ„˜μΉ˜λŠ” μž‘ν’ˆλ„ λ©‹μ§€λ„€μš”! λ‚˜λ„ bear clicker 같은 λ‚˜λ§Œμ˜ κ²Œμž„μ„ λ§Œλ“€μ–΄λ³΄κ³  μ‹Άμ–΄μ§€λ„€!

λ‹΅κΈ€ 달기