【问题标题】:Unable to get the conditions right无法获得正确的条件
【发布时间】:2011-06-13 16:25:45
【问题描述】:

我正在尝试制作一个弹跳球的程序。我已经尝试了一些条件。但我没有得到我想要的。球一直在框架的对角线方向上来回移动。问题出在哪里?我已经强调了这个程序的主要逻辑。

这是程序:

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

class MovingBall2D extends JPanel{
 int x_Pos=0;
 int y_Pos=0;
 int speedX=1;
 int speedY=1;
 int diameter=30;
 int height=30;
 int frameX=500;
 int frameY=500;

 MovingBall2D() {
  ActionListener taskPerformer = new ActionListener() {
   public void actionPerformed(ActionEvent ae) {
    if( x_Pos > ( frameX - diameter ) ) {       //  <------ logic starts from here
      x_Pos =  frameX - diameter;
      speedX = -1; 
    }
    else if(x_Pos < 0) {
      x_Pos = 0;
      speedX = 1;
     }
    else if( y_Pos > ( frameY - diameter ) ) {
      y_Pos =  frameY - height; 
      speedY = -1;
     }
    else if(y_Pos < 0) {
     y_Pos = 0;
     speedY = 1;
    } 
    x_Pos = x_Pos + speedX;
    y_Pos = y_Pos + speedY;    
    repaint();
   }
  };
  new Timer(10,taskPerformer).start();   // <------- logic ends here
 }

public void paintComponent(Graphics g) {
 super.paintComponent(g);
 g.setColor(Color.red);
 g.fillOval(x_Pos,y_Pos,diameter,height);
}
}

class Main2D {
 Main2D() {
 JFrame fr=new JFrame();
 MovingBall2D o = new MovingBall2D();
 fr.add(o);
 fr.setSize(500,500);
 fr.setVisible(true);
 fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

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

编辑 - 球来回移动。 为什么会发生这种情况?我希望输出 shown here如果任何人不清楚问题,请编译然后运行以查看输出。

【问题讨论】:

  • 你能解释一下你得到了什么吗?你想得到什么?
  • 嗯...你想要什么?你应该准确地描述你所看到的(什么是问题?)以及你想看到的(什么是解决方案?)。球会离开屏幕吗?球是否会弹跳,但在以特定角度弹跳之前仍会离开屏幕?窗口根本不显示吗?我们不知道您想要什么样的答案。帮助我们帮助你:)
  • @Hunter 我正在尝试制作弹跳球的程序。我希望在此小程序roseindia.net/java/java-tips/45examples/40animation/… 中显示此处的输出
  • 我想要的输出显示在这个小程序roseindia.net/java/java-tips/45examples/40animation/…

标签: java swing user-interface graphics 2d


【解决方案1】:

球从位置 0, 0 开始。从那时起直到撞到墙壁的每个时间步,它的 x 位置和 y 位置都增加 1。所以在时间 471,它的位置是 (471, 471)。此时转身的 x 和 y 条件都为真,因此两者都被切换并且球完全转身。

如果您将起始位置更改为 (0, 30) 或将其中一个速度更改为 1 或 -1 以外的值,您将看到您的代码有效。球总是会跟随一些循环,但由于框架大小和球的位置,你的球恰好非常小。

但是,我建议您删除 else 条件。在一个帧中,球可能会在左侧太远和向下太远,因此在该帧中,两个条件都应该是固定的,而不仅仅是一个。此外,您可能会注意到球在 y 方向上继续离开屏幕。这是因为您的主框架设置为与面板相同的高度。框架高度包括用于顶部窗口栏的部分,因此它需要比它所持有的面板略大。

【讨论】:

  • 是的,球在 y 方向和 x 方向上继续离开屏幕。我能做些什么来避免这种情况。?
  • 为避免这种情况,您需要将 JFrame 初始化为在 y 方向上稍大一些。我不确定到底要大多少,不过大约是 40 像素。玩弄它。
  • 要让框架完全包含面板,请在 MovingBall2D 类上使用 setPreferredSize()。例如,在构造函数中你说 setPreferedSize(new Dimension(frameX, frameY))。然后,不要在主框架上显式调用 fr.setSize(),而是使用 fr.pack()。这将自动调整框架大小。
【解决方案2】:

在所有四种情况下,您都将相应的速度设置为 -1:

speedX = -1;
//...
speedY = -1;

但你只希望它在 X 大于宽度或 Y 大于高度时为负数。在其他两种情况下,您希望速度为正值。

或者,也许你想要的是

speedX *= -1;

这会将速度切换到相反的方向。

【讨论】:

【解决方案3】:

在我看来 speedXspeedY 没有正确更新。我认为应该是这样的:

if( x_Pos > ( frameX - diameter ) ) {       //  <------ logic starts from here
  x_Pos =  frameX - diameter;
  speedX = -1; 
}
else if(x_Pos < 0) {
  x_Pos = 0;
  speedX = 1;
 }
else if( y_Pos > ( frameY - diameter ) ) {
  y_Pos =  frameY - height; 
  speedY = -1;
 }
else if(y_Pos < 0) {
 y_Pos = 0;
 speedY = 1;
} 
x_Pos = x_Pos + speedX;
y_Pos = y_Pos + speedY;    

【讨论】:

【解决方案4】:

我认为您的所有逻辑都是正确的,但是您的初始化确保它会沿对角线反弹(从左下角到右上角)

改变它们,使用随机值或像这样对它们进行硬编码

 int x_Pos=100; // These are changed so the ball no longer starts at bottom left
 int y_Pos=20;
 int speedX=1;  //This should be fine as long as your initial position is different
 int speedY=1;
 int diameter=30;
 int height=30;
 int frameX=500;
 int frameY=500;

我也认为这可行

int x_Pos = 100* Math.Rand(1);

等等

【讨论】:

  • 这是什么int x_Pos = 100* Math.Rand(1); ?这给出了一个错误。
  • 哦,这只是伪代码(语法不正确)......基本上无论 Rand() 函数做什么(通常它返回一个从 0 到 1 的数字),你将它相乘以获得所需的bounds 然后你可以得到任何数字。只需找到 Math.Rand() 的文档即可。
猜你喜欢
  • 2016-09-05
  • 1970-01-01
  • 2021-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-23
  • 2020-02-23
相关资源
最近更新 更多