반응형
html 코드
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>UP & DOWN 게임</title>
<!-- reset.css -->
<!-- custom css -->
<link rel="stylesheet" href="./main.css">
<!-- custom js -->
<script src="./app.js" defer></script>
</head>
<body>
<div class="wrapper">
<section class="main">
<h1 class="main-title">신나는 UP & DOWN 게임~!</h1>
<article class="number-wrapper">
<h2>
<em id="begin">1</em>부터 <em id="end">100</em>사이의 숫자를 입력하세요.
</h2>
<div id="numbers"></div>
</article>
</section>
<aside class="result">
<div id="up">UP!</div>
<div id="down">DOWN!</div>
</aside>
<div id="finish">Congratulation!</div>
</div>
</body>
</html>
js 코드
//게임에 필요한 데이터 객체
const gameData = {
secret : Math.floor(Math.random()*100) + 1,
answer : null, //사용자가 클릭한 숫자
min : 1,
max : 100
};
//숫자 아이콘 생성 함수
function makeNumberIcons() {
//id=numbers 태그 안에다가 숫자 아이콘을 배치해 주세요.
//숫자 아이콘의 개수는 객체의 min, max에 따라 달라집니다.
//숫자 아이콘은 div태그이고 클래스 이름이 icon입니다.
//리턴값은 id=numbers 태그 요소입니다.
const $numbers = document.getElementById('numbers');
const $frag = document.createDocumentFragment();
for(let i=gameData.min; i<=gameData.max; i++) {
const $icon = document.createElement('div');
$icon.classList.add('icon');
$icon.textContent = i;
$frag.appendChild($icon);
}
$numbers.appendChild($frag);
return $numbers;
}
//아이콘 전체 삭제 함수 정의
function clearNumberIcons($numbers) {
for(let $icon of [...$numbers.children]) {
$numbers.removeChild($icon);
}
}
//up & down 애니메이션을 작동시킬 클래스 추가/제거 함수 정의
function executeUpDownAnimation(isUp) {
const ANI_CLASS_NAME = 'selected';
document.getElementById('up').classList.toggle(ANI_CLASS_NAME, isUp);
document.getElementById('down').classList.toggle(ANI_CLASS_NAME, !isUp);
}
//정답을 맞췄을 때 처리를 수행할 함수 정의
function processCorrect($target) {
//축하메세지 박스를 나타내게 하는 코드
const $finish = document.getElementById('finish');
$finish.classList.add('show');
//정답 아이콘을 움직이게 하는 코드
$target.setAttribute('id', 'move');
}
//정답을 판별해 주는 함수 정의
function checkAnswer($numbers, $target) {
//객체에서 정답과 사용자의 선택값 가져오기
const {secret, answer} = gameData;
console.log(secret);
const $begin = document.getElementById('begin');
const $end = document.getElementById('end');
//정답을 맞췄을 시 정답처리하는 함수를 호출 (processCorrect)
//up 또는 down일 경우에는 min과 max값을 변경하고
//executeUpDownAnimation 함수를 호출.
if(secret === answer) {
processCorrect($target);
return;
} else if(secret < answer) {
//down일 경우
gameData.max = answer - 1;
$end.textContent = answer;
executeUpDownAnimation(false);
} else {
//up인 경우
gameData.min = answer + 1;
$begin.textContent = answer;
executeUpDownAnimation(true);
}
//판별 후에는 아이콘을 재 배치.
clearNumberIcons($numbers); //현재 렌더링 되어 있는 아이콘들을 전체 삭제
makeNumberIcons(); //min, max는 변경되어 있고 다시 아이콘을 배치
}
//핵심 실행 로직 즉시 실행 함수 (main 비슷한 역할)
(function() {
const $numbers = makeNumberIcons();
//숫자 아이콘 클릭 이벤트 (부모 요소에 이벤트를 설정)
$numbers.addEventListener('click', e => {
if(!e.target.matches('#numbers > .icon')) {
return;
}
console.log(`${e.target.textContent} 클릭됨!`);
gameData.answer = +e.target.textContent;
//정답 체크 함수 호출
checkAnswer($numbers, e.target);
});
}());
css 코드
/* reset */
a {
color: inherit;
text-decoration: none;
}
/* layout */
.wrapper {
font-size: 18px;
background: #8c8c8c;
height: 100vh;
position: relative;
}
section.main {
width: 40%;
background: #f6f6f6;
border-radius: 10px;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.7);
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
overflow: hidden;
}
section.main .main-title {
padding: 30px 20px;
font-size: 30px;
font-weight: 700;
text-align: center;
background: #a3f8ff;
border-bottom: 1px solid #d3d3d3;
}
section.main .number-wrapper {
padding: 50px 20px;
}
section.main .number-wrapper h2 {
font-size: 22px;
text-align: center;
text-decoration: underline;
}
section.main .number-wrapper h2 em {
font-size: 1.2em;
font-weight: 700;
color: red;
}
#numbers {
width: 70%;
height: 400px;
border: 1px solid #000;
border-radius: 10px;
margin: 30px auto 0;
padding: 30px 50px;
overflow: auto;
}
#numbers .icon {
width: 100px;
height: 100px;
font-size: 32px;
font-weight: 700;
border-radius: 50%;
color: #fff;
text-align: center;
line-height: 100px;
margin-right: 15px;
margin-bottom: 10px;
display: inline-block;
cursor: pointer;
}
#numbers .icon:hover {
opacity: 0.7;
transform: scale(1.1);
}
#numbers .icon:nth-child(4n) {
background: orangered;
}
#numbers .icon:nth-child(4n-1) {
background: skyblue;
}
#numbers .icon:nth-child(4n-2) {
background: yellowgreen;
}
#numbers .icon:nth-child(4n-3) {
background: orange;
}
/* UP & DOWN 아이콘 */
.result {
position: absolute;
top: 50%;
right: 20%;
transform: translateY(-50%);
}
.result div[id] {
width: 150px;
height: 150px;
border-radius: 50%;
font-size: 30px;
font-weight: 700;
color: #fff;
text-align: center;
line-height: 150px;
margin-bottom: 30px;
}
#up {
background: red;
}
#down {
background: blue;
}
.result div.selected {
animation: jumping 0.1s infinite linear alternate;
}
@keyframes jumping {
0% {
transform: translateY(0);
}
50% {
transform: translateY(-10px);
}
100% {
transform: translateY(-20px);
}
}
/* finish 영역 */
#finish {
width: 60%;
height: 200px;
background: tomato;
font-size: 80px;
font-weight: 700;
border: 2px solid #000;
border-radius: 20px;
text-align: center;
line-height: 200px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
opacity: 0;
z-index: -10;
}
#finish.show {
animation: showUp 1s linear forwards;
}
@keyframes showUp {
0% {
opacity: 0;
z-index: -10;
top: -50%;
}
50% {
opacity: 0.5;
top: 0;
}
100% {
opacity: 1;
z-index: 10;
top: 50%;
}
}
/* 정답 아이콘에 id=move가 붙으면 해당 아이콘이 커지면서 움직이도록 */
#move {
position: absolute;
left: 50%;
top: 10%;
z-index: 10;
border: 4px dashed #000;
animation: move 2s linear forwards;
}
@keyframes move {
0% {
top: 0;
transform: translateX(0) scale(1);
}
100% {
top: 10%;
transform: translateX(-50%) scale(2);
}
}
완성된 사이트
※ 모든 코드는 중x정보x리학원 이x민 강사님의 코드를 활용하여 제작하였음을 알려드립니다.
반응형
'Web 개발' 카테고리의 다른 글
맥북에어 M1칩셋 후기 겸 M1칩셋으로 웹 개발 환경(이클립스 스프링 등) (0) | 2022.01.31 |
---|---|
(HTML,CSS,JS) 자바스크립트 TODOlist만들기 (0) | 2022.01.19 |
(Web) 드디어 첫 사이트 완성하다. (HTML, CSS) (0) | 2022.01.11 |
HTML 방문자 카운팅 커터 카운터 (0) | 2022.01.10 |
파일질라로 내 포트폴리오 사이트 올리기 (HTML, CSS) (0) | 2022.01.09 |