flappyvird-vim/autoload/flappyvird.vim

216 lines
4.7 KiB
VimL
Raw Permalink Normal View History

2014-07-09 06:03:02 -04:00
scriptencoding utf-8
2014-07-09 09:42:11 -04:00
let s:CURSOR_OFF = 0
2014-07-09 09:43:02 -04:00
let s:CURSOR_ON = 1
2014-07-09 06:03:02 -04:00
let s:STATE_LOOP = 1
let s:STATE_DIE = 2
2014-07-09 07:19:22 -04:00
let s:STATE_FINISH = 3
2014-07-09 06:03:02 -04:00
2014-07-09 09:42:11 -04:00
let s:t_ve = &t_ve
let s:top_score = 0
2014-07-09 06:03:02 -04:00
let s:seed = 0
function! s:srand(seed) abort
let s:seed = a:seed
endfunction
function! s:rand() abort
let s:seed = s:seed * 214013 + 2531011
return (s:seed < 0 ? s:seed - 0x80000000 : s:seed) / 0x10000 % 0x8000
endfunction
2014-07-09 09:43:02 -04:00
function! s:toggle_cursor(f) abort
2014-07-09 07:19:22 -04:00
let &t_ve = a:f ? s:t_ve : ''
endfunction
2014-07-09 06:03:02 -04:00
function! s:stage_init() abort
" open new buffer
silent edit `='==FlappyVird=='`
silent normal! gg0
silent only!
setlocal buftype=nowrite
setlocal noswapfile
setlocal bufhidden=wipe
setlocal buftype=nofile
setlocal nonumber
setlocal nolist
setlocal nowrap
setlocal nocursorline
setlocal nocursorcolumn
syn match FlappyVirdGreen1 '\~'
hi FlappyVirdGreen1 ctermfg=black ctermbg=green guifg=black guibg=green
syn match FlappyVirdGreen2 '\^'
hi FlappyVirdGreen2 ctermfg=yellow ctermbg=yellow guifg=yellow guibg=yellow
syn match FlappyVirdBar '*'
hi FlappyVirdBar ctermfg=magenta ctermbg=magenta guifg=magenta guibg=magenta
2014-07-09 09:42:11 -04:00
call s:toggle_cursor(s:CURSOR_OFF)
2014-07-09 06:03:02 -04:00
redraw
endfunction
function! s:stage_wipeout() abort
2014-07-09 09:42:11 -04:00
call s:toggle_cursor(s:CURSOR_ON)
2014-07-09 06:03:02 -04:00
bdelete
endfunction
2014-07-09 06:18:42 -04:00
function! s:loop()
2014-07-09 06:03:02 -04:00
call s:stage_init()
" clear whole screen
let ww = winwidth('.') " window width
let wh = winheight('.') " window height
2014-07-09 09:39:26 -04:00
let sh = 20 " stage height
2014-07-09 06:03:02 -04:00
" fill screen
for i in range(1, wh)
call setline(i, repeat(' ', ww + 10))
endfor
" draw ground
call setline(sh+1, repeat("~", ww))
let state = s:STATE_LOOP
let rate = 100
2014-07-09 09:39:26 -04:00
let jx = 20 " x offset
let jy = 1600 " y offset
let ry = jy / rate " real y
let dy = 40 " diff y
let sl = 0 " stage level
let sc = 0 " score
let st = 100 " stage timer
let cf = get(g:, 'flappyvird_face', '(; @_@)') " character face
let cw = len(cf) " character width
let cb = getline(ry)[jx :jx+cw-1] " character background
let ss = 20 " sleep! sleep!
2014-07-09 06:03:02 -04:00
let rt = reltime()
call s:srand(localtime())
call setline(sh + 2, printf(" SCORE: %10d", 0))
call setline(sh + 3, printf(" TOP SCORE: %6d", s:top_score))
2014-07-09 06:18:42 -04:00
2014-07-09 06:23:12 -04:00
let pause = 0
2014-07-09 06:18:42 -04:00
let retry = 0
2014-07-09 06:03:02 -04:00
while 1
let c = getchar(0)
2014-07-09 06:23:12 -04:00
if c == 27 || c == 113 " esc or q to quit
2014-07-09 06:03:02 -04:00
" quit loop
break
2014-07-09 06:23:12 -04:00
elseif c == 112 " p to pause
let pause = !pause
endif
if pause
continue
2014-07-09 06:03:02 -04:00
endif
if state == s:STATE_FINISH
2014-07-09 06:23:12 -04:00
if c == 114 " r to retry
2014-07-09 06:18:42 -04:00
let retry = 1
break
endif
2014-07-09 06:03:02 -04:00
" do nothing
continue
endif
" erase character
if ry > 0
let l = getline(ry)
let l = l[:jx] . cb . l[jx+cw+1:]
call setline(ry, l)
endif
" calculate next position
let jy -= dy
let dy -= 1
let ry = jy / rate
if state == s:STATE_LOOP
" move left screen
for i in range(1, sh)
call setline(i, getline(i)[1:] . ' ')
endfor
" move ground
let l = getline(sh + 1)
let l = l[1:] . (s:rand() < 2000 ? '^' : '~')
call setline(sh + 1, l)
if getline(sh)[jx-2: jx-1] == '* '
let sc += 1
call setline(sh + 2, printf(" SCORE: %10d", sc))
if sc > s:top_score
let s:top_score = sc
call setline(sh + 3, printf(" TOP SCORE: %6d", s:top_score))
endif
2014-07-09 06:03:02 -04:00
endif
endif
" redraw character
if ry > 0
let l = getline(ry)
let cb = l[jx+1 :jx+cw]
let l = l[:jx] . cf . l[jx+cw+1:]
call setline(ry, l)
endif
redraw
" calculate diff times to sleep
let dt = str2float(reltimestr(reltime(rt))) * 1000.0
let ds = float2nr(ss - dt)
if ds > 0
exe 'sleep' ds . 'ms'
endif
let rt = reltime()
if state == s:STATE_DIE
if ry >= sh
let state = s:STATE_FINISH
endif
continue
endif
" if contains non-space characters, or overrun, it's hit!
if cb =~ '\S' || ry < 1 || ry >= sh
let state = s:STATE_DIE
let dy = 0
let cf = get(g:, 'flappyvird_face', '(; x_x)') " character face
2014-07-09 06:03:02 -04:00
continue
endif
if c == 32 " space key
let dy = 40
endif
if st == 0
" draw bar
2014-07-09 07:05:49 -04:00
let bw = 4 + s:rand() % (7 - sl / 5)
let bb = 1 + s:rand() % (sh - bw - 3)
2014-07-09 06:03:02 -04:00
for i in range(1, sh)
let l = getline(i)
2014-07-09 07:05:49 -04:00
let of = i >= bb && i <= bb + bw
call setline(i, l[:ww] . repeat(of ? ' ' : '*', 3))
2014-07-09 06:03:02 -04:00
endfor
" set next bar timer
2014-07-09 07:05:49 -04:00
let st = (60 - sl) + s:rand() % 20
let sl += 1
2014-07-09 06:03:02 -04:00
else
let st -= 1
endif
endwhile
call s:stage_wipeout()
2014-07-09 06:18:42 -04:00
return retry
endfunction
function! flappyvird#start() abort
while s:loop()
endwhile
2014-07-09 06:03:02 -04:00
endfunction
" vim:set et: