반응형

https://myhappyman.tistory.com/94

 

HTML, JAVASCRIPT - 테트리스 만들기 - 3

https://myhappyman.tistory.com/93 HTML, JAVASCRIPT - 테트리스 만들기 - 2 https://myhappyman.tistory.com/92 HTML, JAVASCRIPT - 테트리스 만들기 - 1(table요소, 배열값으로 테트리스 만들기) 웹 개발을 해..

myhappyman.tistory.com

 

3장에서 키보드 입력 이벤트까지 처리해보았습니다.

 

이번 포스팅에서는 어떤 입력을 받거나 일정시간마다 내려가더라도 테트리스 블럭이 게임 맵을 뚫고 넘어가지 않는 함수를 작성하고 사용하도록 해보겠습니다.

 

isMove()라는 함수를 추가해서, 키 이벤트값이나 setInterval함수에 따라 진행이 되었을때, 벽인지 아닌지 체크 후 boolean값을 리턴하는 함수를 만들어보겠습니다.

 

움직임 제한 함수 추가 isMove()

function isMove(TYPE, TURN, GX, GY){
    TURN = TURN > 3 ? TURN % 4 : TURN;
    for(var i=0; i<4; i++){
        for(var j=0; j<4; j++){
            if(TETRIS[TYPE][TURN][i][j] == 1){ //테트리스의 블럭모양이 나왔는데
                if(MAP[GX+2+i][GY+2+j] != 0){ //닿을곳이 맵이 아니면
                    return false;
                }
            }
        }
    }
    return true;
}

이러한 함수를 추가할겁니다. 파라미터값들에 대해 설명을 하면 아래와 같습니다.

첫번째 파라미터(TYPE)에는 테트리스의 현재 타입값을 넣습니다.

두번째 파라미터(TURN)에는 테트리스의 현재 회전값을 넣습니다.

세번째 파라미터(GX)는 현재 테트리스가 위치한 위아래 위치값 넣습니다.

네번째 파라미터(GY)는 현재 테트리스가 위치한 좌우의 위치값을 넣습니다.

리턴값은 boolean값인 true, false값을 처리합니다.

 

그리고 맵 데이터에서 현재 이동이 가능한 값 0으로 된 데이터인지 체크를하고 0이 아니라면 움직이지 못하도록 false값을 리턴할겁니다.

모든 조건을 통과했을때만 true값이 나와서 동작을 시킵니다.

 

 

isMove()함수에 대해서 좀 더 알아보겠습니다.

숫자 1번키를 눌러서 왼쪽으로 이동한다!

숫자1번(또는 왼쪽으로 이동하는 키)을 눌러서 왼쪽으로 이동한다고 가정을 했을때,

MAP배열 데이터와 테트리스 데이터가 위 그림처럼 되어있을텐데, 여기서 계속해서 이동이 가능한 영역은 회색입니다. 현재 그림을 기준으로 왼쪽으로 2번까진 이동이 가능하겠죠. 테트리스 모양인 'ㄱ'자의 막대는 넘어가면 안되니까요.

 

즉, 현재의 테트리스의 타입과 회전모양을 값으로 받고 TETRIS배열의 0번째부터 끝까지 배열모양을 조사해서 1이라는건 테트리스의 모양이므로 입력한 동작이 움직일수 있는지 없는지 체크하는 조건문이 진행됩니다. 

if(TETRIS[TYPE][TURN][i][j] == 1)

 

전역변수 GX값, GY값은 MAP배열을 기준으로 2만큼씩 안으로 들어가 있기 때문에 MAP데이터를 검사할때 2만큼 추가하였고, 각각 닿는 부위를 체크하기 위해 위아래는 검사하는 GX축에 i값만큼 더하고, 좌우를 검사하는 GY부분에 j만큼 더하였습니다.

if(MAP[GX+2+i][GY+2+j] != 0)

와 같은 조건문이 만들어졌습니다. 0이 아니라는건 맵이 아니기 때문에 return false가 처리되면서 이동을 못하도록 하죠.

 

그럼 이제 실질적으로 isMove()를 써봐야겠죠 키이벤트를 정의했던 myFunction()을 수정해보겠습니다.

 

myFunction함수에 키이벤트에 따른 이동제한 처리

function myFunction(input){
    //그리기 전에 지우기
    erase(GX, TYPE, TURN);
    switch(input){
        case 53://회전
            if(isMove(TYPE, TURN+1, GX, GY)){
                TURN++;
                TURN = TURN % 4;
            }
            break;
        case 49://블럭왼쪽이동
            if(isMove(TYPE, TURN, GX, GY-1)){
                GY--;
            }
            break;
        case 51://블럭오른쪽이동
            if(isMove(TYPE, TURN, GX, GY+1)){
                GY++;
            }
            break;
        case 50://블럭아래로이동
            if(isMove(TYPE, TURN, GX+1, GY)){
                GX++;
            }
            break;
        case 32://스페이스
            while(isMove(TYPE, TURN, GX+1, GY)){
                GX++;
            }
            break;
    }
    //테트리스 블럭 그리기
    drawTetris(GX, TYPE, TURN);
}

3장에서 입력된 키보드 값을 처리할 때 위 방향키를 입력받으면 TURN값을 ++처리하여 증가하거나

왼쪽으로 이동하면 전역변수 GY값을 --시켰는데 이번 포스팅에서는 if문인 조건문이 추가되었습니다.

회전을 하게되면 파라미터값에 현재의 전역변수의 회전값에 +1을 처리한 값을 넣고 움직일 수 있는지 없는지 체크합니다. 조건이 만족되면 그때서야 TURN의 전역변수 값을 ++하여 증감해줍니다.

 

왼쪽으로 이동할땐, 좌우를 처리하는 GY값에 -1을 처리하고 왼쪽으로 이동이 가능한지 아닌지 체크합니다.

마찬가지로 조건이 만족되었을때만 GY--처리를 합니다.

 

스페이스값은 아래로 이동하는것을 더이상 진행이 불가할때까지 처리해주면 됩니다.

while문을 통해 처리하였고 이동을 못하면 false값이 나오니 자연스럽게 빠져오겠죠.

 

이제 마지막으로 action()함수의 setInterval부분을 추가하겠습니다.

일정시간마다 자연스럽게 내려가다보니 일정시간이 지나면 제한이 없어서 뚫고 지나가게 됩니다.

 

 

action() 함수의 일정시간마다 동작하는 setInterval() 이동제한 추가

function action(){
    //keyEvent
    document.addEventListener("keypress", function(){
        myFunction(event.keyCode);
    });

    var intervalID = setInterval(function(){
        erase(GX, TYPE, TURN); //생성한 전위치 블럭 삭제
        if(isMove(TYPE, TURN, GX+1, GY)){
            GX++; //한줄씩 내리기
        }
        drawTetris(GX, TYPE, TURN); //테트리스를 그린다.
    }, GAME_SPEED);
}

키 이벤트부분과 유사합니다.

먼저 현재의 블럭을 지워주고 아래로 이동하는 키값이 강제로 입력되었다고 생각하시면 됩니다.

아래 위값을 제어하는 GX값이 증가하였다고 생각하고 isMove()함수를 통해 체크합니다.

 

그러면 더이상 맵을 뚫고 블럭이 사라지는 일은 없을 겁니다.

더이상 벽을 뚫고 들어가지 않는다.

 

여기까지 동작하는 소스를 한번 올리도록 하겠습니다.

 

아래의 ZIP파일을 받아주시면 됩니다.

tetris_v3.zip
0.00MB

반응형