【问题标题】:Simple bouncing ball program in JavaJava中的简单弹跳球程序
【发布时间】:2016-11-17 01:36:01
【问题描述】:

我正在尝试编写一个简单的弹跳球程序。它有一个矩形和两个球。球必须从矩形的墙壁上反弹(我已经成功编码)并且它们还必须相互反弹。这是我需要你帮助的地方。当我给球以相同的速度时,它们会很好地弹跳并且程序可以正常工作,但是我必须给球随机的速度。当我这样做时,球将不再弹跳,而是相互穿过。

import java.applet.*; 
import java.awt.*; 
import javax.swing.*;
import javax.swing.event.*;

public class BallApplet2 extends Applet implements Runnable 
{ 
  // Begin variabelen
  int x_pos1 = 150; 
  int y_pos1 = 200; 
  int radius1 = 20; 

  int x_pos2 = 250; 
  int y_pos2 = 200; 
  int radius2 = 20;

  private float ballspeedx1 = -3;   
  private float ballspeedy1 = 0;

  private float ballspeedx2 = 3;   
  private float ballspeedy2 = 0; 


  public void init() {} 

  public void start() { 
  Thread th = new Thread (this); 
   th.start (); } 
   public void stop() {} 
  public void destroy() {} 
  public void run () {
Thread.currentThread().setPriority(Thread.MIN_PRIORITY); 
while (true) 
{ 
  x_pos1 += ballspeedx1;
  y_pos1 += ballspeedy1;
  x_pos2 += ballspeedx2;
  y_pos2 += ballspeedy2;  


  repaint();
  // als x_pos < 100 is draait de richting van de bal om
  if (x_pos1  < 100) {
    ballspeedx1 = -ballspeedx1; 
    x_pos1 = 100; 
  } 
  if (x_pos2  < 100) {
    ballspeedx2 = -ballspeedx2; 
    x_pos2 = 100; 
  }  
  // als x_pos > 300 is draait de richting van de bal om
  if (x_pos1  > 300) {
    ballspeedx1 = -ballspeedx1; 
    x_pos1 = 300; 
  } 
  if (x_pos2  > 300) {
    ballspeedx2 = -ballspeedx2; 
    x_pos2 = 300; 
  }                                       
  // als de x van de rode bal gelijk is aan de x en twee keer de straal van de blauwe bal, draaien beide ballen om.
  if (x_pos1 == x_pos2 + 40) {
    ballspeedx1 = -ballspeedx1;
    ballspeedx2 = -ballspeedx2;
  }
  // als de x van de blauwe bal gelijk is aan de x van de rode bal, draaien beide ballen om.
  if (x_pos2 == x_pos1 ) {
    ballspeedx1 = -ballspeedx1;
    ballspeedx2 = -ballspeedx2;
  }
  // als de x en twee keer de straal van de rode bal gelijk is aan de x van de blauwe bal, draaien beide ballen om.
  if (x_pos1 + 40 == x_pos2) {
    ballspeedx1 = -ballspeedx1;
    ballspeedx2 = -ballspeedx2;  
  }
  // als de x en twee keer de straal    
  if (x_pos2 + 40 == x_pos1) {
    ballspeedx1 = -ballspeedx1;
    ballspeedx2 = -ballspeedx2;  
  }

  try { Thread.sleep (20); } 



  catch (InterruptedException ex) {} 

Thread.currentThread().setPriority(Thread.MAX_PRIORITY); }} 

public void paint (Graphics g) {

g.setColor (Color.red); 
g.fillOval (x_pos1 - radius1, y_pos1 - radius1, 2 * radius1, 2 * radius1); 

g.setColor (Color.blue); 
g.fillOval (x_pos2 - radius2, y_pos2 - radius2, 2 * radius2, 2 * radius2); 


g.setColor(Color.black);
g.drawLine(80,80,80,320); // lijn links
g.drawLine(320,80,320,320); // lijn rechts
g.drawLine(80,80,320,80);  // lijn boven
g.drawLine(80,320,320,320); // lijn onder
  }




  // Einde eventmethoden


} 

有人有解决办法吗?如果是这样,请尽量保持简单:)

【问题讨论】:

  • 这种事情可能很棘手,你是在任何时候解决碰撞(物理地将球移出碰撞)还是仅仅解决速度
  • 我猜是速度/速度使球的位置不匹配,即不会出现x_pos2 == x_pos1。也许尝试通过Math.abs(x_pos2-x_pos1)&lt; bdist 进行比较(bdist 是相对于速度/速度计算的)
  • 啊,是的,JScooby 是对的,您正在比较它们的中心是否发生碰撞,您似乎没有使用半径 1 和半径 2 进行碰撞检测
  • 同意@JScoobyCed,但您可能应该通过Math.sqrt((x_pos2-x_pos1)*(x_pos2-x_pos1)+(y_pos2-y_pos1)*(y_pos2-y_pos1)) &lt; 2 * radius)测试中心是否太近(小于半径的2倍)
  • 顺便说一句,要进行逼真的弹跳,​​您可能应该做一些更复杂的数学运算。当两个球以任意角度相互撞击时,不能只反转 x 和 y 速度。

标签: java bounce


【解决方案1】:

这 4 个条件似乎与检测碰撞有关

  if (x_pos1 == x_pos2 + 40) {
    ballspeedx1 = -ballspeedx1;
    ballspeedx2 = -ballspeedx2;
  }
  if (x_pos2 == x_pos1 ) {
    ballspeedx1 = -ballspeedx1;
    ballspeedx2 = -ballspeedx2;
  }
  if (x_pos1 + 40 == x_pos2) {
    ballspeedx1 = -ballspeedx1;
    ballspeedx2 = -ballspeedx2;  
  }  
  if (x_pos2 + 40 == x_pos1) {
    ballspeedx1 = -ballspeedx1;
    ballspeedx2 = -ballspeedx2;  
  }

但他们都询问对象是否在相对于其他对象的确切位置而不是在一个范围内。请记住,因为这种程序运行时会在发生碰撞时跳跃一个对象可能部分位于另一个对象内,将所有这 4 个条件更改为仅这一个条件可以解决问题

  if (Math.abs(x_pos2-x_pos1)<radius1+radius2){
    ballspeedx1 = -ballspeedx1;
    ballspeedx2 = -ballspeedx2;
  }

这不是询问彼此之间特定距离的球是否完全重叠,这提供了更安全的测试。

显然您知道这些简单的反向速度碰撞在物理上是不正确的,但另外需要注意的是,如果碰撞发生在重叠中并且(无论出于何种原因)两个物体在下一个时间步,然后发生另一次碰撞,一旦发生这种情况,两个球似乎“粘在一起”。这可以通过物理移动物体脱离碰撞,然后应用速度变化来解决。这个问题在非弹性碰撞中经常发生,但在多个物体同时碰撞时也会发生。

【讨论】:

  • 谢谢你这个伟大而简单的答案,理查德!我知道这个程序在物理上是不正确的,但它不一定是。
  • @user2919717 很高兴为您提供帮助。我有一种感觉,我自己做了一次这一系列程序,并经历了完全相同的步骤
  • @user2919717 顺便说一句,我强烈建议将您的球位置更改为双精度(或浮点数),因为如果您使用非常小的时间步长,您最终会得到 position_int+=0.01;这不会改变 position_int
  • 我不完全理解您在上一条评论中的意思。你能进一步解释一下吗?
  • @user2919717 目前,在每个时间步上,您向球的位置添加(例如)3 个像素。一开始这很好用,但如果你想改变帧速率就不是很好,当你改变帧速率时速​​度突然改变了。通常将 frameTime 作为参数(在您的情况下为 0.02)并将其乘以速度(以每秒像素为单位)以获得该帧的实际移动。这可以是一个非整数,并且在浮点/双精度中更好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-20
  • 1970-01-01
  • 2023-03-13
  • 2012-10-12
  • 1970-01-01
相关资源
最近更新 更多