2

Why is it that the ellipse does not respond correctly to user input? I want the a-s-d-w to control Player1 and the arrow keys to control Player2.

Class Robot

//imports
...

public class Robot extends JComponent{

public Color color = null;
public int direction = 360;
public int xPos = 100;
public int yPos = 100;
public int xVel = 10;
public int yVel = 10;

Robot(){

}

public int getXpos(){
    return xPos;
}

public void setXpos(int x){
    this.xPos = x;
}

public int getYpos(){
    return yPos;
}

public void setYpos(int y){
    this.yPos = y;
}

// Same thing for getXvel, setXvel, getYvel, and setYvel

public void move(){
    switch(this.direction){

    case 0: 
        this.yPos -= this.yVel;
        break;

    case 90:
        this.xPos+= this.xVel;
        break;

    case 180:
        this.yPos += this.xVel;
        break;

    case 270:
        this.xPos -= this.xVel;
        break;

    default:
        System.out.println("hi");
        break;

    }
}
}

Class Player1 and Player2

public class Player1 extends Robot{

Player1(){
xPos = 300;
yPos = 300;
xVel = 10;
yVel = 10;
direction = 0;
Color = Color.WHITE;
}

public void paintComponent(Graphics g){ 
    Graphics2D g2 = (Graphics2D)g;

            Ellipse2D.Double ball = new Ellipse2D.Double(xPos, yPos, 100, 100);
    g2.setPaint(Color);
    g2.draw(ball);
    g2.fill(ball);


    }       
}

// Class Player2 is the same exact copy. The xPos = 500; yPos = 500; xVel = 10; yVel = 10;

Class KeyController

public class KeyController implements KeyListener{

Player1 player1 = new Player1();
Player2 player2 = new Player2();

KeyController(){

}

public void keyPressed(KeyEvent e) {

    // Player 1 Left

    if(e.getKeyCode() == KeyEvent.VK_A){
        player1.setDirection(270);
    }

    // Player 1 Down

    if(e.getKeyCode() == KeyEvent.VK_S){
        player1.setDirection(180);
    }

...

if(e.getKeyCode() == KeyEvent.VK_LEFT){

        player2.setDirection(270);

    }
...
}
public void keyReleased(KeyEvent e) {       
}
public void keyTyped(KeyEvent e) {  
}
}

The Main Class: SpaceGame

public class SpaceGame extends JFrame implements Runnable{

Player1 player1 = new Player1();
Player2 player2 = new Player2();
KeyController key = new KeyController();
Thread animator;
int delay = 1000;
int frame = 0;
public static final int DEFAULT_WIDTH = 1280;
public static final int DEFAULT_HEIGHT = 740;

SpaceGame(){

    // Making the frame
    animator = new Thread(this);
    animator.start();
    setTitle("Game");
    setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); 
    setBackground(Color.GREEN);
    addKeyListener(key);
    add(player1);
    add(player2);
}

public void run(){

        while (animator != null) 
        {
            repaint();

            player1.move();
player1.setDirection(360); // 360 does nothing
            player2.move();
player2.setDirection(360); // 360 does nothing
            try  
            {  
                Thread.sleep(delay);  
            }  
            catch (InterruptedException e)  
            {  
                break;  
            }  
            frame++; 
            System.out.println(frame);
        }
}

    public void paint(Graphics g){

        Graphics2D g2 = (Graphics2D)g;
        super.paintComponents(g);
        player1.paintComponent(g2);
        player2.paintComponent(g2);

        }


    public static void main(String[] args) {

        SpaceGame game = new SpaceGame();
        game.setVisible(true);

        }

}
Anonymous181
  • 1,863
  • 6
  • 24
  • 27

1 Answers1

3

As noted in the Key Listener API, "To fire keyboard events, a component must have the keyboard focus". Use Key Bindings instead, as shown here.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • Do you think that will fix the problem or do keybindings make it more efficient? – Anonymous181 May 03 '12 at 22:54
  • 1
    @Anonymous181: 1) Yes, if used correctly key bindings will fix the problem. 2) Please define just what you mean by "efficient" as I'm not sure how what I conceive of as efficiency applies to capturing key presses. I believe that key bindings are a "cleaner" solution since they are a higher level concept than KeyListeners. 1+ to trash. – Hovercraft Full Of Eels May 03 '12 at 23:01
  • Oops, wrong link; answer updated. Key listeners don't work when the component doesn't have focus. You can try [`requestFocusInWindow()`](http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html). – trashgod May 03 '12 at 23:02
  • do I add the inputmap and actionmaps to the JFrame? (in the spacegame class) – Anonymous181 May 03 '12 at 23:04
  • 1
    @Anonymous: No, I would advise against adding them to the JFrame as that will limit you some. Instead it makes more sense to me to the JPanel that's doing the animation, or to a non top-level window component that is getting input from the user. – Hovercraft Full Of Eels May 03 '12 at 23:04
  • @HovercraftFullOfEels is correct: a `JFrame` is not a `JComponent`; use the enclosing panel's `WHEN_IN_FOCUSED_WINDOW` map. – trashgod May 03 '12 at 23:10