if pad:right() then
if canMoveRight(currentblock,positionx,positiony) then
snd_move:play()
positionx = positionx+1
end
end
so if pad is presed right then check if i am allowed to move
its ok--> play sound and change the position
now when i press the right button, it jumps 2 or 3 blocks right.
when i only tip it very fast, it keeps one or two block
how can i slow it down a bit (never thought i would have SUCH a speed problem) without blocking the whole game?
check key-up and key-down events. And how much time has passed inbetween and if you want to repeat some action. Sometimes it makes sense to make movement directly dependent of time:
movement = msecs_since_keypress * movement_per_msec;
I saw some code using a debounce variable, counting it down if a button is pressed, to add a delay in the repetition rate. I thought about this, and figured that you'd likely need a separate repetition rate for each button. Here's the code that I came up with: (It's not tested, and it's rather advanced)
local buttons = {Controls.right, Controls.left, Controls.square, Controls.cross}
local debounces = {}
for k,v in ipairs(buttons) do
debounces[v] = 0
end
local repetitionRates = {[Controls.right] = 10, [Controls.left] = 10, [Controls.square] = 0, [Controls.cross] = 0} -- ignores button for ten frames.
while true do
pad = Controls.read()
for k, buttonfunc in ipairs(buttons) do
if buttonfunc(pad) and not debounces[buttonfunc] then -- button is pressed
debounces[buttonfunc] = repetitionRates[buttonfunc]
if buttonfunc == Controls.right then
if canMoveRight(currentblock,positionx,positiony) then
snd_move:play()
positionx = positionx+1
end
elseif buttonfunc == Controls.left then
-- do something funky
end -- and so on for the rest of the buttons
end
if debounces[buttonfunc] then
debounces[buttonfunc] = debounces[buttonfunc] - 1
end
if not buttonfunc(pad) and debounces[buttonfunc] then
debounces[buttonfunc] = 0
end
end -- for each buttons
end -- main loop
that's pretty much what i was doing now.. i've even got some acceleration tables for moving the cursor faster the longer it's held down.
the only problem is that the buttons seem to be retriggering exactly once after they are released. the key input when holding down the x key looks like this...
01234567901234 <-- polling intervals
xxxxxx_x______ <-- x button held down, then released
except for very quick button presses which look like this:
01234567901234 <-- polling intervals
x____________ <-- x button pressed once very quickly.
so, i told the polling routine to ignore the button until it's been held for at least 2 polling intervals, effectively filtering out the 1 interval retrigger that happens when you release the button. this adds a little bit of delay to button presses, because it's ignoring it for an entire polling cycle.. and it also misses very quick button presses. i'm trying to find some way around this, but so far i haven't.
ok, the results are in. i rewrote my code, and the bug is gone.
here's the code. i use it to move a 16x16 cursor around the screen in 16 pixel steps. i've left out the code for button presses, because it's handled the same way as movement, and the extra code would be redundant.
the code has support for four levels of cursor acceleration, though it's a bit of a hack. if you're going to use a higher resolution cursor, you'll probably want to come up with something that scales better.
function checkPad()
pad = Controls.read()
if pad:up() then
p.upCount = p.upCount + 1
moveCursor(0,-1, p.upCount)
else
p.upCount = 0
end
if pad:down() then
p.downCount = p.downCount + 1
moveCursor(0,1, p.downCount)
else
p.downCount = 0
end
if pad:left() then
p.leftCount = p.leftCount + 1
moveCursor(-1,0, p.leftCount)
else
p.leftCount = 0
end
if pad:right() then
p.rightCount = p.rightCount + 1
moveCursor(1,0, p.rightCount)
else
p.rightCount = 0
end
end
function moveCursor(dx, dy, count)
allowMove = false
-- allow move if this is the first press
if count == 1 then
allowMove = true
end
-- allow move every 3rd polling interval if we've been holding for more than 8 intervals
-- slow movement rate
if count > 8 and math.mod(count, 3) == 1 then
allowMove = true
end
-- allow move every 2rd polling interval if we've been holding for more than 20 intervals
-- medium movement rate
if count > 20 and math.mod(count, 2) == 1 then
allowMove = true
end
-- if we've been holding for more than 30 intervals, allow move every interval
-- fastest movement rate
if count > 30 then
allowMove = true
end
if allowMove == true then
-- save cursor position
cursor.lastX = cursor.x
cursor.lastY = cursor.y
-- update cursor position
cursor.x = cursor.x + dx
cursor.y = cursor.y + dy
-- keep the cursor in bounds
if cursor.x > 29 or cursor.x < 0 then
cursor.x = cursor.lastX
end
if cursor.y > 16 or cursor.y < 0 then
cursor.y = cursor.lastY
end
end
end