본문 바로가기
programming/renpy

[renpy 강좌 05 ] 특정 조건에 맞는 이벤트 실행하기

by FAPER 2024. 7. 3.

event_dispatcher.rpy
0.01MB

이전 강의

https://faper.tistory.com/43

https://faper.tistory.com/39

https://faper.tistory.com/38

https://faper.tistory.com/37

 


게임을 만들다 보면 특정 호감도나, 특정 스탯에 대해서 조건을 달성하면 이벤트가 시작되게 하고 싶을 때가 있다.

 

예를 들어서,  게임 진행도가 10일 이상이고, 행운이 5 이상이면 '로또 당첨'이라는 이벤트를 진행하게 하고 싶다거나

특정 상황까지 왔을 때 현재 스탯을 고려해서 누군가의 호감도가 몇 이상일 때 다음 이벤트가 진행되게 만들고 싶다.

물론 파이썬으로 조건분기를 빡세게 걸어서 만들 수 있긴 한데.. 굳이 그럴 필요 없이 렌파이에서 만들어 놓은 DSE라는 스크립트가 있다.

 

https://github.com/renpy/dse

 

GitHub - renpy/dse: Dating Sim Engine

Dating Sim Engine. Contribute to renpy/dse development by creating an account on GitHub.

github.com

이 사람의 저장소를 보고 정리한 내용이다.

DSE는 Dating Sim Engine으로, 이벤트를 등록하고 우선순위 등을 설정해서 선행되는 이벤트를 지정하거나, 한 번만 이벤트가 진행되거나 하게 할 수 있다.

 

일단 이 event_dispatcher.rpy 파일을 다운로드 후 game/ 폴더 밑에 넣어주면 된다. 

그리고 새롭게 events.rpy라는 파일을 만들어 준다.

 

init python:
    event('rest', "act=='휴식'" ,priority=200)
    event('health', "act=='운동'", priority=200)
    event('walk', "act=='산책'", priority=200)
    event('study', "act=='공부'", priority=200)
    event('anger', "stress >= 5", event.once(), priority=200)



label anger:
    '너무 화나서 분노 조절 장애에 걸렸다.'
    $diss = True
    return
label health:
    $stress +=1
    $strength +=2
    '운동을 했다.'
    return

label walk:
    $stress = max(stress - 1, 0)
    $luck +=3
    '산책을 했다.'
    return

label study:
    '공부를 했다.'
    $stress += 1
    $inteligence +=2
    return

label rest:
    $ stress = max(stress - 3, 0)
    '푹 쉬었다.'
    return

 

event() 라는 함수를 통해서 이벤트를 생성할 수 있고, 우선순위와 조건 등을 쓸 수 있다.

그리고 만들면서 알게 된 사실인데, 렌파이는 *. rpy안에 있는 모든 파이썬 변수를 공유한다. 무슨 말이냐면 내가 events.rpy에서 변수를 선언하든, scripts.rpy에서 선언하든 일단 init python으로 만들어 놓으면 label에서는 모두 $변수명으로 호출할 수 있다. 

 

# 이 파일에 게임 스크립트를 입력합니다.
init python:
    name = ""
    day = 0 #일 수
    stress = 0  #스트레스
    strength  = 0 #근력
    inteligence = 0 #지성
    luck = 0 # 운
    morning = '휴식' 
    free = '휴식'
    afternoon = '휴식'
    act = ''
    
    diss = False # 분노 조절 장애

# 게임에서 사용할 캐릭터를 정의합니다.
define e = Character('아이린', color="#c8ffc8", image='airin01')
define sys = Character('system', color="#d42a1e")
# image 문을 사용해 이미지를 정의합니다.
# image eileen happy = "eileen_happy.png"
image city = "bg01.png"
image cafe = "cafe.png"
image park = "park.png"

image airin01 = "airin01.png"
image airin01 idle = "airin02.png"



init: 
    screen stat: #스텟창
        frame:
            align (0.95, 0.05)
            grid 5 2:
                text ' 시간  '
                text ' 분노  '
                text ' 근력  '
                text ' 지성  '
                text ' 행운  '

                text "%2d일" % day
                text "%2d" % stress
                text "%2d" % strength
                text "%2d" % inteligence
                text "%2d" % luck

    screen planner:
        frame:
            align(0.5, 0.4)
            vbox:
                grid 3 2:
                    text '오전'
                    text '점심'
                    text '오후'

                    textbutton morning action Show('schedule', period='morning')
                    textbutton free action Show('schedule', period='free')
                    textbutton afternoon action Show('schedule',period='afternoon')
                textbutton '완료' action Return() align (.5, .5)
    screen schedule:
        frame:
            align(.5, .2)
            vbox:
                text '실행할 스케줄 선택'
                textbutton '휴식' action [ SetVariable(period, '휴식'), Hide('schedule')]
                textbutton '운동' action [ SetVariable(period, '운동'), Hide('schedule')]
                textbutton '공부' action [ SetVariable(period, '공부'), Hide('schedule')]
                textbutton '산책' action [ SetVariable(period, '산책'), Hide('schedule')]


# 여기에서부터 게임이 시작합니다.
label start:
    scene city

    sys "오른쪽 상단에서 현재 상태를 알 수 있습니다."
    sys "하루의 일과를 정해보세요."
    $ news = renpy.fetch("https://cifrar.cju.ac.kr/robots.txt", result="text")
    "[news]"
    show screen stat
    jump schedule_set
    return

label schedule_set:
    $ day += 1
    "오늘 뭐하지"
    call screen planner

    "오늘의 일정은 아침에 [morning] , 점심엔 [free] , 저녁에 [afternoon]"

    # $ result = renpy.fetch("https://example.com/api", json={"name": "Ren'Py"}, result="json")
    jump morning
    jump free
    jump afternoon


label morning:
    # centered "아침.."
    "[morning]을(를) 하자"
    
    $ period = "morning"
    $ act = morning
    call events_run_period
label free:
    #  centered "점심.."
    $ act = free
    call events_run_period
label afternoon:
    #  centered "저녁.."
    $ act = afternoon
    call events_run_period

    if day == 365:
        jump ending
    else:
        jump schedule_set
label ending:
    '엔딩'

 

그리고 하루마다 선택지를 고를 수 있는 스크립트를 짜봤다. 여기 보면 하루마다 아침/점심/저녁 으로 어떤 행동을 할지 결정할 수 있고, 선택하면 call events_run_period라는 구문을 통해서 이벤트를 실행한다. 

 

그럼 이렇게 일과를 정할 수 있고

 

일정이 결정되면 아침, 점심, 저녁 순서로 일정이 진행된다.

다시 events.rpy로 돌아와서 설명하면.

init python:
    event('rest', "act=='휴식'" ,priority=200)
    event('health', "act=='운동'", priority=200)
    event('walk', "act=='산책'", priority=200)
    event('study', "act=='공부'", priority=200)
    event('anger', "stress >= 5", event.once(), priority=200)



label anger:
    '너무 화나서 분노 조절 장애에 걸렸다.'
    $diss = True
    return
label health:
    $stress +=1
    $strength +=2
    '운동을 했다.'
    return

label walk:
    $stress = max(stress - 1, 0)
    $luck +=3
    '산책을 했다.'
    return

label study:
    '공부를 했다.'
    $stress += 1
    $inteligence +=2
    return

label rest:
    $ stress = max(stress - 3, 0)
    '푹 쉬었다.'
    return

 

act가 행위이고, 해당 행위가 어떤 것인지에 따라 변수의 값을 조정하고 있다.

act == '휴식' 을 만족한다면 label rest를 호출하고, 스트레스를 3 감소시킨다. max(stress - 3, 0 )은 값이 음수가 되지 않게 처리한 것이다. 

act == '운동' 을 만족한다면 label health를 호출하고 스트레스를 1 증가시키고 근력을 2 증가시킨다.

그리고 보면 이벤트 중에 anger라고 있는데, 스트레스가 5 이상으로 넘어가면 딱 한번 실행되며, 분노 조절장애가 걸리고 diss라는 변수에 값을 참으로 바꾼다. 

 

이렇게 분노가 6이 되자 anger 이벤트가 실행된 모습이다.

 

이를 응용하면 특정 일수에 특정 스탯을 만족하면 결과를 다르게 보여주는 이벤트를 짤 수 있다.