본문 바로가기

Web Development/Front-end

[Zerocho-13] 2048 (MouseEvent, Switch)

오늘은 그 이름도 유명한 2048게임입니다.

 

2048게임은 

《2048》은 이탈리아의 웹 개발자 Gabriele Cirulli이 개발한 싱글 플레이어 슬라이딩 블록 퍼즐 게임이다.

 《2048》은 본래 자바스크립트 CSS로 작성되었으며 2014년 3월 9일 MIT 라이선스에 속하는 자유-오픈 소스 소프트웨어로 출시되었다.

(위키백과)

에 이렇게 소개되어있네요 ㅎ_ㅎ

 

아무튼, 원래 2048게임은 보통 키보드 상하,좌우 버튼으로 구현하는게 보통입니다.

근데 강의에서는 마우스 이벤트 수업느낌으로 해서 마우스 드레그한 것을 상,하,좌,우로 구분지어 구현하더라구요.

그래서 !

오늘은 마우스이벤트에 대해 알아보겠습니다.

 

1. Mouse Event

마우스이벤트는 , 마우스의 클릭(누를때), 마우스의 클릭(뗄떼), 마우스의 움직임을 감지하는 것 등 세가지가 있습니다.

게임에서는,

마우스의 누르는 시점의 좌표와 마우스의 클릭을 뗄때의 좌표를 비교해서 계산해 상,하,좌,우 드래그 판단을 했습니다.

 

우선 마우스의 움직임을 감지하는 'mousemove'에 대해 살펴보겠습니다.

window.addEventListener('mousemove', function(event){
	console.log(event);
}

브라우저 자체에서 동작해야하므로, 대상은 window로 주고,

이렇게 이벤트리스너에, mosemove 값을 줌으로써, 동작합니다.

그리고 console.log로 event 를 출력해보면, 마우스가 조금이라도 움직일 때마다, 콘솔이 찍히는 것을 확인할 수 있습니다.

 

 

다음은, 마우스를 클릭하는 순간(누를때) 동작하는 'mousedown'입니다.

window.addEventListener('mousemove', function(event){
	console.log(event);
}

마우스를 클릭하는 순간 동작하며, 로직은 mousemove와 동일하게 적용됩니다.

마우스를 한번 클릭해보시면 그 순간의 좌표들이 출력되는 것을 확인할 수 있습니다.

 

 

다음은, 마우스에서 클릭을 뗄떼 동작하는 'mouseup'입니다.

window.addEventListener('mouseup', function(event){
	console.log(event);
}

이 또한, 로직은 위와 동일하며, 마우스의 클릭을 떼는 순간 동작합니다.

 

콘솔에 보면, 출력하는 값이 나오는데,

screenX, Y 값과, client X,Y값에 대해서 설명드리겠습니다.

 

screen X,Y 값은 = 모니터 기준 좌표이며,

clientX, Y 값은 = 인터넷 브라우저 기준의 좌표입니다.

 

따라서 게임에서는 좀더 수월하게 이용할 수 있는 client X, Y 값을 이용했습니다.

 

2. switch문

switch문은 조건문입니다.

(if문과 유사)

 

switch문은,

 

switch(조건){

case 조건의결과값:

실행내용;

break;

}

case 조건결과값2:

실행내용:

break;

}

 

이런식으로 생겼는데요. 코드로 살펴보겠습니다.

var condition = 8;

switch(condition){
    case 5:
        console.log('정답은 8 입니다.');
        break;
    case 6:
        console.log('정답은 8 입니다.');
        break;
    case 7:
        console.log('정답은 8 입니다.');
        break;
    case 8:
        console.log('정답 ! 8 입니다.');
        break;
    case 9:
        console.log('정답은 8 입니다.');
        break;
}

이런식으로 스무고개하는 느낌처럼 쓰입니다.

 

 

 

 

3. 2048 영상 & 코드

2048게임

 

2048.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>2048</title>
    <style>
        #table {
            border-collapse: collapse;
            user-select: none;
        }
        #table td{
            border: 1px solid black;
            width: 100px;
            height: 100px;
            font-size: 50px;
            font-weight: bold;
            text-align: center;
        }
        #score{
            display : none;
        }
    </style>
</head>
<body>
    <table id='table'>

    </table>
    <div id='score'></div>
    <script src='./2048.js'></script>
</body>
</html>

2048.js

var 테이블 = document.getElementById('table');
var 데이터 = [];
var 점수표 = document.getElementById('score');

function 초기화(){//이차원배열 만들기 4 * 4
    var fragment = document.createDocumentFragment();
    [1,2,3,4].forEach(function(){
        var 열데이터 = [];
        데이터.push(열데이터);
        var tr = document.createElement('tr');
        [1,2,3,4].forEach(function(){
            열데이터.push(0);
            var td = document.createElement('td');
            tr.appendChild(td);
        });
        fragment.appendChild(tr);
    });
    테이블.appendChild(fragment);
}

function 랜덤생성(){
    var 빈칸배열 = [];
    데이터.forEach(function(열데이터, i){
        열데이터.forEach(function(행데이터, j){
            if(!행데이터){
                빈칸배열.push([i, j]);
            }
        });
    });
    if (빈칸배열.length === 0) {
        alert('GameOver !');
        테이블.innerHTML = '';
        초기화();
    } else {
        var 랜덤칸 = 빈칸배열[Math.floor(Math.random() * 빈칸배열.length)];
        데이터[랜덤칸[0]][랜덤칸[1]] = 2;
        그리기();
    }
}

function 그리기(){
    데이터.forEach(function(열데이터, i){
        열데이터.forEach(function(행데이터, j){
            if(행데이터 > 0){
                테이블.children[i].children[j].textContent = 행데이터;
            } else {
                테이블.children[i].children[j].textContent = '';
            }
        });
    });
}

초기화();
랜덤생성();
그리기();

//스와이프, 드래그
var 드래그시작 = false;
var 드래그중 = false;
var 시작좌표;
var 끝좌표;
window.addEventListener('mousemove', function(event){
    if(드래그시작){
        드래그중 = true;
    }
});
window.addEventListener('mouseup', function(event){
    끝좌표 = [event.clientX, event.clientY];
    if(드래그중){
        var 방향;
        var x차이 = 끝좌표[0] - 시작좌표[0];
        var y차이 = 끝좌표[1] - 시작좌표[1];
        if (x차이 < 0 && Math.abs(x차이) / Math.abs(y차이) > 1) {
            방향 = '왼쪽';
          } else if (x차이 > 0 && Math.abs(x차이) / Math.abs(y차이) > 1) {
            방향 = '오른쪽';
          } else if (y차이 > 0 && Math.abs(x차이) / Math.abs(y차이) < 1) {
            방향 = '아래';
          } else if (y차이 < 0 && Math.abs(x차이) / Math.abs(y차이) < 1) {
            방향 = '위';
          }
        console.log(방향);
    }
    드래그시작 = false;
    드래그중 = false;
    //데이터 이동시키기.
    switch (방향) {
        case '왼쪽':
            var 새데이터 = [
              [],
              [],
              [],
              []
            ];
            데이터.forEach(function(열데이터, i) {
              열데이터.forEach(function(행데이터, j) {
                if (행데이터) {
                  if (새데이터[i][새데이터[i].length - 1] && 새데이터[i][새데이터[i].length - 1] === 행데이터) {
                    새데이터[i][새데이터[i].length - 1] *= 2;
                    var 현점수 = parseInt(점수표.textContent, 10);
                    점수표.textContent = 현점수 + 새데이터[i][새데이터[i].length - 1];
                } else {
                    새데이터[i].push(행데이터);
                    }
                }
              });
            });
            [1, 2, 3, 4].forEach(function(열데이터, i) {
            [1, 2, 3, 4].forEach(function(행데이터, j) {
                데이터[i][j] = 새데이터[i][j] || 0;
              });
            });
        break;
        case '오른쪽':
            var 새데이터 = [
                [],
                [],
                [],
                []
            ];
              데이터.forEach(function(열데이터, i) {
                열데이터.forEach(function(행데이터, j) {
                if (행데이터) {
                    if (새데이터[i][0] && 새데이터[i][0] === 행데이터) {
                    새데이터[i][0] *= 2;
                    var 현점수 = parseInt(점수표.textContent, 10);
                    점수표.textContent = 현점수 + 새데이터[i][0];
                } else {
                    새데이터[i].unshift(행데이터);
                    }
                }
                });
            });
            [1, 2, 3, 4].forEach(function(열데이터, i) {
            [1, 2, 3, 4].forEach(function(행데이터, j) {
                데이터[i][3 - j] = 새데이터[i][j] || 0;
                });
            });
        break;
        case '위':
            var 새데이터 = [
                [],
                [],
                [],
                []
            ];
            데이터.forEach(function(열데이터, i) {
                열데이터.forEach(function(행데이터, j) {
                if (행데이터) {
                    if (새데이터[j][새데이터[j].length - 1] && 새데이터[j][새데이터[j].length - 1] === 행데이터) {
                    새데이터[j][새데이터[j].length - 1] *= 2;
                    var 현점수 = parseInt(점수표.textContent, 10);
                    점수표.textContent = 현점수 + 새데이터[j][새데이터[j].length - 1];
                } else {
                    새데이터[j].push(행데이터);
                    }
                }
                });
            });
            [1, 2, 3, 4].forEach(function(행데이터, i) {
                [1, 2, 3, 4].forEach(function(열데이터, j) {
                데이터[j][i] = 새데이터[i][j] || 0;
                });
            });
        break;
        case '아래':
            var 새데이터 = [
                [],
                [],
                [],
                []
              ];
              데이터.forEach(function(열데이터, i) {
                열데이터.forEach(function(행데이터, j) {
                  if (행데이터) {
                    if (새데이터[j][0] && 새데이터[j][0] === 행데이터) {
                      새데이터[j][0] *= 2;
                      var 현점수 = parseInt(점수표.textContent, 10);
                      점수표.textContent = 현점수 + 새데이터[j][0];
                    } else {
                      새데이터[j].unshift(행데이터);
                    }
                  }
                });
              });
              [1, 2, 3, 4].forEach(function(행데이터, i) {
                [1, 2, 3, 4].forEach(function(열데이터, j) {
                  데이터[3 - j][i] = 새데이터[i][j] || 0;
                });
            });
        break;
    }
    그리기();
    랜덤생성();
})
window.addEventListener('mousedown', function(event){
    드래그시작 = true;
    시작좌표 = [event.clientX, event.clientY];
})