1

Dealing with collisions in Processing is straightforward. However, how do I identify collisions with trails?

Example: imagine the light cycles in Tron, if you wish, with the alteration that trails of derezzed light cycles do not disappear. In Tron, if a cycle intersects any point another cycle, itself included, has ever been, it 'dies'. How do I efficiently find this event in Processing?

Chris vCB
  • 1,023
  • 3
  • 13
  • 28

2 Answers2

2

One hacky workaround is to draw the line into a PImage and check if the colour at a location is the same as the background or not (e.g. a pre-existing line, hence a collision).

Here's a rough (and slightly inefficient (due to get()/set() calls) proof of concept:

PImage buffer;

//how mutch we scale down = how pixely this will look
int multiplier = 8;
//scaled down width/height
int w,h;
//cursor position
int px,py;
//cursor velocity;
int vx,vy;


void setup(){
  size(400,400);
  noSmooth();

  w = width / multiplier;
  h = height / multiplier;

  buffer = createImage(w,h,RGB);
  clear();
}
void clear(){
  java.util.Arrays.fill(buffer.pixels,color(0));
  buffer.updatePixels();
}
void draw(){
  //update cursor
  px += vx;
  py += vy;
  //check edges
  if(px < 0){
    px = w-1;
  }
  if(px > w){
    px = 0;
  }
  if(py < 0){
    py = h-1;
  }
  if(py > h){
    py = 0;
  }
  //check collision
  if(keyPressed){
    if(keyCode == UP || keyCode == DOWN || keyCode == LEFT || keyCode == RIGHT){
      checkSelfIntersection();
    }
  }
  //paint cursor
  buffer.set(px,py,color(0,192,0));

  //render on screen
  image(buffer,0,0,width,height);
}
void checkSelfIntersection(){
  //if the pixel ahead is not the same colour as the background
  if(buffer.get(px+vx,py+vy) > color(0)){
    clear();  
    println("Cycle go BOOM!");
  }
}
void keyPressed(){
  if(keyCode == UP){
    vy = -1;
  }
  if(keyCode == DOWN){
    vy = +1;
  }
  if(keyCode == LEFT){
    vx = -1;
  }
  if(keyCode == RIGHT){
    vx = +1;
  }
}
void keyReleased(){
  vx = vy = 0;
}

A similar concept can be done be keeping track of points in a list and checking if a new point is already part of this list (collision) or not:

ArrayList<PVector> path = new ArrayList<PVector>();


//cursor position
int px,py;
//cursor velocity;
int vx,vy;

void setup(){
  size(400,400);
  noFill();
  strokeWeight(10);
}
void draw(){
  //update cursor
  px += vx;
  py += vy;
  //check edges
  if(px < 0){
    px = 0;
  }
  if(px > width){
    px = width;
  }
  if(py < 0){
    py = 0;
  }
  if(py > height){
    py = height;
  }
  //check collision
  if(keyPressed){
    if(keyCode == UP || keyCode == DOWN || keyCode == LEFT || keyCode == RIGHT){
      checkSelfIntersection();
    }
  }

  background(255);
  beginShape();
  for(int i = 0 ; i < path.size(); i++){
    PVector p = path.get(i);
    vertex(p.x,p.y);
  }
  endShape();
}
void checkSelfIntersection(){
  PVector cursor = new PVector(px,py);
  if(path.contains(cursor)){
    path.clear();
    println("Cycle go BOOM!");
  }else{
    path.add(cursor);
  }
}
void keyPressed(){
  if(keyCode == UP){
    vy = -5;
  }
  if(keyCode == DOWN){
    vy = +5;
  }
  if(keyCode == LEFT){
    vx = -5;
  }
  if(keyCode == RIGHT){
    vx = +5;
  }
}
void keyReleased(){
  vx = vy = 0;
}

The concept isn't that different from how games like Snake/Volfied/etc. check for self intersections.

Note I'm cheating a bit by updating a "cursor" on keys with a small velocity: this avoid gaps in the lines. If you try to replace with the mouse, you'll notice the collision check may fail if the mouse moves fast as it checks one point against a list of recorded points. An alternative might be to split the list of points into pairs of lines and check if the new point intersects any of them.

You might want to also check this similar question

Community
  • 1
  • 1
George Profenza
  • 50,687
  • 19
  • 144
  • 218
-2

Stack Overflow isn't really designed for general "how do I do this" type questions. It's for specific "I tried X, expected Y, but got Z instead" type questions. That being said, I'll try to help in a general sense.

You can probably just keep track of the lines formed by the cycles, in the form of an ArrayList of all of the points where a player turned. Then at each step, you can check whether the player is intersecting with any of those lines.

More specifically, you'd probably want to form another line between the previous player coordinate and the next player coordinate. Then check whether that line intersects with any of the other lines using formulas that I'm sure you can find through a google search or two.

You probably don't have to do anything smarter than that unless you're talking about very very large playing fields (as in, millions of lines). So it's a little early to ask about efficiency.

There are of course many other ways to approach the problem. You might also use a 2D array that keeps track of the trails, or you could use pixel-based collision, or probably any number of other solutions. The point is you need to try something and post a MCVE along with a specific question if you get stuck, and we'll go from there. Good luck.

Community
  • 1
  • 1
Kevin Workman
  • 41,537
  • 9
  • 68
  • 107