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