Input - kuimoani/defold GitHub Wiki

Input

์ด ๋งค๋‰ด์–ผ์€ ์ž…๋ ฅ ๋™์ž‘(input action)์„ ์บก์ณํ•˜๊ณ  ์ƒํ˜ธ์ž‘์šฉ ์Šคํฌ๋ฆฝํŠธ์˜ ๋ฐ˜์‘(interactive script reactions)์„ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

Defold๋Š” ๋‹ค์–‘ํ•œ ์žฅ์น˜๋กœ๋ถ€ํ„ฐ ์ž…๋ ฅ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ ์‚ฌ์šฉ์ž์˜ ์„ค๊ณ„์™€ ์ผ์น˜ํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ ๋กœ์ง์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Defold๊ฐ€ ์ง€์›ํ•˜๋Š” ์ž…๋ ฅ์žฅ์น˜์˜ ์ข…๋ฅ˜๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  1. ํ‚ค๋ณด๋“œ (ํ‚ค ์ž…๋ ฅ ๋ฐ ํ…์ŠคํŠธ ์ž…๋ ฅ)
  2. ๋งˆ์šฐ์Šค (๋งˆ์šฐ์Šคํœ  ๋™์ž‘ ํฌํ•จ)
  3. ๋ฉ€ํ‹ฐํ„ฐ์น˜ (iOS ๋ฐ Android ๊ธฐ๊ธฐ)
  4. ๊ฒŒ์ž„ํŒจ๋“œ (์šด์˜์ฒด์ œ๋ฅผ ํ†ตํ•ด ์ง€์›๋จ)

MS์œˆ๋„์šฐ์—์„œ๋Š” ํ˜„์žฌ XBox 360 ์ปจํŠธ๋กค๋Ÿฌ๋งŒ ์ง€์›๋ฉ๋‹ˆ๋‹ค. 360 ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์œˆ๋„์šฐ ์žฅ์น˜์— ์—ฐ๊ฒฐํ•˜๋ ค๋ฉด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์…‹์—…์ด ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ  http://www.wikihow.com/Use-Your-Xbox-360-Controller-for-Windows ๋ฅผ ์ฐธ๊ณ  ๋ฐ”๋ž๋‹ˆ๋‹ค.

๋ชจ๋“  ์œ ์ € ์ž…๋ ฅ์€ ์—”์ง„์— ์˜ํ•ด ์ˆ˜์ง‘(capture)๋˜๋ฉฐ ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ์˜ ์Šคํฌ๋ฆฝํŠธ๋‚˜ GUI ์Šคํฌ๋ฆฝํŠธ๋กœ ์ „๋‹ฌ(dispatch)๋˜์–ด ์ž…๋ ฅ ํฌ์ปค์Šค๋ฅผ ํš๋“ํ•˜๊ณ  on_input() ํ•จ์ˆ˜๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ž…๋ ฅ์ด ์Šคํฌ๋ฆฝํŠธ์— ๋„๋‹ฌํ•˜๊ธฐ ์ „์— ์ž…๋ ฅ ๋ฐ”์ธ๋”ฉ(input bindings)๋ฅผ ํ†ตํ•ด ์˜๋ฏธ ์žˆ๋Š” ๋™์ž‘(meaningful actions)์œผ๋กœ ๋ฒˆ์—ญ๋ฉ๋‹ˆ๋‹ค.

Input bindings

์ž…๋ ฅ ํฌ์ปค์Šค๋ฅผ ํš๋“ํ•œ ์ปดํฌ๋„ŒํŠธ์— ๋”ฐ๋ผ์„œ ์ด ์ž…๋ ฅ์„ ๊ทธ๋ƒฅ ๋„˜๊ฒจ๋ฒ„๋ฆด์ง€ on_input() ํ•จ์ˆ˜๋กœ ๋„๋‹ฌํ–ˆ๋Š”์ง€ ์•ˆํ–ˆ๋Š”์ง€๊ฐ€ ๊ฒฐ์ •๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์•„๋ž˜์—์„œ ์ด๋“ค์ด ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ์ž์„ธํžˆ ์‚ดํŽด ๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

Input bindings

์ž…๋ ฅ ๋ฐ”์ธ๋”ฉ์€ Lua ์Šคํฌ๋ฆฝํŠธ๋กœ ์ž…๋ ฅ๊ฐ’์„ ๋ณด๋‚ด๊ธฐ ์ด์ „์— ์›์‹œ ์ž…๋ ฅ(raw input)์„ ์˜๋ฏธ ์žˆ๋Š” actions์œผ๋กœ ๋ฒˆ์—ญํ•˜๊ธฐ ์œ„ํ•œ ํ…Œ์ด๋ธ”์ž…๋‹ˆ๋‹ค. ์ž…๋ ฅ ๋ฐ”์ธ๋”ฉ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ "game.input_binding"๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ์˜ "input" ํด๋”์— ์œ„์น˜ํ•ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์—”์ง„์ด ๋ฐ”์ธ๋”ฉ์„ ์ฐพ์„ ์ˆ˜ ์žˆ๋„๋ก ํ”„๋กœ์ ํŠธ ์…‹ํŒ…(Project settings ์ฐธ๊ณ )์„ ์—…๋ฐ์ดํŠธํ•ด์„œ ๊ฒฝ๋กœ์™€ ์ด๋ฆ„์„ ์ˆ˜์ •ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

Input set bindings

์—ฌ๊ธฐ ์žฅ์น˜๋ณ„๋กœ ํŠน์ •ํ•œ 5๊ฐ€์ง€ ์ข…๋ฅ˜์˜ ํŠธ๋ฆฌ๊ฑฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. key_trigger ์™€ text_trigger ๋Š” ํ‚ค๋ณด๋“œ ๋ฒ„ํŠผ ์ž…๋ ฅ์šฉ
  2. mouse_trigger ๋Š” ๋งˆ์šฐ์Šค ์ž…๋ ฅ์šฉ
  3. gamepad_trigger ๋Š” ์‹œ์Šคํ…œ ๊ฒŒ์ž„ํŒจ๋“œ์šฉ (์˜ˆ: Xbox ๋‚˜ Playstation ์ปจํŠธ๋กค๋Ÿฌ)
  4. touch_trigger๋Š” ํ„ฐ์น˜ ์ž…๋ ฅ์˜ ๋ชจ๋“  ์ข…๋ฅ˜
  5. text_trigger๋Š” ํ…์ŠคํŠธ ์ž…๋ ฅ์šฉ

trigger type ์— ๋งˆ์šฐ์Šค ์˜ค๋ฅธ์ชฝ ํด๋ฆญํ•˜๊ณ  "Add TYPE_triggerโ€ฆ?"๋ฅผ ์„ ํƒํ•ด์„œ ์ƒˆ ํŠธ๋ฆฌ๊ฑฐ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ ํŠธ๋ฆฌ๊ฑฐ๋Š” ๋‘๊ฐœ์˜ ํ•„๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

input

์ž…๋ ฅ์„ ๋Œ€๊ธฐํ•  ์ˆ˜ ์žˆ๋Š” ์Šคํฌ๋กค ๋ชฉ๋ก(scroll list)

action

์ž…๋ ฅ์ด ๋ฐœ์ƒํ• ๋•Œ ์ƒ์„ฑ๋˜๋ฉฐ ์Šคํฌ๋ฆฝํŠธ๋กœ ์ „๋‹ฌ๋˜๋Š” ์•ก์…˜์˜ ์ด๋ฆ„. ์—ฌ๋Ÿฌ ์•ก์…˜์— ๋™์ผํ•œ ์ด๋ฆ„์„ ์„ค์ •ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, Space ํ‚ค์— "jump" ์•ก์…˜์„ ๋ฐ”์ธ๋”ฉํ•˜๊ณ  ๊ฒŒ์ž„ํŒจ๋“œ "A" ๋ฒ„ํŠผ์—๋„ ๊ฐ™์€ ์•ก์…˜์„ ๋ฐ”์ธ๋”ฉ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ถˆํ–‰ํ•˜๊ฒŒ๋„ ํ„ฐ์น˜ ์ž…๋ ฅ์€ ๋‹ค๋ฅธ ์ž…๋ ฅ๊ณผ ๋™์ผํ•œ ์•ก์…˜ ์ด๋ฆ„์„ ๊ฐ€์งˆ์ˆ˜ ์—†๋‹ค๋Š” ๋ฒ„๊ทธ๊ฐ€ ์•Œ๋ ค์ ธ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ๊ฒŒ์ž„์—์„œ ์ขŒ์šฐ๋กœ ์ด๋™ํ•˜๊ธฐ ์œ„ํ•œ ํ‚ค๋ฅผ ๋ฐ”์ธ๋”ฉ ํ•˜๋ ค ํ•œ๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Input key bindings

์—ฌ๊ธฐ์„œ, KEY_LEFT์™€ KEY_RIGHT ์ž…๋ ฅ์€ ๊ฐ๊ฐ "move_left" ์™€ "move_right" ๋ผ๋Š” ์•ก์…˜ ์ด๋ฆ„์œผ๋กœ ๋ฐ”์ธ๋”ฉ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋…ผ๋ฆฌ์ ์ธ ์•ก์…˜๊ณผ ํ•˜๋“œ์›จ์–ด์˜ ์ž…๋ ฅ์„ ๋ถ„๋ฆฌํ•˜๋Š” ์ด์œ ๋Š” ๋‚˜์ค‘์— ํ•˜๋“œ์›จ์–ด ์ž…๋ ฅ์ด ์–ด๋–ค ๋™์ž‘์„ ํŠธ๋ฆฌ๊ฑฐ ํ• ์ง€ ๋ณ€๊ฒฝํ•ด์•ผํ•  ๊ฒฝ์šฐ ํ•œ ๊ณณ๋งŒ ์ˆ˜์ •ํ•˜๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

Acquiring and releasing input focus

์ž…๋ ฅ ๋™์ž‘(input action)์„ ๋“ฃ๊ธฐ ์œ„ํ•ด์„œ๋Š”, ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ์— ์Šคํฌ๋ฆฝํŠธ(ํ˜น์€ GUI ์Šคํฌ๋ฆฝํŠธ)๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์Šคํฌ๋ฆฝํŠธ์—์„œ "acquire_input_focus" ๋ฉ”์„ธ์ง€๋ฅผ ์ž์‹ ์˜ ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ๋กœ ๋ณด๋‚ด๋ฉด ๋ฉ๋‹ˆ๋‹ค.

function init(self)
        msg.post(".", "acquire_input_focus")
end

์ด ๋ฉ”์„ธ์ง€๋Š” Defold์—๊ฒŒ ํ˜„์žฌ ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ์˜ ์ž…๋ ฅ ๋™์ž‘์„ ์ง์ ‘ ์•Œ๋ ค์ค๋‹ˆ๋‹ค. ๊ธฐ์ˆ ์ ์œผ๋กœ, ์ด ์˜ค๋ธŒ์ ํŠธ์—๊ฒŒ ๋ฐœ์ƒํ•˜๋Š” ์ผ์€ ์ž…๋ ฅ์Šคํƒ(input stack)(์ž์„ธํ•œ ์„ค๋ช…์€ ์•„๋ž˜ ์ฐธ๊ณ )์— ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. ์ž…๋ ฅ ๋™์ž‘ ๋“ฃ๊ธฐ๋ฅผ ์ค‘์ง€ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ์— "release_input_focus" ๋ฉ”์„ธ์ง€๋ฅผ ๋ณด๋‚ด๋ฉด ๋ฉ๋‹ˆ๋‹ค.

...
msg.post(".", "release_input_focus")
...

on_input()

์ž…๋ ฅ ๋™์ž‘์— ๋ฐ˜์‘ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š”, ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ(์ž…๋ ฅ ํฌ์ปค์Šค๋ฅผ ํš๋“ํ•œ)์˜ ์Šคํฌ๋ฆฝํŠธ์— on_input() ํ•จ์ˆ˜๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๊ฒŒ์ž„ ์—”์ง„์€ ์ด ํ•จ์ˆ˜์— ์ž…๋ ฅ ๋™์ž‘๋“ค์„ ์ „๋‹ฌ(dispatch) ํ•ฉ๋‹ˆ๋‹ค.

function on_input(self, action_id, action)

์ด ํ•จ์ˆ˜๋Š” 2๊ฐœ์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ทจํ•ฉ๋‹ˆ๋‹ค. ("self" ์ œ์™ธ) :

action_id

์ธํ’‹ ๋ฐ”์ธ๋”ฉ(input bindings)์—์„œ ์„ค์ •๋œ ๋ฉ”์„ธ์ง€์˜ ์ด๋ฆ„. ํ•ด์‰ฌ๋จ

action

๋ฉ”์„ธ์ง€ ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ๋Š” Lua ํ…Œ์ด๋ธ”

์šฐ๋ฆฌ๊ฐ€ ์œ„์—์„œ ์„ค์ •ํ–ˆ๋˜ "move_left" ๊ณผ "move_right" ๋ฐ”์ธ๋”ฉ์„ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•ด์„œ๋Š” ์•„๋ž˜ ์ฝ”๋“œ์ฒ˜๋Ÿผ ์ž‘์„ฑํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

function on_input(self, action_id, action)
        if action_id == hash("move_left") and action.pressed then
                local pos = go.get_position()
                pos.x = pos.x - 100
                go.set_position(pos)
        elseif action_id == hash("move_right") and action.pressed then
                local pos = go.get_position()
                pos.x = pos.x + 100
                go.set_position(pos)
        end
end

์ปฌ๋ ‰์…˜ ํ”„๋ก์‹œ๋กœ ์ž‘์—…ํ•˜๋ ค๋ฉด, ์ปฌ๋ ‰์…˜์„ ํ†ตํ•ด ์ž…๋ ฅ์ด ์–ด๋–ป๊ฒŒ ์ „๋‹ฌ๋˜๋Š”์ง€๋ฅผ ์ดํ•ดํ•˜๋Š”๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์ปฌ๋ ‰์…˜ ํ”„๋ก์‹œ๋ฅผ ์‚ฌ์šฉํ•ด ์ž…๋ ฅ์„ ํš๋“ํ•  ์ˆ˜ ์—†๋‹ค๋ฉด, ์•„๋ž˜ Input and Collection Proxies๋ฅผ ์ฝ์–ด ๋ณด์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

Action fields

๊ฐ๊ฐ์˜ ์ž…๋ ฅ ๋ฉ”์„ธ์ง€์— ๋Œ€ํ•ด on_input() ํ•จ์ˆ˜๋กœ ์ „๋‹ฌ๋˜๋Š” ์•ก์…˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ์ž…๋ ฅ๊ฐ’, ์ž…๋ ฅ์˜ ์œ„์น˜, ์ž…๋ ฅ ๋ฒ„ํŠผ์˜ "pressed", "repeated", "released" ์ƒํƒœ์™€ ๊ฐ™์€ ์œ ์šฉํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ๋Š” Lua ํ…Œ์ด๋ธ”์ž…๋‹ˆ๋‹ค.

action.pressed

์ž…๋ ฅ์ด ๊ฒ€์ถœ๋œ ์ฒซ๋ฒˆ์งธ ํ”„๋ ˆ์ž„์—์„œ true, ๊ทธ์™ธ์—๋Š” false

action.repeated

์ž…๋ ฅ์ด ๋ฐ˜๋ณต๋˜๊ณ  ์žˆ์œผ๋ฉด true, ๊ทธ ์™ธ์—๋Š” false. ์ด ๊ฐ’์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋งค ํ”„๋ ˆ์ž„๋งˆ๋‹ค ์„ค์ •๋˜์ง€๋Š” ์•Š์ง€๋งŒ [ํ”„๋กœ์ ํŠธ ์„ค์ •(project settings)](Project settings#input)์˜ repeat_delay์™€ repeat_interval ์˜ ์„ค์ •์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค.

action.released

์ž…๋ ฅ์ด ํ•ด์ง€(release)๋œ ํ”„๋ ˆ์ž„์— true, ๊ทธ ์™ธ์—๋Š” false

์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์•ก์…˜ ํ•„๋“œ๋ฅผ ์ž์„ธํžˆ ๋ณด๊ณ  ์‹ถ๋‹ค๋ฉด on_input() ์ฐธ๊ณ 

Screen positions

๋งˆ์šฐ์Šค ์ž…๋ ฅ ๋ฐ ํ„ฐ์น˜ ์ž…๋ ฅ์€ ์œ„์น˜(x, y) ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ด๋™ ๋ฐ˜๊ฒฝ(dx, dy)๋„ ์•ก์…˜ ํ…Œ์ด๋ธ”์— ํ•„๋“œ๋ฅผ ์…‹ํŒ…ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ์ด ์ž…๋ ฅ์€ ์‹ค์ œ ํ™”๋ฉด ๊ณต๊ฐ„์— ๋Œ€ํ•˜์—ฌ ๊ณ„์‚ฐ๋œ ์•„๋ž˜์™€ ๊ฐ™์€ ํŠน์ • ํ•„๋“œ๋„ ์…‹ํŒ…ํ•ฉ๋‹ˆ๋‹ค.

screen_x and screen_y

์‹ค์ œ ํ™”๋ฉด์—์„œ์˜ ์œ„์น˜

screen_dx and screen_dy

๋งˆ์ง€๋ง‰ ์—…๋ฐ์ดํŠธ ์ดํ›„์˜ ์‹ค์ œ ํ™”๋ฉด์—์„œ์˜ ๋ณ€๊ฒฝ๋œ ์œ„์น˜(delta)

์ด ํ•„๋“œ๋Š” ๋ ˆํ‹ฐ๋‚˜ ๋””์Šคํ”Œ๋ ˆ์ด์—์„œ ๋‚ฎ์€ ํ•ด์ƒ๋„์˜ ๊ฒŒ์ž„์„ ํ™•๋Œ€ํ•ด์„œ ์‹คํ–‰ํ•˜๋ ค ํ•˜๋Š” ๊ฒฝ์šฐ์ฒ˜๋Ÿผ ๊ฒŒ์ž„์›”๋“œ์—์„œ์˜ ์œ„์น˜์™€ ํ™”๋ฉด์—์„œ์˜ ํ”ฝ์…€ ์œ„์น˜๊ฐ’์ด ์„œ๋กœ ๋‹ค๋ฅด๊ฒŒ ๋‚˜์˜ค๋Š” ์žฅ์น˜์—์„œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด 1024x768 ํ•ด์ƒ๋„์˜ ๊ฒŒ์ž„์„ iPad์—์„œ ์‹คํ–‰ํ•˜๋ฉด 2048x1536 ๋ฌผ๋ฆฌ ํ•ด์ƒ๋„์— ๋งคํ•‘๋˜์–ด "๋…ผ๋ฆฌ์ " ํ”ฝ์…€์ด 4๊ฐœ์˜ ์‹ค์ œ ํ”ฝ์…€๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค.

Key triggers

ํ‚ค ํŠธ๋ฆฌ๊ฑฐ๋Š” ๋ฒ„ํŠผ ์ž…๋ ฅ์— ๋ฐ˜์‘ํ•˜๋Š” ๊ฐ„๋‹จํ•œ ํ‚ค ์ž…๋ ฅ์ž…๋‹ˆ๋‹ค. ์ด ๊ธฐ๋Šฅ์€ ์œ„์—์„œ ์„ค์ •ํ•œ "move_left"์™€ "move_right"์ฒ˜๋Ÿผ ํŠน์ • ๋ฒ„ํŠผ๊ณผ ํŠน์ • ํ•จ์ˆ˜๋ฅผ ์—ฎ๋Š” ๊ฒƒ์ด ํ•„์š”ํ•œ ๊ฒŒ์ž„์ผ ๊ฒฝ์šฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์ž„์˜์˜ ํ‚ค ์ž…๋ ฅ์„ ์ฝ์–ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ, text triggers ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. (์•„๋ž˜ ์ฐธ๊ณ )

Mouse triggers

๋งˆ์šฐ์Šค ํŠธ๋ฆฌ๊ฑฐ๋Š” input bindings์—์„œ ์„ค์ •ํ•œ ํœ  ์ž…๋ ฅ๊ณผ ๋งˆ์šฐ์Šค ๋ฒ„ํŠผ ์ž…๋ ฅ์œผ๋กœ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค.

Mouse button inputs

๋งˆ์šฐ์Šค๊ฐ€ ๋ˆŒ๋ ธ๋Š”์ง€(press) ๊ฐ์ง€ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. "MOUSE_BUTTON_LEFT", "MOUSE_BUTTON_RIGHT", "MOUSE_BUTTON_MIDDLE" ์ž…๋ ฅ์€ "MOUSE_BUTTON_1", "MOUSE_BUTTON_2", "MOUSE_BUTTON_3"๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ MOUSE_BUTTON_LEFT (๋˜๋Š” MOUSE_BUTTON_1)์ž…๋ ฅ ์•ก์…˜์€ ๋‹จ์ผ ํ„ฐ์น˜ ์ž…๋ ฅ(single touch inputs)์— ๋Œ€ํ•ด์„œ๋„ ์ „์†ก๋ฉ๋‹ˆ๋‹ค.

Mouse wheel inputs

์Šคํฌ๋กค ๋™์ž‘์„ ๊ฐ์ง€ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. action.value ํ•„๋“œ๋Š” ํœ ์ด ์Šคํฌ๋กค ๋  ๋•Œ 1, ๊ทธ ์™ธ์—๋Š” 0 ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. (์Šคํฌ๋กค ๋™์ž‘์€ ๋ฒ„ํŠผ ์ž…๋ ฅ๊ณผ ๋™์ผํ•˜๊ฒŒ ์ฒ˜๋ฆฌ๋˜๋ฉฐ Defold๋Š” ํ˜„์žฌ ํ„ฐ์น˜ํŒจ๋“œ์˜ ๋ฏธ์„ธํ•œ ์Šคํฌ๋กค ์ž…๋ ฅ์€ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.)

Mouse movement

๋งˆ์šฐ์Šค ์›€์ง์ž„์€ input bindings์—์„œ ๋ฐ”์ธ๋”ฉ ํ•  ์ˆ˜ ์—†๊ณ  action_id ์ด๋ฆ„์„ ์„ค์ •ํ•  ์ˆ˜๋„ ์—†์Šต๋‹ˆ๋‹ค. ๋Œ€์‹ , action_id๋Š” nil๋กœ ์„ค์ •๋˜๊ณ  ์•ก์…˜ ํ…Œ์ด๋ธ”์—๋Š” ๋งˆ์šฐ์Šค์˜ ์œ„์น˜์™€ ์ด๋™๊ฐ’(delta movement)์ด ์ฑ„์›Œ์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

Gamepad triggers

๊ฒŒ์ž„ ํŒจ๋“œ ํŠธ๋ฆฌ๊ฑฐ๋Š” ๊ฒŒ์ž„ ํ•จ์ˆ˜์— ํ‘œ์ค€ ๊ฒŒ์ž„ ํŒจ๋“œ ์ž…๋ ฅ์„ ๋ฐ”์ธ๋”ฉํ•ด ์ค๋‹ˆ๋‹ค. Defold๋Š” ์šด์˜์ฒด์ œ๋ฅผ ํ†ตํ•ด ์—ฌ๋Ÿฌ ๊ฒŒ์ž„ ํŒจ๋“œ๋ฅผ ์ง€์›ํ•˜๋ฉฐ ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฐ”์ธ๋”ฉ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

  1. ์™ผ์ชฝ, ์˜ค๋ฅธ์ชฝ ์Šคํ‹ฑ(๋ฐฉํ–ฅ, ํด๋ฆญ)
  2. ์™ผ์ชฝ, ์˜ค๋ฅธ์ชฝ ๋””์ง€ํƒˆ ํŒจ๋“œ
  3. ์™ผ์ชฝ, ์˜ค๋ฅธ์ชฝ ํŠธ๋ฆฌ๊ฑฐ
  4. ์™ผ์ชฝ, ์˜ค๋ฅธ์ชฝ ์ˆ„๋” ๋ฒ„ํŠผ
  5. ์‹œ์ž‘, ๋’ค๋กœ๊ฐ€๊ธฐ, ๊ฐ€์ด๋“œ ๋ฒ„ํŠผ

์ผ๋ฐ˜์ ์œผ๋กœ Xbox ์ปจํŠธ๋กค๋Ÿฌ์—์„œ๋Š” A, B, X, Y ๋ฒ„ํŠผ์œผ๋กœ, Playstation ์ปจํŠธ๋กค๋Ÿฌ์—์„œ๋Š” square, circle, triangle, cross ๋ฒ„ํŠผ์œผ๋กœ ํ•ด์„๋ฉ๋‹ˆ๋‹ค.

๊ฒŒ์ž„ํŒจ๋“œ ์ž…๋ ฅ์€ ์•ก์…˜ ํ…Œ์ด๋ธ”์˜ gamepad ํ•„๋“œ๋ฅผ ์ž…๋ ฅ์ด ๋ฐœ์ƒํ•œ ๊ฒŒ์ž„ ํŒจ๋“œ์˜ ๋ฒˆํ˜ธ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

function on_input(self, action_id, action)
    if action_id == hash("gamepad_start") then
        ...
        if action.gamepad == 0 then
            -- gamepad ๊ฐ€ 0์ด๋ฉด ๊ฒŒ์ž„ ์ ‘์†์„ ํ•˜๋ ค๋Š” ๋™์ž‘์ž„
            ...
        end
    end
end

Touch triggers

ํ„ฐ์น˜์™€ ๋ฉ€ํ‹ฐํ„ฐ์น˜ ํŠธ๋ฆฌ๊ฑฐ๋Š” ์•ก์…˜ ํ…Œ์ด๋ธ”์— action.touch ์ด๋ผ๋Š” ํ•˜์œ„ ํ…Œ์ด๋ธ”์„ ์ฑ„์›๋‹ˆ๋‹ค. ์ด ํ…Œ์ด๋ธ”์˜ ์š”์†Œ๋“ค์€ 1~n ์ˆœ์„œ(n์€ ํ„ฐ์น˜๋œ ์ž…๋ ฅ์˜ ์ˆ˜)๋กœ ๋ฒˆํ˜ธ๊ฐ€ ๋‚˜์—ด๋˜๋ฉฐ ์ž…๋ ฅ ๋ฐ์ดํ„ฐ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉ๊ฐ€๋Šฅํ•œ ํ„ฐ์น˜ ์•ก์…˜ ํ•„๋“œ๋ฅผ ์ž์„ธํžˆ ์•Œ๊ณ  ์‹ถ๋‹ค๋ฉด on_input() ์ฐธ๊ณ 

ํ…Œ์ด๋ธ”์ด ๋ฐฐ์—ด์ฒ˜๋Ÿผ ๋„˜๋ฒ„๋ง ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ, ์•„๋ž˜์™€ ๊ฐ™์ด ์‰ฝ๊ฒŒ ์กฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

function on_input(self, action_id, action)
        if action_id == hash("touch") and #action.touch > 1 and #action.touch < 4 then
                -- 2~3๊ฐœ ํ„ฐ์น˜์ง€์ ์ด ๋ฐœ์ƒํ•˜๋ฉด ๋งˆ๋ฒ• ์ŠคํŒŒํฌ ํŒŒํ‹ฐํด์„ ๊ฐ ํฌ์ธํŠธ์— ์Šคํฐ์‹œํ‚ค๊ธฐ
                for i, tpoint in ipairs(action.touch) do
                        local pos = vmath.vector3(tpoint.x, tpoint.y, 0)
                        factory.create("#factory", pos)
                end
        end
end

์—ฌ๊ธฐ์„œ๋Š” "factory" ์ปดํฌ๋„ŒํŠธ๊ฐ€ factory.create()๋ฅผ ํ†ตํ•ด ๊ฐ„๋‹จํ•œ ํŒŒํ‹ฐํด ์ดํŽ™ํŠธ๋ฅผ ์Šคํฐํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋‘ ์„ธ๊ฐœ ์†๊ฐ€๋ฝ์œผ๋กœ ์žฅ์น˜์˜ ํ™”๋ฉด์„ ํ„ฐ์น˜ํ•˜๋ฉด ์†๊ฐ€๋ฝ์„ ๋”ฐ๋ผ ํŒŒํ‹ฐํด์ด ๋”ฐ๋ผ๋‹ค๋‹ˆ๋ฉฐ ์Šคํฐ๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

Input multitouch

Text triggers

ํ…์ŠคํŠธ ํŠธ๋ฆฌ๊ฑฐ๋Š” ์ž„์˜์˜ ํ…์ŠคํŠธ ์ž…๋ ฅ์„ ์ฝ์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด ์ค๋‹ˆ๋‹ค. ํ…์ŠคํŠธ ํŠธ๋ฆฌ๊ฑฐ๋Š” ๋‘ ๊ฐ€์ง€ ์ข…๋ฅ˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

TEXT

์ด ์ž…๋ ฅ ํŠธ๋ฆฌ๊ฑฐ๋Š” ๋ณดํ†ต์˜ ํ…์ŠคํŠธ ์ž…๋ ฅ์„ ์บก์ณํ•ฉ๋‹ˆ๋‹ค.

ํ…์ŠคํŠธ ํŠธ๋ฆฌ๊ฑฐ๋Š” ์•ก์…˜ ํ…Œ์ด๋ธ”์˜ "text" ํ•„๋“œ๋ฅผ ์ž…๋ ฅ๋œ ๋ฌธ์ž๋ฅผ ํฌํ•จํ•œ ๋ฌธ์ž์—ด๋กœ ์…‹ํŒ…ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋™์ž‘์€ ๋ฒ„ํŠผ์ด ๋ˆŒ๋ ค์งˆ ๋•Œ(press)์—๋งŒ ๋ฐœ์ƒํ•˜๋ฉฐ, "release"๋‚˜ "repeated" ๋™์ž‘์—๋Š” ๋ฐ˜์‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

function on_input(self, action_id, action)
    if action_id == hash("text") then
        -- ์ž…๋ ฅ๋œ ๋ฌธ์ž๋ฅผ "text" ๋…ธ๋“œ์— ์ด์–ด ๋ถ™์ด๊ธฐ...
        local node = gui.get_node("text")
        local text = gui.get_text(node)
        text = text .. action.text
        gui.set_text(node, text)
    end
end

MARKED_TEXT

์ด ๊ธฐ๋Šฅ์€ ๋‹จ์ผ ์ž…๋ ฅ์— ๋งคํ•‘๋˜๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํ‚ค ์ž…๋ ฅ๊ฐ™์€ ์•„์‹œ์•„์šฉ ํ‚ค๋ณด๋“œ์— ์ฃผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, iOS์˜ "Japanese-Kana" ํ‚ค๋ณด๋“œ์˜ ๊ฒฝ์šฐ์—” 10๊ฐœ์˜ ํ‚ค๋กœ ๊ตฌ์„ฑ๋œ ํ‚ค๋ณด๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”๋ฐ, ์œ ์ €๊ฐ€ ํ‚ค๋ฅผ ์กฐํ•ฉํ•˜์—ฌ ํ‚ค๋ณด๋“œ์˜ ์œ„์ชฝ์— ์‚ฌ์šฉ๊ฐ€๋Šฅํ•œ ์‹ฌ๋ณผ์ด ํ‘œ์‹œ๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

Input marked text

๊ฐ๊ฐ์˜ ํ‚ค ์ž…๋ ฅ์€ ๋ณ„๋„ ์•ก์…˜์„ ์ƒ์„ฑํ•˜๋ฉฐ "text" ํ•„๋“œ์—์„œ ์ž…๋ ฅ๋œ ํ‚ค์ž…๋ ฅ์˜ ๋ชจ์Œ์„ ์•ก์…˜ ํ•„๋“œ์— ์„ค์ •ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

{
  repeated = false,
  released = false,
  text = ใŸ,
  value = 0,
  pressed = false,
}

์œ ์ €๊ฐ€ ์‹ฌ๋ณผ์ด๋‚˜ ์กฐํ•ฉ๋œ ์‹ฌ๋ณผ์„ ์„ ํƒํ•˜๋ฉด, ๋ณดํ†ต์˜ ํ…์ŠคํŠธ ํŠธ๋ฆฌ๊ฑฐ ์•ก์…˜์ด ์ „์†ก๋ฉ๋‹ˆ๋‹ค.

The input stack

์ž…๋ ฅ ํฌ์ปค์Šค๋ฅผ ํš๋“ํ•˜๋Š” ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ๋Š” ์ž…๋ ฅ์„ ์ˆ˜์‹ ํ•˜๋Š” ์˜ค๋ธŒ์ ํŠธ ๋ฆฌ์ŠคํŠธ์— ์šฐ์„  ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. ์ด ๋ฆฌ์ŠคํŠธ๋Š” ์ธํ’‹ ์Šคํƒ(input stack)์œผ๋กœ ๋ถˆ๋ฆฌ๋Š”๋ฐ, ์ž…๋ ฅ ๋™์ž‘์€ ๊ฐ€์žฅ ์ƒ์œ„์˜ ์˜ค๋ธŒ์ ํŠธ ์ปดํฌ๋„ŒํŠธ๋กœ ๋จผ์ € ์ „๋‹ฌ๋˜๊ณ  ๋‹ค๋ฆ„ ์ปดํฌ๋„ŒํŠธ๋กœ ์ฐจ๋ก€๋กœ ์ „๋‹ฌ๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

Input stack

์ด ๋™์ž‘์˜ ์ „๋‹ฌ(dispatch)์€ ๋™์ผํ•œ ํ”„๋ ˆ์ž„ ๋‚ด์—์„œ ๋ฐœ์ƒํ•˜๋ฏ€๋กœ ์Šคํƒ์˜ ์•„๋ž˜๋ฐฉํ–ฅ์œผ๋กœ ์ž…๋ ฅ์ด ์ „๋‹ฌ๋˜๋Š” ๊ฒƒ์„ ์˜๋„์ ์œผ๋กœ ์กฐ์ž‘ํ•˜์ง€ ์•Š์•˜๋‹ค๋ฉด, (์•„๋ž˜ "Consuming input" ์ฐธ๊ณ ) ๋ชจ๋“  ์ˆ˜์‹  ์ปดํฌ๋„ŒํŠธ์˜ on_input() ํ•จ์ˆ˜๊ฐ€ ๋™์‹œ์— ์ž…๋ ฅ์„ ๋ฐ›๋Š”๊ฒƒ ์ฒ˜๋Ÿผ ๋ณด์ด๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

Stack order

๋ชจ๋“  ์ž…๋ ฅ์„ ํš๋“ํ•˜๋Š” ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ์žˆ๋‹ค๋ฉด, ์ธํ’‹ ์Šคํƒ์˜ ์ƒ์œ„์— ์ฐจ๋ก€ ์ฐจ๋ก€ ์ถ”๊ฐ€๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

-- "listener1.script"์—์„œ
function init(self)
        msg.post(".", "acquire_input_focus")
end

-- "listener2.script"์—์„œ
function init(self)
        msg.post(".", "acquire_input_focus")
end

ํ•˜์ง€๋งŒ, ์˜ค๋ธŒ์ ํŠธ๊ฐ„์˜ ์ดˆ๊ธฐํ™”๋‚˜ ์—…๋ฐ์ดํŠธ ์ˆœ์„œ๋Š” ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํŠน์ •ํ•œ ์ˆœ์„œ๋กœ ๋ฆฌ์Šค๋„ˆ๊ฐ€ ์Šคํƒ์— ๋‚˜ํƒ€๋‚  ๊ฒƒ์ด๋ผ๋Š” ๋ณด์žฅ์€ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํŠน์ • ์ˆœ์„œ๋กœ ์Šคํƒ์— ๋ฆฌ์Šค๋„ˆ๊ฐ€ ํ•„์š”ํ•œ ์ƒํ™ฉ์ด๋ผ๋ฉด, ๋ฉ”์„ธ์ง€๋“ค์„ ์—ฐ๊ฒฐํ•˜์—ฌ ์˜ค๋ธŒ์ ํŠธ๊ฐ„์˜ ํŠน์ • ์ž…๋ ฅ ์ˆœ์„œ๋ฅผ ๊ฐ•์ œ๋กœ ์ ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

-- "listener1.script"์—์„œ
function init(self)
        -- ์—ฌ๊ธฐ์„œ ๋จผ์ € ์ž…๋ ฅ์„ ํš๋“ํ•˜๊ณ  "listener2"๋กœ ๋ณด๋ƒ„
        msg.post(".", "acquire_input_focus")
        msg.post("listener2", "acquire_input")
end

-- "listener2.script"์—์„œ
function on_message(self, message_id, message, sender)
        if message_id == hash("acquire_input") then
                -- ๋ฉ”์„ธ์ง€๋ฅผ ๋ฐ›์œผ๋ฉด ์ž…๋ ฅ ํš๋“ํ•˜๊ธฐ
                msg.post(".", "acquire_input_focus")
        end
end

์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์ธํ’‹ ์Šคํƒ์ด ์•„๋ž˜์™€ ๊ฐ™์ด ์ •๋ ฌ๋ฉ๋‹ˆ๋‹ค.

Input stack order

Consuming input

์ปดํฌ๋„ŒํŠธ์˜ on_input() ์ฝ”๋“œ๋Š” ์•ก์…˜์„ ์Šคํƒ ์•„๋ž˜๋กœ ๋ณด๋‚ผ์ง€ ๋ง์ง€๋ฅผ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ๋งŒ์•ฝ on_input() ์ฝ”๋“œ๊ฐ€ false๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ฑฐ๋‚˜ ์•„๋ฌด๊ฒƒ๋„ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š์œผ๋ฉด(return๋ฌธ์„ ์ƒ๋žตํ•˜๋ฉด lua์—์„œ ์ž„์˜๋กœ false๊ฐ’์„ ์˜๋ฏธํ•˜๋Š” nil์„ ๋ฐ˜ํ™˜ํ•จ), ์ž…๋ ฅ ์•ก์…˜์„ ์ธํ’‹ ์Šคํƒ์˜ ๋‹ค์Œ ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ๋กœ ๋„˜๊น๋‹ˆ๋‹ค.
  2. ๋งŒ์•ฝ ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ ์ปดํฌ๋„ŒํŠธ์˜ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ on_input()์—์„œ true๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉด, ์ด ์ž…๋ ฅ์€ ์†Œ๋น„(consume)๋˜์–ด ๋ฒ„๋ฆฌ๋ฉฐ ์ธํ’‹ ์Šคํƒ์˜ ๋‹ค์Œ ์˜ค๋ธŒ์ ํŠธ๋กœ ์ „๋‹ฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ๋Š” ์—ฌ๋Ÿฌ ์Šคํฌ๋ฆฝํŠธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ์ž…๋ ฅ ๋™์ž‘์€ ์ด ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ์˜ ์ปดํฌ๋„ŒํŠธ๋“ค์—๊ฒŒ ๋ธŒ๋กœ๋“œ์บ์ŠคํŠธ ๋ฉ๋‹ˆ๋‹ค.

on_input() ํ•จ์ˆ˜๊ฐ€ ์—†๋Š” ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ๋Š” on_input() ํ•จ์ˆ˜๊ฐ€ false๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ ์ฒ˜๋Ÿผ ์ž…๋ ฅ ์•ก์…˜์„ ์Šคํƒ ์ˆœ์„œ๋Œ€๋กœ ๋„˜๊ธฐ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

Consuming input

์—ฌ๊ธฐ, ์ž…๋ ฅ ์†Œ๋น„(input consumption)๊ฐ€ ๊ฒŒ์ž„์˜ ๊ฐ๊ธฐ ๋‹ค๋ฅธ ํŒŒํŠธ๊ฐ„์— ์ž…๋ ฅ์„ ์ œ์–ดํ•˜๋Š” ๊ฐ„๋‹จํ•˜๊ณ  ๊ฐ•๋ ฅํ•œ ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•˜๋Š” ๋ช‡ ๊ฐ€์ง€ ์‚ฌ๋ก€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ผ์‹œ์ ์œผ๋กœ ํŒ์—… ๋ฉ”๋‰ด๊ฐ€ ํ•„์š”ํ•ด์„œ ๊ฒŒ์ž„์˜ ํ•œ ๋ถ€๋ถ„์—์„œ ์ž…๋ ฅ์„ ์ˆ˜์‹ ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ„ฐ์น˜ ์ž…๋ ฅ์„ ํ†ตํ•ด ๋งˆ๋ฒ•์‚ฌ๋ฅผ ์ปจํŠธ๋กคํ•˜๋Š” ๊ฒŒ์ž„์„ ๋งŒ๋“ ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ด…์‹œ๋‹ค. ํ™”๋ฉด ํ•œ ๊ตฌ์„์—๋Š” HUD ๋ฉ”๋‰ด๊ฐ€ ํ”Œ๋ ˆ์ด์–ด๊ฐ€ ๊ฒŒ์ž„์„ ์ค‘์ง€(pause)ํ• ์ง€ ํ‘œ์‹œํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

Input pause menu

์ผ์‹œ์ค‘์ง€ ๋ฉ”๋‰ด๋Š” ์ฒ˜์Œ์—๋Š” ์ˆจ๊ฒจ์ ธ(disable) ์žˆ์œผ๋ฉฐ, ์œ ์ €๊ฐ€ "PAUSE" HUD ๋ฉ”๋‰ด๋ฅผ ํ„ฐ์น˜ํ•˜๋ฉด ํ™œ์„ฑํ™” ๋ฉ๋‹ˆ๋‹ค.

function init(self)
        msg.post(".", "acquire_input_focus")
end

function on_input(self, action_id, action)
        if action_id == hash("mouse_press") and action.pressed then
                local x = action.x
                local y = action.y
                -- "pause" ๋…ธ๋“œ๋ฅผ ๊ฐ€์ ธ์™€์„œ ์œ ์ €๊ฐ€ ํ„ฐ์น˜ํ–ˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ
                local pausenode = gui.get_node("pause")
                if gui.pick_node(pausenode, x, y) then
                        -- pause ๋ฉ”๋‰ด์—๊ฒŒ ์•Œ๋ ค์ฃผ๊ธฐ
                        msg.post("pause_menu", "show")
                end
        end
end

Input pause menu

pause ๋ฉ”๋‰ด๋Š” ์ƒ‰์ƒ์ด ์ž…ํ˜€์ง„ ๋ฐฐ๊ฒฝ๊ณผ ๋ช‡ ๊ฐ€์ง€ ์ž์‹ ๋ฉ”๋‰ด ์•„์ดํ…œ์œผ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. "background" ๋…ธ๋“œ๋ฅผ ํ™œ์„ฑํ™”/๋น„ํ™œ์„ฑํ™” ํ•ด์„œ pause ๋ฉ”๋‰ด ์ „์ฒด GUI๊ฐ€ ๋‚˜ํƒ€๋‚ฌ๋‹ค ์‚ฌ๋ผ์กŒ๋‹ค ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Input pause GUI

pause ๋ฉ”๋‰ด GUI๋Š” ์•„๋ž˜ ์ฝ”๋“œ๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

function init(self)
        -- background ๋…ธ๋“œ๋ฅผ ๊ฐ€์ ธ์™€ ๋น„ํ™œ์„ฑํ™” ํ•˜๊ธฐ
        -- ๋ชจ๋“  ๊ฒƒ์ด ์ž์‹ ๋…ธ๋“œ๋กœ ๋˜์–ด์žˆ์Œ
        local node = gui.get_node("background")
        gui.set_enabled(node, false)
end

function on_message(self, message_id, message, sender)
        if message_id == hash("show") then
                -- ์šฐ์„ , pause ๋ฉ”๋‰ด ๋ณด์ด๊ธฐ
                local node = gui.get_node("background")
                gui.set_enabled(node, true)

                -- ์ด์ œ ์ž…๋ ฅ์„ ํš๋“ํ•˜๋ฉด ์šฐ๋ฆฌ๋Š” ์ž…๋ ฅ์Šคํƒ ๋งจ ์œ„์— ์žˆ๊ฒ ์ง€!
                msg.post(".", "acquire_input_focus")
        end
end

function on_input(self, action_id, action)
        if action_id == hash("mouse_press") and action.pressed then
                local x = action.x
                local y = action.y
                -- ๋…ธ๋“œ๋ฅผ ๊ฐ€์ ธ์™€์„œ ๋ˆŒ๋ ธ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ
                local loadnode = gui.get_node("load")
                local savenode = gui.get_node("save")
                local resumenode = gui.get_node("resume")
                if gui.pick_node(loadnode, x, y) then
                        print("THE GAME WILL LOAD...")
                elseif gui.pick_node(savenode, x, y) then
                        print("THE GAME WILL SAVE...")
                elseif gui.pick_node(resumenode, x, y) then
                        -- ๊ฒŒ์ž„ ์žฌ๊ฐœ(resume)ํ•˜๊ธฐ...
                        -- ์šฐ์„ , pause ๋ฉ”๋‰ด๋ถ€ํ„ฐ ์ˆจ๊ธฐ๊ธฐ
                        local node = gui.get_node("background")
                        gui.set_enabled(node, false)

                        -- ๋งˆ์ง€๋ง‰์œผ๋กœ ์ž…๋ ฅ ํ•ด์ง€(release)ํ•˜๊ธฐ
                        msg.post(".", "release_input_focus")
                end
        end

		-- ์ž…๋ ฅ์„ ์ˆ˜์‹ ํ•˜๋Š” ๋™์•ˆ์—”, ์ž…๋ ฅ์„ ์†Œ๋น„(consume)ํ•ด๋ฒ„๋ฆฌ์ž
		-- pause ๋ฉ”๋‰ด๊ฐ€ ๋ณด์ด๋Š” ๋™์•ˆ์—” ๊ฒŒ์ž„ ์ปจํŠธ๋กค์„ ๋น„ํ™œ์„ฑํ™” ํ•จ
        return true
end

pause ๋ฉ”๋‰ด์˜ GUI ์Šคํฌ๋ฆฝํŠธ์˜ on_input() ํ•จ์ˆ˜๋Š” ๋ฉ”๋‰ด๊ฐ€ ๋ณด์ด๋Š” ๋™์•ˆ์—” true๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ๋ชจ๋“  ์ž…๋ ฅ ์•ก์…˜์„ ์†Œ๋ชจ(consume)ํ•˜๋ฏ€๋กœ ์ด ๊ฒŒ์ž„์€ ์‚ฌ์šฉ์ž ์ž…๋ ฅ์„ ํšจ๊ณผ์ ์œผ๋กœ ์ค‘์ง€์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Input and Collection Proxies

์ธํ’‹ ์Šคํƒ์€ ์‹ค์ œ๋กœ๋Š” ์ „์—ญ(global)์ด ์•„๋‹ˆ๋ฉฐ ๊ฐ ์ปฌ๋ ‰์…˜์— ๋Œ€ํ•ด ๋ณ„๋„์˜ ๋กœ์ปฌ ์ธํ’‹ ์Šคํƒ(local input stack)์œผ๋กœ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ๊ฒŒ์ž„์ด ์ปฌ๋ ‰์…˜ ํ”„๋ก์‹œ ๊ตฌ์กฐ๋กœ ์‚ฌ์šฉ๋œ๋‹ค๋ฉด ์ปฌ๋ ‰์…˜์„ ํ†ตํ•ด ์ž…๋ ฅ์ด ์ „๋‹ฌ๋˜๋Š” ๋ฐฉ์‹์— ๋Œ€ํ•ด ์ดํ•ดํ•  ํ•„์š”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์ž…๋ ฅ ์•ก์…˜์ด ํ˜„์žฌ ์ปฌ๋ ‰์…˜์˜ ์ธํ’‹ ์Šคํƒ ์•„๋ž˜๋กœ ์ „๋‹ฌ๋˜์–ด ์ปฌ๋ ‰์…˜ ํ”„๋ก์‹œ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ™œ์„ฑํ™”๋œ ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ์— ๋„๋‹ฌํ•˜๋ฉด, ์ด ์•ก์…˜์€ ๋ฉ”์ธ ์ปฌ๋ ‰์…˜์˜ ์Šคํƒ ์ˆœ์„œ๋Œ€๋กœ ๋„˜์–ด๊ฐ€๊ธฐ ์ „์—, ์ด๋ฏธ ๋™์ ์œผ๋กœ ๋กœ๋“œ๋œ ์ปฌ๋ ‰์…˜์˜ ์ธํ’‹ ์Šคํƒ๋ถ€ํ„ฐ ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค. ์•„๋ž˜ ๋‹ค์ด์–ด๊ทธ๋žจ์€ ์ด ํ”„๋กœ์„ธ์Šค๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

Input stack proxy

๋™์ ์œผ๋กœ ๋กœ๋“œ๋œ ์ปฌ๋ ‰์…˜์˜ ๋ชจ๋“  on_input() ์ปดํฌ๋„ŒํŠธ ์ฝ”๋“œ๊ฐ€ ์ž…๋ ฅ ์•ก์…˜์„ ๋ฐ›๊ธฐ ์œ„ํ•ด์„œ๋Š”, ์ปฌ๋ ‰์…˜ ํ”„๋ก์‹œ๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ๋Š” ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ๋ฐ˜๋“œ์‹œ ์ธํ’‹ ์Šคํƒ์— ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ปฌ๋ ‰์…˜ ํ”„๋ก์‹œ์˜ ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ๊ฐ€ on_input() ์ฝ”๋“œ๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ์ง€ ์•Š๋”๋ผ๋„, ์ž…๋ ฅ์Šคํƒ์˜ ์ƒ์œ„์— ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด์„œ "acquire_input_focus" ๋ฉ”์„ธ์ง€๊ฐ€ ๋ฐ˜๋“œ์‹œ ์ „์†ก๋˜์–ด์•ผ ํ•˜๋ฉฐ, ๋กœ๋“œ๋œ ์ปฌ๋ ‰์…˜ ๋‚ด์— ์žˆ๋Š” ๊ฒŒ์ž„์˜ค๋ธŒ์ ํŠธ๋„ ์ปฌ๋ ‰์…˜์˜ ์ธํ’‹ ์Šคํƒ์— ์ถ”๊ฐ€๋˜๊ธฐ ์œ„ํ•ด "acquire_input_focus" ๋ฉ”์„ธ์ง€๋ฅผ ๋ณด๋‚ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ž…๋ ฅ ์Šคํƒ์˜ ์–ด๋–ค ๋‹จ๊ณ„์—์„œ๋“  on_input() ํ•จ์ˆ˜๊ฐ€ true๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉด, ์ด ์ž…๋ ฅ์€ ์†Œ๋น„(consume)๋˜์–ด ์–ด๋– ํ•œ ๋™์ž‘๋„ ๋„˜๊ธฐ์ง€ ์•Š๊ณ  ์•„๋ฌด ์ผ๋„ ๋ฐœ์ƒํ•˜์ง€ ์•Š๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ํ•„์š”์— ๋”ฐ๋ผ์„œ, ๋กœ๋“œ๋œ ์ปฌ๋ ‰์…˜์ด ๋ฉ”์ธ ์ปฌ๋ ‰์…˜์—์„œ ์ˆ˜์‹ ์ค‘์ธ ์•ก์…˜์„ ๋™์ž‘ ๋ชปํ•˜๋„๋ก ์ž…๋ ฅ์„ ์†Œ๋น„ํ•ด ๋ฒ„๋ฆด ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.