Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (477)
Games in Android Showcase (107)
games submitted by our members
Games in WIP (535)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Key handling  (Read 1244 times)
0 Members and 1 Guest are viewing this topic.
Offline pjt33
« Posted 2009-01-21 19:04:40 »

I'm more-or-less done with my first game and I'm thinking about a second. This would use keys, and I want to ensure that the key handling code is thread-safe. The topic of handling keys is discussed a bit in the tips thread, but I don't want to pollute that one, hence this thread. It might be appropriate to link to this thread, or a post in it, from that one once the dust settles.

The issue I have is this: the standard key handling discussed there is basically to detect key pressed and released events and update a boolean. That's fine if my game logic only cares whether keys are up or down, but not so fine if I care about detecting key presses: e.g. for jumping. If the pressed and released events both occur before the logic call then the character won't jump and may meet a frustrating doom.

My idea for approaching this is to borrow a trick from lock-free synchronisation (e.g. lock-free single-producer single-consumer, which is essentially what we have here: an event thread which produces events and another thread which does updates and probably renders). I would be grateful for critiques and improvements on this implementation, and suggestions of cheaper ways to obtain the same result.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
public class Game4k extends Applet
{
   // Constants. You can make this slightly larger if it will compress better, but making it
  // smaller risks ArrayIndexOutOfBoundsExceptions in the event thread unless you add
  // bounds testing to processKeyEvent(...).
  private static final int NUM_KEYS = 0x10000;

   // Shared state. In the spirit of lock-free synchronisation, this is written
  // only by the event thread, and it advances values rather than setting /
  // resetting.
  private int[] keyEventCount = new int[NUM_KEYS];

   // This can be adapted if you do stuff properly rather than hackily, or if you use a JFrame
  @Override
   public void start()
   {
      // Set up event handling. Note: keyDown[key] and keyPressed[key] are 0
     // for false; any other value should be interpreted as true.
     enableEvents(KeyEvent.KEY_EVENT_MASK);
      int[] prevKeyEventCounts = new int[NUM_KEYS];
      int[] keyDown = new int[NUM_KEYS];
      int[] keyPressed = new int[NUM_KEYS];

      // Other setup...

      // Main game loop. Against, adapt as necessary.
     while (isActive())
      {
         // Handle events.
        for (int i = 0; i < NUM_KEYS; i++)
         {
            int eventCount = keyEventCount[i];
            // An odd number of events means that it's down. Simple!
           keyDown[i] = eventCount & 1;
            // The key was pressed since the last loop if the number of events
           // since then is at least two, by the pigeonhole principle, or if
           // the number of events since then is positive and the key is down.
           // Since we only need to catch the second case when delta == 1,
           // we can simplify the key-is-down test a bit.
           int delta = eventCount - prevKeyEventCounts[i];
            keyPressed[i] = (delta / 2) + (delta & eventCount);
            prevKeyEventCounts[i] = eventCount;
         }

         // Do game logic...
        // Render...
        // Sleep...
     }
   }

   @Override
   public void processKeyEvent(KeyEvent evt)
   {
      // The valid key event ids are 400, 401, 402.
     // Of those we care about 401 (KEY_PRESSED) and 402 (KEY_RELEASED).
     int id = evt.getID() & 3;
      if (id != 0)
      {
         keyEventCount[evt.getKeyCode()]++;
      }
   }
}


Ideally I'd like to debounce both keyDown and keyPressed as well, to work around the issue with some window managers (e.g. KDE) doing auto-repeat. However, there's no sure-fire way of telling whether multiple key presses come from the user or the WM, so I think I'll have to live with that issue.
Offline BitDragon

Junior Member


Projects: 1


Sunset? Nice gradient paint!


« Reply #1 - Posted 2009-01-24 11:02:58 »

The issue I have is this: the standard key handling discussed there is basically to detect key pressed and released events and update a boolean.

I prefer keeping things simple. I use a key state array, but it is int, not boolean, and pressed keys set the int value of 1. This way, I can immediately use pressed key values in computations, e.g. (in pseudocode)

1  
rotation+=keystate[KEY_LEFT]*somevalue


To handle typed keys, I store the keycode of the most recently typed key in array entry 0 and I process this entry in the game loop, and reset it's value to 0, if its non-0.

hth Wolfgang

"I'm a ****ing starship, I'm allowed to cheat!"
GCU Arbitrary, Culture Craft
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Riven (7 views)
2014-07-29 18:09:19

Riven (5 views)
2014-07-29 18:08:52

Dwinin (8 views)
2014-07-29 10:59:34

E.R. Fleming (25 views)
2014-07-29 03:07:13

E.R. Fleming (10 views)
2014-07-29 03:06:25

pw (39 views)
2014-07-24 01:59:36

Riven (39 views)
2014-07-23 21:16:32

Riven (26 views)
2014-07-23 21:07:15

Riven (28 views)
2014-07-23 20:56:16

ctomni231 (59 views)
2014-07-18 06:55:21
HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22

How do I start Java Game Development?
by ra4king
2014-05-17 11:13:37

HotSpot Options
by Roquen
2014-05-15 09:59:54

HotSpot Options
by Roquen
2014-05-06 15:03:10

Escape Analysis
by Roquen
2014-04-29 22:16:43

Experimental Toys
by Roquen
2014-04-28 13:24:22
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!