deleting an object?

Hi guys,
I'm wondering how i would go about deleting an object when it collides with something,i.e a wall, target etc.
ive done the collision detection inside the class where i set up everything for making the projectile(ball) but cannot do a pointer too that object in the class it is created in but cant delete it in my main when it hits the wall because all of my collsion testing is in the class ive created, am i right in believing the only way too delete an object is by having a pointer too it? kinda confused at the moment, any help appreciated guys. Let me know if youd prefer too see code.
Ryan
Some code would be nice, you might be messing things up ... if you're using OpenGL (?) if you try to delete an object in your main loop in an "unprotected" way you may end up with a crash when going the next time through that loop (using the object just deleted, delete the object again, etc)...
Circle *c = new Circle();
...
loop{
if(detected_collision(c))
{
c->hide(); //so that it won't remain "stuck" in the "picture"
delete c;
}
}

bool detected_collision(Circle *c)
{
if(c != NULL)
do whatever you want with c
...
}

no problem, ill post my class header, my class and my main oh and yeah completely forgot too mention i am using OpenGL lol

header:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <cmath>


class Ball{
public:
	Ball(float ix, float iy, float irad, float icol[]);
    void Show();
	void update();
	void fire(float dx, float dy);
	void KeyboardUpdate(int UserPow);
	void bColDet(float &xBall, float &yBall);
	//float getRight(float rB);
private:
	float x, y, rad, v;
	bool fired;
	float dx, dy;
	float col[3];
	bool stopped;
};


class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include "Projectile.h"
#include <glut.h>
float YV = 0;
float XV = 0;
float USERPOW = 0;

float GRAV = -0.1;
bool wallColX = false;
bool wallColY = false;


Ball::Ball( float ix, float iy, float irad, float icol[])
{
	fired = false;
	x = ix;
	y = iy;
	rad = irad;
	//This is where hor movement
	dy = 0;
	dx = 0;
	for(int i = 0; i<3; i++)
		col[i]=icol[i];

}

void Ball::fire(float dx, float dy){
	fired = true;
	this->dx = dx;
	this->dy = dy;
}

void Ball::Show(){

	glColor4fv(col);
	 
 //glColor3f(1, 1, 0);
	glPointSize(20.0); 
	const int NPOINTS=60; 
	const float TWOPI=2*3.14159268; 
	const float STEP=TWOPI/NPOINTS; 
		glBegin(GL_POLYGON);
			
		for(float angle=0; angle<TWOPI; angle+=STEP) 
				glVertex2f(rad * cos(angle)+x+dx, rad* sin(angle)+y+dy); 

			
			glEnd(); 
}

	
void Ball::KeyboardUpdate(int UserPow){
	USERPOW = UserPow;
	}

void Ball::update(){
	if(fired){
		
		x += dx;
		y += dy;
		dy += GRAV;
		
		if(x+rad >= 1200 || x-rad <= 0 ){ //Right and Left side collision
			dx = -dx*0.9;}
     	if(y-rad <= 140 || y+rad >=590){ //Top and Bottom collision
		dy = -dy*0.83;}
		
		
		if(y-rad <280){  
		 wallColY = true;
		}else wallColY = false;

		if (x+rad > 650 &&  x-rad < 700){
		 wallColX = true;
		}	else wallColX = false;

		if(wallColY == true && wallColX == true){
		 dx = -dx*0.9;
		}
	}

}
void Ball::bColDet(float &xBall, float &yBall){
	xBall = x;
	yBall = y;
}


Main(well bits that include the ball)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Ball *ball;

void initObject()
{
	int irad = 8;
	int ix = 20;
	int iy = 150;
	float col[3];
	col[0]=0;
	col[1]=1;
	col[2]=0;
	cannonPower = 2;
	angle = 0;
	ball = new Ball(ix, iy, irad, col);
	
}	
void display()

{
	 ball -> Show();
}

void update()
{
	float distBetweenObjects;
	float xDist;
	float yDist;
	target->tUpdate();
	target ->tColDet(xTarget, yTarget);
	ball ->update();
	ball->bColDet(xBall, yBall);
	//distance between objects
	
	xDist = xBall - xTarget;
	yDist = yBall - yTarget;
	distBetweenObjects = sqrt(pow(xDist, 2) + pow(yDist, 2));
	if( distBetweenObjects <= 40 ){
	cout << "lolololololol";
	
	}

}

int main(int argc, char** argv)
{
	width=1200;
	height=600;
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
	glutInitWindowSize(width, height);
	glutInitWindowPosition(100, 100);
	glutCreateWindow (argv[0]);
	glClearColor(1.0, 0.0, 1.0, 1.0);
	gluOrtho2D(0, width, 0, height);
	
	glutSpecialFunc(special_keys);
	glutKeyboardFunc(keyboard);
	glutDisplayFunc(display);
	glutTimerFunc(20, timer, 0);
	initWall();
	initTargObject();
	bitmapInit();
	initObject();
	glutMainLoop();
	delete background;
	return 0;
}


Sorry i know theres alot of unexplained junk in main.
again, thanks
Ryan
You have function update() but you never call it in main ... (??????)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
void update()
{
	float distBetweenObjects;
	float xDist;
	float yDist;
	target->tUpdate();
	target ->tColDet(xTarget, yTarget);

//!!!
if(ball != NULL)
{
	ball ->update();
	ball->bColDet(xBall, yBall);
	//distance between objects
	
	xDist = xBall - xTarget;
	yDist = yBall - yTarget;
	distBetweenObjects = sqrt(pow(xDist, 2) + pow(yDist, 2));
	if( distBetweenObjects <= 40 )
	{
//hide ball ? or it does it automatically
		delete ball;	
	}
}
}

Last edited on
Ah sorry its becuase there was too much code just to copy everything, ive got a timer function that i call update inside and then i call the timer function in main.

That worked for destroying it when it hits the target thanks alot! But i would also like too get it too delete when it hits the wall(its meant to be like a cannonball type thing for a game).

Cheers,
Ryan
Yes, what you're doing is you create one single "bullet"/ball and when you destroy it, that's it.

A really fancy idea would be if you're shooting one ball and wait for it to get destroyed before shooting another one, to re-use that ball ... so in the update() code you don't need if(ball != null) and also reset ball's coords
1
2
3
4
5
6
7
8
9
10
if( distBetweenObjects <= 40 )
	{
//hide ball

//this is illegal, do a function inside Ball which does that and call it here
//ball.x = 0
//bal.y = 0

//increase score if hit target
	}


Else, if you want multiple balls at the same time, you may want to work with a list (from STL) (Efficient insertion and removal of elements anywhere in the container (constant time))

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <list>

//Ball *ball;
list<Ball*> balls;

void initObject()
{
//nothing about ball
}

void display()
{
//to show all balls
for (list<Ball*>::iterator it = balls.begin(); it != balls.end(); it++)
    it->Show();
}


whenever you want to fire a new ball just write the .push_back line, no need to add this function:
1
2
3
4
void fire_a_new_ball()
{
list.push_back(new Ball(...coords...);
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void update()
{
	float distBetweenObjects;
	float xDist;
	float yDist;
	target->tUpdate();
	target ->tColDet(xTarget, yTarget);

//update each ball
for (list<Ball*>::iterator it = balls.begin(); it != balls.end(); it++)
{
	it->update();
	it->bColDet(xBall, yBall);
	//distance between objects
	
	xDist = xBall - xTarget;
	yDist = yBall - yTarget;
	distBetweenObjects = sqrt(pow(xDist, 2) + pow(yDist, 2));
	if( distBetweenObjects <= 40 )
{
	delete *it; //delete the actual Ball object (calls destructor, etc)
	it = balls.erase(it);//remove object from list and advance to the next //object in list (hope this works)
}

}//end for
}
Last edited on
what is "hide"? like in:
hide ball;

Ive never heard of this before and when i type it in its not a function ?
what is "hide"? like in:
hide ball;

I think it's just pseudo code.
That line should have been commented, what i call hide is the opposite of Show() :)
I forgot how this works, but i think when you put the object to 0,0,0 for example, move it +10, +10, +10 , and then you see you don't need it there anymore, so just destroy it, you have to wait for the update ... and yes if the object isn't present anymore it won't show it anymore on screen .. so i guess you don't need a hide() function, it's done automatically by the refreshing system.

see the code above, i modified it just a bit ... it's delete *it; not delete it; you delete the value of the iterator not the iterator.
That's what i said there. You need a hide mechanism for the first case and don't need one for the second.
If you want to re-use the object then just moving it to 0,0 isn't enough because it will get drawn on the screen at 0,0 and that's not what you want. So you'll also need a bool value to tell you when to show it and when not. So again, this is only for the case you shoot a ball and wait for it to get destroyed and just then shoot another one. Else, for multiple balls use the second case code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
bool okToShow = false;

//when you fire a bullet put this line with ok to true
void fire_bullet()
{
okToShow = true;
}

void display()
{
if(okToShow)
	 ball -> Show();
}

void update()
{
	float distBetweenObjects;
	float xDist;
	float yDist;
	target->tUpdate();
	target ->tColDet(xTarget, yTarget);

//optimisation
if(okToShow)
{
	ball ->update();
	ball->bColDet(xBall, yBall);
	//distance between objects
	
	xDist = xBall - xTarget;
	yDist = yBall - yTarget;
	distBetweenObjects = sqrt(pow(xDist, 2) + pow(yDist, 2));
	if( distBetweenObjects <= 40 )
	{
//this should do the trick and don't redraw the ball on the next loop
okToShow = false;

//
//ball.x = 0;
//ball.y = 0;
//
//instead of this (because they are private) create a function in Ball, called Reset(), in which you put the //coords to 0, so just reset the object.
ball.Reset();
	}
}
}
Last edited on
Topic archived. No new replies allowed.