2015-05-18 78 views
1

這是正確的網站來問這個問題,因爲我現在已被兩次提到另一個網站。物理彈跳球

我試圖用真實的物理學來創建彈跳球。此刻,當球撞到對方時,他們會以同樣的方向反彈回來,現在,我已經在網上搜索瞭如何做到這一點,但我只能找到如何檢測碰撞的事情,而不是什麼之後去做。我對物理學瞭解不多,在我能夠做到這一點之前,我應該先學習他們的主題?這是一幅我想象的球如何在現實生活中反彈的圖像。這是如何工作的?

how I think it should work http://thewombatguru.nl/Bouncing.png

另外,我要在我的代碼不好的做法? (也許,但我學到了很多東西,我喜歡它)

這是我當前的代碼:

Asteroids.java

package Asteroids; 

import javax.swing.*; 

public class Asteroids { 

    public static void createAndShowGui() { 
     GamePanel gamePanel = new GamePanel(); 
     JFrame frame = new JFrame("Asteroids"); 
     frame.getContentPane().add(gamePanel); 
     frame.pack(); 
     frame.setVisible(true); 
     frame.setResizable(false); 
     frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
     frame.setLocation(2000, 50); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> createAndShowGui()); 
    } 

} 

GamePanel.java

package Asteroids; 

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

public class GamePanel extends JPanel implements ActionListener { 

    private final int WIDTH = 1000; 
    private final int HEIGHT = 1000; 

    Timer animationTimer; 

    ArrayList<Rock> rocks; 

    public GamePanel() { 
     Dimension preferredDimension = new Dimension(WIDTH, HEIGHT); 
     setPreferredSize(preferredDimension); 

     animationTimer = new Timer(10, this); 

     setUp(); 
    } 

    public void setUp() { 

     rocks = new ArrayList<>(); 

     rocks.add(new Rock(475, 1000, 0, -1)); 
     rocks.add(new Rock(0, 500, 1, 0)); 
     //rocks.add(new Rock(300, 270, -2, 2)); 
     //rocks.add(new Rock(400, 315, -5, -1)); 

     animationTimer.start(); 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     repaint(); 

     for (Rock rock : rocks) { 
      for (Rock rockToCheck : rocks) { 
       if (!rock.equals(rockToCheck)) { 
        rock.checkForCollisionWithRocks(rockToCheck); 
       } 
      } 
      rock.checkForCollisionWithFrame(WIDTH, HEIGHT); 
      rock.setxPos(rock.getxPos() + rock.getxVelocity()); 
      rock.setyPos(rock.getyPos() + rock.getyVelocity()); 
     } 
    } 

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

     Graphics2D g2d = (Graphics2D) g.create(); 

     RenderingHints mainRenderingHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
     g2d.setRenderingHints(mainRenderingHints); 

     for (Rock rock : rocks) { 
      rock.display(g2d); 
     } 

     g2d.dispose(); 
    } 
} 

Rock.java

package Asteroids; 

import java.awt.*; 

public class Rock { 

    private int xPos; 
    private int yPos; 
    private int rockWidth; 
    private int rockHeight; 
    private int xVelocity; 
    private int yVelocity; 
    private int rockRadius; 
    private Color rockColor; 

    public Rock(int xPos, int yPos, int xVelocity, int yVelocity) { 
     this.xPos = xPos; 
     this.yPos = yPos; 
     this.xVelocity = xVelocity; 
     this.yVelocity = yVelocity; 
     rockWidth = 50; 
     rockHeight = rockWidth; 
     rockRadius = rockWidth/2; 
     rockColor = new Color((int) (Math.random() * 255),(int) (Math.random() * 255),(int) (Math.random() * 255)); 
    } 

    public void setxPos(int xPos) { 
     this.xPos = xPos; 
    } 
    public int getxPos() { 
     return xPos; 
    } 
    public int getRockWidth() { 
     return rockWidth; 
    } 
    public void setRockWidth(int rockWidth) { 
     this.rockWidth = rockWidth; 
    } 
    public int getRockHeight() { 
     return rockHeight; 
    } 
    public void setRockHeight(int rockHeight) { 
     this.rockHeight = rockHeight; 
    } 
    public int getyPos() { 
     return yPos; 
    } 
    public void setyPos(int yPos) { 
     this.yPos = yPos; 
    } 
    public int getxVelocity() { 
     return xVelocity; 
    } 
    public void setxVelocity(int xVelocity) { 
     this.xVelocity = xVelocity; 
    } 
    public int getyVelocity() { 
     return yVelocity; 
    } 
    public void setyVelocity(int yVelocity) { 
     this.yVelocity = yVelocity; 
    } 
    public int getRockRadius() { 
     return rockRadius; 
    } 
    public void setRockRadius(int rockRadius) { 
     this.rockRadius = rockRadius; 
    } 

    public void checkForCollisionWithRocks(Rock rock) { 
     int radiusOfBoth = rock.getRockRadius() + rockRadius; 
     int horDistance = Math.abs((rock.getxPos() + rock.getRockRadius()) - (xPos + rockRadius)); 
     int verDistance = Math.abs((rock.getyPos() + rock.getRockRadius()) - (yPos + rockRadius)); 
     int diagDistance = (int) Math.sqrt(Math.pow(horDistance, 2) + Math.pow(verDistance, 2)); 

     if (diagDistance <= radiusOfBoth) { 

      xVelocity = -xVelocity; 
      yVelocity = -yVelocity; 

      rock.setxVelocity(-rock.getxVelocity()); 
      rock.setyVelocity(-rock.getyVelocity()); 
      rock.setxPos(rock.getxPos() + rock.getxVelocity()); 
      rock.setyPos(rock.getyPos() + rock.getyVelocity()); 
     } 
    } 

    public void checkForCollisionWithFrame(final int WIDTH, final int HEIGHT) { 
     if (xPos < 0) { 
      xVelocity *= -1; 
      xPos = 0; 
     } else if (xPos + rockWidth > WIDTH) { 
      xVelocity *= -1; 
      xPos = WIDTH - rockWidth; 
     } 

     if (yPos < 0) { 
      yVelocity *= -1; 
      yPos = 0; 
     } else if (yPos + rockHeight > HEIGHT) { 
      yVelocity *= -1; 
      yPos = HEIGHT - rockHeight; 
     } 
    } 

    public void display(Graphics2D g2d) { 
     g2d.setColor(rockColor); 
     g2d.fillOval(xPos, yPos, rockWidth, rockHeight); 
    } 

} 

任何人都可以幫忙嗎?

+0

如果通過*之後會發生什麼,你的意思是每個組件的速度(速度+方向),我認爲你應該讀一些關於彈性碰撞的內容。你可以問[physics.stackexchange.com](http://physics.stackexchange.com/)一些數學模型,我認爲值得一提的是一些背景知識,因爲它可以非常快速地變得非常複雜。最後,對於代碼評論,請轉到[codereview.stackexchange.com](http://codereview.stackexchange.com/)。 – npinti

+0

@npinti是的,我的意思是速度和方向,但我只想從方向開始,因爲我所有的球都以相同的速度移動,而且我不希望它們在碰到某物時「失去能量」。我會做一些關於彈性碰撞的閱讀。 codereview在這裏寄給我 –

+0

我認爲這將是一個很好的閱讀,除非你已經消化它:http://en.wikipedia.org/wiki/Elastic_collision#Two-Dimensional_Collision_With_Two_Moving_Objects – laune

回答

1

真實生活中的物理是棘手的(重力,慣性等),但與啓動,彈跳球掉對方的:

當兩個球擊中,有碰撞的角度。幸運的是,因爲它們是圓圈(假設),您可以通過找出穿過兩個球的中心的線的角度來找到入射角。然後,你想發送一個球從垂直於該線的一個方向,另一個方向。

有意義嗎?

+0

是的,謝謝,這將幫助我,一條垂直線條很有意義(即使我之前沒有看到垂直字詞,但現在我知道它是什麼) –

+0

我接受現在的答案:)我認爲我會弄清楚,如果沒有,我會繼續問。 –

+0

如果我只是要切換兩個球的當前x和yvelocity值彼此反彈,那會是現實的嗎? int tempXVelocity = this.xVelocity; int tempYVelocity = this.yVelocity; this.xVelocity = rock.xVelocity; this.yVelocity = rock.yVelocity; rock.xVelocity = tempXVelocity; rock.yVelocity = tempYVelocity; –

2

你可以用動量守恆定律開始。當兩個物體發生碰撞時,總動量不會改變,您可以使用this link來了解後面的計算,同時嘗試預測兩個物體碰撞後的軌跡。

至於你的代碼,你似乎錯過了Rock.java中的關鍵字段mass。你需要質量來計算物體的動量,稍後你將用它來預測物體碰撞後的軌跡。

編輯:請注意,鏈接中的示例是有限的2個方向,其中對象之間相互碰撞180 *之間。然而,通過將動量/速度向量分解爲4個方向,即0,90,180,270度,在碰撞後找出物體的速度並不難。你必須使用矢量數學來表示一個給定物體在4個方向上的速度。

+0

謝謝,我會對該主題進行一些閱讀。我目前沒有考慮添加不同質量的岩石,所以我認爲我可以用1代替所有方程中的m? –

+0

當然你可以做到這一點,如果質量相同,方程變得更加簡單(注意方程兩邊的質量相互抵消)。另請參閱我的編輯:) –