I noticed that my hero in KRPG has somewhat choppy movement. It is related to the keyPressed Method of KeyListener being called a bazillion times. Keys held down fire repeated events. Am I using the Wrong Listener Interface. I really need to iron this problem out.
If all you are doing is setting a flag in your listener,
does it matter how many times the keyPressed listener is called?
hm 2 threads and if u set only a variable its a problem u need some kind of sync, without that you could accidentally change something while rendering.
volatile will prevent any caching of the flags between asynchronously running Threads,
if thats what your worried about.
[quote]If all you are doing is setting a flag in your listener,
does it matter how many times the keyPressed listener is called?
[/quote]
I wouldn’t think so but I have so many logic checks in my Listener that I think sometimes the method takes longer to process than others.
// public void keyPressed(KeyEvent evt)
// {
// if(state == PLAY)
// {
// if(evt.getKeyCode() == KeyEvent.VK_UP)
// {
// diry = -2;
// hero.setDirection(Hero.UP);
// }
// else if(evt.getKeyCode() == KeyEvent.VK_DOWN)
// {
// diry = 2;
// hero.setDirection(Hero.DOWN);
// }
// else if(evt.getKeyCode() == KeyEvent.VK_LEFT)
// {
// dirx = -2;
// hero.setDirection(Hero.LEFT);
// }
// else if(evt.getKeyCode() == KeyEvent.VK_RIGHT)
// {
// dirx = 2;
// hero.setDirection(Hero.RIGHT);
// }
//
// if(evt.getKeyCode() == KeyEvent.VK_ESCAPE) running = false;
// hero.start();
// }
// else if(state == DIALOG)
// {
// DialogManager.setConversation(0);
// hud.triggerKeyEvent(evt);
// }
// else
// {
// mainMenu.triggerKeyEvent(evt);
// }
//
// if(evt.getKeyCode() == KeyEvent.VK_P)
// {
// state = MENU;
// }
// if(evt.getKeyCode() == KeyEvent.VK_SPACE)
// {
// state = DIALOG;
// }
//
// System.out.println("KEYPRESS: " + keyPresses++);
// }
//
// public void keyReleased(KeyEvent evt)
// {
// if(evt.getKeyCode() == KeyEvent.VK_UP) diry = 0;
// if(evt.getKeyCode() == KeyEvent.VK_DOWN) diry = 0;
// if(evt.getKeyCode() == KeyEvent.VK_LEFT) dirx = 0;
// if(evt.getKeyCode() == KeyEvent.VK_RIGHT) dirx = 0;
// hero.stop();
// }
That’s Odd… It seems that KeyReleased is called many more times than the key is actually released. Looks like the KeyPressed and KeyReleased methods are having a duel. One stops the animation and the other starts it. This explains the choppiness. ???
ru using linux?
[quote]ru using linux?
[/quote]
Windows 2000
strange.
Multiple key released events is supposed to only occur in Linux.
As for your key input handling code above - it doesn’t look very thread safe.
Something as simple as :-
int [] controls = new int[256];
public void processKeyEvent(KeyEvent ke)
{
controls[ke.getKeyCode()&0xFF] = (ke.getID()==KeyEvent.KEY_RELEASED)?0:1 ;
}
and then querying the controls [] in your main Thread should work perfectly. (obviously you should only directly query each array element once per game loop - the value may change between subsequent accesses)
Though im not 2 sure about caching of values by asynchronous Threads.
It would be nice if this would work :-
volatile int [] controls = new int[256];
but the JLS doesn’t appear to make a special case of arrays, so placing volatile there may simply prevent the compiler caching the controls reference.
It might still cache the values of the elements of the array.
it’d be ever so nice if u could do this :-
int [] controls = new volatile int[256];
but u can’t
You got 3 ways of doing it…
- Have faith that the compiler doesn’t cache array elements. (fastest and simplest - but potencially buggy)
- Use an explicit set of flags - each marked as volatile. (tedious, requiring extra code each time u want an extra key control adding)
- Use full syncronization. (ugly and relatively slow)
- whatever any1 else can come up with