마인크래프트 CommandHelper 커헬 강좌 5강 - 반복문 , 월드에디터 만들기
안녕하세요 벌써 5강이네요
오늘은 반복문을 설명하면서 간단하게 WorldEdit ( 월드에디터 ) 에 있는 //set 기능을 만들어보도록 하겠습니다
우선 for문을 간단하게 설명드리자면 자신이 원하는만큼 코드를 반복시킬수 있습니다
기본적인 형태는
for(초기화, 조건, 업데이트) {
실행내용
}
입니다
초기화,조건 업데이트가 뭐냐고요?
우선 초기화라는게 뭐냐면 변수를 만드는겁니다
@i = 0;
이런식으로 변수를 선언하는게 초기화입니다
조건은 저번에 if문에서도 본것처럼
if(@i > 10)
이런식으로 조건을 넣을수 있습니다
@i가 10보다 클때 실행되는거죠
마지막으로 업데이트는 @i += 1 이런식으로 변수를 바꿔주는겁니다
한번 명령어로 만들어서 테스트해보죠
*:/test = >>>
for(@i = 0, @i < 10, @i+=1) {
msg(@i)
}
<<<
@i라는 변수를 만들고 @i가 10보다 작은지 체크합니다.
10보다 작을경우 코드를 실행하고 @i에 1을 더합니다
그리고 조건이 만족하지 않을때까지 반복합니다
한번 직접 출력해볼까요?
0부터 9까지 반복하면서 @i를 계속해서 출력해줬습니다.
그리고 10을 넘어가는순간 조건을 만족하지 못해서 for문이 중지됐죠
그리고 for문에서 중간에 탈출하는방법도 있습니다
바로 중간에 break()를 넣어주면 되는겁니다.
*:/test = >>>
for(@i = 0, @i < 10, @i++) {
if(@i == 6) {
break();
}
msg(@i)
}
<<<
@i가 6일때 break()가 실행되도록 해봅시다
@i가 6이되는순간 for문이 중지된걸 볼수있습니다
그렇다면 for문은 중지시키고싶지는 않은데 아래 코드들을 실행하기 싫다면 어떻게해야될까요
continue(); 를 사용하면됩니다
컨티뉴는 바로 실행중인 코드를 끝내고 바로 업데이트단계로 스킵합니다.
직접 코드를 짜서 보여드리겠습니다
*:/test = >>>
for(@i = 0, @i < 10, @i++) {
if(@i % 2 == 0) {
continue();
}
msg(@i)
}
<<<
조건이 맞지 않거나 break가 올때까지 계속해서 반복하는걸 볼수 있습니다
그리고 다른 반복문으로 while문이 있습니다
while은 if문을 반복한다고 생각하시면 편합니다
for은 반복시킬때 많이쓰지만 while은 좀더 조건적인부분에서 쓰입니다.
while(조건) {
실행내용
}
이렇게 쓰이고 조건이 만족하지 않을때까지 반복합니다
정말 간단하죠? 이게 다입니다.
do while이란것도 있는데 이건 실행내용을 한번 실행한다음 원래 while로 돌아옵니다
그림으로 설명하면 이렇습니다
그럼 이걸 이용해서 월드에디터의 //set 기능을 만들어볼수도 있습니다
블럭의 좌표 0~100까지 반복하면서 블럭타입을 바꿔주는겁니다
우선 좌표를 설정해주기 위해서 main.ms에 EventAPI를 추가해줍시다
bind(player_interact, null, null, @event,
if(pinfo( player() , 6) == '271:0') {
if(@event[action] == 'left_click_block') {
store_value(player() . 'set1', @event[location])
msg('1번 좌표설정')
cancel()
}
if(@event[action] == 'right_click_block') {
store_value(player() . 'set2', @event[location])
msg('2번 좌표설정')
cancel()
}
}
)
우선 명령어를 만들고 $code변수를 입력받습니다. 그리고set1과 set2좌표를 가져와줍시다.
그다음 그게 비어있는값인지 아닌지 체크해봅니다
근데 if문에 || 라는 못보던게 보이죠?
이김에 잠시 논리연산자를 설명해드리겠습니다
if문은 항상 조건이 참일때만 실행이되는데
A && B 를 할경우 A와 B가 모두 참일경우에 참이됩니다 ( AND )
' A 그리고 B ' 라고 보시면 됩니다
A || B 는 둘중 하나만 참이여도 참이됩니다 ( OR )
이건' A 또는 B'로 보면 됩니다
!A 는 A가 참일경우 거짓이되고 거짓일경우 참이됩니다. 거꾸로 바꿔주는거죠 ( NOT )
A를 부정할경우 그 반대가되기때문에 NOT입니다
쉽게말하면 '난 A다.' -> 난 'A가 아니다.' 이게 되는거죠.
참 거짓 하니까 어려워보일수도 있겠지만 간단하게 설명하면 이런겁니다
if(A && B)를 할경우 A와 B의 조건이 둘다 만족되야 실행되고
if(A || B)는 둘중 하나마 만족되도 실행됩니다
if(!A)는 A가 만족할경우 실행되지 않고 만족하지 않을경우 실행됩니다
if(!(@loc1 == null || @loc2 == null)) { 는 둘다 비어있는값이 아닐때만 실행됩니다
||를 사용해서 둘중 하나라도 널값이 들어있으면 참이되버리고 그것을 !로 부정해줍니다.
그래서 둘중 하나라도 널값이 들어있으면 실행이 안됩니다
이제 여기에 for문으로 블럭을 채워봅시다
*:/set $code = >>>
@loc1 = get_value(player() . 'set1')
@loc2 = get_value(player() . 'set2')
if(!(@loc1 == null || @loc2 == null)) {
@tmp = 0;
if(@loc2[x] < @loc1[x]) {
@tmp = @loc1[x]
@loc1[x] = @loc2[x]
@loc2[x] = @tmp
}
if(@loc2[y] < @loc1[y]) {
@tmp = @loc1[y]
@loc1[y] = @loc2[y]
@loc2[y] = @tmp
}
if(@loc2[z] < @loc1[z]) {
@tmp = @loc1[z]
@loc1[z] = @loc2[z]
@loc2[z] = @tmp
}
for(@i = @loc1[x], @i <= @loc2[x], @i++) {
for(@j = @loc1[y], @j <= @loc2[y], @j++) {
for(@u = @loc1[z], @u <= @loc2[z], @u++) {
@loc = array(0:@i,1:@j,2:@u,3:@loc1[world],world:@loc1[world],x:@i,y:@j,z:@u)
set_block_at(@loc, $code)
}
}
}
}
<<<
코드가 너무 길어져버렸네요
우선 for문에서 좌표값이 작은것부터 큰것으로 진행하게 만들기 위해서
@loc1이 @loc2보다 클경우 두 값을 바꿔줘서
무조건 @loc1이 작은값이 되도록 만들어줬습니다
근데 왜 @tmp를 넣어서 바꿔주었냐?
왜냐하면
@loc1 = @loc2
@loc2 = @loc1
이런식으로 바꿔줄경우에는 @loc2에 @loc1을 넣을때 @loc1은 이미 @loc2의 값이 들어있기때문에 바뀌지 않게됩니다.
그래서 @tmp에 임시로 값을 저장해놓고 옮겨주는겁니다.
그렇게 x, y ,z값을 모두 @loc1이 작게 만들어준후
for문으로 들어갑니다
for문은 저렇게 한번에 여러개를 중첩시켜서 사용할수도 있습니다
반복문을 반복하는거죠
for문을 for문으로 여러번 실행시켜서 x,y,z를 모두 한번씩 돌수있게됩니다
set_block_at(@loc, $code)
이 함수는 좌표와 블럭코드를 넘겨주면 그 좌표에 해당 블럭을 설치해주는 함수입니다.
한번 잘 작동되는지 볼까요?
나무도끼를 들고 좌클릭으로 1번좌표를 설정해주고
우클릭으로 2번좌표를 설정해줍니다
그리고 '/set 아이템코드'를 치면..?
짠 아이템코드 1번인 돌이 생성되었습니다.
오늘은 반복문을 배우고 월드에디터의 //set 기능을 만들어보았습니다
모르는점 있으면 댓글로 질문해주세요
그리고 혹시 만들고싶은 기능이 있다면 강좌로 올려드리겠습니다