3

I'm trying to write a Pong applet in Java. When the user holds down either up or down, their paddle should move smoothly, but this isn't the case. It moves, then pauses, then starts moving again. Is there a way to stop this short pause from happening?

Main Class:

public class Main extends JApplet {

    public DrawPanel dp = new DrawPanel(400, 400);

    public void init(){
        add(dp);
        setSize(400, 400);
        requestFocusInWindow();

        Action moveDown = new AbstractAction(){
            public void actionPerformed(ActionEvent e){
                dp.player.y += 10;
                dp.repaint();
            }
        };

        dp.getInputMap().put(KeyStroke.getKeyStroke("pressed DOWN"), "move down");
        dp.getActionMap().put("move down", moveDown);       
    }
}

DrawPanel Class:

public class DrawPanel extends JPanel {

    public Paddle player;
    public Paddle opponent;

    public DrawPanel(int height, int width){
        int y = (height / 2) - (height / 10);
        int w = 15;
        int h = height / 5;

        player = new Paddle(2, y, 15, h, Color.white);
        opponent = new Paddle(width - (w+2), y, 15, h, Color.white);
    }

    public void paintComponent(Graphics g){
        super.paintComponent(g);
        this.setBackground(Color.BLACK);

        g.setColor(player.color);
        g.fillRect(player.x, player.y, player.width, player.height);

        g.setColor(opponent.color);
        g.fillRect(opponent.x, opponent.y, opponent.width, opponent.height);
    }   
}

Paddle Class:

public class Paddle {

    public int x, y, width, height;
    public Color color;

    public Paddle(int _x_, int _y_, int w, int h, Color c){
        x = _x_;
        y = _y_;
        width = w;
        height = h;
        color = c;
    }
}
nIcE cOw
  • 24,468
  • 7
  • 50
  • 143
WillumMaguire
  • 537
  • 2
  • 10
  • 21
  • Try taking a look at [this example](http://stackoverflow.com/questions/16328946/java-keylistener-stutters/16329029#16329029). Basically what this does is raises a flag on mouse press/release and allows the update engine to continue responding to that flag as is required – MadProgrammer Aug 04 '13 at 23:52
  • I'm looking at the timer solution, I think it's what I'll go with – WillumMaguire Aug 05 '13 at 00:06
  • unrelated: don't change the state of a component while painting (in your drawPanel, that's setBackground) – kleopatra Aug 05 '13 at 08:42
  • Also, consider key bindings, illustrated [here](http://stackoverflow.com/a/14001011/230513). – trashgod Aug 05 '13 at 12:08

1 Answers1

4

The underlying issue is an impedance mismatch between the "instance" notion of a keyPressed and the "duration" notion of the movement.

Instead of trying to smooth that over in the view (which shouldn't have anything to do with the details of the game logic anyway), enhance the game model with api that's a better fit. F.i. add start/stop logic and bind those methods to keyPressed/keyReleased:

public class Paddle {

     public void startMoveDown() {
         // here goes the logic, f.i. starting a timer
         // in the actionPerformed of that timer:
         ...  moveUnitDown(); 
     }
     public void stopMoveDown() {
        //... 
     }

     protected void moveUnitDown() {
         y+=unit;
         // ideally, have listeners and notify them the change of y
     } 
}

// in the view:
Action startMoveDown = new AbstractAction(){
    public void actionPerformed(ActionEvent e){
        player.startMoveDown();
   }
};

dp.getInputMap().put(KeyStroke.getKeyStroke("pressed DOWN"), "start move down");
dp.getActionMap().put("start move down", startMoveDown); 

// in the view:
Action stopMoveDown = new AbstractAction(){
    public void actionPerformed(ActionEvent e){
        player.stopMoveDown();
   }
};

dp.getInputMap().put(KeyStroke.getKeyStroke("released DOWN"), "stop move down");
dp.getActionMap().put("stop move down", stopMoveDown); 
kleopatra
  • 51,061
  • 28
  • 99
  • 211