#54590 - psycorpse - Tue Sep 20, 2005 6:16 pm
I am somewhat new to programming on the gba (Ok. I am new to gba programming). Just a little background, I am making a bejeweled clone. The problem that I am having is that my cursor or pointer so to speak is moving way to fast. I have my functions setup so that when you press right, left, up, or down it moves an x amount of pixels. So it should look like it moves directly to the other image. The problem is when you press the dpad it moves 2 or 3 times more than it should. Is there a way to slow this down? or only move it once per press. Any kind of feedback would be great. I wouldn't even mind if I was pointed in the right direction.
Thanks in advance.
Mike
#54598 - Miked0801 - Tue Sep 20, 2005 7:07 pm
You need to setup a system whereas you only track when the button is first pressed and translate that to a movement (edge-based) as opposed to just checking to see if the direction is still pressed every tic and reacting off that.
#54601 - Quirky - Tue Sep 20, 2005 7:12 pm
Are you checking the button presses once per frame? Then caching the presses and only reading from that cache? I find that doing something like this works well for the scenario you have, a publock based interface that needs tight response and 'hold down' behaviour:
Code: |
poll hardware key register
for each button
if button is pressed
repeats[button] ++
else
repeats[button] = 0
if repeats[button] == 1 or repeats[button] > REPEAT_LIMIT
pressed [button] = true
else
pressed[button] = false
end for
|
Then check the pressed[] array rather than the hardware register. This means when you press the key it will be pressed, and it will also 'auto repeat' after a few ticks.
#54603 - poslundc - Tue Sep 20, 2005 7:18 pm
Also: make sure you are using fixed-point math to keep track of the object's position and velocity. The GBA ticks 60 times per second, so even if you only check input once in your entire game loop before waiting for the next VBlank, it will still move very quickly if it's moving one pixel per tick.
Dan.
#54608 - Fatnickc - Tue Sep 20, 2005 8:00 pm
Alternatively, and possibly more simply, simply increment a value every tic, and whne it reaches 5 or 10, you then move and reset the value to zero. Or you could not reset it, and use modulus.
Also, with this, it is very easy to change how often it moves (affecting the 'speed' in the players mind) by simply waiting for a different value to come up.
#54615 - tepples - Tue Sep 20, 2005 9:47 pm
Fatnickc wrote: |
possibly more simply, simply increment a value every tic, and whne it reaches 5 or 10, you then move and reset the value to zero. Or you could not reset it, and use modulus. |
Of course, the GBA doesn't have support for hardware division, which means the only moduli that work well are powers of 2, and then you're back to fixed-point math.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#54617 - poslundc - Tue Sep 20, 2005 10:06 pm
tepples wrote: |
Fatnickc wrote: | possibly more simply, simply increment a value every tic, and whne it reaches 5 or 10, you then move and reset the value to zero. Or you could not reset it, and use modulus. |
Of course, the GBA doesn't have support for hardware division, which means the only moduli that work well are powers of 2, and then you're back to fixed-point math. |
Or ugly/slow if-statements all over the place.
Learn fixed-point math if you haven't already. There are plenty of times when you'll want to use counters instead, but generally speaking anything involving motion physics (position, velocity, acceleration, etc.) your code will be infinitely easier to write/understand/maintain - not to mention more compact and optimal - if you simply use fixed-point values.
Dan.
#54620 - psycorpse - Tue Sep 20, 2005 10:47 pm
Ok. I see what you mean. However, I don't know fixed-point math. Well I might a little but I am not 100% sure. I will google it but can anyone offer a site that has good tutorials on fixed-point math?
Mike
#54624 - tepples - Wed Sep 21, 2005 12:01 am
I actually learned fixed-point from a Mac programming book, so that might not help much. Google [ fixed-point math tutorial ] gives Fun With Fixed Point Numbers.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#54629 - blacksun - Wed Sep 21, 2005 1:21 am
If you are just trying to increment the cursor one square at a time, I have found a way to do it. It has to do with checking the key presses and doesn't need to keep a counter of any kind. It may not be the best, but it seems to work for me.
Here is my input code to check if a button was pressed
Code: |
if(KEY_PRESSED(KEY_UP)) //if the up key is pressed
{
numY -= 4;
cursorY -= GRID_SQUARE_SIZE;
if(cursorY < Y_START_SINGLE)
cursorY += GRID_SQUARE_SIZE;
while(KEY_PRESSED(KEY_UP));
}
|
Here is my macro for KEY_PRESSED
Code: |
#define KEYS (*(volatile u16*)0x04000130)
#define KEY_PRESSED(k) (!(KEYS & k))
|
The while(KEY_PRESSED(KEY_UP)); will wait until you have let go of the button before moving on. Inputs are a little off in my opinion, where you have it set to 1 if not using and 0 if it is active. Hope this helps and I didn't steer you wrong.
#54636 - psycorpse - Wed Sep 21, 2005 2:20 am
I will give that a try. It sounds like what I am wanting to do. I will also be doing more research on the fixed-point math. Thanks and I will post if this works.
Mike
#54639 - psycorpse - Wed Sep 21, 2005 3:04 am
blacksun wrote: |
Code: |
while(KEY_PRESSED(KEY_UP));
|
|
Wouldn't this make the program hang if someone was holding down the key?
#54652 - poslundc - Wed Sep 21, 2005 7:35 am
Yes, it would. And it's generally an ill-advised way to set up your program, and shouldn't be used except maybe in quick tests of an algorithm or something.
A much more effective, scalable structure is to have an infinite loop that cycles every VBlank. Read the input once per frame, and make a decision about what to do next once per frame. Then do all of your graphics updates, etc. as normal. Don't hang inside part of your program waiting for input to happen.
Dan.