[마인크래프트 포지 1.12.2] 현실시간 알려주는 전자시계탑만들기, CustomNPC mod 사용

     

 

디지털 시계탑 만들기.

 

마인크래프트에서 현실 시간을 나타내는 시계탑을 만들어보도록 하겠습니다. ㅋㅋ

마인크래프트안에 레드스톤으로 현실 논리회로를 구성할 수 있습니다. 논리회로중에 "카운터"회로를 만들면 시계를 만들 수 있긴 한데, 현실 시간 시계와 동기화가 힘듭니다. 하지만 모드를 사용해서 스크립트를 하면 현실 시간을 불러올 수 있습니다.

그래서 CustomNPC 모드와 약간의 논리회로 이론을 참고해서 위와같이 움직이는 디지털 시계를 만들어볼까 합니다. CustomNPC 모드는 아주 개꿀모드니까 꼭 설치하세요 서버운영자님들!!

일단 시작하기 전에 어떤 로직으로 돌아가는지 설명해드리겠습니다.

1. 세븐세그먼트 방식으로 각 자리숫자블록을 만듬
2. 시간을 불러옴
3. 각 자리수의 숫자에 알맞게 레드스톤파워를 줌. 레드스톤파워가 들어가면 불이 들어오는 레드스톤조명을 사용.
4. 끝.

일단 이런 논리이긴한데.. 하나씩 해봅시다.

1. 세븐세그먼트 방식으로 각 자리 숫자블록을 만듬

일단 세븐세그먼트가 무엇인지 알고 넘어가는게 좋을것같습니다. 디지털 시계에서 숫자를 그릴때 8모양으로 되있는거 보신적 있으신가요? 

논리회로에서 사용되는 세븐세그먼트

위 그림처럼 생긴게 세븐세그먼트입니다. 사실 제조사마다 생긴게 다르긴 하지만 그건 신경쓰실필요는 없어요. 우리가 봐야하는건 저 숫자를 구성하는 abcdefg입니다. 세븐세그먼트라는 이름은 7개의 구역으로 숫자를 표기하기 때문에 붙여진 이름인데요, 예를들어 1이라는 숫자를 표현하기위해서는 b와 c에만 불이 들어오면 됩니다. 마찬가지로 2라는 숫자를 표현하기위해 a,b,g,e,d가 불이들어오면 2모양이 되겠죠?

 

숫자 0~9까지 표기법

"레드스톤 조명"을 세븐세그먼트 모양으로 설치합니다. 단 일렬로 하면 안되고 ㅓ 모양으로 만들어야 됩니다. 아래처럼요.

3개중에 가운데가 튀어나오게 설치
옆에서 보면 이렇습니다.

이렇게 가운데를 튀어나오게 하는 이유는 저기에 전력을 넣을 스크립트 블록을 넣기 위함입니다. 레드스톤블록을 일렬로 배치하면 이상하게 잘 작동 안하더라구요. 이렇게 숫자를 시,분,초 각각2개씩해서 6개를 만들어주시면 됩니다.

 

2. 시간 불러오기

이제 스크립트를 만들건데요, CustomNPC에 보면 ScriptBlock이 있습니다. 커맨드블록이랑 비슷한데 커맨드 대신 스크립트를 실행할 수 있는 블록입니다. 

제가 가장 많이사용하는 블록

이 스크립트 블록을 "레드스톤 조명" 3개 사이에 하나씩 넣어줍니다.

 

요런식으로 7개를 설치

아마 설치할 때마다 스크립트 창이 뜰텐데 일단은 무시합니다. 이 스크립트 블록 하나하나가 세븐세그먼트에 a,b,c,d,e,f,g 역할을 하게됩니다.

이제 스크립트에서 시간을 불러오겠습니다. 블록에 스크립트를 다시 열려면 CustomNPC도구중에 Scripter(나무삽모양)을 블록에 사용하면 됩니다. 시간을 불러오는건 한줄이면 됩니다.

시간 불러오기

여기서 function tick(event) 라는건 1틱에 한번씩 { } 괄호 안에 코드를 실행시킨다는 의미입니다. CustomNPC에서 1틱은 0.5초정도 됩니다. 즉 2틱이 1초입니다. 이제 이 코드는 0.5초마다 시간을 읽어와서 date에 저장합니다. new Date()는 Java에서 현재시간을 불러오는 함수입니다. 

 

3. 각 자리수의 숫자에 알맞게 레드스톤파워를 줌. 레드스톤파워가 들어가면 불이 들어오는 레드스톤조명을 사용

 

이제 가장 중요한 알맞은 위치에 불을 들어오게 하는 방법입니다.

1에서 설명했던 세븐세그먼트를 다시 보시면 a,b,c,d,e,f,g 각각 어느 숫자에는 불이 들어오고 어느 숫자에는 불이 안들어오는지 찾을 수 있습니다. 예를들어 a같은경우 숫자 1과 4를 제외하면 모두 불이 들어옵니다. b는 숫자 5,6을 제외하고는 모두 불이 들어오구요. 이런식으로 각 위치별로 어떤 숫자일때 불이 들어오고 안들어오는지를 계산합니다. 각 자리별로 불이 들어오는숫자만 나열하면 아래 표와 같습니다.

불이들어오는경우를 1로 표기

먼저 a를 만들어 볼까요? a는 세븐세그먼트중에 제일 위에있는 ㅡ 입니다. a는 숫자 1과 4를 제외하면 항상 불이 켜집니다. 즉 숫자가 1,4일때는 레드스톤 파워를 끄고, 그외일경우 레드스톤 파워를 키면 됩니다.

 

a 스크립트

function tick(event)  //a
{
    var date = new Date();
    
    switch(date.getSeconds()%10)
    {
        case 1:
        case 4:
            event.block.setRedstonePower(0);
        break;
        default :
            event.block.setRedstonePower(15);
        break;
    }
}

 

switch()라는게 사용됬는데, swtich - case는 조건문으로 ( ) 괄호 안에있는 값이 얼마냐에 따라 알맞은 case문을 실행하게됩니다. 위에 코드에선 date.getSeconds()%10이라는 값이 1이거나 4일때는 event.block.setRedstonePower(0)을 실행하고, 그 외의경우는 default인 event.block.setRedstonePower(15)를 실행합니다.

date.getSeconds()%10은 현제 시간의 1의자리를 구하는 식입니다. date.getSeconds()는 java에서 현제 시간의 초를 불러옵니다. 하지만 여기서 우리가 필요한건 초의 1의자리이기 때문에 10의자리를 버리기 위해 %연산자를 써줍니다. %는 나머지연산자로 %10을 하게되면 숫자를 10으로 나누고 나머지를 반환합니다. 어떤수를 10으로 나누면 1의자리만 남겠죠? 즉 date.getSeconds()%10은 초의 1의자리를 나타냅니다. 초의 1의자리가 1이거나 4면 a에 불을끄기 위해 event.block.setRedstonePower(0)을 하고, 그외면 event.block.setRedstonePower(15)로 합니다. 위와같이 코드를 짜고, 위에 텝에서 "설정"을 눌른다음 사용 을 예로 만들면 코드가 작동합니다.

이렇게 동작합니다.

동작하는게 보이시죠? 하지만 하나만 만들었더니 이게 잘 작동하는건지 마는건지 모르겠네요... ㅋㅋ 위랑 비슷하게 b,c,d,e,f,g도 만듭니다.

function tick(event) //b
{
    var date = new Date();
    
    switch(date.getSeconds()%10)
    {
        case 5:
        case 6:
            event.block.setRedstonePower(0);
        break;
        default :
            event.block.setRedstonePower(15);
        break;
    }
}

//--------------------------------------------
function tick(event) //c
{
    var date = new Date();
    
    switch(date.getSeconds()%10)
    {
        case 2:
            event.block.setRedstonePower(0);
        break;
        default :
            event.block.setRedstonePower(15);
        break;
    }
}
//--------------------------------------------

function tick(event) //d
{
    var date = new Date();
    
    switch(date.getSeconds()%10)
    {
        case 1:
        case 4:
        case 7:
            event.block.setRedstonePower(0);
        break;
        default :
            event.block.setRedstonePower(15);
        break;
    }
}

//--------------------------------------------
function tick(event) //e
{
    var date = new Date();
    
    switch(date.getSeconds()%10)
    {
        case 1:
        case 3:
        case 4:
        case 5:
        case 7:
        case 9:
            event.block.setRedstonePower(0);
        break;
        default :
            event.block.setRedstonePower(15);
        break;
    }
}

//--------------------------------------------

function tick(event) //f
{
    var date = new Date();
    
    switch(date.getSeconds()%10)
    {
        case 1:
        case 2:
        case 3:
        case 7:
            event.block.setRedstonePower(0);
        break;
        default :
            event.block.setRedstonePower(15);
        break;
    }
}
//--------------------------------------------

function tick(event) //g
{
    var date = new Date();
    
    switch(date.getSeconds()%10)
    {
        case 0:
        case 1:
        case 7:
            event.block.setRedstonePower(0);
        break;
        default :
            event.block.setRedstonePower(15);
        break;
    }
}

 

각 블록 위치에 알맞은 코드를 넣어주고 실행하면 시간이 제대로 나오는것을 확인할 수 있습니다.!!

여기서는 초의 1의단위를 구현했는데 초의 10의단위를 구현하기 위해서는?

아까 위에서 date.getSeconds()%10가 초의 1의단위를 말한다고 했습니다. 10의 단위를 쓰기 위해선 parseInt(date.getSeconds()/10)를 사용하면 됩니다. 만약 34초이면 /10을 하면 3.4가 됩니다. 여기서 parseInt라는 java함수가 ( ) 괄호안에 숫자를 강제로 정수로 만들어줍니다. 즉 3.4를 3으로 만들어줍니다. 그럼 10의자리를 얻을 수 있겠죠?

만약 분을 구하고 싶으면 date.getSeconds()가 아니라 date.getMinutes()를 하면 됩니다. 시간은 date.getHours()입니다. 각각 일의 자리는 %10으로, 십의 자리는 /10과 parseInt로 구할 수 있습니다. 숫자를 표현하는 a,b,c,d,e,f,g는 똑같기 때문에 switch( )괄호안에 값만 바꿔주면 쉽게 분과 시간을 만들 수 있습니다.

초의 10의 자리 a
분의 1의자리
시간의 10의자리

 

자 그럼 시계탑이 완성되었습니다!!!

레드스톤보다 만들기는 쉬운데 코드를 넣는게 조금 복잡하지만, 깔끔하고 현실시간과 쉽게 동기화되는 시계를 만들 수 있습니다. 혹시 프로그래밍 공부하시는 분이면 자바스크립트 공부도 되구요

다음에는 좀더 재밌는걸 만들어보겠습니다 ^^

반응형

댓글

Designed by JB FACTORY