Skip to content

Instantly share code, notes, and snippets.

@pancelor
Last active February 24, 2022 10:17
Show Gist options
  • Save pancelor/7d47c31e881484615d792165710ffa11 to your computer and use it in GitHub Desktop.
Save pancelor/7d47c31e881484615d792165710ffa11 to your computer and use it in GitHub Desktop.
--
-- UPDATE 2022-02-23
-- blog post about input buffering: https://pancelor.tumblr.com/post/677053912115707904/input-buffering-in-grid-based-games
--
--
-- button queue
--
-- requires:
-- * btnp(b): returns whether button b (0-3) was pressed this frame
-- * btnr(b): returns whether button b was released this frame
--
-- I used a version of this in ocelotsafari.p8:
-- https://github.com/pancelor/ocelot-safari/blob/main/1.lua
--
btnq={}
-- update button queue tracking
-- call this at the start of each frame
function update_btnq()
for b=0,3 do
if btnp(b) then
add(btnq,{b=b})
end
end
for e in all(btnq) do
if btnr(e.b) then
e.rm=true
end
end
end
-- get the next button (0-3 or nil)
function poll_btnq()
-- delayed button release
for e in all(btnq) do
if e.rm and e.seen then
del(btnq,e)
end
end
--find first unseen entry, or last entry
for i,e in ipairs(btnq) do
if not e.seen or i==#btnq then
e.seen=true
return e.b
end
end
end
-- has any queued button not been seen yet?
function any_btnq()
for e in all(btnq) do
if not e.seen then
return true
end
end
end
--
-- usage example:
--
function approach(x,target,delta)
delta=delta or 1
return x<target and min(x+delta,target) or max(x-delta,target)
end
function _init()
-- button->x,y mappings.
-- e.g. pressing button 1 should make you move right, so dirx[1] is 1 and diry[1] is 0
dirx={1,0,0}
dirx[0]=-1
diry={0,-1,1}
diry[0]=0
x,y=64,64 --current position
x1,y1=x,y --goal position
end
function _update()
update_btnq()
-- move towards goal position
-- move faster if there are unseen buttons in the queue
local spd=any_btnq() and 2 or 1
x=approach(x,x1,spd)
y=approach(y,y1,spd)
if x==x1 and y==y1 then
-- if we've reached goal position, read from queue
local b=poll_btnq()
if b then
local dx,dy=dirx[b],diry[b]
x1=x+8*dx
y1=y+8*dy
if b==0 then flp=true end
if b==1 then flp=false end
end
end
end
function _draw()
cls()
spr(0,x,y)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment