trying to make bouncing balls collide and change direction

hi ive succeeded in making an array of balls that bounce off the edges of the screen.

however im not being able to make the balls bounce off each other.

what ive tried to do(with little success) is to create a method called ‘collide’ within the class ofBall. in the ‘collide’ method ive defined a pointer called inBall.

within the ‘collide’ method in the cpp file im trying to use ofDist to tell the program that if the distance between inBall posX, posY and the larger ofBall posX, posY is less than twice the radius it should do something, like so…

  
  
  
void ofBall::collide(ofBall* inBall){  
	  
	if (ofDist(inBall.posX, inBall.posY, posX, posY) < radius*2) {  
		ofDrawBitmapString("crash", 150,150);  
  
	}  
		  
	  
}  
  
  

im just trying to make it say “crash” now, but i want the balls to bounce off each other. i havent even got to that part yet!

is my logic wrong or is it just my syntax? when i run this, the error i get is :

error: request for member ‘posX’ in ‘inBall’, which is of non-class type ‘ofBall*’
error: request for member ‘posY’ in ‘inBall’, which is of non-class type ‘ofBall*’
error: ‘self’ was not declared in this scope

by saying inBall.posX am i not calling the X position of inBall?

Hello virajcircar,

I think that when you use a pointer to an object you have call that class variables and function using “->” insted of “.”
Try using:

  
if (ofDist(inBall->posX, inBall->posY, posX, posY) < radius*2)  

Have a happy new year

hey thanks very much!

its compiling fine now. no errors.

and a very happy new year to you too!

now that you can check if the balls are colliding, you simply need to change their directions: inside your if block you can do something like:

  
  
...  
speedX*=-1; //change X direction  
speedY*=-1; //change Y direction  
...  
  

this way the balls will bounce in the exact opposite direction; checking the corresponding positions of the 2 colliding balls you should be able to fine tune the direction change a little more and make it look more natural.

thanks naus3a. makes sense.

really appreciate it.

okay…sorry its me again.

i think i know what im doing wrong…im not being able to activate the collide method.

no errors, but he balls arent colliding either…

how do i activate the collide method?

heres the code for the .h file

  
  
#ifndef _OF_BALL  
#define _OF_BALL  
  
  
#include "ofMain.h"  
  
class ofBall{  
	  
public:  
	  
	//methods  
	void setup();  
	void update();  
	void draw();  
	  
	//constructor  
	  
	ofBall(int posX, int posY, int radius );  
	  
	//variables  
	  
	int speedX;  
	int speedY;  
	int posX;  
	int posY;  
	int radius;  
	  
	  
	  
	void collide(ofBall* inBall);  
};  
  
#endif  
   

and heres the .cpp file

  
  
  
#include "ofBall.h"  
  
  
//--------------------------------------------------------------  
ofBall::ofBall(int _posX , int _posY , int _radius ){  
	  
		  
	posX = _posX;  
	posY = _posY;  
	radius = _radius;  
	  
	  
  
  
	  
	speedX = ofRandom(1, 5);  
	speedY = ofRandom(1, 5);  
	  
  
	}  
  
     
	  
	  
  
//--------------------------------------------------------------  
void ofBall::update(){  
	  
	posX = posX + speedX;  
	posY = posY + speedY;  
	  
	////////////////////////////////////  
	  
	if (posY > ofGetHeight()-radius) {  
		posY = ofGetHeight()-radius;  
		speedY = speedY * -1;  
		  
		  
		  
	}  
	  
	  
	  
	////////////////////////////////  
	  
	  
	if (posX > ofGetWidth()-radius) {  
		posX = ofGetWidth()-radius;  
		speedX = speedX * -1;  
		  
		  
	}  
	  
	  
	///////////////////////////////////  
	  
	if (posY < radius) {  
		posY = radius;  
		speedY = speedY * -1;  
		  
	}  
	  
	  
	  
	////////////////////////////////////  
	  
	if (posX < radius) {  
		posX = radius;  
		speedX = speedX * -1;  
		  
		  
	}  
	  
	  
	///////////////////////////////////  
	  
	string str = "Ball X,Y positions are X ";  
	str += ofToString(posX, 0) + " and Y ";   
	str += ofToString(posY, 0);   
	str += " Screen width is ";  
	str += ofToString(ofGetWidth(), 0) + " and height is ";  
	str += ofToString(ofGetHeight(), 0) + ".";  
	  
	ofSetWindowTitle(str);  
	  
	///////////////////////////////////  
  
// how do i call the collide method here in the update method?  
	  
		  
}  
  
//--------------------------------------------------------------  
void ofBall::draw(){  
	  
	  
	  
	ofFill();  
	ofSetColor(0, 255, 0);  
	ofCircle(posX, posY , radius);  
	  
	ofSetColor(0, 255, 255);  
	ofDrawBitmapString("my first of app", 100,100);  
	  
	  
		  
}  
  
//--------------------------------------------------------------------------------------------  
  
void ofBall::collide(ofBall* inBall){  
	  
	if (ofDist(inBall->posX, inBall->posY, posX, posY) < radius*2) {  
		ofDrawBitmapString("crash", 150,150);  
		speedX*=-1; //change X direction  
		speedY*=-1; //change Y direction  
		  
	}  
	  
	  
	}  
  
   

Virajcircar:

Here is a similar code you are trying to do but writed on Processing. I sugest to take a look. In order to see how it works, specially the collide function and how it is used.

http://openprocessing.org/visuals/?visualID=9702

I have a similar issue. I can get the balls to bouce off the walls and each other but when one of the balls hits the corner of the screen the program will crash. It only happens in the upper right hand corner. I know there is a problem somewhere but I for whatever reason cannot see it. Any Suggestions?

Thanks!

Nathan

its working fine!

achieved what i set out to do. many thanks patriciogonzalezvivo. really appreciate it.

hey nathan, im appending the enitire code below for all my files. that should help you. feel free to revert if youre not understanding what ive done anywhere.

heres the ofBall.h file.

  
  
  
  
#ifndef _OF_BALL  
#define _OF_BALL  
  
  
#include "ofMain.h"  
  
class ofBall{  
	  
public:  
	  
	//methods  
	void setup();  
	void update();  
	void draw();  
	  
	//constructor  
	  
	ofBall(int posX, int posY, int radius );  
	  
	//variables  
	  
	int speedX;  
	int speedY;  
	int posX;  
	int posY;  
	int radius;  
	  
	  
	  
	void collide(ofBall* inBall);  
};  
  
#endif  
  
  
   

heres the ofBall.cpp

  
  
  
#include "ofBall.h"  
  
  
//--------------------------------------------------------------  
ofBall::ofBall(int _posX , int _posY , int _radius ){  
	  
		  
	posX = _posX;  
	posY = _posY;  
	radius = _radius;  
	  
	  
  
  
	  
	speedX = ofRandom(1, 5);  
	speedY = ofRandom(1, 5);  
	  
  
	}  
  
     
	  
	  
  
//--------------------------------------------------------------  
void ofBall::update(){  
	  
	posX = posX + speedX;  
	posY = posY + speedY;  
	  
	////////////////////////////////////  
	  
	if (posY > ofGetHeight()-radius) {  
		posY = ofGetHeight()-radius;  
		speedY = speedY * -1;  
		  
		  
		  
	}  
	  
	  
	  
	////////////////////////////////  
	  
	  
	if (posX > ofGetWidth()-radius) {  
		posX = ofGetWidth()-radius;  
		speedX = speedX * -1;  
		  
		  
	}  
	  
	  
	///////////////////////////////////  
	  
	if (posY < radius) {  
		posY = radius;  
		speedY = speedY * -1;  
		  
	}  
	  
	  
	  
	////////////////////////////////////  
	  
	if (posX < radius) {  
		posX = radius;  
		speedX = speedX * -1;  
		  
		  
	}  
	  
	  
	///////////////////////////////////  
	  
	string str = "Ball X,Y positions are X ";  
	str += ofToString(posX, 0) + " and Y ";   
	str += ofToString(posY, 0);   
	str += " Screen width is ";  
	str += ofToString(ofGetWidth(), 0) + " and height is ";  
	str += ofToString(ofGetHeight(), 0) + ".";  
	  
	ofSetWindowTitle(str);  
	  
	///////////////////////////////////  
	  
		  
}  
  
//--------------------------------------------------------------  
void ofBall::draw(){  
	  
	  
	  
	ofFill();  
	ofSetColor(0, 255, 0);  
	ofCircle(posX, posY , radius);  
	  
	ofSetColor(0, 255, 255);  
	ofDrawBitmapString("my first of app", 100,100);  
	  
	  
		  
}  
  
//--------------------------------------------------------------------------------------------  
  
void ofBall::collide(ofBall* inBall){  
	  
	if (ofDist(inBall->posX, inBall->posY, posX, posY) < radius*2) {  
		ofDrawBitmapString("crash", 150,150);  
		speedX*=-1; //change X direction  
		speedY*=-1; //change Y direction  
		  
	}  
	  
	  
	}  
  
  
  
  
   

heres my testApp.h

  
   
#ifndef _TEST_APP  
#define _TEST_APP  
  
  
#include "ofMain.h"  
#include "ofBall.h"  
  
  
  
  
  
class testApp : public ofBaseApp{  
  
	public:  
	  
	//methods  
		void setup();  
		void update();  
		void draw();  
	  
  
	  
	//declaring the object  
	  
	ofBall **myBall;// creating an array of pointers  
	int nBalls;  
	  
		  
  
};  
  
#endif  
  
  
  

and heres my testApp.cpp

  
  
  
#include "testApp.h"  
  
//--------------------------------------------------------------  
void testApp::setup(){  
	  
	ofBackground(0, 0, 0);  
	//ofSetFrameRate(60);  
	ofSetVerticalSync(true); //sets fps to your monitor refresh rate. makes animation smoother.   
	//ofSetWindowTitle("simple bouncing ball");  
	  
	  
	  
	nBalls = 10; // the number of ball objects we want to create  
	  
	myBall = new ofBall*[nBalls];   // an array of pointers for the objects  
	  
	  
	for (int i = 0; i < nBalls; i++){ //assigning values to posX and posY and radius  
		int posX = ofRandom(0, 1024);  
		int posY = ofRandom(0, 768);  
		  
  
		int radius = 10;  
		  
		myBall[i] = new ofBall(posX,posY,radius);  //create each object from the array  
		  
	}  
		  
	}  
	  
	  
//--------------------------------------------------------------  
void testApp::update(){  
	  
	for (int i=0; i < nBalls; i++) {  
		  
		myBall[i]->update();  
		  
		for (int j=0; j < nBalls; j++){  
		  if (i != j) {  
			  myBall[i] -> collide(myBall[j]);  
		  }  
		  
		}  
		  
	  
	    	  
	}  
	  
	  
	   
	}  
  
//--------------------------------------------------------------  
void testApp::draw(){  
	  
	for (int i=0; i < nBalls; i++) {  
  
	myBall[i]->draw();  
	  
			  
	}  
  
	  
	  
	}  
  
  
  
  
  

that bit in the testApp update where im calling the collide method i created in the ofBall.cpp is where i was getting stuck.

good luck man.:slight_smile:

cheers.

and any idea how to report/get rid of spammers like gasybow in this thread?