【问题标题】:Simple Collision Detection Project简单的碰撞检测项目
【发布时间】:2020-10-19 10:03:46
【问题描述】:

我是一名新手,正在为我的作业编写代码并进行碰撞检测项目。我认为我的算法是正确的,但我的问题是如何从我创建的 ArrayList 访问对象并在检测到碰撞后删除该对象。请查看我的代码并帮助我改进它以从中添加 remove() 。我添加了一个布尔变量来检查是真还是假,然后执行删除功能。

我的最终目标是在幽灵与绿球碰撞时将其移除


    ArrayList<Greenball> array1 = new ArrayList<Greenball>();
    ArrayList<Ghost> array2 = new ArrayList<Ghost>();

    void setup(){
      size(1000,500);
      
      
    }
    
    void draw(){
      background(255);
      
      
      for(int i = 0; i < array1.size() ; i++){
       array1.get(i).move();
       array1.get(i).display();
      }
      
      for (int i = 0; i < array2.size() ; i++){
       array2.get(i).move();
       array2.get(i).display();
      }
    }
    
    void mousePressed(){
      if (array1.size() != 5) array1.add(new Greenball(int(mouseX),int(mouseY), 40, 40)); //max at 5
    }
    
    void keyPressed(){
      if (array2.size() != 5)array2.add(new Ghost(int(random(40,960)), int(random(40,460)), 40, 40)); //max at 5

class Ghost{
  
  PImage ghost;
  int x,y,w,h,xSpeed,ySpeed;
  int pixelSize = 40;
  Ghost(int x_, int y_, int w_, int h_){
  x = x_;
  y = y_;
  w = w_;
  h = h_;  
  xSpeed = int(random(-10,10));
  ySpeed = int(random(1,10));  
  }
  
  void move(){
   x = x + xSpeed;
   y = y + ySpeed;
   
   if(x > width-pixelSize || x < 0){
    xSpeed = xSpeed * -1; 
   }
   if(y > height-pixelSize || y < 0){
    ySpeed = ySpeed * -1; 
   }
    
  }
  
  void display(){
   ghost = loadImage("greenghost.png");
   image(ghost,x,y,w,h);
}

class Greenball{
  
 PImage g;
 int x,y,w,h,xSpeed,ySpeed;
 int pixelSize = 40;
 boolean alive=true;
 Greenball(int x_, int y_, int w_, int h_){
   x = x_;
   y = y_;
   w = w_;
   h = h_;
   xSpeed = int(random(-10,10));
   ySpeed = int(random(1,10));
 }
 
 void move(){
   x = x + xSpeed;
   y = y + ySpeed;
   
   if(x > width-pixelSize || x < 0){
    xSpeed = xSpeed * -1; 
   }
   if(y > height-pixelSize || y < 0){
    ySpeed = ySpeed * -1; 
   }
 }
 
 void display(){
   g = loadImage("green.png");
   image(g,x,y,w,h);
 }
 
 
 void checkForCollision(Ghost ghost){
   float d = dist(x,y,ghost.x,ghost.y);
   float r1 = (x+y)/2;
   float r2 = (ghost.x + ghost.y)/2;
   
   if (d < r1 + r2) alive = false;
   else alive = true;
   }

}

【问题讨论】:

  • 我被困在幽灵物体与绿球碰撞后如何移除它。我不知道该怎么做。
  • "我将如何从我的 ArrayList 访问对象" 访问是为了什么?对于程序的其他部分,您必须经常访问它。有什么不同吗?为什么要“检测到碰撞后移除对象”。只是将其标记为“被驱除”不是一种选择吗?您可以跳过显示和程序的其他逻辑中的被驱除的鬼魂。

标签: java processing collision-detection


【解决方案1】:

draw() 内添加碰撞检测函数 并运行两个嵌套的for 循环,以便检查是否有任何Ghosts 与任何Greenballs 发生碰撞 您可以使用以下代码替换您的绘图功能:

void draw() {
  background(255);

   // loop through all the Ghosts
   for(int i = 0; i < array2.size(); i++) {

     //move and display the Ghosts
     array2.get(i).move();
     array2.get(i).display();

     /*
      * For every Ghost, check if that Ghost is colliding with any Greenball.
      * Here you are checking collision with each Ghost for each Greenball.
      */
     for (int j = 0; j < array2.size(); j++) { // for each Greenball,
       if (array1.get(i).checkForCollision(array2.get(j)) { // if any Ghost is Colliding with it,
         array1.get(j).alive = false; // then set "alive = false" for it     
       }     
     }
   }

  // loop through all the Greenballs in reverse order, so that each and every Greenball is checked
  for(int i = array1.size() - 1; i >= 0; i--) {
    if (array1.get(i).alive = false) { // if any Greenball is dead,
      array1.remove(i); // then remove it
    } else { // else, move and display it.
      array1.get(i).move();
      array1.get(i).display();
    }
  }
 
}

建议:您不需要每次显示GhostGreenball 时都使用loadImage(),因为这对您的系统非常不利。只需在构造函数中使用一次ghost = loadImage("ghost.png") 即可。

【讨论】:

    【解决方案2】:

    这取决于你从哪里调用checkForCollision 方法。我认为最好的地方是draw 方法。尝试用以下代码替换你的第二个循环:

    Iterator<Ghost> ghostIterator = array2.iterator();  // get iterator object
    while (ghostIterator.hasNext()) {
        Ghost ghost = ghostIterator.next();             // get current ghost object
        ghost.move();                                   // recalculate position
        boolean collided = false;
        for (int i = 0, len = array1.size(); i < len; i++) {
            if (array1.get(i).checkForCollision(ghost)) {   // check for collision
                ghostIterator.remove(ghost);               // remove current ghost if it collided
                collided = true;
                break;               // stop inside loop due to collision detected
            }
            if (!collided) {
                ghost.display();  // if ghost isn`t collided display it
            }
        }
    }
    

    请注意,您应该将checkForCollision 方法的返回类型从void 更改为boolean 并返回计算得到的alive 值。

    【讨论】:

      【解决方案3】:
      void draw(){
        background(0);
        
        for(int i = 0; i < gball1.size() ; i++){
          Greenball gball = gball1.get(i);
          gball.move();
          gball.display(); 
         }
        
      
        for(int i = 0; i < ghost2.size() ; i++){
          
          Ghost ghost = ghost2.get(i);
          ghost.move();
          ghost.display();
          
          for(int e = 0; e < gball1.size(); e++){
            Greenball b = gball1.get(e);
            if(ghost.ifCollided(b)){
              ghost2.remove(i);
            }
          }
         }
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-11-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-26
        • 1970-01-01
        相关资源
        最近更新 更多