collision between objects in classes

edited January 2017 in Questions about Code

in my game when an asteroid hits the ship the ship will die. the problem is i dont know how to make the ship and asteroid collide when the x and y of both objects are in separate classes. should i make the variables global? also i have a minor thing, when you make a object out of a class you use something like this right? (assuming asteroid is a class and it is made to do something)

Asteroid drawAsteroid; void setup() { drawAsteroid = new Asteroid(); }

lets say i wanted two asteroids that had different x values (lets say the different x values were already coded, just focus on the two asteroids)i would do something like this right?

Asteroid drawAsteroid1; Asteroid drawAsteroid2; void setup(){ drawAsteroid1 = new Asteroid(); drawAsteroid2 = new Asteroid(); }

Well i could just make a new asteroid every time i wanted 1 more, is there a simpler way to create more (like if i had to make 1000000000 asteroids and was on a time schedule meaning i couldnt code 1 million asteroids manually) how would i do that?

Thanks - cloudi

Answers

  • ... is there a simpler way to create more...

    Yes, use a container to store your object references. *-:)

    If the number of objects is fixed, go w/ regular arrays:
    https://Processing.org/reference/Array.html

    Otherwise, an ArrayList is more appropriate as a dynamicly-sized container:
    https://Processing.org/reference/ArrayList.html

  • edited January 2017

    ... how to make the ship and asteroid collide when the x and y of both objects are in separate classes.

    http://www.JeffreyThompson.org/collision-detection/table_of_contents.php

    abstract class Entity {
      float x, y, w, h;
    
      boolean checkRectCollision(final Entity e) {
        return
          x+w > e.x & x < e.x+e.w &
          y+h > e.y & y < e.y+e.h;
      }
    
      boolean checkCircleCollision(final Entity e) {
        final float rad1 = .5*w, rad2 = .5*e.w;
        return sq(e.x - x) + sq(e.y - y) < sq(rad1 + rad2);
      }
    }
    
    class Ship extends Entity {
    }
    
    class Asteroid extends Entity {
    }
    
  • @GoToLoop this is helpful however im having a hard time trying to put this example into my code. I made my asteroid and ship and its all based on x and y, meaning i have no variables that are for width and height. also i watched a video on collision (im sure you have seen it) and the lady uses

        if (_dist_(x1,y1,x2,y2)<50) {
        -code-
        }
    

    i thought that it would work but im not too sure since you mentioned this more complicated stuff. let me know your thoughts on this code and yours and if your code makes more sense too use can you explain why cause im kind of lost, thanks.

  • edited January 2017

    and its all based on x and y, meaning i have no variables that are for width and height.

    • Unless they're merely points, they occupy some area w/ width & height dimensions. :-B
    • Collision calculations need both location & dimension coordinate pairs.
    • Therefore your Entity classes should have fields like x, y, w, h to represent those 4 values. >-)

    The same example I've posted above, but now w/ an extra display() method: O:-)

    abstract class Entity {
      float x, y, w, h;
    
      abstract void display();
    
      boolean checkRectCollision(final Entity e) {
        return
          x+w > e.x & x < e.x+e.w &
          y+h > e.y & y < e.y+e.h;
      }
    
      boolean checkCircleCollision(final Entity e) {
        final float rad1 = .5*w, rad2 = .5*e.w;
        return sq(e.x - x) + sq(e.y - y) < sq(rad1 + rad2);
      }
    }
    
    class Ship extends Entity {
      @ Override void display() {
        rect(x, y, w, h);
      }
    }
    
    class Asteroid extends Entity {
      @ Override void display() {
        rect(x, y, w, h);
      }
    }
    
  • edited January 2017

    A slightly larger example, so you can have a better idea how to instantiate those classes: :-bd

    // forum.Processing.org/two/discussion/20124/
    // collision-between-objects-in-classes#Item_5
    
    // GoToLoop (2017-Jan-08)
    
    import java.util.List;
    final List<Asteroid> asteroids = new ArrayList<Asteroid>();
    
    Ship ship;
    
    void setup() {
      size(800, 600);
      smooth(3);
      frameRate(60);
    
      imageMode(CORNER);
      rectMode(CORNER);
      ellipseMode(CENTER);
    
      strokeWeight(1.5);
      stroke(0);
    
      ship = new Ship(width>>1, height>>1, 10, 20);
      println("ship ->", ship, "\n\nasteroids ->");
    
      for (int i = 0; i < 10; ++i) {
        final float x = random(50, width  - 50);
        final float y = random(50, height - 50);
    
        final int w = (int) random(10, 50);
        final int h = (int) random(10, 50);
    
        asteroids.add(new Asteroid(x, y, w, h));
      }
    
      println(asteroids);
    }
    
    void draw() {
      background(050);
    
      fill(Asteroid.COLOUR);
      for (Asteroid a : asteroids)  a.display();
    
      fill(Ship.COLOUR);
      ship.display();
    }
    
    abstract class Entity {
      float x, y;
      int w, h;
    
      float sx, sy;
    
      Entity() {
      }
    
      Entity(float _x, float _y, int _w, int _h) {
        x = _x;
        y = _y;
        w = _w;
        h = _h;
      }
    
      abstract void display();
    
      boolean checkRectCollision(final Entity e) {
        return
          x+w > e.x & x < e.x+e.w &
          y+h > e.y & y < e.y+e.h;
      }
    
      boolean checkCircleCollision(final Entity e) {
        final float rad1 = .5*w, rad2 = .5*e.w;
        return sq(e.x - x) + sq(e.y - y) < sq(rad1 + rad2);
      }
    
      @ Override String toString() {
        return "x: " + x + ", y: " + y + ", w: " + w + ", h: " + h;
      }
    }
    
    class Ship extends Entity {
      static final color COLOUR = #0000FF;
    
      Ship(float x, float y, int w, int h) {
        super(x, y, w, h);
      }
    
      @ Override void display() {
        rect(x, y, w, h);
      }
    }
    
    class Asteroid extends Entity {
      static final color COLOUR = #FF0000;
    
      Asteroid(float x, float y, int w, int h) {
        super(x, y, w, h);
      }
    
      @ Override void display() {
        rect(x, y, w, h);
      }
    }
    
  • edited January 2017

    @GoToLoop well im still not understanding too much, i think its because of my perameters.

            class Ship {
            float sx;
            float sy;
            boolean hit = false;
    
            Ship() {
              sx = width/2;
              sy = height/2;
            }
    
            void draw() {
              drawShip();
              moveShip();
              if (hit) stroke(255,0,0);
              else stroke(0);
            }
    
            void drawShip() {
              pushMatrix();
              translate(sx,sy);
              stroke(255);
              noFill();
              line(0,-10,10,10);
              line(10,10,0,5);
              line(0,5,-10,10);
              line(-10,10,0,-10);
              popMatrix();
             }
    
            void moveShip() {
              if (keyPressed && key==CODED) {
               if (keyCode==LEFT) sx = sx - 3;
               if (keyCode==RIGHT) sx = sx + 3;
               if (keyCode==UP) sy = sy - 3;
               if (keyCode==DOWN) sy = sy + 3;
              }
              if (sx > 400) sx = 0;
              if (sx < 0) sx = 400;
              if (sy > 688) sy = 688;
              if (sy < 570) sy = 570;
             }
            }
    
            class Asteroid {
              float ax;
              float ay;
              float aydelta;
    
              Asteroid(float axA, float ayA) {
                ax = axA;
                ay = ayA;
              }
    
              void draw() {
                drawAsteroid();
                moveAsteroid();
              }
    
              void drawAsteroid() {
                pushMatrix();
                translate(ax,ay);
                rotate((random(0,6)));
                stroke(255);
                noFill();
                line(15,-30,30,0);
                line(30,0,15,30);
                line(15,30,-15,30);
                line(-15,30,-30,0);
                line(-30,0,-15,-30);
                line(-15,-30,15,-30);
                popMatrix();
              }
    
              void moveAsteroid() {
              ay = ay + aydelta;
              if (ax > 400) ax = 400;
              if (ax < 0) ax = 0;
              if (ay > 700) ay = -10;
              if (ay <= -10) aydelta = (random(3,6));
              if (ay <= -10) ax = (random(0,400));
              }
             }
    
  • edited January 2017
    • My example relies on class inheritance.
    • Both classes Ship & Asteroid extends class Entity.
    • It means both sub-classes automatically inherit fields x, y, w, h, sx & sy from class Entity.
    • Plus methods checkRectCollision(), checkCircleCollision() & toString().
    • And both are obliged to implement method display() too.
    • Obviously you need to adapt the example for your actual code.
    • Paying attention on any different names used by fields & methods.
  • Is this another question about your asteroids game? That's 7 now, how are we meant to know which one to answer? How are you meant to know which answer to believe?

    This is why we prefer to keep the number of threads relating to a topic to a minimum.

  • edited January 2017

    i did some research about this and i found many people saying to use this http://www.jeffreythompson.org/collision-detection/object_oriented_collision.php i tried my hardest to use what this code is teaching and apply it to my code but i still doesn't work,i've also used other types of "easy" collision detection and it doesn't work out, i really just need to be able to use the variables that are inside my classes (x and y) outside. i know that i could just use a global variable but when i do that for my asteroid class it becomes very glitchy. there is a function called dist (im sure you guys have heard of it) and i want to do something like.

    if (dist(sx,sy,ax,ay)) { // do something... }

    maybe you guys can drill it into my head, heres all my code that relates with this, thanks.

            class Ship {
              float sx;
              float sy;
              float sw;
              float sh;
    
              Ship(float x, float y) {
                sx = width/2;
                sy = height/2;
                sw = 10;
                sh = 10;
              }
    
              void draw() {
                moveShip(); 
                drawShip();
              }
    
              void drawShip() {
                pushMatrix();
                translate(sx, sy);
                stroke(255);
                noFill();
                line(0, -10, 10, 10);
                line(10, 10, 0, 5);
                line(0, 5, -10, 10);
                line(-10, 10, 0, -10);
                popMatrix();
              }
    
              void moveShip() {
                if (keyPressed && key==CODED) {
                  if (keyCode==LEFT) {
                    sx = sx - 3;
                  }
                  if (keyCode==RIGHT) {
                    sx = sx + 3;
                  }
                  if (keyCode==UP) {
                    sy = sy - 3;
                  }
                  if (keyCode==DOWN) {
                    sy = sy + 3;
                  }
                }
                if (sx > 400) sx = 0;
                if (sx < 0) sx = 400;
                if (sy > 688) sy = 688;
                if (sy < 570) sy = 570;
              }
            }
    
            class Asteroid {
              float ax;
              float ay;
              float aydelta;
    
              Asteroid(float x, float y) {
                ax = x;
                ay = y;
              }
    
              void draw() {
                drawAsteroid();
                moveAsteroid();
              }
    
              void drawAsteroid() {
                pushMatrix();
                translate(ax, ay);
                rotate((random(0, 6)));
                stroke(255);
                noFill();
                line(15, -30, 30, 0);
                line(30, 0, 15, 30);
                line(15, 30, -15, 30);
                line(-15, 30, -30, 0);
                line(-30, 0, -15, -30);
                line(-15, -30, 15, -30);
                popMatrix();
              }
    
              void moveAsteroid() {
                ay = ay + aydelta;
                if (ax > 400) ax = 400;
                if (ax < 0) ax = 0;
                if (ay > 700) ay = -10;
                if (ay <= -10) aydelta = (random(3, 6));
                if (ay <= -10) ax = (random(0, 400));
              }
            }
    
            Asteroid[] asteroids = new Asteroid[12];
            Ship Ship;
            void setup() {
              size(400, 700);
              frameRate(60);
            Ship = new Ship(width/2, height/2);
            for (int i=0; i<asteroids.length; i++) {
                float ax = random(0, 400);
                float ay = -10;
                asteroids[i] = new Asteroid(ax, ay);
              }
            }
    
            void draw() {
              background(0);
            Ship.draw(); 
              for (Asteroid a : asteroids) {
                a.draw();
              }
            }
    
  • I think you may need to read up about Inheritance.

  • You can access the x,y outside the class by saying

    ship.x or

    asteroids[2].x

    etc.

    ....

  • @lord_of_the_galaxy thanks, i will read up on that later, @chrisir i could do that but then i would have to write manual code for 12 different asteroids, should i put in the asteroids for loop?

  • Yes. Do you mean ship versus asteroid?

    That's easy

  • @chrisir yup i mean ship versus asteroid, i should use the dist function like i mentioned earlier right

  • edited January 2017

    Yes for-loop over asteroids and check with dist against ship

    for(int i..... )    {
    
        if (dist(ship.sx,ship.sy, asteroids[i].ax, asteroids[i].ay) < 22)   { 
            ....... 
            } // if 
    
    } // for 
    
  • @chrisir thanks, it looks like it should work. Unfortunately i cant try this until later, i have a big day of stuff to do. Ill let you know how it works and thanks again

  • Just PM me if you need something

Sign In or Register to comment.