κ²Œμž„ κ°œλ°œμ„ ν•˜λ‹€λ³΄λ©΄, ν•˜λ‚˜ ν•˜λ‚˜ 레벨 데이터λ₯Ό 직접 μž…λ ₯ν•˜λŠ” 것이 μ§„μ ˆλ¨Έλ¦¬κ°€ λ‚  λ•Œκ°€ μžˆμŠ΅λ‹ˆλ‹€.

그것이 csvλ‚˜ json을 μ΄μš©ν•˜λŠ” κ²ƒμ΄λ˜, κ²Œμž„ μ—”μ§„μ—μ„œ 직접 μž…λ ₯ν•˜λŠ” κ²ƒμ΄λ˜,

무진μž₯ λ§Žμ€ λ°μ΄ν„°μ˜ ν…μŠ€νŠΈλ₯Ό μž‘μ„±ν•˜κ±°λ‚˜ λ“œλž˜κ·Έ μ•€ λ“œλ‘­μœΌλ‘œ κΎΈμ—­κΎΈμ—­ λ°”μΈλ”©ν•˜λŠ” 것은 λΆ„λͺ… 즐거운 일은 μ•„λ‹™λ‹ˆλ‹€.


특히 리듬 κ²Œμž„μ€ μ‹€μ œ κ²Œμž„ ν”Œλ ˆμ΄μ™€λŠ” 달리 평면적인 데이터가 λ§Žκ²ŒλŠ” 수 천 회 λ°˜λ³΅λ˜λŠ” ꡬ쑰이기 λ•Œλ¬Έμ—,Β 

직접 ν•˜λ‚˜ ν•˜λ‚˜ μž…λ ₯ν•œλ‹€λŠ” 것은 μž¬λ―Έκ°€ μ—†μ–΄μ„œ 무척 μ–΄λ €μš΄ μΌμž…λ‹ˆλ‹€.



a15714ab041eb360be3335625683746f01534428d6a6e889d63461f19d13cd6e418b9b0df7feb4948b828d13e705


κ·Έλž˜μ„œ λ§Œλ“€μ–΄μ§„ 것인 μ›Ή λΈŒλΌμš°μ €μ—μ„œ μž‘λ™ν•˜λŠ” νŒ¨ν„΄ μ—λ””ν„°μž…λ‹ˆλ‹€.

λ‘œμ»¬μ΄λ‚˜ μ„œλ²„μ—μ„œ node.js같은 μ›Ή μ—”μ§„μœΌλ‘œ 기동할 μˆ˜λ„ μžˆμ§€λ§Œ,Β 

별도 μ„œλ²„ μ›Œν¬ μ—†λŠ” 정적 μ„œλΉ„μŠ€λ‘œ ꡬ성해 κΉƒν—ˆλΈŒ νŽ˜μ΄μ§€λ‘œ λ°°ν¬ν–ˆμŠ΅λ‹ˆλ‹€.

μ›Ή λΈŒλΌμš°μ €λ₯Ό μ΄μš©ν•œ 레벨 μ—λ””ν„°λŠ” μ„±λŠ₯λ©΄μ—μ„œλŠ” λ©”λ¦¬νŠΈκ°€ μ—†μ§€λ§Œ, 개발이 λΉ λ₯΄κ³  이용자의 접근성이 μ’‹λ‹€λŠ” 점이 λ©”λ¦¬νŠΈμž…λ‹ˆλ‹€.



a15714ab041eb360be3335625683746f01534428d6a6e889d63760f19f16cd6e3a5e3ff0540ffa7a409eb9e9a12f


λ…ΈνŠΈλŠ” 크게 Tab, Direction, Both의 3 μ’…λ₯˜λ‘œ λ‚˜λ‰˜μ–΄μ§€κ³ 

λ‘±λ…ΈνŠΈλ₯Ό μœ„ν•œ 각 λ…ΈνŠΈμ˜ Long νƒ€μž…, μΆ”κ°€λ‘œ λ³€μ†μ΄λ‚˜ 이벀트 μ œμ–΄λ₯Ό μœ„ν•΄μ„œλ§Œ μ‘΄μž¬ν•˜λŠ” Node νƒ€μž…μ΄ μžˆμŠ΅λ‹ˆλ‹€.

κ²½λ‘œλŠ” Node νƒ€μž… λ…ΈνŠΈμ˜ λ°©ν–₯ μ œμ–΄κ°€ μ•„λ‹ˆλΌλ©΄ Direction의 μœ„μΉ˜μ™€ λ°©ν–₯만으둜 κ·Έλ €μ§€λ―€λ‘œ,

νŒ¨ν„΄ λ””μžμ΄λ„ˆλ“€μ€ Direction λ…ΈνŠΈλ₯Ό μ΄μš©ν•΄ μŒμ•…μ— μ–΄μšΈλ¦¬λŠ” 경둜λ₯Ό λ§Œλ“€ 수 μžˆμŠ΅λ‹ˆλ‹€.



이 νŒ¨ν„΄ μ—λ””ν„°λŠ” 각 λ…ΈνŠΈ 별 bpm, 레벨, λΆ„λ°•κ³Ό 전역적인 μ •λ°€ 보정 λ“±μ˜ 섀정을 λͺ¨λ‘ μ§€μ›ν•˜κ³ ,

데이터 λ³€κ²½ μ‹œ λΈŒλΌμš°μ € μŠ€ν† λ¦¬μ§€μ— μžλ™ μ €μž₯ν•˜λ©°, μΈκ²Œμž„κ³Ό μœ μ‚¬ν•œ 프리뷰 ν”Œλ ˆμ΄λ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€.

κ±΄λ°˜ν˜•μ΄ μ•„λ‹Œ 경둜 μœ„λ₯Ό 캐릭터가 μ΄λ™ν•˜λŠ” ν˜•νƒœμ˜ 리듬 κ²Œμž„μ΄λ―€λ‘œ, μ΄λŸ¬ν•œ 프리뷰 κΈ°λŠ₯은 ν•„μˆ˜μ˜€μŠ΅λ‹ˆλ‹€.



a15714ab041eb360be3335625683746f01534428d6a6e889d63760f09d10cd6e33b0153a0fdc8170c45984eb3b





7cea8073b18568f13fec84e64e9c3c38c4b39f746c949d73ae4e81d89cd177a5485527e75dfd4c5c



μœ„μ˜ λ…ΈνŠΈ κΈ°λŠ₯λ§ŒμœΌλ‘œλ„ 저희 κ²Œμž„μ˜ 근본이 λ˜λŠ” κ²½λ‘œμ™€ λ…ΈνŠΈ λ°°μΉ˜λŠ” κ°€λŠ₯ν•˜μ§€λ§Œ,

카메라 μ‘°μž‘μ΄λ‚˜ λ°°κ²½ 이미지 λ³€κ²½, μˆœκ°„μ μΈ 점멸 νš¨κ³Όλ‚˜ 광원 효과 ν™œμ„±ν™” λ“±μ˜ 특수 νš¨κ³ΌλŠ” μ‹€ν–‰ν•  수 μ—†μ—ˆμŠ΅λ‹ˆλ‹€.

특히, λŒ€μ„Έ 해상도인 16:9 λΉ„μœ¨μ—μ„œ μœ„, μ•„λž˜μ— μœ„μΉ˜ν•œ λ…ΈνŠΈκ°€ λ„ˆλ¬΄ 늦게 화면에 λ“±μž₯ν•΄ λΆˆμΎŒκ°μ„ μ£ΌλŠ” μ£Όμš” 원인이 λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

λ”°λΌμ„œ 쀌인, μ€Œμ•„μ›ƒκ³Ό 같은 μΉ΄λ©”λΌμ›Œν¬λ₯Ό μ§€μ›ν•˜κ³ μž 이벀트 κΈ°λŠ₯ κ°œλ°œμ— μ°©μˆ˜ν–ˆμŠ΅λ‹ˆλ‹€.



a15714ab041eb360be3335625683746f01534428d6a6e889d63760f39815cd6e3242ea5f3eb0b8fe64f7eae8e7


μ²˜μŒμ—λŠ” ν•΄λ‹Ή λ…ΈνŠΈμ— μ‹€ν–‰ν•˜κ³ μž ν•˜λŠ” 이벀트λ₯Ό μΆ”κ°€ν•˜λŠ” μ‹μœΌλ‘œ 데이터 ꡬ쑰λ₯Ό μ„€κ³„ν•˜λ € ν–ˆμ§€λ§Œ,

이 경우 μ‹€μ œ json 데이터 뿐만 μ•„λ‹ˆλΌ μ—λ””ν„°μ—μ„œλ„ 극히 비직관적인 ν˜•νƒœλ‘œ λ³΄μ—¬μ‘ŒμŠ΅λ‹ˆλ‹€.

그럴 수 밖에 μ—†λŠ” 것이, κΈ°μ‘΄ 데이터 μ•„λž˜μ— 좔가적인 데이터 ꡬ쑰λ₯Ό ν‘œμ‹œν•˜λŠ” κ²ƒμ΄λ‹ˆκΉŒμš”.

λ˜ν•œ λ™μ‹œμ— λ Œλ”λ§ ν•΄μ•Όν•  것이 λ§Žμ•„μ§„λ‹€λŠ” 것은 μ•ˆκ·Έλž˜λ„ μ•ˆμ’‹μ€ μ„±λŠ₯의 μ›Ή 에디터λ₯Ό λ”μš± 느리게 λ§Œλ“ λ‹€λŠ” λœ»μ΄μ—ˆμŠ΅λ‹ˆλ‹€.


λ”°λΌμ„œ 기쑴의 λ…ΈνŠΈ λ°μ΄ν„°λŠ” NoteList, μ‹€ν–‰ν•  이벀트 λ°μ΄ν„°λŠ” EventList둜 λ‚˜λˆ„μ–΄μ„œ json에 μ €μž₯λ˜λ„λ‘ ν–ˆμŠ΅λ‹ˆλ‹€.

μ›Ή μ—λ””ν„°μ—μ„œλ„ λ¬Όλ‘  두 리슀트λ₯Ό νƒ­μœΌλ‘œ λ‚˜λˆ„μ–΄ ν‘œμ‹œν•˜λ„λ‘ ν•˜μ—¬ λžœλ”λ§κ³Ό μ—°μ‚° λΆ€ν•˜λ₯Ό κ°€λŠ₯ν•œ μ΅œμ†Œν™”ν–ˆμŠ΅λ‹ˆλ‹€.


note듀은 pre-delay와 bpm, subdivision(λΆ„λ°•) 값을 κΈ°λ°˜μœΌλ‘œν•˜λŠ” beat 값을 μ„€μ •ν•˜λ„λ‘ ν–ˆμŠ΅λ‹ˆλ‹€.


즉, 120 bpm의 16 subdivision에 pre-delayκ°€ 30ms라면, 10beat에 ν•΄λ‹Ήν•˜λŠ” μ‹œκ°„μ€Β 

10(beat) * 60(초) / 120(bpm) / 16(subdivision) + 0.03(pre-delay) = 0.3155μ΄ˆμ— ν•΄λ‹Ήν•˜λŠ” μ‹μž…λ‹ˆλ‹€.


μ΄λ ‡κ²Œ ν–ˆμ„ λ•Œ μœ λ¦¬ν•œ 점은, λ”°λ‘œ μ‹œκ°„μ„ κ³„μ‚°ν•˜μ§€ μ•Šμ•„λ„ BPMκ³Ό subdivision 값에 λ”°λΌμ„œ κ²°κ³Ό μ‹œκ°„μ΄ λ„μΆœλœλ‹€λŠ” μ μž…λ‹ˆλ‹€.

μ‹œκ°„μœΌλ‘œ μž…λ ₯ν•  수 μžˆλ‹€λ©΄ μž…λ ₯의 μžμœ λ„λŠ” λ†’μ•„μ§€κ² μ§€λ§Œ μ‚¬λžŒμ΄ 직접 μŒμ•…μ˜ BPMκ³Ό subdivision을 κ³ λ €ν•΄μ„œ μ‹œκ°„μ„ μž…λ ₯ν•΄μ•Όν• ν…Œλ‹ˆκΉŒμš”.


ν•˜μ§€λ§Œ event듀은 μ‹œκ°„μœΌλ‘œ μž…λ ₯ν•  수 μžˆλ„λ‘ ν–ˆμŠ΅λ‹ˆλ‹€.

일단 note 듀을 λ§Œλ“€μ–΄ 두고 μž‘μ—…ν•˜λŠ” 것이 μ „μ œμ΄κΈ° λ•Œλ¬Έμ— κ·Έ λ…ΈνŠΈμ˜ μ‹œκ°„μ„ κ°€μ Έμ™€μ„œ μž…λ ₯ν•˜λ©΄ λ©λ‹ˆλ‹€.

λ˜ν•œ μ΄λ²€νŠΈλŠ” κ·Έ μ‹œκ°„μ— νŒμ •μ΄ μ΄λ£¨μ–΄μ§€λŠ” 것은 μ•„λ‹ˆκΈ° λ•Œλ¬Έμ— μ˜λ„μ— λ”°λΌμ„œ μŒμ•…μ˜ λ°•μžμ™€ λ‹€λ₯΄κ²Œ μž¬μƒλ˜λŠ” μ—°μΆœλ„ 지원해야 ν–ˆκΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.


event의 데이터 κ΅¬μ‘°λŠ” Type - id - parameters - param(key-value)둜 κ΅¬μ„±λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.

Type, idλŠ” 에디터와 κ²Œμž„ μ–‘μͺ½μ— enum으둜 μ •μ˜λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.

type은 카메라, λ°°κ²½ λ“±μ˜ 이벀트의 μΉ΄ν…Œκ³ λ¦¬λ₯Ό,

idλŠ” 쀌인, μ€Œμ•„μ›ƒ, 이미지 λ³€κ²½ λ“±μ˜ μΉ΄ν…Œκ³ λ¦¬ λ‚΄λΆ€μ—μ„œ μ²˜λ¦¬ν•  ꡬ체적인 이벀트 λ‚΄μš©μ„ μ •μ˜ν•©λ‹ˆλ‹€.

parametersλŠ” 사전 μ •μ˜κ°€ λ˜μ–΄ μžˆμ§€λŠ” μ•Šμ§€λ§Œ, 이벀트λ₯Ό μ²˜λ¦¬ν•  λ•Œ ν•„μš”ν•œ νŒŒλΌλ―Έν„° 킀와 ν•¨κ»˜ 값을 μž…λ ₯ν•˜λ©΄ 그에 맞게 μ²˜λ¦¬λ˜λŠ” μ‹μž…λ‹ˆλ‹€.





이제 κ²Œμž„μ—μ„œ μ§€μ •λœ μ‹œκ°„μ΄ λ˜μ—ˆμ„ λ•Œ μ‹€ν–‰λ˜λŠ” event μ‹œμŠ€ν…œμ„ μœ„ν•œ 데이터 ꡬ쑰가 μ™„μ„±λ˜μ—ˆμŠ΅λ‹ˆλ‹€.



7cea8073b18568f13fec84e64e9c3c38c4b39f746c949d73ae4e81d89cd177a5485527e75dfd4c5c


κ²Œμž„ 이벀트의 꽃, λ‹€μ΄μ–Όλ‘œκ·Έλ₯Ό κ΅¬ν˜„ν•©λ‹ˆλ‹€.

리듬 κ²Œμž„ 쀑간에 λ‹€μ΄μ–Όλ‘œκ·Έ 이벀트λ₯Ό??? 이게 무슨 κ°œμ†Œλ¦°κ°€μš” κ°œλ°œμžλ‹˜?

μ΄λ ‡κ²Œ μƒκ°ν•˜μ‹  뢄도 κ³„μ‹œκ² μ§€λ§Œ, νŠœν† λ¦¬μ–Όμ„ μœ„ν•΄ λ§Œλ“€μ–΄μ•Ό ν–ˆμŠ΅λ‹ˆλ‹€.


νŠœν† λ¦¬μ–Όλ§Œμ„ μœ„ν•œ μƒˆλ‘œμš΄ μ‹œμŠ€ν…œμ„ λ§Œλ“€ μˆ˜λ„ μžˆκ² μ§€λ§Œ, κ·Έ 편이 였히렀 μ‹œκ°„μ΄ 더 κ±Έλ¦°λ‹€λŠ” νŒλ‹¨μ΄μ—ˆμŠ΅λ‹ˆλ‹€.

κ²Œλ‹€κ°€ μ „μš© μ‹œμŠ€ν…œμ€ μœ μ‚¬ν•œ μƒν™©μ—μ„œμ˜ μž¬μ‚¬μš©λ„ μ–΄λ ΅κ΅¬μš”.

νŠœν† λ¦¬μ–Όμ„ μœ„ν•΄ λ§Œλ“œλŠ” κ²ƒμ΄κΈ°λŠ” ν•˜μ§€λ§Œ, μŠ€ν† λ¦¬ μ§„ν–‰ λ“±μ—μ„œ μΆ©λΆ„νžˆ μ‚¬μš©ν•  μ—¬μ§€κ°€ μžˆλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€.


이 μ‹œμŠ€ν…œμ˜ 특히 μ–΄λ €μ› λ˜ 뢀뢄은, 기쑴의 μŒμ•… μ‹œκ°„μ— λ”°λΌμ„œ μ›€μ§μ΄λŠ” κ²Œμž„ μ‹œμŠ€ν…œ μ‚¬μ΄μ—μ„œ 순차 μ²˜λ¦¬λ˜λŠ” λŒ€ν™” μ‹œν€€μŠ€λ₯Ό λ„£μ–΄μ•Ό ν•˜λŠ”λ°,

κ·Έ 데이터가 κΈ°μ‘΄ λ…ΈνŠΈ, 이벀트 데이터 μœ„μ— μ–Ήμ–΄μ Έμ„œ λ‚˜μ™€μ•Ό ν•œλ‹€λŠ” λΆ€λΆ„μ΄μ—ˆμŠ΅λ‹ˆλ‹€.

이 두 λ°μ΄ν„°λŠ” λͺ¨λ‘ μ‹œκ°„ 기반의 λ°μ΄ν„°λ‘œ, μ‹€ν–‰ μ‹œκ°„μ΄ κ°™μœΌλ©΄ λ™μ‹œμ— μ²˜λ¦¬ν•  뿐이고 μˆœμ„œλ₯Ό κΈ°λ‹€λ¦¬λŠ” κΈ°λŠ₯은 μ—†μŠ΅λ‹ˆλ‹€.


μ²˜μŒμ—λŠ” κΈ°μ‘΄ 이벀트 μ‹œμŠ€ν…œλ§ŒμœΌλ‘œ μ²˜λ¦¬ν•  방법이 μ—†μ„κΉŒ κ³ λ―Όν–ˆμœΌλ‚˜,

기쑴의 λ°©μ‹μœΌλ‘œλŠ” 순차적으둜 μ²˜λ¦¬ν•˜κΈ° μœ„ν•΄μ„œλŠ” λŒ€ν™” 데이터 ν•˜λ‚˜ ν•˜λ‚˜μ— 처리 μˆœμ„œ indexλ₯Ό λ„£μ–΄μ€˜μ•Ό ν•˜κ³ ,

λΆˆν•„μš”ν•˜κ²Œ 이벀트 ν•„λ“œκ°€ κΈΈμ–΄μ Έμ„œ 가독성을 맀우 ν•΄μΉœλ‹€λŠ” λ¬Έμ œκ°€ μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

λ˜ν•œ 같은 μ‹œκ°„μ— μ—¬λŸ¬ 이벀트λ₯Ό μ‹€ν–‰μ‹œν‚€κ²Œ λ˜λŠ”λ°, 이것을 μˆœμ„œλŒ€λ‘œ μ²˜λ¦¬ν•˜κΈ° μœ„ν•΄ indexλ₯Ό νŒŒμ‹±ν•΄μ„œ μž¬μ •λ ¬ν•˜λŠ” λ“±μ˜ μ²˜λ¦¬κ°€ 맀우 번작슀럽게 λŠκ»΄μ‘ŒμŠ΅λ‹ˆλ‹€.



a15714ab041eb360be3335625683746f01534428d6a6e889d63760f69e1dcd6e7e23b7f3c1cccc6bce5146f34a


결과적으둜 μ„ νƒν•œ 방법은, parametersλ₯Ό λŒ€μ²΄ν•˜λŠ” dialog용 데이터 ꡬ쑰λ₯Ό λ§Œλ“œλŠ” κ²ƒμ΄μ—ˆμŠ΅λ‹ˆλ‹€.

event 내에 또 λ‹€λ₯Έ ꡬ쑰의 eventκ°€ μ‘΄μž¬ν•˜λŠ” λ°©μ‹μ΄μ§€μš”.

μ΄λ²€νŠΈμ—μ„œ system - dialogλ₯Ό μ„ νƒν•˜λ©΄, κΈ°μ‘΄ 이벀트 λ³€μˆ˜λ₯Ό μž…λ ₯ν•˜λŠ” parameters ν•„λ“œ λŒ€μ‹  dialogItems ν•„λ“œκ°€ ν‘œμ‹œλ©λ‹ˆλ‹€.

즉, κ²Œμž„μ—μ„œ dialog μ΄λ²€νŠΈκ°€ μ‹€ν–‰λ˜μ—ˆμ„ λ•ŒλŠ” parameters λŒ€μ‹  dialogItems에 μž…λ ₯ν•œ 값을 μ΄μš©ν•΄μ„œ 이벀트λ₯Ό μ²˜λ¦¬ν•©λ‹ˆλ‹€.


dialogItemsμ—μ„œλŠ” ν…μŠ€νŠΈ μ„€μ •, 캐릭터 μ„€μ •, ν‘œμ • μ„€μ •, νŠΉμ • 지점 ν¬μ»€μŠ€μ™€ 같은 기본적인 νŠœν† λ¦¬μ–Ό, λ‹€μ΄μ–Όλ‘œκ·Έ κΈ°λŠ₯을 선택할 수 μžˆλ„λ‘ λ˜μ–΄μžˆμŠ΅λ‹ˆλ‹€.

λ˜ν•œ νŠΉμ • ν‚€κ°€ μž…λ ₯될 λ•ŒκΉŒμ§€ 기닀리도둝 ν•˜λŠ” κΈ°λŠ₯을 λ§Œλ“€μ–΄ νŠœν† λ¦¬μ–Ό μ‹œ ν”Œλ ˆμ΄μ–΄μ˜ μ˜¬λ°”λ₯Έ ν‚€ μž…λ ₯을 λŒ€κΈ°ν•  수 μžˆλ„λ‘ ν–ˆμŠ΅λ‹ˆλ‹€.



μ΄λ ‡κ²Œ ν•΄μ„œ 리듬 κ²Œμž„ 쀑간에 ν‘œμ‹œλ˜λŠ” λ‹€μ΄μ–Όλ‘œκ·Έ μ‹œμŠ€ν…œκΉŒμ§€ κ΅¬ν˜„μ„ μ™„λ£Œν–ˆμŠ΅λ‹ˆλ‹€.


μ§€κΈˆκΉŒμ§€ κ°œλ°œν•œ 것은 μ—¬κΈ°κ°€ λμ΄μ§€λ§Œ,

μ•„λ§ˆ μ•žμœΌλ‘œλ„ μƒˆλ‘œμš΄ μš”κ΅¬μ‚¬ν•­μ— λŒ€μ‘ν•˜κΈ° μœ„ν•΄μ„œ λ‹€μ‹œ ν•œ 번 데이터 ꡬ쑰와 μ‹œμŠ€ν…œ κ΅¬ν˜„μ΄ ν•„μš”ν•  λ•Œκ°€ μ˜¬κ²λ‹ˆλ‹€.

κ·Έ λ•Œ, μ§€κΈˆκΉŒμ§€ λ§Œλ“  것을을 μ „λΆ€ λ‹€μ‹œ λ§Œλ“€μ–΄μ•Ό ν•˜λŠ” μƒν™©λ§Œμ€ μ˜€μ§€ μ•ŠκΈ°λ₯Ό κ°„μ ˆνžˆ λ°”λžλ‹ˆλ‹€...