input troubles

Discuss using and improving Lua and the Lua Player specific to the PSP.

Moderators: Shine, Insert_witty_name

Post Reply
LuMo
Posts: 410
Joined: Sun Aug 21, 2005 2:45 am
Location: Austria
Contact:

input troubles

Post by LuMo »

i just wrote (once again) a tetris clone
when i come to collision detection all works fine...
BUT,
it seems that the input repeats too fast

Code: Select all

	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?

greets
holger
Posts: 204
Joined: Thu Aug 18, 2005 10:57 am

Post by holger »

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;
chaos
Posts: 135
Joined: Sun Apr 10, 2005 5:05 pm

Post by chaos »

i've been having the same problem with a game i am making.. i've come up with a few solutions, but so far, none of them are very elegant.
holger wrote:check key-up and key-down events.
where is some good example code for this method?
Chaosmachine Studios: High Quality Homebrew.
nevyn
Posts: 136
Joined: Sun Jul 31, 2005 5:05 pm
Location: Sweden
Contact:

Post by nevyn »

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)

Code: Select all

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

chaos
Posts: 135
Joined: Sun Apr 10, 2005 5:05 pm

Post by chaos »

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.
Chaosmachine Studios: High Quality Homebrew.
nevyn
Posts: 136
Joined: Sun Jul 31, 2005 5:05 pm
Location: Sweden
Contact:

Post by nevyn »

Chaos: Sounds to me like a bug in your code. Working /around/ the bug by disabling its sideeffects is a bad way of solving it :P
chaos
Posts: 135
Joined: Sun Apr 10, 2005 5:05 pm

Post by chaos »

nevyn wrote:Chaos: Sounds to me like a bug in your code. Working /around/ the bug by disabling its sideeffects is a bad way of solving it :P
it does sound like a bug.. i'm rewritting all my control routines to make sure. i'll post the results when i'm done.
Chaosmachine Studios: High Quality Homebrew.
chaos
Posts: 135
Joined: Sun Apr 10, 2005 5:05 pm

Post by chaos »

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.

Code: Select all

function checkPad&#40;&#41;
	pad = Controls.read&#40;&#41;
	
	if pad&#58;up&#40;&#41; then
		p.upCount = p.upCount + 1
		moveCursor&#40;0,-1, p.upCount&#41;
	else
		p.upCount = 0
	end
	
	if pad&#58;down&#40;&#41; then
		p.downCount = p.downCount + 1
		moveCursor&#40;0,1, p.downCount&#41;
	else
		p.downCount = 0
	end
	
	if pad&#58;left&#40;&#41; then
		p.leftCount = p.leftCount + 1
		moveCursor&#40;-1,0, p.leftCount&#41;
	else
		p.leftCount = 0
	end
	
	if pad&#58;right&#40;&#41; then
		p.rightCount = p.rightCount + 1
		moveCursor&#40;1,0, p.rightCount&#41;
	else
		p.rightCount = 0
	end
end

function moveCursor&#40;dx, dy, count&#41;
	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&#40;count, 3&#41; == 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&#40;count, 2&#41; == 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
Chaosmachine Studios: High Quality Homebrew.
Post Reply