KeyListener

Hello everyone

I’m currently learning java at school, so I get these program examples that I should copy and compile, to see how the code works. The problem is, that the one I’m currently working on doesn’t work, and I havent been able to figure out why. The program is an applet game that lets the user control a little blue dot, and move it around the screen using the arrow keys. The problem is that once I run the applet, the dot won’t move. Could anyone help me with this?

Source code:

import java.applet.;
import java.awt.
;
import java.awt.event.*;

public class KeyApp4 extends Applet implements Runnable, KeyListener
{
// Bilens variabler
int RADIE = 20;
double bilx = 200, bily = 200;
double vx = 0, vy = 0;

  // Fönsterstorleksvariabler
  Dimension appletSize;
  
  // Knapptryckningsvariabler
  boolean left = false, right = false, up = false, down = false;
  
  public void init()
  {
        appletSize = getSize();
        addKeyListener( this);
        requestFocus();
  }
  
  public void paint( Graphics g)
  {
        // Ritar bilen
        g.setColor( Color.blue);
        g.fillOval( (int) (bilx - RADIE), (int) (bily - RADIE), 2*RADIE, 2*RADIE);
  }
  
  public void start()
  {
        // Ny animeringstråd
        Thread tråd = new Thread( this);
        tråd.start();
  }
  
  public void run()
  {
        while( true) {
              // Ändrar hastigheten beroende på användarens knapptryckningar
              if( left)      vx = vx - 0.05;
              if( right)      vx = vx + 0.05;
              
              // Kollar så att bilen stannar när den träffar väggen
              if( bilx + RADIE > appletSize.width || bilx - RADIE < 0)       vx = 0;
              if( bily + RADIE > appletSize.height || bily - RADIE < 0)       vy = 0;
              
              // Förflyttar bilen
              bilx = bilx + vx;
              bily = bily + vy;
              
              repaint();
              
              try { Thread.sleep( 10); } catch( InterruptedException ie) {}
        }
  }
  
  public void keyTyped( KeyEvent e) {}

  public void keyPressed(KeyEvent e) { 
        int key = e.getKeyChar(); 
        if (key == KeyEvent.VK_LEFT) left = true; 
        if (key == KeyEvent.VK_RIGHT) right = true; 
        if (key == KeyEvent.VK_UP) up = true; 
        if (key == KeyEvent.VK_DOWN) down = true; 
  }
  
  public void keyReleased(KeyEvent e) { 
        int key = e.getKeyChar(); 
        if (key == KeyEvent.VK_LEFT) left = false; 
        if (key == KeyEvent.VK_RIGHT) right = false; 
        if (key == KeyEvent.VK_UP) up = false; 
        if (key == KeyEvent.VK_DOWN) down = false; 
  }

}

there’s your problem. those v’s stand for “velocity” I imagine, change those variables to something other than 0 and it should work, because:


// Förflyttar bilen 
   bilx = bilx + vx; 
   bily = bily + vy; 

won’t work unless vx and/or vy is not 0

Thanks alot for the help, but unfortunately i did not help me.

"double vx = 0, vy = 0;
there’s your problem. those v’s stand for “velocity” I imagine, change those variables to something other than 0 and it should work, because:
Code:
// Förflyttar bilen
bilx = bilx + vx;
bily = bily + vy;

won’t work unless vx and/or vy is not 0"

Yes, v stands for veliocity, and vx for the veliocity in the x-axis. vy stands for the veliocity in the y-axis. But I may have to clarify a little:

public void keyPressed(KeyEvent e) {
int key = e.getKeyChar();
if (key == KeyEvent.VK_LEFT) left = true;
if (key == KeyEvent.VK_RIGHT) right = true;
if (key == KeyEvent.VK_UP) up = true;
if (key == KeyEvent.VK_DOWN) down = true;
}

public void keyReleased(KeyEvent e) {
int key = e.getKeyChar();
if (key == KeyEvent.VK_LEFT) left = false;
if (key == KeyEvent.VK_RIGHT) right = false;
if (key == KeyEvent.VK_UP) up = false;
if (key == KeyEvent.VK_DOWN) down = false;
}

The thing is that I have defined keyReleased and keyPressed myself, to make them set boolean values to true/false depending on if any of the arrow-keys is pressed or released.

public void run()
{
while( true) {
// Ändrar hastigheten beroende på användarens knapptryckningar
if( left) vx = vx - 0.05;
if( right) vx = vx + 0.05;

// Kollar så att bilen stannar när den träffar väggen
if( bilx + RADIE > appletSize.width || bilx - RADIE < 0) vx = 0;
if( bily + RADIE > appletSize.height || bily - RADIE < 0) vy = 0;

// Förflyttar bilen
bilx = bilx + vx;
bily = bily + vy;

repaint();

try { Thread.sleep( 10); } catch( InterruptedException ie) {}
}
}

Then these boolean values would be used to make the dot’s veliocity to increase:

if( left) vx = vx - 0.05;
if( right) vx = vx + 0.05;

(Note that I haven’t written the code for the up and down keys yet)

Finally the dot is moved and the picture repainted:

bilx = bilx + vx;
bily = bily + vy;

repaint();

My problem is that the dot wont move event though I press the arrow-keys like a maniac. Any help is appreciated.

\Gewran ???

You chck for collisions against walls, and then set the velocity on that axis to 0. That means that the ball will STAY in collision with the wall. When you detect a collision, you should either repel the velocity for a bounce effect, or you should make the ball stop (as you’re doing) and move the ball back within the play area so that it’s no longer colliding with the wall.

Don’t forget to click in the Applet portion of the web page to give the Applet the focus. When the web page loads the Applet, it maintains control of the input focus. You have to click on the Applet to give it the input focus.

[QUOTE]You chck for collisions against walls, and then set the velocity on that axis to 0. That means that the ball will STAY in collision with the wall. When you detect a collision, you should either repel the velocity for a bounce effect, or you should make the ball stop (as you’re doing) and move the ball back within the play area so that it’s no longer colliding with the wall.
[/quote]
That bouncing thing seems good. I’ll try to implement it as soon as I’ve got this problem sorted out.

[QUOTE]Don’t forget to click in the Applet portion of the web page to give the Applet the focus. When the web page loads the Applet, it maintains control of the input focus. You have to click on the Applet to give it the input focus.
[/quote]
I’ve tried this and it doesn’t work. My applet does ask for focus in the init() method:

public void init()
{
appletSize = getSize();
addKeyListener( this);
requestFocus();
}

And I belive this is the problem. That my applet doesn’t get the keyboard focus even though it should. Is there any other way to get the keyboard focus?

Thanks for the help.

\Gewran

Remember that it is requestFocus - i.e. not guaranteed to be obeyed. This is one of those really annoying thigns, because it’s rather hard to see how you can cope if your request is not fulfilled :(.

[QUOTE]Remember that it is requestFocus - i.e. not guaranteed to be obeyed. This is one of those really annoying thigns, because it’s rather hard to see how you can cope if your request is not fulfilled .
[/quote]
Is there any way to make sure you get the focus, or am I stuck with no way to make it work?

import java.applet.;
import java.awt.
;
import java.awt.event.*;

public class KeyApp4 extends Applet implements Runnable, KeyListener
{
// Bilens variabler
int RADIE = 20;
double bilx = 200, bily = 200;
double vx = 0, vy = 0;

// Fönsterstorleksvariabler
Dimension appletSize;

// Knapptryckningsvariabler
boolean left = false, right = false, up = false, down = false;

public void init()
{
appletSize = getSize();
addKeyListener( this);
requestFocus();
}

public void paint( Graphics g)
{
// Ritar bilen
//System.out.println(“paint()”);
g.setColor( Color.blue);
g.fillOval( (int) (bilx - RADIE), (int) (bily - RADIE), 2RADIE, 2RADIE);
}

public void start()
{
// Ny animeringstråd
Thread tråd = new Thread( this);
tråd.start();
}

public void run()
{
while( true) {
// Ändrar hastigheten beroende på användarens knapptryckningar
if( left) vx = vx - 0.05;
if( right) vx = vx + 0.05;
if( up) vy = vy + 0.05;
if( down) vy = vy - 0.05;

// Kollar så att bilen stannar när den träffar väggen

/*
* This is just modified safegaurds.
*
* Just setting the velocity to 0 will result in the ball getting stuck
* because part of it is already outside the bounds of the applet and the
* velocity will continually be set to 0. Need to set velocity to 0 then
* reposition the ball so it is completely inside the bounds of the applet.
*/
if( bilx + RADIE > appletSize.width)
{
vx = 0;
bilx = appletSize.width-RADIE;
}
if( bilx - RADIE < 0)
{
vx = 0;
bilx = RADIE;
}
if( bily + RADIE > appletSize.height)
{
vy = 0;
bily = appletSize.height-RADIE;
}
if( bily - RADIE < 0)
{
vy = 0;
bily = RADIE;
}
//end modified safegaurds.

// Förflyttar bilen
bilx = bilx + vx;
bily = bily + vy;

repaint();

try { Thread.sleep( 10); } catch( InterruptedException ie) {}
}
}

public void keyTyped( KeyEvent e) {}

/*

  • The values 50, 52, 54, and 56 are just the values
  • that correspond to my non-standard keyboard. This was
  • where your problem was. Just changing these values made
  • the applet work for me.
    */
    public void keyPressed(KeyEvent e) {
    int key = e.getKeyChar();
    if (key == 52) left = true;
    if (key == 54) right = true;
    if (key == 50) up = true;
    if (key == 56) down = true;
    }

public void keyReleased(KeyEvent e) {
int key = e.getKeyChar();
if (key == 52) left = false;
if (key == 54) right = false;
if (key == 50) up = false;
if (key == 56) down = false;
}
}

This code works great for me. All I did was change values in keyPressed and keyReleased that key was being checked against. You may need to change them since I use a non-standard keyboard, but I think this is where your problem was. Did you use Systm.out.println(key); to test if the keyboard input was matching VK_LEFT ect… ?

Note that when running the applet I did have to click in the applet’s bounds before keyboard input would register.

I hope this helps.

Ha! That should work:


    public void keyTyped( KeyEvent e) {}

      public void keyPressed(KeyEvent e) { 
            int key = e.getKeyCode(); // get the key CODE

            if (key == KeyEvent.VK_LEFT) left = true; 
            if (key == KeyEvent.VK_RIGHT) right = true; 
            if (key == KeyEvent.VK_UP) up = true; 
            if (key == KeyEvent.VK_DOWN) down = true; 
      }
      
      public void keyReleased(KeyEvent e) { 
            int key = e.getKeyCode(); // get the Key CODE

            if (key == KeyEvent.VK_LEFT) left = false; 
            if (key == KeyEvent.VK_RIGHT) right = false; 
            if (key == KeyEvent.VK_UP) up = false; 
            if (key == KeyEvent.VK_DOWN) down = false; 
      }

Yes that worked! Thanks alot!

\Gewran