Vim으로 박자를 맞추다
최근 지아이허브의 플러그인gh.vim을 만들고 있어서 이쪽 개발이 멈췄어요. 그 이야기를 조금 써보고 싶어요.
어떤 느낌?
그냥 하는 거지만 그런 느낌이에요.
위에서 블록을 무작위로 내리기 때문에
A~L
의 키로 정타를 할 수 있는 수준에 이르렀다.현재 네모난 블록은 무작위로 생성되어 앞으로 음성 기능과 악보 편집 기능을 실행할 것이다.
나는 만약 이 두 개가 완성된다면 아마 놀 수 있을 것이라고 생각한다.
어떤 실패?
블록의 생성에는 Vim
popup window
이 사용됩니다.이것은 timer_start()
를 사용하여 무작위로 생성된 것이다.function! s:make_block(opt, timer) abort
call timer_start(rand(srand()) % 1000, function('s:new_block', [a:opt]))
endfunction
(中略)
for i in range(8)
let press_key = s:bottom_bar_keys[i]
let opt = {
\ 'press_key': press_key,
\ 'col_len': col_len,
\ 'col_pos': col_pos,
\ }
call s:make_bottom_block(opt)
exe printf('nnoremap <silent> <buffer> %s :call <SID>press_bottom_bar("%s")<CR>', press_key, press_key)
call timer_start(1000, function('s:make_block', [opt]), {'repeat': -1})
let col_pos += (col_len + 4)
endfor
참고로 비동기(막히지 않는 조작)로Vimscript 함수를 실행하는 함수는 없지만 timer_start(0, f)
를 사용하면 조작이 막히지 않기 때문에 아날로그 비동기 처리를 할 수 있습니다.이것을 사용하면 네모난 블록을 떨어뜨리는 처리를 하면서 버튼이 눌린 사건을 주워 판정 처리할 수 있다.
블록을 내릴 때
popup window
의 위치를 중복 사용timer_start
+1.function! s:move_block_down(winid, press_key, timer) abort
let opt = popup_getpos(a:winid)
if opt.line is# s:winheight
call timer_stop(a:timer)
call popup_close(a:winid)
call s:delete_block_winid(a:press_key, a:winid)
return
endif
let opt.line += 1
call popup_move(a:winid, opt)
endfunction
(中略)
function! s:new_block(opt, timer) abort
let text = s:make_block_text('0', a:opt.col_len)
let winid = popup_create(text, {
\ 'col': a:opt.col_pos,
\ 'line': 1,
\ 'minwidth': strlen(text),
\ })
call win_execute(winid, 'syntax match beatbanana_bar /0/')
call timer_start(60, function("s:move_block_down", [winid, a:opt.press_key]), {
\ 'repeat': -1,
\ })
call add(s:bar_winid_set[a:opt.press_key], winid)
endfunction
판정 처리에 관해서는 간단하게 말하면 내려온 블록이 가지고 있는 키가 일치하는지 확인한 후 위치가 일치하는지 확인하는 것이다.예를 들어
J
의 버튼열에 J
의 버튼이 있습니다. 이런 메시지 블록이 있기 때문에 그 블록에서 열쇠를 꺼내서 지금 눌렀던 키와 일치하는지 확인하세요.자세한 논리는 코드를 읽어 주세요.
function! s:collision_detection(key) abort
let winids = s:bar_winid_set[a:key]
if empty(winids)
return 0
endif
let bar_winid = winids[0]
let opt = popup_getpos(bar_winid)
return opt.line is# s:winheight || opt.line is# s:winheight - 1
endfunction
function! s:press_bottom_bar(key) abort
let winid = s:bottom_bar_winid_set[a:key]
if s:collision_detection(a:key)
call win_execute(winid, 'syntax match beatbanana_hit_good /1/')
else
call win_execute(winid, 'syntax match beatbanana_hit /1/')
endif
call timer_start(150, function('s:restore_bottom_bar_highlight', [winid]))
endfunction
최후
아직 제작 중인데 제대로 놀 수 있을지 모르겠다는 말을 들으면 이상하겠지만 가능하면 플러그인화해서 공개하고 싶어요.
기대 많이 해주세요.
Reference
이 문제에 관하여(Vim으로 박자를 맞추다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/skanehira/articles/2020-12-25-vim-beatbanana텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)