简体   繁体   中英

How do I make it so the circle in this frame actually moves automatically?

I can't get around this problem. I've created this frame and panel with my desired output. Only thing is that I haven't been able to figure out was how to make the ball move "automatically". My ideal game would have the ball/circle dropping at the start of the game, perhaps with a click of a button or such. How would I go about doing this?

I've tried to move the ball with the E key, but that would be too inconvenient for the user, so I figured that having it move without an event handler would be a better choice.

    private int ballX, ballY, ballR;
private int score1, score2;
private JPanel panel;
private JFrame frame;
private DrawingArea canvas;
private int xpos, ypos,width,height;
private int xpos2, ypos2, width2, height2;
public Pong(){
    xpos = 300;
    ypos = 550;
    width = 100;
    height = 50;

    xpos2 = 300;
    ypos2 = 100;
    width2 = 100;
    height2 = 50;

    ballR = 50;
    ballX = 325; 
    ballY = 330;


}
public static void main(String[]args){
    Pong p = new Pong();
    p.run();
}
public void run(){
    frame = new JFrame("Pong");
    frame.setSize(700,700);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    canvas = new DrawingArea();     // create a panel to draw on
    canvas.setBackground(Color.WHITE);
    canvas.addFocusListener(this);
    canvas.addKeyListener(this);
    canvas.addMouseListener(this);


    frame.getContentPane().add(canvas);
    frame.setVisible(true);
}
class DrawingArea extends JPanel {
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor ( Color.blue );
        g.fillRect ( xpos, ypos, width, height );
        g.setColor(Color.red);
        g.fillRect(xpos2, ypos2, width2, height2);


        g.setColor(Color.black);
        g.fillRect(0,0,700,50);
        g.fillRect(0,630,700,50);

        g.fillOval(ballX,ballY,ballR, ballR);

    }
}
public void keyPressed ( KeyEvent e )    {
    int value = e.getKeyCode();

    switch ( value )    {
        case KeyEvent.VK_RIGHT:     xpos += 50; break;
        case KeyEvent.VK_LEFT:      xpos -= 50; break;
        case KeyEvent.VK_A:         xpos2 -= 50; break;
        case KeyEvent.VK_D:         xpos2 += 50; break;
        /*try to drop the ball with the space button
         * case KeyEvent.VK_SPACE:
            ballX+=25;
            ballY+=25;
            break;
        case KeyEvent.VK_ENTER:
            xpos = (int)( Math.random ( ) * ( 500 - (2 * radius) ) );
            ypos = (int)( Math.random ( ) * ( 500 - (2 * radius) ) );
            break; 
        */
    }
    if( (xpos < 0 || xpos >= 700) || (xpos2 < 0 || xpos2 >= 700)){
         if(xpos < 0 || xpos2 < 0){
            if(xpos < 0) xpos = 0;
            else if(xpos2 < 0) xpos2 = 0;
            return;
        }
        else if(xpos >= 700 || xpos2 >= 700){
            if(xpos >= 700)xpos = 550;
            else if(xpos2 >= 700) xpos2=550;
            return;
        }
    }

    canvas.repaint ( );
}

}

I expect the output to have the ball drop down on to the blue rectangle with the start of the game/press of a button, but I can't get that to work.

As you want to move the ball automatically, in run() method change position of the ball(Your xpos, ypos, xpos1 and ypos2) with some increment values(as you have done in keyPressed() interface method) dx, dy etc. and invoke repaint() method of your JFrame.

public class BouncingBall extends JPanel {

  // Box height and width
  int width;
  int height;

  // Ball Size
  float radius = 40; 
  float diameter = radius * 2;

  // Center of Call
  float X = radius + 50;
  float Y = radius + 20;

  // Direction
  float dx = 3;
  float dy = 3;

  public BouncingBall() {

    Thread thread = new Thread() {
      public void run() {
        while (true) {

          width = getWidth();
          height = getHeight();

          X = X + dx ;
          Y = Y + dy;

          if (X - radius < 0) {
            dx = -dx; 
            X = radius; 
          } else if (X + radius > width) {
            dx = -dx;
            X = width - radius;
          }

          if (Y - radius < 0) {
            dy = -dy;
            Y = radius;
          } else if (Y + radius > height) {
            dy = -dy;
            Y = height - radius;
          }
          repaint();

          try {
            Thread.sleep(50);
          } catch (InterruptedException ex) {
          }

        }
      }
    };
    thread.start();
  }

  public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.setColor(Color.BLUE);
    g.fillOval((int)(X-radius), (int)(Y-radius), (int)diameter, (int)diameter);
  }

  public static void main(String[] args) {
    JFrame.setDefaultLookAndFeelDecorated(true);
    JFrame frame = new JFrame("Bouncing Ball");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(300, 200);
    frame.setContentPane(new BouncingBall());
    frame.setVisible(true);
  }
}

As I have used render time of 50 ms in Thread.sleep(), you can specify your own time. So for me each 50 ms your JFrame gets updated.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM