2015-05-18 79 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

当然你可以做到这一点,如果质量相同,方程变得更加简单(注意方程两边的质量相互抵消)。另请参阅我的编辑:) –