2016-06-11 84 views
-1

我有一個簡單的類,它創建一個框架,其中有一些球從側面反彈。由於某些原因,球在框架的北側,西側和東側反彈很小,但稍微從南側稍微偏離,然後反彈離開。我在設置邊界時考慮了球的大小,這在x軸上很好,但在y軸上沒有問題。設置動畫球的邊界

import javax.swing.*; 

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.RenderingHints; 
import java.awt.Shape; 
import java.awt.event.*; 
import java.awt.geom.Ellipse2D; 
import java.util.ArrayList; 

public class BallBounceFrame 
{ 

public static void main(String[] args) 
{ 
    new BallBounceFrame(); 
} 

JFrame frame; 
static int WIDTH = 500; 
static int HEIGHT = 500; 

public BallBounceFrame() 
{ 
    frame = new JFrame("Ball Bounce Frame"); 
    frame.setSize(WIDTH, HEIGHT); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setLocationRelativeTo(null); 
    frame.setResizable(false); 
    BallCanvas c = new BallCanvas(5); 
    frame.add(c, BorderLayout.CENTER); 
    frame.setVisible(true); 
    c.animate(); 
} 

class BallCanvas extends JPanel 
{ 

    private static final long serialVersionUID = 1L; 

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

    public BallCanvas(int ballNum) 
    { 
     for(int i = 0; i < ballNum; i++) 
     { 
      balls.add(new Ball(20)); 
     } 
    } 

    public void paint(Graphics g) 
    { 
     Graphics2D g2 = (Graphics2D) g; 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
     g2.setColor(Color.RED); 
     for(Ball b : balls) 
     { 
      b.move(); 
      g2.fill(b); 
     } 
    } 

    public void animate() 
    { 
     while(true) 
     { 
      try 
      { 
       frame.repaint(); 
       Thread.sleep(10); 
      } 
      catch(Exception e) 
      { 
       System.out.println(e); 
      } 
     } 
    } 
} 

class Ball extends Ellipse2D.Float 
{ 
    private int xVel, yVel; 
    private int size; 
    private int WIDTH = BallBounceFrame.WIDTH; 
    private int HEIGHT = BallBounceFrame.HEIGHT; 

    public Ball(int size) 
    { 
     super((int) (Math.random() * (BallBounceFrame.WIDTH - 20) + 1), (int) (Math.random() * (BallBounceFrame.HEIGHT - 20) + 1), size, size); 
     this.size = size; 
     this.xVel = (int) (Math.random() * 5 + 1); 
     this.yVel = (int) (Math.random() * 5 + 1);   
    } 

    public void move() 
    { 
     if(super.x < 0 || super.x > WIDTH - size) xVel *= -1; 
     if(super.y < 0 || super.y > HEIGHT - size) yVel *= -1; 
     super.x += xVel; 
     super.y += yVel; 
    } 
} 
} 

回答

0

問題是WIDTH和HEIGHT來自JFrame。特別是窗口標題說明會降低面板的高度。人們可以將面板邊界/大小傳遞給球的移動。

@Override 
public void paint(Graphics g) 
{ 
    ... 
     b.move(getSize()); 
    ... 
} 

public void move(Dimension panelSize) 
{ 
    if (x < 0 || x > panelSize.getWidth() - size) xVel *= -1; 
    if (y < 0 || y > panelSize.getHeight - size) yVel *= -1; 
    x += xVel; 
    y += yVel; 
} 

爲了保持邊界內的球,你可能會考慮:

public void move(Dimension panelSize) 
{ 
    x += xVel; 
    y += yVel; 
    if (x < 0) { 
     x *= -1; 
     xVel *= -1; 
    } else if (x > panelSize.getWidth() - size) { 
     x -= 2 * (x - panelSize.getWidth() - size); 
     xVel *= -1; 
    } 
    if (y < 0) { 
     y *= -1; 
     yVel *= -1; 
    } else if (y > panelSize.getHeight() - size) { 
     y -= 2 * (y - panelSize.getHeight() - size); 
     yVel *= -1; 
    } 
} 

根據

\ |   (xVel == 5) 
    \| 
    /|\ 
    /| \ 
/| \ 

(人們通常也在BallBounceFrame年底進行佈局馬蹄蓮pack()計算)。

0

我覺得,原因是xVel/yVel加入移動。

當你靠近邊界時,你檢查你是否已經越過了邊界。如果不是,則添加速度。

如果到邊界的距離是10並且速度是15,那麼您將在邊界框架上移動5。在接下來的步驟中,你將倒退速度並彈開。在這種情況下,此舉可能會分裂。移動10,反向速度,移動5.