개인 자료란 (JE)

  서버 커뮤니티

Profile 눙이 대표칭호 없음

NUngiboy 6e95e864e48245c2afe38069f3b5551f

Profile

자료 자바 에디션(JE) 플러그인 스크립트

skDragon 없이 SkBee만 사용하여 간단한 원과 구, 포물선을 그려보자!

2021.11.22 조회 수 1691 추천 수 1
장르 정보전달, 그 외에 장르 
게임버전 1.17.1 
원산지 국산 
개발자 NUngiboy 
저작권 알 수 없음 
자료 출처 https://skripthub.net/docs/ 


90ca1aa0c557d574729150b538e41c7b.png

개요


1.17에는 skdragon 지원이 안 되어서 한번 만들어본 원과, 구, 포물선을 만드는 스크립트입니다


버전 및 필요 애드온


Skript 2.6 Beta 3 / Skript 2.6 정식 버전에서의 정상 작동을 확인하였으며

SKbee 애드온이 반드시 필요합니다


사용법


명령어는 총 3가지가 있습니다.



1. drawCircle

/drawCircle [숫자] [정수] [정수] [정수]

형태로 실행할 수 있으며 (ex. /drawCircle 4.1 256 256 256)

첫번째 숫자는 반지름을 나타내며

뒤의 정수 3개는 각각 R G B 색깔을 나타냅니다

현재 플레이어의 머리와 발 위치 사이에 원점을 잡습니다


2. drawSphere

/drawSphere  [숫자] [정수] [정수] [정수]

형태로 실행할 수 있으며 (ex. /drawSphere 4.1 256 256 256)

첫번째 숫자는 반지름을 나타내며

뒤의 정수 3개는 각각 R G B 색깔을 나타냅니다

현재 플레이어의 머리와 발 위치 사이에 원점을 잡습니다


3.drawParabola

/drawParabola  [숫자] [숫자] [정수] [정수] [정수]

형태로 실행할 수 있으며  (ex.drawParabola 1.7 50 256 256 256)

첫번째 숫자는 속도, 두번째 숫자는 발사각을 의미하며

뒤의 정수 3개는 각각 R G B 색깔을 나타냅니다

현재 플레이어의 머리와 발 위치 사이에 원점을 잡고, 플레이어가 바라보는 방향으로 포물선을 그립니다


구문 설명

※주의 : 일반물리 지식이 필요하여 이과가 아니신 분들에겐 조금 어려울 수 있습니다.


마크에서는 참으로 편리한 기능이 있습니다.

그것은 f3 키를 누르면 나오는 xyz 좌표입니다.

이는 우리가 흔히 쓰는 직교 좌표계(Cartesian Coordinate)로

마인크래프트 세계에서는 각각 x축과 z축이 평면, y축이 높이를 나타내는데 쓰이죠

그러나 우리가 이번에 구현할 것은 원, 구 같은 곡면입니다.

보통 이런 것들은 극좌표계(Polar Coordinate) 또는 구면좌표계(spherical coordinate)를 많이 사용합니다

따라서 이를 적절히 잘 변환하기만 하면, 마크 내에서도 충분히 자연스러운 원을 만들 수 있는 것이죠


첫 번째인 drawCircle, 즉 원과 극좌표계에 대해서 알아볼까요

극좌표계에서는 기본적으로 다음과 같은 두가지 요소로 좌표계 내에서 점의 위치를 결정합니다

1. 원점까지의 거리 r

2. 원점과 이루는 각도 θ(세타/theta)


96990b4e1a63cb3c203dbe2b078790af.png

[그림 1] polar coord의 개요


위 [그림 1]에서도 보다시피 점 A는 직교좌표계로 나타내면 (C, D)의 위치인데

이는 삼각법 cos과 sin을 이용하여 구할 수 있습니다.

C=x=r*cosθ

D=y(이번 마크에서는 z축)=r*sinθ

따라서 반지름 r의 길이만 정해주면,  0도부터 360도까지 적절하게 자른 theta값만 돌려서 원을 구현할 수 있습니다.

function drawCircle(loc:location, radius:number, r:integer, g:integer, b:integer):
    set {_loc0} to {_loc} #원점의 위치를 변수로 임시저장합니다
    set {_index} to 1 #index를 설정합니다
    set {_loop} to {_radius}*24 #radius 뒤의 숫자로 밀도 조절, 밀도 올릴시 계산량 증가
    set {_theta} to (360/{_loop}) #정해준 밀도로 360도를 나눠줍니다
    set {_theta0} to {_theta} #단위 각도를 변수로 임시저장합니다
    loop {_loop} times: #밀도만큼 반복합니다 (360도를 다 돌아야 하므로)
        set {_dx} to {_radius}*cos({_theta}) #x변화량을 계산합니다
        set {_dz} to {_radius}*sin({_theta}) #z변화량을 계산합니다
        add {_dx} to {_loc}'s x-coord #x변화량을 원점에 더해줍니다
        add {_dz} to {_loc}'s z-coord #z변화량을 원점에 더해줍니다
        set {_loc::%{_index}%} to {_loc} #위치를 목록변수에 저장합니다
        set {_loc} to {_loc0} #다시 위치를 원점으로 되돌리고
        add 1 to {_index} #인덱스를 1 더합니다
        set {_theta} to {_index}*{_theta0} #인덱스*단위 각도를 이용하여 다음 각도를 만듭니다
    loop {_loc::*}: #아까 저장한 목록 변수에 대하여 반복
        play 1 of dust using dustOption(rgb({_r}, {_g}, {_b}), 1) at loop-value #그 위치에 파티클을 뿌립니다


두 번째로, drawSphere과 구면좌표계입니다

구면좌표계는 평면에서 입체가 됨에 따라서 축이 한방향 더 늘어났기 때문에,

점을 구성하는 요소가 3가지가 됩니다.

1. 원점까지의 거리 r

2. 원점과 두 축이 이루는 각도 φ(파이/phi)

3.  원점과 남은 한 축이 이루는 각도 θ(세타/theta)

02204199ed6b18f1e346157a58f61abd.png

[그림 2] spherical coord의 개요


위와 같은 상황에서 각각 xyz는 다음과 같이 나타낼 수 있습니다

x=r*sinθ*cosϕ 

y=r*sinθ*sinϕ
z=r*cosθ

마크에서는 y축과 z축의 역할이 바뀌었다는 것에 주의하여 코드를 짜면 다음과 같습니다

function drawCircle(loc:location, radius:number, r:integer, g:integer, b:integer):
    set {_loc0} to {_loc} #원점의 위치를 변수로 임시저장합니다
    set {_index} to 1 #index를 설정합니다
    set {_index.theta} to 1 #theta의 index를 설정합니다
    set {_index.phi} to 1 #phi의 index를 설정합니다
    set {_loop} to {_radius}*24 #radius 뒤의 숫자로 밀도 조절, 밀도 올릴시 계산량 증가
    set {_theta} to (360/{_loop}) #정해준 밀도로 360도를 나눠줍니다
    set {_theta0} to {_theta} #단위 각도를 변수로 임시저장합니다
    set {_phi} to (360/{_loop}) #phi도 똑같이 해줍니다
    set {_phi0} to {_phi}
    loop {_loop}/2 times: #phi는 180도만 돌아도 되므로 ÷2 해줍니다
        loop {_loop} times: #밀도만큼 반복합니다 (360도를 다 돌아야 하므로)
            set {_dx} to {_radius}*sin({_theta})*cos({_phi}) #x변화량을 계산합니다
            set {_dz} to {_radius}*sin({_theta})*sin({_phi}) #z변화량을 계산합니다
            set {_dy} to {_radius}*cos({_theta}) #y변화량을 계산합니다
            add {_dx} to {_loc}'s x-coord #x변화량을 원점에 더해줍니다
            add {_dz} to {_loc}'s z-coord #z변화량을 원점에 더해줍니다
            add {_dy} to {_loc}'s y-coord #y변화량을 원점에 더해줍니다
            set {_loc::%{_index}%} to {_loc} #위치를 목록변수에 저장합니다
            set {_loc} to {_loc0} #다시 위치를 원점으로 되돌리고
            add 1 to {_index} #인덱스를 1 더합니다
            add 1 to {_index.theta} #theta index를 1 더합니다
            set {_theta} to {_index.theta}*{_theta0} #인덱스*단위 각도를 이용하여 다음 각도를 만듭니다
        add 1 to {_index.phi} #phi도 똑같이 해줍니다
        set {_phi} to {_index.phi}*{_phi0}
    loop {_loc::*}: #아까 저장한 목록 변수에 대하여 반복
        play 1 of dust using dustOption(rgb({_r}, {_g}, {_b}), 1) at loop-value #그 위치에 파티클을 뿌립니다



마지막으로 drawParabola, 포물선에 관한 구문입니다

포물선은 간단하게 얘기하면 물체를 던질때 나타나는 궤적이며, 

화살이나 눈덩이도 포물선의 궤적을 띈다는 것을 알 수 있습니다

a96fc4c9bca57586e469ed4e2ca8d2c1.png

[그림 3] 포물선 운동의 개요


2차원 상에서의 포물선은 다음과 같이 나타낼 수 있지만,

3차원 상에서의 포물선 운동은 각도 하나가 더 들어가게 됩니다

따라서 위의 구면좌표계와 같이 각도가 두 개 필요한데, 

구를 만들 때에는 그냥 전체적으로 다 돌려버렸기에 특정한 세타값을 지정하지 않았지만

여기서는 세타값을 지정할 필요가 있습니다.

그러면 플레이어가 현재 바라보는 방향이 좌표계 내에서 어떤 각도를 가지는지 구해야 합니다


set {_unitvector} to vector from yaw ( yaw of player ) and pitch (+0)
set {_unitvector} to "%{_unitvector}%"
replace all ":" , "x","y","z"," " with "" in {_unitvector}
set {_vector::*} to {_unitvector} split by ","
loop {_vector::*}:
    set {_vector::%loop-index%} to {_vector::%loop-index%} parsed as number
set {_theta} to fixPitchVectorToAngle({_vector::1}, {_vector::3})

일단 위의 구문을 통해 플레이어의 pitch and yaw가 벡터로 어떻게 나타내지며

각각 {_vector::*}에 x,y,z 벡터로 저장되어집니다.

이 때, 주어진 벡터로 어떻게 각을 구하는지 알아야 합니다

function fixPitchVectorToAngle(x:number, z:number) :: number:
    set {_length.xz} to sqrt((({_x})^2)+(({_z})^2))
    set {_length.x} to abs({_x})
    set {_theta} to acos((({_x})^2)/({_length.xz}*{_length.x}))
    if {_x} > 0:
        if {_z} > 0:
            return {_theta} #x증 z증 east-south
        else if {_z} < 0:
            set {_theta} to abs(90-{_theta})
            add 270 to {_theta} #x증 z감 east-north
            return {_theta}
       else:
            set {_theta} to 0 #x증 z0 east
            return {_theta}
    else if {_x} < 0:
        if {_z} > 0:
            set {_theta} to abs(90-{_theta})
            add 90 to {_theta} #x감 z증 west-south
            return {_theta}
        else if {_z} < 0:
            add 180 to {_theta} #x감 z감 west-north
            return {_theta}
        else:
            set {_theta} to 180 #x감 z0 west
            return {_theta}
    else:
        if {_z} > 0:
            set {_theta} to 90 #x0 z증 south
            return {_theta}
        else:
            set {_theta} to 270 #x0 z감 north
            return {_theta}

이런 함수를 통하여 x축 east 방향을 0도로 하는 좌표계를 만들 수 있습니다

이를 이용하여 이제 진짜 포물선을 구하는 공식을 대입하여 함수를 짜면

function drawParabola(loc:location, velocity:number, theta:number, phi:number, r:integer, g:integer, b:integer):
    set {_loc0} to {_loc}  #원점의 위치를 변수로 임시저장합니다
    set {_index} to 1 #index를 설정합니다
    set {_time0} to 0.1 #시간에 관한 변수 / 기본은 1tick = 0.05초
    set {_time} to {_time0} #단위 시간을 저장합니다
    set {_gravity.acc} to 1 #중력가속도 변수 (원하는 대로 조절해보세요!)
    loop 100 times: #일단은 100번만 반복 (반복 횟수 조절 가능)
        set {_dx} to {_velocity}*cos({_phi})*cos({_theta})*{_time}
        set {_dy} to ({_velocity}*sin({_phi})*{_time})-(0.5*{_gravity.acc}*({_time}^2)
        set {_dz} to {_velocity}*cos({_phi})*sin({_theta})*{_time}
        add {_dx} to {_loc}'s x-coord
        add {_dy} to {_loc}'s y-coord
        add {_dz} to {_loc}'s z-coord
        set {_loc::%{_index}%} to {_loc}
        set {_loc} to {_loc0}
        add 1 to {_index}
        set {_time} to {_time0}*{_index}
    wait 1 tick
    loop {_loc::*}:
        play 1 of dust using dustOption(rgb({_r}, {_g}, {_b}), 1) at loop-value

이렇게 나타낼 수 있습니다

phi 값을 어떻게 설정하냐에 따라서 초기 발사 각도가 달라집니다!


파일 및 적용법


DrawParticle.sk 


서버 실행 폴더 중에서

plugins > Skript > scripts

  폴더에 위 파일을 집어 넣은 후,

서버를 재시작 하시거나, /sk reload all 명령어를 입력하여

서버가 스크립트를 인식하게 해주시면 됩니다!


여담


skdragon 1.17 나오면 그거 씁시다....
질문은 언제나 환영입니다




5개의 댓글

프리루트
2021.11.22

와우 아주 구체적인 설명 좋습니다 bb

그 자료 적용법을 간단하게 본문에 추가해주시면 감사하겠습니다 :>

눙이
2021.11.22
@프리루트

확인하였고 추가하였습니다!

깜빡했는데 감사합니다 ㅎㅎ

프리루트
2021.11.22
@눙이

빠른 반영 감사합니다 :D

앞으로도 이런 질좋은 창작물 잘부탁드립니다!

qsef1256
2021.11.23

skript 공식 디코 채널에 skDragon 1.17버전이 올라와 있습니다. 제작자가 귀찮았는지 테스트도 안해봤다는군요.

눙이
2021.11.24
@qsef1256

헉 그랬군요 어쩐지 인터넷에는 없다 했습니다 ㅎ...

뉴스 및 창작물
/files/thumbnails/268/789/003/262x150.crop.jpg?20240515192032

레드스톤

벌레먹은 돌 빠르게 제거하는 법

GlassesFilm

2024-05-15

0

/files/thumbnails/797/788/003/262x150.crop.jpg?20240515090924

건축

마인크래프트로 구현한 카르카손 보드게임

Warak

2024-05-15

1

/files/thumbnails/487/784/003/262x150.crop.jpg?20240508233607

모드

Windows Borderless 모드에서 악성코드 발견 2

학교가기싫다

2024-05-08

1

/files/thumbnails/384/778/003/262x150.crop.jpg?20240512002324

업데이트

마인크래프트 자바 에디션 스냅샷 24w18a

학교가기싫다

2024-05-06

0

/files/thumbnails/855/781/003/262x150.crop.jpg?20240505141129

레드스톤

레이저 클리너

GlassesFilm

2024-05-05

1

/files/thumbnails/576/775/003/262x150.crop.jpg?20240426232553

아티클

이달의 블록: 단단한 진흙

학교가기싫다

2024-04-26

0

/files/thumbnails/115/774/003/262x150.crop.jpg?20240428135129

업데이트

마인크래프트 1.20.5 정식 업데이트

학교가기싫다

2024-04-24

0

/files/thumbnails/762/770/003/262x150.crop.jpg?20240418073724

레드스톤

T.B.H (고민중독) | 노트블럭 버전 | NoteBlock Cover [한국어 영어 중국어 가사 추가]

노트블럭전문가

2024-04-18

1

/files/thumbnails/218/767/003/262x150.crop.jpg?20240412130213

레드스톤

우리의 꿈 - 원피스 오프닝

노트블럭전문가

2024-04-12

0

/files/thumbnails/505/766/003/262x150.crop.jpg?20240411122306

레드스톤

기동전사 건담 수성의 마녀 | 노트블럭 커버 1

노트블럭전문가

2024-04-11

1

/files/thumbnails/932/765/003/262x150.crop.jpg?20240410124459

레드스톤

마인크래프트 노트블록으로 만든 『 밤양갱 (Bam Yang Gang) 』

노트블럭전문가

2024-04-10

0

/files/thumbnails/403/765/003/262x150.crop.jpg?20240409190538

레드스톤

마인크래프트 노트블록으로 만든 『 밤양갱 (Bam Yang Gang) 』 2

Sonttukk

2024-04-09

5