首页 > 解决方案 > 处理 - 将 mousePressed 添加到具有 100 个球的动画中

问题描述

我想创建一个球对象的 ArrayList,它应该在一个循环中,直到有 100 个。

现在我的问题是:我必须实现一个函数 hitTest,这样当你点击一个球时它就会被移除。在同一个位置,应该会出现两个球,它们会朝不同的方向移动。我包括了 mousePressed 和一个私有布尔值,但它不起作用,我不知道为什么。

有人能帮我吗?我好失落……

到目前为止,这是我的代码:Tab 1

ArrayList<Ball> balls;

void setup()
{
  size(800,800);
  balls = new ArrayList<Ball>();

  for(int i = 0; i<100; i++)
  {
    drawBall();
  }
}

void draw()
{
  background(255);
  //b.update();
  for(int i= 0; i<balls.size(); i++)
  {
    balls.get(i).update();
  }
}

void drawBall()
{
  Ball b = new Ball();
  balls.add(b);
}

void mousePressed()
{
  for(int i = balls.size()-1; i>=0; i--)
  Ball ball = balls.get (i);
  if (ball.hitTest())
  {
    balls.get(i).hitTest();
    balls.remove(ball);
    Ball b1 = new Ball(mouseX, mouseY);
    Ball b2 = new Ball(mouseX, mouseY);
    balls.add(b1);
    balls.add(b2);
  }
}

/*Tab 2:*/

class Ball
{
  private float x;
  private float y;
  private float ballSize;
  private float dirX;
  private float dirY;
  private boolean moving = true;

  Ball()
  {
    this.x = width/2;
    this.y = height/2;
    this.ballSize = random(10.0,30.0);
    this.dirX = random(-3.0,3.0);
    this.dirY = random(-3.0,3.0);
    if(this.dirX<1.0 && this.dirX>1.0)//1 statt -1 macht zufälliger
    {
      this.dirX = 1.0;
    }
    if(this.dirY<1.0 && this.dirY>1.0)
    {
      this.dirY = 1.0;
    }
  }

  public void update()
  {
    stroke(255);
    fill(random(255),random(255),random(255), random(255));
    ellipse( this.x, this.y, this.ballSize, this.ballSize);

    if(this.moving == true)
    {
      this.x += this.dirX;
      this.y += this.dirY;
    }

    if(this.x+ this.ballSize/2> width ||this.x- this.ballSize/2<0)
    {
      this.dirX= dirX*-1;
    }
    if(this.y+ this.ballSize/2> height ||this.y- this.ballSize/2<0)
    {
      this.dirY= dirY*-1;
    }
  }
  
  private boolean hitTest()
  {
    float d = dist(this.x, this.y, mouseX, mouseY);
    if (d < ballSize)
    {
      println("h");
      return true;
    }
    else
    {
      return false;
    }
  }
}

标签: javaprocessing

解决方案


你非常非常亲近!您发布的大部分代码都在那里。

有几个语法问题:

mousePressed()需要附上for 循环中的指令:

本节在这里:

for(int i = balls.size()-1; i>=0; i--)
  Ball ball = balls.get (i);
  if (ball.hitTest())
  {
    balls.get(i).hitTest();
    balls.remove(ball);
    Ball b1 = new Ball(mouseX, mouseY);
    Ball b2 = new Ball(mouseX, mouseY);
    balls.add(b1);
    balls.add(b2);
  }

应该:

for(int i = balls.size()-1; i>=0; i--){
  Ball ball = balls.get (i);
  if (ball.hitTest())
  {
    balls.get(i).hitTest();
    balls.remove(ball);
    Ball b1 = new Ball(mouseX, mouseY);
    Ball b2 = new Ball(mouseX, mouseY);
    balls.add(b1);
    balls.add(b2);
  }
}

这部分本身就是有效的语法:

for(int i = balls.size()-1; i>=0; i--)
      Ball ball = balls.get (i);

您可以使用for不带花括号的循环,但前提是您计划在循环中使用单个指令。在这种情况下,它正在检索 Ball,它本身并不是很有用。假设您要检查每个球的条件,即需要包含在{}.

(很遗憾处理只在特定情况下显示这个无用的错误:

考虑添加“=”

)

另一个小细节是重复调用hitTest()

ballballs.get (i)与上面的上下文相同,因此调用balls.get(i).hitTest();后调用ball.hitTest()是多余的。(它返回的布尔结果也没有做任何事情):

for(int i = balls.size()-1; i>=0; i--){
  Ball ball = balls.get (i);
  if (ball.hitTest())
  {
    balls.remove(ball);
    Ball b1 = new Ball(mouseX, mouseY);
    Ball b2 = new Ball(mouseX, mouseY);
    balls.add(b1);
    balls.add(b2);
  }
}

继续前进,您会遇到此错误:

构造函数“Ball(int, int)”不存在

new Ball(mouseX, mouseY);构造函数在 中调用,mousePressed()但是您的 Ball 类只提供没有参数的默认值(例如Ball(),不是Ball(x,y)。)

您可以轻松复制/粘贴现有​​构造函数并对其进行修改以添加 x、y 参数:

Ball(float x, float y)
  {
    this.x = x;
    this.y = y;
    this.ballSize = random(10.0,30.0);
    this.dirX = random(-3.0,3.0);
    this.dirY = random(-3.0,3.0);
    if(this.dirX<1.0 && this.dirX>1.0)//1 statt -1 macht zufälliger
    {
      this.dirX = 1.0;
    }
    if(this.dirY<1.0 && this.dirY>1.0)
    {
      this.dirY = 1.0;
    }
  }

避免重复代码(不推荐)的另一种选择是调用第一个构造函数:

Ball(float x, float y){
    this();// this() calls Ball()
    this.x = x;
    this.y = y;
  }

完整代码清单:

ArrayList<Ball> balls;

void setup()
{
  size(800,800);
  balls = new ArrayList<Ball>();

  for(int i = 0; i<100; i++)
  {
    drawBall();
  }
}

void draw()
{
  background(255);
  //b.update();
  for(int i= 0; i<balls.size(); i++)
  {
    balls.get(i).update();
  }
}

void drawBall()
{
  Ball b = new Ball();
  balls.add(b);
}

void mousePressed()
{
  for(int i = balls.size()-1; i>=0; i--){
    Ball ball = balls.get (i);
    if (ball.hitTest())
    {
      balls.remove(ball);
      Ball b1 = new Ball(mouseX, mouseY);
      Ball b2 = new Ball(mouseX, mouseY);
      balls.add(b1);
      balls.add(b2);
    }
  }
}

/*Tab 2:*/

class Ball
{
  private float x;
  private float y;
  private float ballSize;
  private float dirX;
  private float dirY;
  private boolean moving = true;

  Ball()
  {
    this.x = width/2;
    this.y = height/2;
    this.ballSize = random(10.0,30.0);
    this.dirX = random(-3.0,3.0);
    this.dirY = random(-3.0,3.0);
    if(this.dirX<1.0 && this.dirX>1.0)//1 statt -1 macht zufälliger
    {
      this.dirX = 1.0;
    }
    if(this.dirY<1.0 && this.dirY>1.0)
    {
      this.dirY = 1.0;
    }
  }
  
  Ball(float x, float y){
    this();
    this.x = x;
    this.y = y;
  }

  public void update()
  {
    stroke(255);
    fill(random(255),random(255),random(255), random(255));
    ellipse( this.x, this.y, this.ballSize, this.ballSize);

    if(this.moving == true)
    {
      this.x += this.dirX;
      this.y += this.dirY;
    }

    if(this.x+ this.ballSize/2> width ||this.x- this.ballSize/2<0)
    {
      this.dirX= dirX*-1;
    }
    if(this.y+ this.ballSize/2> height ||this.y- this.ballSize/2<0)
    {
      this.dirY= dirY*-1;
    }
  }
  
  private boolean hitTest()
  {
    float d = dist(this.x, this.y, mouseX, mouseY);
    if (d < ballSize)
    {
      println("h");
      return true;
    }
    else
    {
      return false;
    }
  }
}

我注意到hitTest()正在使用这种条件:

if (d < ballSize)

ballSize在这里使用:ellipse( this.x, this.y, this.ballSize, this.ballSize); 这意味着它是直径。通常对于圆形撞击测试,您会检查距离是否小于半径,而不是直径。也许这不是一个错误,而是一个特性:) ?允许两倍的尺寸以便在球区域外更容易点击?

另一个小建议:如果您不希望颜色在一秒钟内随机更改多次,您可以创建一个color属性以在Ball构造函数中存储一次随机颜色,然后简单地引用该设置颜色update()

你已经完成了大部分任务。记住要放轻松,休息后重新阅读代码,并在运行之前想象它是如何在你的脑海中运行的。它可能有助于发现此类问题。放慢速度似乎违反直觉,但从长远来看,这样做并注意细节实际上会加快你的速度。祝你好运


推荐阅读