2013-03-24 109 views
0

下面是代码:如何随意移动球体,如何让球体在框架内弹跳?

public class BallGame extends JPanel implements Runnable { 

    JPanel panel1 = new JPanel(); 

    private int ballX = 10, ballY = 110, ...; 
    Thread aThread; 
    int toRight=5; 
    int toLeft= -5; 
    int upWard=5; 
    int downWard= -5; 
    int widthBall, heightBall; 

    public BallGame(){ 
     game=true; 
     aThread=new Thread(this); 
     aThread.start(); 
    } 

    public void paintComponent(Graphics g){ 
     setOpaque(false); 
     super.paintComponent(g); 

     g.setColor(Color.RED); 
     g.fillOval(ballX, ballY, 7,7); 
     g.setColor(Color.BLUE); 
     g.fillOval(ballX + 15, ballY + 10, 7,7); 
     g.setColor(Color.GREEN); 
     g.fillOval(ballY - 10, ballY - 15, 7,7); 

    } 

    public void positionBall(int sx, int sy) 
    { 
     ballX = sx; 
     ballY = sy; 
     this.widthBall = this.getWidth(); 
     this.heightBall = this.getHeight(); 
     repaint(); 
    } 
public void run() { 
     boolean leftRight = false; 
     boolean upDown = false; 

     while(true){ 

      if(game){ 

      if (leftRight) 
      { 
       ballX += toRight; 
       if (ballX >= (widthBall - 5)) 
        leftRight= false; 
      } 
      else 
      { 
       ballX += toLeft; 
       if (ballX <= 0) 
        leftRight = true; 
      } 

      if (upDown) 
      { 
       ballY += upWard; 
       if (ballY >= (heightBall - 5)) 
        upDown = false; 

      } 
      else 
      { 
       ballY += downWard; 
       if (ballY <= 0) 
        upDown = true; 
      } 
      positionBall(ballX, ballY); 

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

       } 

我不知道,我提请球的部分是正确的。球在相同的路径上移动。我如何将它们移动到不同的方向,我怎样才能将它们限制在框架内?我需要立即为我们的案例研究。感谢您的时间!

+1

注意,对于挥杆的动画,你最好用的,而不是你自己的'主题了'javax.swing.Timer'生产'。 [This](http://stackoverflow.com/q/9849950/1076463)是一个使用Timer类的Swing移动应用程序的例子 – Robin 2013-03-24 12:46:31

回答

0

为了让球独立移动,你需要把它们当作3个球。 他们总是走同一个方向的原因是,你使用相同的三角洲,只是反转三角洲x和三角洲的标志,因此你将永远保持相同的速度,并在90度反弹。

在下面这基本上是因为你有相同的代码,我保持在分开的情况下,增量x和增量Y的变化速度一次侧被触摸的每个球的状态,并且使用Swing定时器这是一个正如上面罗宾所指出的那样,在Swing的时机方面更好。

enter image description here

我已经更新的例子,让4个球在中间开始,他们从彼此离开。这应该给你足够的信息,以适应你的要求。下面的图片是由只允许10次迭代,并设置

ballGame.setOpaque(true); 

enter image description here

import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.ArrayList; 

import javax.swing.*; 

public class BallGame extends JPanel { 

    private class Ball { 
     private int x; 
     private int y; 
     private int width; 
     private int height; 
     private Color color; 
     private boolean leftRight; 
     private boolean upDown; 
     private int deltaX; 
     private int deltaY; 

     Ball(Color color, int x, int y, int width, int height) { 
      this(color, x, y, width, height, false, false); 
     } 

     Ball(Color color, int x, int y, int width, int height, boolean leftRight, boolean upDown) { 
      this.color = color; 
      this.x = x; 
      this.y = y; 
      this.width = width; 
      this.height = height; 
      this.leftRight = leftRight; 
      this.upDown = upDown; 
      updateDelta(); 
     } 

     private void updateDelta() { 
      final int minimumMovement = 5; 
      final int maxExtra = 10; 
      deltaY = minimumMovement + (int) (Math.random() * maxExtra); 
      deltaX = minimumMovement + (int) (Math.random() * maxExtra); 
     } 

     public void positionBall() { 
      if (leftRight) { 
       x += deltaX; 
       if (x >= (BallGame.this.getWidth() - width/2)) { 
        leftRight = false; 
        updateDelta(); 
       } 
      } else { 
       x += -deltaX; 
       if (x <= 0) { 
        leftRight = true; 
        updateDelta(); 
       } 
      } 

      if (upDown) { 
       y += deltaY; 

       upDown = !(y >= (BallGame.this.getHeight() - height/2)); 
       if (y >= (BallGame.this.getHeight() - height/2)) { 
        upDown = false; 
        updateDelta(); 
       } 
      } else { 
       y += -deltaY; 
       if (y <= 0) { 
        upDown = true; 
        updateDelta(); 
       } 
      } 
     } 

     public Color getColor() { 
      return color; 
     } 

     public int getX() { 
      return x; 
     } 

     public int getY() { 
      return y; 
     } 

     public int getWidth() { 
      return width; 
     } 

     public int getHeight() { 
      return height; 
     } 
    } 

    private ArrayList<Ball> balls = new ArrayList<>(3); 

    public BallGame() { 
     createBalls(); 
     startGame(); 
    } 

    private void startGame() { 
     int framesPerSecond = 30; 
     int timeToWait = 1000/framesPerSecond; 
     Timer timer = new Timer(timeToWait, new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       for (Ball ball : balls) { 
        ball.positionBall(); 
       } 
       repaint(); 
      } 
     }); 
     timer.start(); 
    } 

    private void createBalls() { 
     int startX = 400; 
     int startY = 200; 
     balls.add(new Ball(Color.green, startX, startY, 10, 10)); 
     balls.add(new Ball(Color.blue, startX, startY, 15, 15, true, true)); 
     balls.add(new Ball(Color.red, startX, startY, 20, 20, false, true)); 
     balls.add(new Ball(Color.orange, startX, startY, 20, 20, true, false)); 
    } 

    public void paintComponent(Graphics g) { 
     Graphics2D g2 = (Graphics2D) g.create(); 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
     g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); 

     for (Ball ball : balls) { 
      g2.setColor(ball.getColor()); 
      g2.fillOval(ball.getX(), ball.getY(), ball.getWidth(), ball.getHeight()); 
      g2.setColor(ball.getColor().darker()); 
      g2.drawOval(ball.getX(), ball.getY(), ball.getWidth(), ball.getHeight()); 
     } 
     g2.dispose(); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       JFrame frame = new JFrame("Ball Game"); 
       BallGame ballGame = new BallGame(); 
       ballGame.setOpaque(false); 
       frame.getContentPane().add(ballGame); 
       frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
       frame.setMinimumSize(new Dimension(800, 450)); 
       frame.setLocationRelativeTo(null); // Center 
       frame.pack(); 
       frame.setVisible(true); 
      } 
     }); 
    } 
} 
+0

非常感谢您的帮助!但红色和蓝色的球仍然朝着同一个方向前进。可能是什么问题? – 2013-03-24 14:25:18

+0

谢谢,非常感谢!我现在可以看到差异了! :) – 2013-03-24 14:31:45

+0

这是您创建的leftRight和upDown,它给出了方向。更新了示例以提供不同的开始方向。 – Skjalg 2013-03-24 14:47:53