2

I know J2ME is pretty outdated, but I have to do this for an assignment. Currently, I am using the GameCanvas class, and my game is a thread, so my code looks something like this..

class Game extends GameCanvas implements Runnable {
    public GameCanvas() {
        super(false);
    }

    public void run() {
        while (true) {
            draw();
            flushGraphics();
        }
    }

    protected void keyPressed(int keyCode) {
        System.out.println("Hey, it actually worked.");
        // other code to handle key press...
    }
}

The sad thing is that the keyPressed method never gets called no matter how hard I spam hits on the emulator's numpad. I know of the getKeyStates() method that GameCanvas has, but I don't want to use it because I want to capture not just the game keys, but also the number keys 1~9.

Does anyone have any idea why my code doesn't go into my keyPressed() method, and what I can do about it? Many thanks.


Don't know where I went wrong... but after tweaking a little here and there, it started working perfectly fine. Thanks a lot guys! :)

gnat
  • 6,213
  • 108
  • 53
  • 73
matt
  • 2,857
  • 7
  • 33
  • 58

2 Answers2

0

You have a busy wait within Game#run method which most likely causes device ignore all your hits, making your UI loose responsiveness.

For simple test if above assumption is correct, just insert sleep within the loop, about like below:

    while (true) {
        draw();
        flushGraphics();
        try { Thread.sleep(100); } // sleep for 1/10 sec
        catch (InterruptedException ie) { System.out.println(ie); }
    }

If above helps to recover UI responsiveness, redesign your application to avoid busy waits - MIDP API provides a couple of ways to achieve that.

gnat
  • 6,213
  • 108
  • 53
  • 73
  • Hmm, thanks for the idea. I gave it a go, but unfortunately I still can't get the keyPressed() to fire like it does on a Canvas class... :( If it helps, I tried implementing a method input() called inside the while loop, whereby I try using GameCanvas's getKeyStates(). It doesn't work either, and I have no idea why... – matt Dec 12 '11 at 15:17
  • @matt when experimenting, double-check that you invoke **super** in constructor with **false** value of parameter - this value can make or break key events delivery, see [API docs for GameCanvas constructor](http://docs.oracle.com/javame/config/cldc/ref-impl/midp2.0/jsr118/javax/microedition/lcdui/game/GameCanvas.html#GameCanvas(boolean)). Also, for a while, drop using `getKeyStates` - leave it for later debugging – gnat Dec 12 '11 at 15:22
  • Yup, I do use **super(false)** but it still doesn't work. I'm not sure what exactly is the problem... if it helps, this class is called by a thread, and calls other threads, all using `.start()`. – matt Dec 12 '11 at 15:45
  • @matt hm sounds interesting. The way you describe it looks OK to me, threads and start and such. How do you debug? are you using an emulator? also, try pushing sleeps harder - say, `sleep(1000)` - refresh will likely look awful but you'd at least make sure that it's not a bottleneck – gnat Dec 12 '11 at 15:51
  • Tried it with `sleep(5000)`, refreshes were terrible, but still no go.. Yup Im using an emulator, the DefaultFxPhone1, if that helps.. – matt Dec 12 '11 at 16:00
  • @matt have you tried testing with cldc phone emulator - iirc in WTK/ME SDK it's called `DefaultColorPhone`? I have a bit more trust in reliability of this old emulator over new shiny fx :) – gnat Dec 12 '11 at 16:05
  • I think I don't have it... Tried it with `DefaultCldcPhones` and they told me there's too little memory. Anyway, I created a brand new Java ME app with the implementation, and it appears that it works perfectly fine. I think the problem might lie somewhere else... Going to take a break. Thanks for all the ideas anyway! :) – matt Dec 12 '11 at 16:23
0

The MIDP documentation excerpt for GameCanvas(...)

If the developer only needs to query key status using the getKeyStates method, the regular key event mechanism can be suppressed for game keys while this GameCanvas is shown. If not needed by the application, the suppression of key events may improve performance by eliminating unnecessary system calls to keyPressed, keyRepeated and keyReleased methods.

Note that key events can be suppressed only for the defined game keys (UP, DOWN, FIRE, etc.); key events are always generated for all other keys.

So super(false) will suppress the Canvas key event listener methods in GameCanvas. In which case if you still want to register the key events use getKeyEvents(...) in your run(), the example is as under

 // Get the Graphics object for the off-screen buffer
 Graphics g = getGraphics();

 while (true) {
    // Check user input and update positions if necessary
    int keyState = getKeyStates();
    if ((keyState & LEFT_PRESSED) != 0) {
          sprite.move(-1, 0);
    }
    else if ((keyState & RIGHT_PRESSED) != 0) {
          sprite.move(1, 0);
    }

    // Clear the background to white
    g.setColor(0xFFFFFF);
    g.fillRect(0,0,getWidth(), getHeight());

    // Draw the Sprite
    sprite.paint(g);

    // Flush the off-screen buffer
    flushGraphics();
 }
Vimal
  • 1,266
  • 1
  • 9
  • 16