We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpSyntax Questions › URGENT Help with collision detection and movement
Pages: 1 2 
URGENT Help with collision detection and movement (Read 895 times)
URGENT Help with collision detection and movement
Dec 9th, 2008, 1:10am
 
i want to make a game where there are two players that are balls and the object is to bump the other "off the map"...i cant seem to get smooth and fast movement using the arrow keys and i dont know how to detect collisons...can anyone help...its is for a project for school and I can not figure it out..
Re: URGENT Help with collision detection and movem
Reply #1 - Dec 9th, 2008, 1:41am
 
why don't you post some code so we can see what you got.
Re: URGENT Help with collision detection and movem
Reply #2 - Dec 9th, 2008, 3:40am
 
void setup()
{
size(500,500);
frameRate(10);
}

int playerOneSpeed = 20;
int playerTwoSpeed = 20;
int playerOneXaxis = 0;
int playerOneYaxis = 0;
int playerTwoYaxis = 300;
int playerTwoXaxis = 300;
int nothing = 0;

void draw(){
 background(200,200,0);
 smooth();
 fill(255,0,0);
 ellipse(playerOneXaxis,playerOneYaxis,20,20);
 fill(0,0,255);
 ellipse(playerTwoXaxis,playerTwoYaxis,20,20);
}

void keyPressed() {
 if (key == CODED) {
   if (keyCode == UP) {
     playerOneYaxis=playerOneYaxis-playerOneSpeed;
   }
   else if (keyCode == DOWN)
   {
     playerOneYaxis=playerOneYaxis+playerOneSpeed;
    }  

else if (keyCode == RIGHT)
{
playerOneXaxis=playerOneXaxis+playerOneSpeed;
}
 else if (keyCode == LEFT)
 {
   playerOneXaxis=playerOneXaxis-playerOneSpeed;
 }
else if (keyCode == LEFT && keyCode == UP)
{
 playerOneYaxis=playerOneYaxis-playerOneSpeed;
 playerOneXaxis=playerOneXaxis-playerOneSpeed;
}
else
nothing = 0;
 }  

//------------------------------------------------------------------------------
---------------------------
if (key == 'w')
   {
     playerTwoYaxis=playerTwoYaxis-playerTwoSpeed;
   }

else if (key == 's')
   {
     playerTwoYaxis=playerTwoYaxis+playerTwoSpeed;
   }
else if (key == 'd')
{
playerTwoXaxis=playerTwoXaxis+playerTwoSpeed;
}
 else if (key == 'a')
 {
   playerTwoXaxis=playerTwoXaxis-playerTwoSpeed;
 }
 
 else
 nothing = 0;
}


im not sure how to approach the collision issue, i was thinking a comparison of coordinate values but i would need 360 degree turning and smooth movements with friction possibly...the first thing i want to do is to have smooth movement that responds to multiple arrow keys pressed (example: left and up goes diagonally) or maybe a way to rotate the ball's heading and press forward to move in that direction...
Re: URGENT Help with collision detection and movem
Reply #3 - Dec 9th, 2008, 12:19pm
 
The line

else if (keyCode == LEFT && keyCode == UP)

cannot work... Variable has one value or the other, not both.

Fast and smooth movement: remove the frameRate call...

Collision detection: since both are circles, just check dist() between center of players is equal or below the cumulated radii (you should put radius in constants, allowing easier change if needed).
Re: URGENT Help with collision detection and movem
Reply #4 - Dec 9th, 2008, 8:37pm
 
a couple things i noticed:

take smooth() out of draw and put it in setup() since it only needs to be called once.

even after changing the last if to (keyCode == LEFT || keyCode == UP), it will still never be called since one of the earlier ifs would have evaluated to true. you also may want to consider a switch case instead of if-elses for this application.
Re: URGENT Help with collision detection and movem
Reply #5 - Dec 9th, 2008, 9:36pm
 
what would i do for a bounce, you said use dist() but how would it go in opposite ways if collision is head on or if one ball hits the other at an angle?
Re: URGENT Help with collision detection and movem
Reply #6 - Dec 9th, 2008, 10:12pm
 
Good question... Collision against a wall is easy:
Code:
int radius1 = 23, radius2 = 31;
int speedX1 = -5, speedX2 = 7, speedY1 = 8, speedY2 = -3;
int posX1 = 20, posX2 = 120, posY1 = 50, posY2 = 150;

void setup()
{
size(600, 400);
smooth();
noStroke();
}

void draw()
{
background(#AAFFEE);
MoveBall1();
MoveBall2();
DrawBall1();
DrawBall2();
}

void MoveBall1()
{
posX1 += speedX1;
if (posX1 < radius1 || posX1 > width - radius1)
{
speedX1 = -speedX1;
posX1 += speedX1;
}
posY1 += speedY1;
if (posY1 < radius1 || posY1 > height - radius1)
{
speedY1 = -speedY1;
posY1 += speedY1;
}
}

void MoveBall2()
{
posX2 += speedX2;
if (posX2 < radius2 || posX2 > width - radius2)
{
speedX2 = -speedX2;
posX2 += speedX2;
}
posY2 += speedY2;
if (posY2 < radius2 || posY2 > height - radius2)
{
speedY2 = -speedY2;
posY2 += speedY2;
}
}

void DrawBall1()
{
fill(#007722);
ellipse(posX1, posY1, radius1 * 2, radius1 * 2);
}

void DrawBall2()
{
fill(#002277);
ellipse(posX2, posY2, radius2 * 2, radius2 * 2);
}

(I would use classes to avoid repetition of code, but I prefer to keep things "simple").
I can manage collisions like this:
Code:
[...]
int collisionDist = radius1 + radius2;

void setup()
{
[...]
}

void draw()
{
background(#AAFFEE);
MoveBall1();
MoveBall2();
float d = dist(posX1, posY1, posX2, posY2);
if (d < collisionDist)
{
speedX1 = -speedX1;
posX1 += speedX1;
speedY1 = -speedY1;
posY1 += speedY1;
speedX2 = -speedX2;
posX2 += speedX2;
speedY2 = -speedY2;
posY2 += speedY2;
}
DrawBall1();
DrawBall2();
}

[...]

but it looks artificial and wrong...
I suppose the solution is somewhere on this forum, but it is funnier to find by myself. I will search for combinations of vectors or something.
Re: URGENT Help with collision detection and movem
Reply #7 - Dec 9th, 2008, 10:34pm
 
as of now it is impossible for the balls to collide at anything other than right angles.   you need to come up with some other way of controlling the direction of the ball.  perhaps UP can accelerate and LEFT and RIGHT change the DIRECTION of the ball to the left and right.

another thing i noticed is that your ball gets stuck for a second in the beginning before sliding off.  this is because windows has a delay before sending repeated key stroke. (try holding down a letter in a text editor and see what happens.)  to fix this you could use keyPressed() to set movement to on, and keyReleased() to turn it off. or intead of holding UP down to move, you could make UP accelerate and DOWN decelerate.

in order to figure out how the balls should bounce at different angles, you first need a way of storing their angles.  you would also use the angles to figure out how much they should move by x and by y.  to bounce the balls appropriately, remember: angle of incidents equals angle of reflection. think about pool balls.
Re: URGENT Help with collision detection and movem
Reply #8 - Dec 9th, 2008, 10:39pm
 
thank you guys so much, this really helps a lot. I have another question if anyone mind answering: How can i make it so that each ball has a rectangle on it that points in the direction that the ball will head if someone holds down the up arrow key. What i envision is a game kind of like the "mario party" mini-game where each character is on a ball and the object is to knock the other one off the small elevated platform while staying in control of where they are going. The physics behind it is that each ball has inertia and if the player forces the ball in the opposite directions, the ball will gradually slow and then move with the force. This inertia will be another issue that im going to work on and I would appretiate any help i can get. Its all for a final project in intro to programming and the professor and the textbook was not helpful yet he wants an interesting presentation by tommorow. I have been working on this for weeks and i kept changing my mind on what to do and now its crunch time and i have a crappy program and i mostly blame myself for not applying myself to self-teaching. But whatever thats not important. I need some help and any help is more than welcome. Thanks ( :
Re: URGENT Help with collision detection and movem
Reply #9 - Dec 9th, 2008, 10:55pm
 
i found the following code for a billards game and now im working on deciphering it so i can extract the collision detection and add it to my bumper balls game...this is gonna be a long night (:


/**
* Welcome to Skanaar microBilliard<br><br>
*
* Click, drag and release on a ball to give it a push.<br>
* numerical keys 1-4 respawns different number of balls
**/

Table game;
//--------------
void setup(){
 size(210,330);
 smooth();
 game = new Table(6,5,200,300);
 game.startGame();
}
//--------------
void draw(){
 background(32);
 game.update();
 game.visualize();
}
//--------------
void keyPressed(){
 println( game.kineticEnergy() );
}
//--------------
void mousePressed(){
 game.mousePressed(mouseX-game.x,mouseY-game.y);
}
//--------------
void mouseReleased(){
 game.mouseReleased(mouseX-game.x,mouseY-game.y);
}
//=============================
class Table{
 float drag = 0.985;
 float elasticity = 0.9;
 float wallElasticity = 0.8;
 float pushFactor = 0.05;
 float maxPush = 10;
 color[] ballColors = new color[]{color(192),color(192,64,32),color(64,192,0)};
 Ball[] balls;
 Ball selectedBall;
 int x,y,width,height;
 //--------------
 Table(int x, int y, int w, int h){
   this.x = x;
   this.y = y;
   width = w;
   height = h;
 }
 //--------------
 void startGame(){
   buildBalls(8);
 }
 //--------------
 void buildBalls(int count){
   balls = new Ball[2*count+1];
   for(int i=0;i<count;i++)
     balls[i] = new Ball( random(width), random(height),1, this);
   for(int i=0;i<count;i++)
     balls[count+i] = new Ball( random(width), random(height),2, this);
   balls[2*count] = new Ball( 0.5*(width), 0.5*(height),0, this);
 }
 //--------------
 void update(){
   //simulation
   for(int i=0;i<balls.length;i++)
     balls[i].update();

   //collision detection
   for(int i=0;i<balls.length;i++)
     for(int j=i+1;j<balls.length;j++)
       balls[i].collisionDetect(balls[j]);
 }
 //--------------
 void visualize(){
 
   translate(x,y);
   noStroke();
   fill(0,128,0);
   rect(0,0,width,height);

   //draw que
   stroke(255);
   if(mousePressed && selectedBall != null)
     line(selectedBall.x,selectedBall.y,mouseX-x,mouseY-y);

   //drawing
   for(int i=0;i<balls.length;i++)
     balls[i].visualize();
 }
 //--------------
 float kineticEnergy(){
   float energy=0;
   for(int i=0;i<balls.length;i++)
     energy += mag( balls[i].vx, balls[i].vy );
   return energy;
 }
 //--------------
 void mousePressed(int mx, int my){
   for(int i=0;i<balls.length;i++)
     if( dist(balls[i].x,balls[i].y,mx,my) < balls[i].radius) {
       selectedBall = balls[i];
       break;
     }
 }
 //--------------
 void mouseReleased(int mx, int my){
   if(selectedBall != null){
     float px = (selectedBall.x-mx) * pushFactor;
     float py = (selectedBall.y-my) * pushFactor;
     float push = mag(px,py);
     if( push > maxPush ){
       px = maxPush*px/push;
       py = maxPush*py/push;
     }
     selectedBall.push(px,py);
   }
   selectedBall = null;
 }
}
Re: URGENT Help with collision detection and movem
Reply #10 - Dec 10th, 2008, 12:11am
 
Intermediary: class version of the first code (only bound collision)
Code:
Ball ball1, ball2;

void setup()
{
size(600, 400);
smooth();
noStroke();

ball1 = new Ball(20, 50, -5, 8, 23, #002277);
ball2 = new Ball(120, 150, 7, -3, 31, #007722);
}

void draw()
{
background(#AAFFEE);
ball1.Move();
ball2.Move();
ball1.Display();
ball2.Display();
}

class Ball
{
float posX, posY; // Position
float speedX, speedY; // Movement (linear)
float radius;
color ballColor;

Ball(float px, float py, float sX, float sY, float r, color c)
{
posX = px; posY = py;
speedX = sX; speedY = sY;
radius = r; ballColor = c;
}

void Move()
{
posX += speedX;
if (posX < radius || posX > width - radius)
{
speedX = -speedX;
posX += speedX;
}
posY += speedY;
if (posY < radius || posY > height - radius)
{
speedY = -speedY;
posY += speedY;
}
}

void Display()
{
fill(ballColor);
ellipse(posX, posY, radius * 2, radius * 2);
}
}
Re: URGENT Help with collision detection and movem
Reply #11 - Dec 10th, 2008, 12:42am
 
i don't have a lot of time right now to look at this (i'm at work :-D) but i think the PVector class will be really useful to you.

http://processing.org/reference/PVector.html

i agree with Philho that Object Oriented is the way to go.

i think your Ball class should have one PVector for position, one PVector for velocity and one PVector for acceleration. i hope this helps.
Re: URGENT Help with collision detection and movem
Reply #12 - Dec 10th, 2008, 1:43am
 
OK i lied. i did have time to play with this.  here the balls move like in Asteroids (i think). arrow keys for red ball. w,a,s,d for blue. try controlling both at once, it takes quite a lot of coordination! there's a game right there. oh and i made the screen wrap instead of bounce.

anyway, you can see i used PVector for position and velocity.  on second thought you'll only need a vector for acceleration if you want to control the acceleration itself rather than just accelerating once on a button press.

here's the code!:

Code:

Ball ball_1, ball_2;

void setup()
{
 size(400,400);
 smooth();
 ball_1 = new Ball(color(255,0,0),50,100, random(-5,5), random(-5,5), 20);
 ball_2 = new Ball(color(0,0,255),200,200,random(-5,5), random(-5,5), 15);
}

void draw()
{
 background(0);
 smooth();
 ball_1.update();
 ball_2.update();
 ball_1.drawBall();
 ball_2.drawBall();
}

class Ball
{
 private color ball_color;
 private PVector position, velocity;
 private int radius;

 Ball(color ball_color_, float x, float y, float x_v, float y_v, int radius_){
   position = new PVector(x,y);
   velocity = new PVector(x_v,y_v);
   ball_color = ball_color_;
   radius = radius_;
 }

 void update(){
   position.add(velocity);
   if(position.x < 0)
     position.x = width;
   if(position.x > width)
     position.x = 0;
   if (position.y < 0)
     position.y = height;
   if(position.y > height)
     position.y = 0;
 }

 void up() {
   velocity.y -= .5;
 }

 void down() {
   velocity.y += .5;
 }

 void left() {
   velocity.x -= .5;
 }

 void right() {
   velocity.x += .5;
 }

 void drawBall() {
   fill(ball_color);
   ellipse(position.x, position.y, radius, radius);
 }
}

void keyPressed() {
 switch (key) {
 case CODED:
   switch (keyCode) {
   case UP:
     ball_1.up();
     break;
   case DOWN:
     ball_1.down();
     break;
   case LEFT:
     ball_1.left();
     break;
   case RIGHT:
     ball_1.right();
     break;
   }
   break;
 case 'w':
   ball_2.up();
   break;
 case 's':
   ball_2.down();
   break;
 case 'a':
   ball_2.left();
   break;
 case 'd':
   ball_2.right();
   break;
 }
}
Re: URGENT Help with collision detection and movem
Reply #13 - Dec 10th, 2008, 6:02am
 
when i tried to run it to see how it works i get an error

Cannot find class or type named "PVector"

it was at the "private PVector position, velocity" line in the code under the class "Ball"
Re: URGENT Help with collision detection and movem
Reply #14 - Dec 10th, 2008, 6:13am
 
upgrade to 1.0
Pages: 1 2