//// X5: collisions. //// (Assume ball diameter of 30.) //// GLOBALS: pool table, 3 colored balls String title= "Pool"; String news= "Use 'r' key to reset."; String author= "Evelyn Levine"; int balldiam = 30; float friction = 1.007; float left, right, top, bottom; float middle; float cueX, cueY, cueDX, cueDY; float redX, redY, redDX, redDY; float yelX, yelY, yelDX, yelDY; float bluX, bluY, bluDX, bluDY; float modX,modY; float pW = 1; //// SETUP: size and table void setup() { size( 600, 400 ); rectMode( CORNERS ); left= 50; right= width-50; top= 100; bottom= height-50; middle= left + (right-left) / 2; // reset(); } void reset() { cueX= left + (right-left) / 4; cueY= top + (bottom-top) / 2; // Random positions. redX= random( middle,right ); redY= random( top, bottom ); yelX= random( middle,right ); yelY= random( top, bottom ); if(dist(redX,redY, yelX,yelY) <= balldiam){ reset(); } bluX= random( middle,right ); bluY= random( top, bottom ); if(dist(bluX,bluY, yelX,yelY) <= balldiam){ reset(); } if(dist(redX,redY, bluX,bluY) <= balldiam){ reset(); } // Random speeds redDX= random( 0,5 ); redDY= random( -5,5 ); yelDX= random( 0,5 ); redDY= random( -5,5 ); bluDX= random( 0,5 ); bluDY= random( -5,5 ); cueDX = 0; cueDY = 0; } //// NEXT FRAME: table, bounce off walls, collisions, show all void draw() { background( 240,230,140 ); table( left, top, right, bottom ); bounce(); pointer(); collisions(); show(); messages(); rButton(); } //// SCENE: draw the table with walls void table( float left, float top, float right, float bottom ) { fill( 100, 250, 100 ); // green pool table strokeWeight(10); stroke( 127, 0, 0 ); // Brown walls rect( left-20, top-20, right+20, bottom+20 ); } //// ACTION: bounce off walls, collisions void bounce() { redX += redDX; if ( redX<=left || redX>=right ) redDX = -redDX; redY += redDY; if ( redY<=top || redY>=bottom ) redDY = -redDY; redDX = redDX/friction; redDY = redDY/friction; bluX += bluDX; if ( bluXright ) bluDX *= -1; bluY += bluDY; if ( bluYbottom ) bluDY *= -1; bluDX = bluDX/friction; bluDY = bluDY/friction; yelX += yelDX; if ( yelXright ) yelDX *= -1; yelY += yelDY; if ( yelYbottom ) yelDY *= -1; yelDX = yelDX/friction; yelDY = yelDY/friction; cueX += cueDX; if ( cueXright ) cueDX *= -1; cueY += cueDY; if ( cueYbottom ) cueDY *= -1; cueDX = cueDX/friction; cueDY = cueDY/friction; } void collisions() { float tmp; // Swap velocities! if ( dist( redX,redY, yelX,yelY ) <= balldiam ) { tmp=yelDX; yelDX=+redDX; redDX=+tmp; tmp=yelDY; yelDY=+redDY; redDY=+tmp; } if ( dist( redX,redY, bluX,bluY ) <= balldiam ) { tmp=bluDX; bluDX=+redDX; redDX=+tmp; tmp=bluDY; bluDY=+redDY; redDY=+tmp; } if ( dist( bluX,bluY, yelX,yelY ) <= balldiam ) { tmp=yelDX; yelDX=+bluDX; bluDX=+tmp; tmp=yelDY; yelDY=+bluDY; bluDY=+tmp; } if ( dist( cueX,cueY, yelX,yelY ) <= balldiam ) { tmp=yelDX; yelDX=+cueDX; cueDX=+tmp; tmp=yelDY; yelDY=+cueDY; cueDY=+tmp; } if ( dist( cueX,cueY, bluX,bluY ) <= balldiam ) { tmp=bluDX; bluDX=+cueDX; cueDX=+tmp; tmp=bluDY; bluDY=+cueDY; cueDY=+tmp; } if ( dist( cueX,cueY, redX,redY ) <= balldiam ) { tmp=redDX; redDX=+cueDX; cueDX=+tmp; tmp=redDY; redDY=+cueDY; cueDY=+tmp; } } //// SHOW: balls, messages void show() { noStroke(); fill( 255,0,0 ); ellipse( redX,redY, balldiam,balldiam ); fill(0); text("Red", redX-10, redY+3); fill( 255,255,0 ); ellipse( yelX,yelY, balldiam,balldiam ); fill(0); text("Yel", yelX-10, yelY+3); fill( 0,0,255 ); ellipse( bluX,bluY, balldiam,balldiam ); fill(255); text("Blu", bluX-10, bluY+3); fill( 255,255,255 ); ellipse( cueX,cueY, balldiam,balldiam ); fill(0); text("Cue", cueX-10, cueY+3); } void messages() { fill(0); text( title, width/3, 20 ); text( news, width/3, 40 ); text( author, 10, height-10 ); } void pointer(){ fill(0); strokeWeight(pW); line(cueX,cueY,mouseX,mouseY); strokeWeight(1); pW = 1; } //// HANDLERS: keys, click void mousePressed(){ if(mouseX > 10 && mouseX < 50 && mouseY > 10 && mouseY < 50){ reset(); } else{ cueDX = cueDX + (cueX - mouseX)/50; cueDY = cueDY + (cueY - mouseY)/50; pW = dist(cueX,cueY,mouseX,mouseY)/25; } } void keyPressed() { if (key == 'r') { reset(); } } void rButton(){ fill(0); rect(10,10,50,50); text("Reset", 60,30); }