키맵 사용자 설정

config.keymap 변수에는 이벤트 이름을 해당 이벤트를 발생시키는 키심(keysym) 리스트에 연결하는 맵이 들어 있습니다.

참고

많은 플레이어가 Ren'Py의 기본 키 설정에 익숙하며, 게임이 달라도 같은 설정을 기대합니다.

Ren'Py에서 키심은 마우스 버튼, 조이스틱 버튼 또는 키보드 키를 나타내는 문자열입니다.

마우스 버튼의 키심은 'mouseup_#' 또는 'mousedown_#' 형태이며, #은 버튼 번호입니다. Ren'Py는 버튼 5개가 있는 마우스를 가정합니다. 버튼 1, 2, 3은 각각 왼쪽, 가운데, 오른쪽 버튼이며, 버튼 4와 5는 휠을 위아래로 스크롤할 때 발생합니다. 예를 들어 "mousedown_1"은 일반적으로 왼쪽 마우스 버튼 누르기, "mouseup_1"은 그 버튼 놓기, "mousedown_4"는 스크롤 휠을 위로 돌리기입니다.

키보드 키심에는 두 종류가 있습니다. 첫 번째는 키를 눌렀을 때 생성되는 문자를 담은 문자열입니다. 알파벳과 숫자 키를 연결할 때 유용하며, 예로 "a", "A", "7"이 있습니다. 대소문자를 구분하므로 "a"는 "A"와 일치하지 않습니다. 이 종류의 키심은 이벤트가 텍스트를 생성할 때만 유효합니다. 예를 들어 a 키를 놓으면 텍스트가 생성되지 않으므로 keyup_a와 일치하지 않습니다.

키보드 키심으로 키의 기호 이름을 사용할 수도 있습니다. pygame.constants의 K_ 상수라면 모두 사용할 수 있습니다. "K_BACKSPACE", "K_RETURN", "K_TAB" 같은 형태이며, 전체 목록은 여기에서 확인할 수 있습니다.

키보드와 마우스 키심 앞에는 다음 접두사를 밑줄로 구분하여 붙일 수 있습니다.

alt

Alt 키를 누르고 있을 때 일치합니다. 이 접두사가 없는 키심은 Alt 키를 누르지 않았을 때 일치합니다.

meta

Meta, Command 또는 Windows 키를 누르고 있을 때 일치합니다. 이 접두사가 없는 키심은 meta 키를 누르지 않았을 때 일치합니다.

ctrl

Ctrl 키를 누르고 있을 때 일치합니다. 이 접두사가 없는 키심은 Ctrl 키를 누르지 않았을 때 일치합니다. Ctrl은 보통 건너뛰기를 시작하므로 활용도가 높지 않습니다.

osctrl

Macintosh에서는 Alt, 그 밖의 플랫폼에서는 Ctrl입니다.

anymod

Alt, Meta, Ctrl 키의 상태와 관계없이 일치합니다.

shift

Shift 키를 누르고 있을 때 일치합니다.

noshift

Shift 키를 누르지 않았을 때 일치합니다.

caps

Caps Lock이 켜져 있을 때 일치합니다.

nocaps

Caps Lock이 꺼져 있을 때 일치합니다.

num

Num Lock이 켜져 있을 때 일치합니다.

nonum

Num Lock이 꺼져 있을 때 일치합니다.

repeat

키를 누르고 있어 반복 입력이 발생할 때 일치합니다. repeat 또는 any 접두사가 없는 키심은 반복 입력과 일치하지 않습니다. 마우스 버튼에는 작동하지 않습니다.

anyrepeat

최초 키 입력과 반복 입력 모두에 일치합니다.

keydown

키를 누를 때 일치합니다. 기본 동작입니다.

keyup

키를 놓을 때 일치합니다.

예를 들어 "shift_alt_K_F5" 키심은 Shift와 Alt를 누른 상태에서 F5 키를 누르면 일치합니다. "shift_mouse_1" 키심은 Shift를 누른 상태에서 왼쪽 마우스 버튼을 누르면 일치합니다.

키 연결을 바꾸려면 config.keymap에서 해당 리스트를 수정합니다. 다음 예제는 say 문을 진행시키는 키 목록에 't'를 추가하고 스페이스 키를 제거합니다.

init python:
    config.keymap['dismiss'].append('K_t')
    config.keymap['dismiss'].remove('K_SPACE')

기본 키맵은 renpy/common/00keymap.rpy에 있으며, 버전 8.4.0 기준으로 다음과 같습니다.

config.keymap = dict(

    # Bindings present almost everywhere, unless explicitly
    # disabled.
    rollback = [ 'anyrepeat_K_PAGEUP', 'anyrepeat_KP_PAGEUP', 'K_AC_BACK', 'mousedown_4' ],
    screenshot = [ 'alt_K_s', 'alt_shift_K_s', 'noshift_K_s' ],
    toggle_afm = [ ],
    toggle_fullscreen = [ 'alt_K_RETURN', 'alt_K_KP_ENTER', 'K_F11', 'noshift_K_f' ],
    game_menu = [ 'K_ESCAPE', 'K_MENU', 'K_PAUSE', 'mouseup_3' ],
    hide_windows = [ 'mouseup_2', 'noshift_K_h' ],
    launch_editor = [ 'shift_K_e' ],
    dump_styles = [ ],
    reload_game = [ 'alt_K_r', 'shift_K_r' ],
    inspector = [ 'alt_noshift_K_i', 'shift_K_i' ],
    full_inspector = [ 'alt_shift_K_i' ],
    developer = [ 'alt_K_d', 'shift_K_d', ],
    quit = [ ],
    iconify = [ ],
    help = [ 'K_F1', 'meta_shift_/' ],
    choose_renderer = ['alt_K_g', 'shift_K_g' ],
    progress_screen = [ 'alt_shift_K_p', 'meta_shift_K_p', 'K_F2' ],
    bubble_editor = [ 'alt_K_b', 'shift_K_b' ],

    # Accessibility.
    accessibility = [ 'shift_K_a' ],
    self_voicing = [ 'alt_K_v', 'K_v' ],
    clipboard_voicing = [ 'alt_shift_K_c', 'shift_K_c' ],
    debug_voicing = [ 'alt_shift_K_v', 'meta_shift_K_v' ],
    extra_voicing = [ '?' ],

    # Say.
    rollforward = [ 'anyrepeat_K_PAGEDOWN', 'anyrepeat_KP_PAGEDOWN', 'mousedown_5', ],
    dismiss = [ 'K_RETURN', 'K_SPACE', 'K_KP_ENTER', 'K_SELECT', 'mouseup_1' ],
    dismiss_unfocused = [ ],

    # Pause.
    dismiss_hard_pause = [ ],

    # Focus.
    focus_left = [ 'anyrepeat_K_LEFT', 'anyrepeat_KP_LEFT' ],
    focus_right = [ 'anyrepeat_K_RIGHT', 'anyrepeat_KP_RIGHT' ],
    focus_up = [ 'anyrepeat_K_UP', 'anyrepeat_KP_UP' ],
    focus_down = [ 'anyrepeat_K_DOWN', 'anyrepeat_KP_DOWN' ],

    # Button.
    button_ignore = [ 'mousedown_1' ],
    button_select = [ 'K_RETURN', 'K_KP_ENTER', 'K_SELECT', 'mouseup_1',  ],
    button_alternate = [ 'mouseup_3' ],
    button_alternate_ignore = [ 'mousedown_3' ],

    # Input.
    input_backspace = [ 'anyrepeat_K_BACKSPACE' ],
    input_enter = [ 'K_RETURN', 'K_KP_ENTER' ],
    input_next_line = [ 'shift_K_RETURN', 'shift_K_KP_ENTER' ],
    input_left = [ 'anyrepeat_K_LEFT', 'anyrepeat_KP_LEFT' ],
    input_right = [ 'anyrepeat_K_RIGHT', 'anyrepeat_KP_RIGHT' ],
    input_up = [ 'anyrepeat_K_UP', 'anyrepeat_KP_UP' ],
    input_down = [ 'anyrepeat_K_DOWN', 'anyrepeat_KP_DOWN' ],
    input_delete = [ 'anyrepeat_K_DELETE', 'anyrepeat_KP_DELETE' ],
    input_home = [ 'K_HOME', 'KP_HOME', 'meta_K_LEFT' ],
    input_end = [ 'K_END', 'KP_END', 'meta_K_RIGHT' ],
    input_copy = [ 'ctrl_noshift_K_INSERT', 'ctrl_noshift_K_c', 'meta_noshift_K_c' ],
    input_paste = [ 'shift_K_INSERT', 'ctrl_noshift_K_v', 'meta_noshift_K_v' ],
    input_jump_word_left = [ 'osctrl_K_LEFT', 'osctrl_KP_LEFT' ],
    input_jump_word_right = [ 'osctrl_K_RIGHT', 'osctrl_KP_RIGHT' ],
    input_delete_word = [ 'osctrl_K_BACKSPACE' ],
    input_delete_full = [ 'meta_K_BACKSPACE' ],

    # Viewport.
    viewport_leftarrow = [ 'anyrepeat_K_LEFT', 'anyrepeat_KP_LEFT' ],
    viewport_rightarrow = [ 'anyrepeat_K_RIGHT', 'anyrepeat_KP_RIGHT' ],
    viewport_uparrow = [ 'anyrepeat_K_UP', 'anyrepeat_KP_UP' ],
    viewport_downarrow = [ 'anyrepeat_K_DOWN', 'anyrepeat_KP_DOWN' ],
    viewport_wheelup = [ 'mousedown_4' ],
    viewport_wheeldown = [ 'mousedown_5' ],
    viewport_drag_start = [ 'mousedown_1' ],
    viewport_drag_end = [ 'mouseup_1' ],
    viewport_pageup = [ 'anyrepeat_K_PAGEUP', 'anyrepeat_KP_PAGEUP'],
    viewport_pagedown = [ 'anyrepeat_K_PAGEDOWN', 'anyrepeat_KP_PAGEDOWN' ],

    # These keys control skipping.
    skip = [ 'anymod_K_LCTRL', 'anymod_K_RCTRL' ],
    stop_skipping = [ ],
    toggle_skip = [ 'K_TAB' ],
    fast_skip = [ '>', 'shift_K_PERIOD' ],

    # Bar.
    bar_activate = [ 'mousedown_1', 'K_RETURN', 'K_KP_ENTER', 'K_SELECT' ],
    bar_deactivate = [ 'mouseup_1', 'K_RETURN', 'K_KP_ENTER', 'K_SELECT' ],
    bar_left = [ 'anyrepeat_K_LEFT', 'anyrepeat_KP_LEFT' ],
    bar_right = [ 'anyrepeat_K_RIGHT', 'anyrepeat_KP_RIGHT' ],
    bar_up = [ 'anyrepeat_K_UP', 'anyrepeat_KP_UP' ],
    bar_down = [ 'anyrepeat_K_DOWN', 'anyrepeat_KP_DOWN' ],

    # Delete a save.
    save_delete = [ 'K_DELETE', 'KP_DELETE' ],

    # Save/load screen pagination.
    save_page_prev = ['mousedown_4'],
    save_page_next = ['mousedown_5'],

    # Draggable.
    drag_activate = [ 'mousedown_1' ],
    drag_deactivate = [ 'mouseup_1' ],

    # Debug console.
    console = [ 'shift_K_o', 'alt_shift_K_o' ],
    console_exit = [ 'K_ESCAPE', 'K_MENU', 'K_PAUSE', 'mouseup_3' ],
    console_older = [ 'anyrepeat_K_UP', 'anyrepeat_KP_UP' ],
    console_newer = [ 'anyrepeat_K_DOWN', 'anyrepeat_KP_DOWN' ],

    # Director
    director = [ 'noshift_K_d' ],

    # Ignored (kept for backwards compatibility).
    toggle_music = [ ],
    viewport_up = [ ],
    viewport_down = [ ],

    # Profile commands.
    performance = [ 'K_F3' ],
    image_load_log = [ 'K_F4' ],
    profile_once = [ 'K_F8' ],
    memory_profile = [ 'K_F7' ],
)

게임패드 연결은 조금 다르게 작동합니다. 게임패드 이벤트를 하나 이상의 Ren'Py 이벤트 이름에 연결합니다. 기본 게임패드 연결은 다음과 같습니다.

config.pad_bindings = {
    "pad_leftshoulder_press" : [ "rollback", ],
    "pad_lefttrigger_pos" : [ "rollback", ],
    "pad_back_press" : [ "rollback", ],

    "repeat_pad_leftshoulder_press" : [ "rollback", ],
    "repeat_pad_lefttrigger_pos" : [ "rollback", ],
    "repeat_pad_back_press" : [ "rollback", ],

    "pad_guide_press" : [ "game_menu", ],
    "pad_start_press" : [ "game_menu", ],

    "pad_y_press" : [ "hide_windows", ],
    "pad_x_press" : [ "button_alternate" ],

    "pad_rightshoulder_press" : [ "rollforward", ],
    "repeat_pad_rightshoulder_press" : [ "rollforward", ],

    "pad_righttrigger_pos" : [ "dismiss", "button_select", "bar_activate", "bar_deactivate" ],
    "pad_a_press" : [ "dismiss", "button_select", "bar_activate", "bar_deactivate"],
    "pad_b_press" : [ "game_menu" ],

    "pad_dpleft_press" : [ "focus_left", "bar_left", "viewport_leftarrow" ],
    "pad_leftx_neg" : [ "focus_left", "bar_left", "viewport_leftarrow" ],
    "pad_rightx_neg" : [ "focus_left", "bar_left", "viewport_leftarrow" ],

    "pad_dpright_press" : [ "focus_right", "bar_right", "viewport_rightarrow" ],
    "pad_leftx_pos" : [ "focus_right", "bar_right", "viewport_rightarrow" ],
    "pad_rightx_pos" : [ "focus_right", "bar_right", "viewport_rightarrow" ],

    "pad_dpup_press" : [ "focus_up", "bar_up", "viewport_uparrow" ],
    "pad_lefty_neg" : [ "focus_up", "bar_up", "viewport_uparrow" ],
    "pad_righty_neg" : [ "focus_up", "bar_up", "viewport_uparrow" ],

    "pad_dpdown_press" : [ "focus_down", "bar_down", "viewport_downarrow" ],
    "pad_lefty_pos" : [ "focus_down", "bar_down", "viewport_downarrow" ],
    "pad_righty_pos" : [ "focus_down", "bar_down", "viewport_downarrow" ],

    "repeat_pad_dpleft_press" : [ "focus_left", "bar_left", "viewport_leftarrow" ],
    "repeat_pad_leftx_neg" : [ "focus_left", "bar_left", "viewport_leftarrow" ],
    "repeat_pad_rightx_neg" : [ "focus_left", "bar_left", "viewport_leftarrow" ],

    "repeat_pad_dpright_press" : [ "focus_right", "bar_right", "viewport_rightarrow" ],
    "repeat_pad_leftx_pos" : [ "focus_right", "bar_right", "viewport_rightarrow" ],
    "repeat_pad_rightx_pos" : [ "focus_right", "bar_right", "viewport_rightarrow" ],

    "repeat_pad_dpup_press" : [ "focus_up", "bar_up", "viewport_uparrow" ],
    "repeat_pad_lefty_neg" : [ "focus_up", "bar_up", "viewport_uparrow" ],
    "repeat_pad_righty_neg" : [ "focus_up", "bar_up", "viewport_uparrow" ],

    "repeat_pad_dpdown_press" : [ "focus_down", "bar_down", "viewport_downarrow" ],
    "repeat_pad_lefty_pos" : [ "focus_down", "bar_down", "viewport_downarrow" ],
    "repeat_pad_righty_pos" : [ "focus_down", "bar_down", "viewport_downarrow" ],
}

게임패드 버튼의 이벤트 이름은 "pad_*button*_press" 또는 "pad_*button*_release" 형태입니다. 아날로그 축 이벤트는 "pad_*axis*_pos", "pad_*axis*_neg", "pad_*axis*_zero" 형태입니다. 누른 상태를 유지하면 "repeat_" 접두사가 붙은 두 번째 게임패드 연결이 발생합니다.

특별한 초기화 없이는 작동하지 않는 게임패드는 기본적으로 비활성화됩니다. PC에서 사용하려면 특별한 초기화가 필요한 Nintendo Switch Pro Controller도 여기에 포함됩니다. 이 차단 목록은 config.controller_blocklist로 제어합니다.

renpy.clear_keymap_cache()

키맵 캐시를 비웁니다. Ren'Py를 다시 시작하지 않아도 config.keymap의 변경 사항이 적용됩니다.