본문 바로가기

렌파이/게임 제작하기

텍스트 어드벤처 만들기 (2) 선택지와 분기 만들기

선택지 만들기

menu 문

선택지를 만들 때는 menu: 를 사용하면 됩니다. menu 명령문 다음 줄에는 선택지로 표시할 문장을 입력하고, 그 문장에 콜론을 입력해서 다음 줄에 내용을 적으면, 그 선택지가 선택되었을 때 취할 행동을 결정할 수 있습니다.


위 스크립트를 실행하면 "푸 파이터즈의 디즈 데이즈" 라는 선택지와 "래드윔프스의 덕아웃"이라는 선택지 두 개가 보이며, 각 선택지를 클릭하면 해당 문장 아래에 적은 가사 내용이 출력되는 것을 확인할 수 있습니다.

menu 도 init 나 label 처럼 콜론을 붙여 사용해야 하는 명령문입니다. 이렇게 콜론을 붙여 사용하는 명령문은 렌파이에서는 블록 형태를 취한다고 말합니다(자세한 사항은 블록 항목을 참조하세요).

이야기 진행 흐름 바꾸기

선택지 밑에 계속 선택지를 만들어 이야기의 분기를 만들면 스크립트를 알아보기 힘들어집니다. 게다가 설령 선택지가 한 번 나온다고 해도 menu 문에 계속해서 내용을 적으면 분명 불편한 점이 있습니다. 렌파이에서는 jump 문, call 문으로 이야기 흐름을 바꿀 수 있습니다. 그 전에 label 문을 이용해서 특정 대사 영역에 이름을 지어주어야 합니다.

label 문

label 문을 이용해서 특정한 대사 묶음에 이름을 지으면 이 이름을 call 이나 jump 명령문과 함께 사용해서 게임 진행 흐름을 바꿀 수 있습니다. 이전에 label start 라고 적어 label 문을 이용했는데, label 문은 그대로 두고 옆의 start 글자를 자신이 원하는 이름으로 바꾸면 특정 스크립트들을 한뭉텅이로 지정해 그것에 이름을 붙일 수 있게 됩니다.


label 문 이용시 주의할 점
  1. 당연한 얘기지만 같은 이름을 가진 라벨은 만들 수 없습니다. 
  2. 이름으로는 한글도 사용할 수 있습니다(label 디즈데이즈: 도 됀다는 이야기입니다).
  3. 이름에는 띄어쓰기를 사용할 수 없습니다.

return 문

return 은 해당 영역에서 이야기 진행 흐름을 끊을 때 사용하는 명령문입니다. 위 예제에서 label these_days 에 return 을 입력하지 않는다면 label dugout 에 적힌 대사까지 나타납니다.

jump 문과 call 문

label 로 대사 뭉치에 정해준 이름을 jump 에 사용하면 해당 레이블로 건너뛰게 됩니다.

call 도 비슷한 기능을 하지만 다른 점이 있다면 jump 는 흐름이 아예 넘어가는 반면, call 은 해당 label 블록을 다 진행한 후 return 문을 만나면 call 문이 적힌 다음 문장으로 다시 돌아간다는 것입니다.



위 예제를 실행하면 차례로 1번, 2번, 3번 문장이 나타납니다.

처음 menu 를 이용해 적었던 스크립트를 label 과 jump 를 이용해 정리하면 다음과 같이 바꿀 수 있습니다.




분기 만들기

menu 로 선택지를 만들어 단순 이야기 흐름을 바꾸는 것보다는 플레이어가 무엇을 선택했는지 기억했다가, 이 선택을 나중에 활용해야 할 때가 더 많습니다. 예를 들면 처음에 선택을 잘 해서 호감도가 높아졌다면 엔딩에서는 굿엔딩이 등장한다던가 하는 식으로 말입니다. 이 때 사용하는 것이 변수입니다.

변수

개념

변수는 "변할 수 있는 수"라고 생각하면 됩니다. 변수를 하나 만들면 변수에 숫자, 글자, 문장같은 여러 데이터를 입력해 저장할 수 있습니다. 변수를 만들어서 변수를 만들어서 데이터를 저장하는 방법은 아래와 같습니다.

 define 변수이름 = 변수에 저장할 데이터

변수에 데이터를 저장하려면 위처럼 등호(=)를 하나 입력해야 합니다. 이는 오른쪽에 있는 것을 왼쪽에 적힌 변수에 저장한다는 의미라고 생각하면 됩니다. 수학에서 쓰는 등호와 다릅니다. 참고로 변수 이름은 한글로 지정할 수 없습니다.


변수는 상황에 따라 값이 임의로 바뀔 수 있으며, 게임에서 수시로 참고하므로 init 블록에서 최초값을 설정해주는 것이 좋습니다.

사용법

init 블록에서는 define 문을 이용해 변수에 값을 저장하는데, 이 명령문은 초보자의 이해를 돕기 위한 것으로 init 블록에서만 사용할 수 있습니다. 사실 변수에 값을 저장할 때는 렌파이가 기반으로 하는 프로그래밍 언어인 파이썬의 힘을 직접 빌어야 합니다. 그래서 "파이썬의 힘을 빌린다"는 의미로 변수 앞에 $ 기호를 적어야 합니다.



label 블록 안에서도 변수에 값을 저장하려면 $ 를 사용해야 합니다. 혹, 변수를 여럿 지정하는데 $ 입력이 귀찮다면 파이썬 블록을 이용하면 됩니다. init 문에서는 python: 블록을 사용해도 되지만 합쳐서 init python: 블록을 만들고 변수를 저장해도 됩니다.



변수가 숫자값을 저장했다면 변수에 다른 값을 더하거나 뺄 수도 있습니다.
예를 들어 호감도가 떨어질만한 선택지를 눌렀다면 다음과 같이 입력해서 기존 호감도 수치에서 일정 수치를 뺄 수 있습니다.
(덧셈할 때는 - 대신 + 를 입력하면 됩니다)


또한 다른 변수에 저장된 값을 이용해 변수에 새 값을 저장할 수도 있습니다.


활용 예

첫 번째 스크립트에서 선택지와 변수를 이용해 어떤 사용자가 어떤 노래를 선택했는지 저장하려면 다음과 같이 입력하면 됩니다.


if 문

위에서처럼 지정한 변수를 사용해서 분기를 나누려면 if 문을 이용하면 됩니다. if 문은 "~라면" 의 뜻 그대로의 기능을 하는 명령문입니다. 블록 형태를 취합니다.


if 문의 오른쪽에 적은 식이 True면 그 아래 들여쓰기된 문장이 실행됩니다. 위 스크립트를 해석하면 choice 라는 변수의 값이 1이면 "푸 파이터즈~"  대사를 출력하고, 그렇지 않으면 "래드윔프스~" 대사를 출력한다는 의미입니다. 여기서 등호를 두 개 연달아 쓴 것이 바로 "같다" 는 뜻의 기호입니다. 아까도 적었지만 등호 1개는 변수에 값을 저장하고, 등호 2개는 값을 비교하는 기능을 합니다.

if 문 오른쪽에 적은 비교가 맞지 않을 경우, 위의 예로 설명하면 choice 변수의 값이 1이 아닌 경우 실행할 명령문은 else 블록에 적습니다. 이 때 else 는 같은 양의 들여쓰기가 된 if 문과 짝이된다는 점을 유의해야 합니다. if 문에는 대사 외에도 jump, call, 등의 렌파이 명령문과 변수를 저장하는 명령문을 적을 수도 있습니다.

참고: 블록

같은 양의 들여쓰기가 된 문장들은 서로 같은 블록에 속하게 됩니다.


위 스크립트에서 "어떤 음악을 들을까" 라는 대사와 "가사 참 좋네" 라는 대사는 멀리 떨어져 있긴 하지만 같은 양만큼 들여쓰기 되어있으므로 label start 라는 같은 블록에 있는 것입니다. 또한 두 선택지 블록은 menu 블록에 속한 블록입니다.

스크립트를 보면  init 블록, label start 블록, menu 블록, 각 선택지 블록, 총 5개의 블록이 눈에 들어옵니다. 그러나 스크립트 파일 자체도 들여쓰기가 하나도 안 된 하나의 블록으로 볼 수 있으므로 위 스크립트에는 총 6개의 블록이 있습니다.

스크립트 파일 자체를 제외하면 블록은 끝에 콜론(:)을 적는 명령문 다음줄부터 만들어집니다. 이 때 자동으로 들여쓰기가 되는데 이는 앞 포스트에 적었듯 렌파이/파이썬에서는 반드시 지켜야할 법칙입니다. 

FAQ


if 문이 / 변수가 작동하지 않습니다. 에러메시지는 없습니다.

등호 갯수를 확인하세요. if 문의 경우 좌우값을 비교할 때는 등호 기호를 두 개(==) 적습니다. 변수에 값을 저장할 때는 등호를 하나(=) 적습니다.

변수에 숫자만 저장할 수 있는 건가요?

변수에는 파이썬 프로그래밍 언어가 지원하는 모든 데이터를 저장할 수 있습니다. 자세한 건 이쪽을 참조하세요.

if 문에서 값을 비교할 때 사용할 수 있는 기호는 무엇인가요?

이 페이지에 나온 비교연산자 항목을 참조하세요.