PACL2/프로그램(r1 Blame)
| r1 | ||
|---|---|---|
| r1 (새 문서) | 1 | [목차] |
| 2 | == 개요 == | |
| 3 | [[PACL2]]의 CustomEvents 기능에 포함된 이벤트로, 변수 조작, 이벤트 실행, 카메라/트랙/장식 이동 등 다양한 동작을 프로그래밍 방식으로 제어할 수 있다. | |
| 4 | ||
| 5 | 이벤트마다 사용할 문법을 '''고수준''' 또는 '''저수준''' 중 하나로 선택할 수 있으며, 고수준 문법을 사용하면 레벨 시작 시 내부적으로 저수준 문법으로 변환된다. | |
| 6 | ||
| 7 | == 공통 문법 == | |
| 8 | * '''값 유형'''은 '''문자열, 배열, 실수, 열거형, 논리, null'''로 정의된다. | |
| 9 | * 논리값은 {{{#!wiki class="code" {{{true}}}}}} 또는 {{{#!wiki class="code" {{{false}}}}}}로 정의된다. | |
| 10 | * 문자열은 큰따옴표 {{{#!wiki class="code" {{{""}}}}}}로 정의된다. | |
| 11 | * 지역 변수를 사용할 때는 {{{#!wiki class="code" {{{_}}}}}} 접두사를 사용한다. 모든 값 유형을 사용할 수 있지만, 해당 이벤트 내에서만 유효하다. | |
| 12 | * 전역 변수는 '''실수형만''' 저장할 수 있다. 다른 값 유형을 대입하면 오류가 발생한다. | |
| 13 | * 초기화되지 않은 변수를 읽으려 하면 오류가 발생한다. | |
| 14 | * 이 이벤트의 전역 변수와 '''변수 관련 이벤트'''는 서로 상호작용할 수 있다. | |
| 15 | ||
| 16 | == 고수준 문법 == | |
| 17 | 프로그램 유형을 "고수준"으로 선택했을 때 적용되는 문법이다. | |
| 18 | ||
| 19 | * {{{#!wiki class="code" {{{변수명}}}}}}을 직접 사용하여 해당 변수의 현재 값을 가져온다. | |
| 20 | * {{{#!wiki class="code" {{{[요소1, 요소2, ...]}}}}}}}로 배열을 정의한다. 배열의 길이는 대괄호 안 {{{#!wiki class="code" {{{,}}}}}}를 구분자로 결정된다. | |
| 21 | * {{{#!wiki class="code" {{{함수(인자1, 인자2, ...)}}}}}}}로 사전 정의된 기능을 수행한다. 인자의 개수와 각 인자에 대응하는 값 유형이 함수의 정의와 모두 일치해야 한다. | |
| 22 | * 실수형 값에서 지원되는 연산자는 {{{#!wiki class="code" {{{+}}}}}}}、{{{#!wiki class="code" {{{"−"}}}}}}}、{{{#!wiki class="code" {{{*}}}}}}}、{{{#!wiki class="code" {{{/}}}}}}}、{{{#!wiki class="code" {{{%}}}}}}}이다. 연산 결과는 대입 연산자 {{{#!wiki class="code" {{{=}}}}}}을 통해 변수에 저장하거나 함수의 인자로 삽입할 수 있다. | |
| 23 | * '''조건문, 루프 및 비교 연산자는 지원되지 않는다.''' | |
| 24 | * 명령은 세미콜론 {{{#!wiki class="code" {{{";"}}}}}}으로 마쳐야 한다. | |
| 25 | * {{{#!wiki class="code" {{{#}}}}}} 접두사로 시작하는 줄에 주석을 작성할 수 있다. | |
| 26 | ||
| 27 | {{{#!syntax python | |
| 28 | # b에 100을 저장 | |
| 29 | b = 100; | |
| 30 | # 지역변수 a에 3 + b * 2를 저장 | |
| 31 | _a = 3 + b * 2; | |
| 32 | # c에 현재 연속 "정확" 판정 개수와 지역변수 a 중 큰 값을 저장 | |
| 33 | c = Max(_a, {PerfectCombo}); | |
| 34 | }}} | |
| 35 | ||
| 36 | == 저수준 문법 == | |
| 37 | 프로그램 유형을 "저수준"으로 선택했을 때 적용되는 문법이다. | |
| 38 | ||
| 39 | C#의 IL 및 ASM 언어를 일부 모방하여 자체 제작된 '''스택 기반 가상 머신'''을 사용한다. 고수준 문법보다 다루기 까다롭지만 '''루프와 조건문''' 등 강력한 기능을 제공한다. | |
| 40 | ||
| 41 | * 명령에 들어갈 피연산자 타입은 일치해야 한다. | |
| 42 | * {{{#!wiki class="code" {{{값}}}}}}에는 모든 값 타입이 들어갈 수 있다. | |
| 43 | * {{{#!wiki class="code" {{{변수}}}}}}는 플레이하는 동안 바뀔 수 있는 가변 값이다. | |
| 44 | * {{{#!wiki class="code" {{{상수}}}}}}는 플레이하지 않아도 알 수 있는 불변 값이다. | |
| 45 | * 스택에서 먼저 빠진 값이 피연산자의 '''뒤쪽'''에 위치한다. | |
| 46 | * {{{#!wiki class="code" {{{";"}}}}}} 접두사로 시작하는 줄에 주석을 작성할 수 있다. | |
| 47 | ||
| 48 | === 명령 목록 === | |
| 49 | ||
| 50 | ||<-2><bgcolor=#555555><color=#fff> '''기본 명령''' || | |
| 51 | ||<bgcolor=#3D3D3D><color=#fff><width=220> 명령 ||<bgcolor=#3D3D3D><color=#fff> 설명 || | |
| 52 | || {{{#!wiki class="code" {{{push}}}}}} {{{#!wiki class="code" {{{값}}}}}} || 값을 스택에 넣는다. || | |
| 53 | || {{{#!wiki class="code" {{{pop}}}}}} {{{#!wiki class="code" {{{변수}}}}}} || 스택에서 값을 빼 지정한 변수에 값을 쓴다. || | |
| 54 | || {{{#!wiki class="code" {{{mov}}}}}} {{{#!wiki class="code" {{{변수}}}}}} {{{#!wiki class="code" {{{값}}}}}} || 지정한 변수에 값을 쓴다. || | |
| 55 | || {{{#!wiki class="code" {{{add}}}}}} || 스택에서 값 2개를 빼고 {{{#!wiki class="code" {{{A + B}}}}}}를 스택에 넣는다. || | |
| 56 | || {{{#!wiki class="code" {{{sub}}}}}} || 스택에서 값 2개를 빼고 {{{#!wiki class="code" {{{A - B}}}}}}를 스택에 넣는다. || | |
| 57 | || {{{#!wiki class="code" {{{mul}}}}}} || 스택에서 값 2개를 빼고 {{{#!wiki class="code" {{{A * B}}}}}}를 스택에 넣는다. || | |
| 58 | || {{{#!wiki class="code" {{{div}}}}}} || 스택에서 값 2개를 빼고 {{{#!wiki class="code" {{{A / B}}}}}}를 스택에 넣는다. || | |
| 59 | || {{{#!wiki class="code" {{{mod}}}}}} || 스택에서 값 2개를 빼고 {{{#!wiki class="code" {{{A mod B}}}}}}를 스택에 넣는다. || | |
| 60 | || {{{#!wiki class="code" {{{neg}}}}}} || 스택에서 값 1개를 빼고 {{{#!wiki class="code" {{{"−A"}}}}}}를 스택에 넣는다. || | |
| 61 | || {{{#!wiki class="code" {{{arr}}}}}} {{{#!wiki class="code" {{{상수}}}}}} || 스택에서 상수만큼 값을 빼 배열을 정의한다.[* 상수는 자연수이며, 값 유형은 모두 실수여야 한다.] || | |
| 62 | || {{{#!wiki class="code" {{{라벨명:}}}}}} || 라벨을 정의한다. 반드시 {{{#!wiki class="code" {{{":"}}}}}}으로 끝나야 한다. || | |
| 63 | || {{{#!wiki class="code" {{{jl}}}}}} {{{#!wiki class="code" {{{라벨명}}}}}} || 스택에서 값 2개를 빼 {{{#!wiki class="code" {{{A < B}}}}}}이면 지정한 라벨로 이동한다. (Jump if Less) || | |
| 64 | || {{{#!wiki class="code" {{{jle}}}}}} {{{#!wiki class="code" {{{라벨명}}}}}} || 스택에서 값 2개를 빼 {{{#!wiki class="code" {{{A <= B}}}}}}이면 지정한 라벨로 이동한다. (Jump if Less or Equal) || | |
| 65 | || {{{#!wiki class="code" {{{jg}}}}}} {{{#!wiki class="code" {{{라벨명}}}}}} || 스택에서 값 2개를 빼 {{{#!wiki class="code" {{{A > B}}}}}}이면 지정한 라벨로 이동한다. (Jump if Greater) || | |
| 66 | || {{{#!wiki class="code" {{{jge}}}}}} {{{#!wiki class="code" {{{라벨명}}}}}} || 스택에서 값 2개를 빼 {{{#!wiki class="code" {{{A >= B}}}}}}이면 지정한 라벨로 이동한다. (Jump if Greater or Equal) || | |
| 67 | || {{{#!wiki class="code" {{{je}}}}}} {{{#!wiki class="code" {{{라벨명}}}}}} || 스택에서 값 2개를 빼 {{{#!wiki class="code" {{{A = B}}}}}}이면 지정한 라벨로 이동한다. (Jump if Equal) || | |
| 68 | || {{{#!wiki class="code" {{{jmp}}}}}} {{{#!wiki class="code" {{{라벨명}}}}}} || 지정한 라벨로 이동한다. || | |
| 69 | ||
| 70 | ||<-2><bgcolor=#555555><color=#fff> '''고급 명령''' || | |
| 71 | ||<bgcolor=#3D3D3D><color=#fff><width=220> 명령 ||<bgcolor=#3D3D3D><color=#fff> 설명 || | |
| 72 | || {{{#!wiki class="code" {{{fparr}}}}}} {{{#!wiki class="code" {{{상수}}}}}} || 함수 인자로 전달할 지정된 길이의 쓰기 전용 빈 배열을 정의한다.[* 상수는 자연수여야 한다.] || | |
| 73 | || {{{#!wiki class="code" {{{fppopi}}}}}} {{{#!wiki class="code" {{{상수}}}}}} || 스택에서 값과 배열을 순서대로 빼 지정된 인덱스에 값을 쓰고 결과 배열을 스택에 넣는다.[* 상수는 음이 아닌 정수이며 인덱스를 가리킨다. 스택에서 뺄 배열은 반드시 {{{#!wiki class="code" {{{fparr}}}}}}로 생성된 배열이어야 한다.] || | |
| 74 | || {{{#!wiki class="code" {{{fpmovi}}}}}} {{{#!wiki class="code" {{{상수}}}}}} {{{#!wiki class="code" {{{값}}}}}} || 스택에서 배열을 빼 지정된 인덱스에 값을 쓰고 결과 배열을 스택에 넣는다.[* 상수는 음이 아닌 정수이며 인덱스를 가리킨다. 스택에서 뺄 배열은 반드시 {{{#!wiki class="code" {{{fparr}}}}}}로 생성된 배열이어야 한다.] || | |
| 75 | || {{{#!wiki class="code" {{{call}}}}}} {{{#!wiki class="code" {{{함수명}}}}}} || 스택에서 함수가 요구하는 인자 개수만큼 빼 함수를 실행한다.[* 스택에서 빼온 첫 번째 값이 {{{#!wiki class="code" {{{fparr}}}}}}로 생성된 배열이면 이 배열을 함수의 각 인자로 사용한다. 이벤트를 실행하는 함수의 인자는 10개가 넘지만 대부분은 {{{#!wiki class="code" {{{null}}}}}}이므로 이 경우 {{{#!wiki class="code" {{{fparr}}}}}}를 활용할 수 있다.] || | |
| 76 | ||
| 77 | === 예시 === | |
| 78 | ||
| 79 | {{{#!syntax nasm | |
| 80 | ; b에 100을 저장 | |
| 81 | mov b 100 | |
| 82 | ||
| 83 | ; 지역변수 a에 3 + b * 2를 저장 | |
| 84 | push 3 | |
| 85 | push b | |
| 86 | push 2 | |
| 87 | mul | |
| 88 | add | |
| 89 | pop _a | |
| 90 | ||
| 91 | ; c에 현재 연속 "정확" 판정 개수와 지역변수 a 중 큰 값을 저장 | |
| 92 | push _a | |
| 93 | push {PerfectCombo} | |
| 94 | call Max | |
| 95 | pop c | |
| 96 | ||
| 97 | ; 위와 동일한 동작 (fparr 사용) | |
| 98 | fparr 2 | |
| 99 | fpmovi 0 _a | |
| 100 | push {PerfectCombo} | |
| 101 | fppopi 1 | |
| 102 | call Max | |
| 103 | pop c | |
| 104 | ||
| 105 | ; c를 100으로 나눈 나머지 연산 (뺄셈 루프) | |
| 106 | loop: | |
| 107 | push c | |
| 108 | push 100 | |
| 109 | jle exit ; c <= 100이면 exit로 이동 | |
| 110 | ||
| 111 | push c | |
| 112 | push 100 | |
| 113 | sub | |
| 114 | pop c ; c = c - 100 | |
| 115 | jmp loop | |
| 116 | ||
| 117 | exit: | |
| 118 | }}} | |
| 119 | ||
| 120 | == 참조 == | |
| 121 | === 태그 === | |
| 122 | {{{#!wiki class="code" {{{{태그}}}}}}}로 지정한 태그의 현재 값을 가져온다. | |
| 123 | ||
| 124 | ||<bgcolor=#3D3D3D><color=#fff><width=200> 태그 ||<bgcolor=#3D3D3D><color=#fff> 설명 || | |
| 125 | || {{{#!wiki class="code" {{{{PerfectCombo}}}}}}} || 연속 "정확" 판정 개수 || | |
| 126 | || {{{#!wiki class="code" {{{{PerfectCount}}}}}}} || "정확" 판정 개수 || | |
| 127 | || {{{#!wiki class="code" {{{{EPerfectCount}}}}}}} || "빠름" 판정 개수 || | |
| 128 | || {{{#!wiki class="code" {{{{EarlyCount}}}}}}} || "빠름!" 판정 개수 || | |
| 129 | || {{{#!wiki class="code" {{{{TooEarlyCount}}}}}}} || "빠름!!" 판정 개수 || | |
| 130 | || {{{#!wiki class="code" {{{{LPerfectCount}}}}}}} || "느림" 판정 개수 || | |
| 131 | || {{{#!wiki class="code" {{{{LateCount}}}}}}} || "느림!" 판정 개수 || | |
| 132 | || {{{#!wiki class="code" {{{{TooLateCount}}}}}}} || "느림!!" 판정 개수 || | |
| 133 | || {{{#!wiki class="code" {{{{MissCount}}}}}}} || "놓침…" 판정 개수 || | |
| 134 | || {{{#!wiki class="code" {{{{OverPressCount}}}}}}} || "과입력!" 판정 개수 || | |
| 135 | || {{{#!wiki class="code" {{{{OverloadCount}}}}}}} || "과부하…" 판정 개수 || | |
| 136 | || {{{#!wiki class="code" {{{{Fps}}}}}}} || 현재 프레임률 || | |
| 137 | ||
| 138 | === 함수 === | |
| 139 | 함수의 인자는 {{{#!wiki class="code" {{{이름:값유형(인덱스)}}}}}}} 형식으로 정의된다. 인자의 개수는 {{{#!wiki class="code" {{{마지막 인자의 인덱스 + 1}}}}}}}이다.[* null이 가능한 인자도 동일한 형식으로 표기한다. 기본적으로 인자가 {{{#!wiki class="code" {{{null}}}}}}인 경우 체크박스 꺼짐 상태로 간주한다.] 특별한 언급이 없는 경우 '''기간'''은 이벤트가 실행되는 타일 기준으로 계산되며 음이 아닌 실수여야 한다. | |
| 140 | ||
| 141 | * {{{#!wiki class="code" {{{TileNum()}}}}}}} — 이 이벤트가 설치된 타일 번호를 반환한다. | |
| 142 | * {{{#!wiki class="code" {{{EntryAngle()}}}}}}} — 이 이벤트가 설치된 타일의 진입 각도를 반환한다. | |
| 143 | * {{{#!wiki class="code" {{{ExitAngle()}}}}}}} — 이 이벤트가 설치된 타일의 진출 각도를 반환한다. | |
| 144 | * {{{#!wiki class="code" {{{Random()}}}}}}} — {{{#!wiki class="code" {{{0~1}}}}}} 사이의 무작위 실수를 반환한다.[* "변수 설정" 이벤트에서 설정된 시드와 무관하게 독립적으로 작동한다.] | |
| 145 | * {{{#!wiki class="code" {{{Min(실수(0), 실수(1))}}}}}}} — 두 수 중 작은 값을 반환한다. | |
| 146 | * {{{#!wiki class="code" {{{Max(실수(0), 실수(1))}}}}}}} — 두 수 중 큰 값을 반환한다. | |
| 147 | * {{{#!wiki class="code" {{{Pow(실수(0), 실수(1))}}}}}}} — 왼쪽 수를 밑, 오른쪽 수를 지수로 하는 거듭제곱 값을 반환한다. | |
| 148 | * {{{#!wiki class="code" {{{Execute(이벤트태그:문자열(0))}}}}}}} — 이벤트를 실행한다. 이벤트 태그는 레벨에 설치된 모든 이벤트에서 검색한다. | |
| 149 | * {{{#!wiki class="code" {{{MoveCamera(기간:실수(0), 가감속:열거(1), 카메라기준좌표:열거(2), 위치오프셋:배열(3), 회전오프셋:실수(4), 확대값:실수(5))}}}}}}} — 카메라를 이동한다.[* {{{#!wiki class="code" {{{위치오프셋}}}}}}은 길이가 {{{#!wiki class="code" {{{2}}}}}}이어야 하며 각 요소는 X, Y를 가리킨다. 요소를 {{{#!wiki class="code" {{{NaN}}}}}}으로 설정하면 해당 축으로의 카메라 이동을 막을 수 있다.] | |
| 150 | * {{{#!wiki class="code" {{{MoveTrack(시작타일:정수(0), 끝타일:정수(1), 틈길이:정수(2), 기간:실수(3), 가감속:열거(4), 위치오프셋:배열(5), 회전오프셋:실수(6), 크기:배열(7), 불투명도:실수(8))}}}}}}} — 트랙을 이동한다.[* {{{#!wiki class="code" {{{위치오프셋}}}}}}과 {{{#!wiki class="code" {{{크기}}}}}}는 길이가 {{{#!wiki class="code" {{{2}}}}}}이어야 하며 각 요소는 X, Y를 가리킨다. 요소를 {{{#!wiki class="code" {{{NaN}}}}}}으로 설정하면 해당 축으로의 속성 변경을 막을 수 있다.] | |
| 151 | * {{{#!wiki class="code" {{{MoveDecorations(태그:문자열(0), 기간:실수(1), 가감속:열거(2), 보이기:논리(3), 장식기준좌표:열거(4), 이미지:문자열(5), 위치오프셋:배열(6), 중심점오프셋:배열(7), 회전오프셋:실수(8), 크기:배열?(9), 색상:배열(10), 불투명도:실수(11), 깊이:정수(12), 시차:배열(13), 시차오프셋:배열(14), 마스킹타입:열거(15), 마스킹깊이사용:논리(16), 마스킹시작깊이:정수(17), 마스킹끝깊이:정수(18))}}}}}}} — 장식을 이동한다.[* {{{#!wiki class="code" {{{위치오프셋}}}}}}、{{{#!wiki class="code" {{{중심점오프셋}}}}}}、{{{#!wiki class="code" {{{크기}}}}}}、{{{#!wiki class="code" {{{시차}}}}}}、{{{#!wiki class="code" {{{시차오프셋}}}}}}는 길이가 {{{#!wiki class="code" {{{2}}}}}}이어야 하며 각 요소는 X, Y를 가리킨다. 요소를 {{{#!wiki class="code" {{{NaN}}}}}}으로 설정하면 해당 축으로의 속성 변경을 막을 수 있다. {{{#!wiki class="code" {{{색상}}}}}}은 길이가 {{{#!wiki class="code" {{{4}}}}}}여야 하며 각 요소는 R, G, B, A를 0과 1 사이의 정규화된 값으로 가리킨다.] | |
| 152 | ||
| 153 | === 열거형 === | |
| 154 | 열거형 값은 문자열의 확장이다. | |
| 155 | ||
| 156 | * {{{#!wiki class="code" {{{가감속}}}}}} | |
| 157 | * {{{#!wiki class="code" {{{Linear}}}}}}、{{{#!wiki class="code" {{{InOutSine}}}}}}、{{{#!wiki class="code" {{{InSine}}}}}}、{{{#!wiki class="code" {{{OutSine}}}}}} | |
| 158 | * {{{#!wiki class="code" {{{InOutQuad}}}}}}、{{{#!wiki class="code" {{{InQuad}}}}}}、{{{#!wiki class="code" {{{OutQuad}}}}}} | |
| 159 | * {{{#!wiki class="code" {{{InOutCubic}}}}}}、{{{#!wiki class="code" {{{InCubic}}}}}}、{{{#!wiki class="code" {{{OutCubic}}}}}} | |
| 160 | * {{{#!wiki class="code" {{{InOutQuart}}}}}}、{{{#!wiki class="code" {{{InQuart}}}}}}、{{{#!wiki class="code" {{{OutQuart}}}}}} | |
| 161 | * {{{#!wiki class="code" {{{InOutQuint}}}}}}、{{{#!wiki class="code" {{{InQuint}}}}}}、{{{#!wiki class="code" {{{OutQuint}}}}}} | |
| 162 | * {{{#!wiki class="code" {{{InOutExpo}}}}}}、{{{#!wiki class="code" {{{InExpo}}}}}}、{{{#!wiki class="code" {{{OutExpo}}}}}} | |
| 163 | * {{{#!wiki class="code" {{{InOutCirc}}}}}}、{{{#!wiki class="code" {{{InCirc}}}}}}、{{{#!wiki class="code" {{{OutCirc}}}}}} | |
| 164 | * {{{#!wiki class="code" {{{InOutBounce}}}}}}、{{{#!wiki class="code" {{{InBounce}}}}}}、{{{#!wiki class="code" {{{OutBounce}}}}}} | |
| 165 | * {{{#!wiki class="code" {{{InOutElastic}}}}}}、{{{#!wiki class="code" {{{InElastic}}}}}}、{{{#!wiki class="code" {{{OutElastic}}}}}} | |
| 166 | * {{{#!wiki class="code" {{{카메라기준좌표}}}}}} | |
| 167 | * {{{#!wiki class="code" {{{Player}}}}}}、{{{#!wiki class="code" {{{Tile}}}}}}、{{{#!wiki class="code" {{{Global}}}}}}、{{{#!wiki class="code" {{{LastPosition}}}}}}、{{{#!wiki class="code" {{{LastPositionNoRotation}}}}}} | |
| 168 | * {{{#!wiki class="code" {{{마스킹타입}}}}}} | |
| 169 | * {{{#!wiki class="code" {{{None}}}}}}、{{{#!wiki class="code" {{{Mask}}}}}}、{{{#!wiki class="code" {{{VisibleInsideMask}}}}}}、{{{#!wiki class="code" {{{VisibleOutsideMask}}}}}} | |
| 170 | * {{{#!wiki class="code" {{{장식기준좌표}}}}}} | |
| 171 | * {{{#!wiki class="code" {{{Tile}}}}}}、{{{#!wiki class="code" {{{Global}}}}}}、{{{#!wiki class="code" {{{RedPlanet}}}}}}、{{{#!wiki class="code" {{{BluePlanet}}}}}}、{{{#!wiki class="code" {{{GreenPlanet}}}}}}、{{{#!wiki class="code" {{{Camera}}}}}}、{{{#!wiki class="code" {{{CameraAspect}}}}}}、{{{#!wiki class="code" {{{LastPosition}}}}}} | |
| 172 | ||
| 173 | == 문법 오류 == | |
| 174 | 자동 플레이 상태에서 프로그램에 오류가 발생하면 이벤트 실행 시점에 화면 좌상단에 해당 이벤트가 위치한 '''타일 번호'''와 '''줄 번호'''가 메시지로 표시된다. |