Why won't my grenades explode?

So... I'm making a game. I made a grenade handler object to keep track of grenades. Its supposed to blow up after a certain time after being "launched". But all it does is go in circles (And I know why that is happening I wanted to to move in a curve, as if it was being thrown. I've never used <time.h> before. Code:

.h:
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
#include <allegro5/allegro.h>
#include <allegro5/allegro_image.h>
#include "collarea.h"
#include "explosionhandler.h"
#include <vector>
#ifndef GRENADE_H
#define GRENADE_H
#define PI 3.14159265
class ALLEGRO_BITMAP;
class collarea;
class explosionhandler;
using std::vector;
class grenadehandler
{
public:
	grenadehandler(float w,float h,float s);
	~grenadehandler();
	
	void setlimit(int l,int fuse);

	void setgrenade(ALLEGRO_BITMAP*& a, ALLEGRO_BITMAP*& b, explosionhandler*& h);
	void launch(float x, float y, float angle);
	void bounce();
	void checkhit(collarea other);
	void move(collarea other);
	void draw(ALLEGRO_BITMAP* screen);
	float drf(float& i);

private:
	ALLEGRO_BITMAP* gre;
	explosionhandler *h;
	struct grenade {
		float x,y,dx,dy;
		float theta;
		float dtheta;
		int bounce;
		unsigned long blowup;
		int seq;
	};
	vector<struct grenade> grenades;
	float width,height;
	float speed;
	collarea area;
	int exptype;
	float incline;
	float decline;
	int limit;
	int fired;
	unsigned long delay;
	float picw,pich;
};
#endif 


.cpp:
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
//http://www.cplusplus.com/forum/beginner/317/
#include "grenadehandler.h"
#include <math.h>
#include <time.h>
grenadehandler::grenadehandler(float w,float h,float s)
{
	exptype=-1;
	width=w;
	height=h;
	speed=s;
	limit=0;
	fired=0;
	delay=5*CLOCKS_PER_SEC;
	incline=PI/4;
	decline=PI/32;
}
grenadehandler::~grenadehandler()
{
	free(h);
}
void grenadehandler::setgrenade(ALLEGRO_BITMAP*& a, ALLEGRO_BITMAP*& b, explosionhandler*& handler)
{
	gre = a;
	picw = al_get_bitmap_width(a);
	pich = al_get_bitmap_height(a);
	area.sethitboundaries(a);
	h = handler;
	h->registerexplosion(exptype,b,5,30,15,3);
}
void grenadehandler::launch(float x, float y, float angle)
{
	if(fired<limit)
	{
		fired++;
		grenade n;
		n.x=x;
		n.y=y;
		if(angle<(PI/2))
		{
			n.theta = angle+incline;
			n.dtheta = -decline;
		}
		else if(angle<PI)
		{
			n.theta = angle-incline;
			n.dtheta = decline;
		}
		else if(angle<(3*PI/2))
		{
			n.theta=angle-incline;
			n.dtheta=decline;
		}
		else {
			n.theta=angle+incline;
			n.dtheta=-decline;
		}
		if(n.theta>(2*PI))
		{
			n.theta-=2*PI;
		}
		else if(n.theta<0)
		{
			n.theta+=2*PI;
		}
		n.dx= speed*cos(n.theta);
		n.dy= speed*sin(n.theta);
		n.bounce=0;
		n.blowup=delay+clock();
		n.seq=0;
		grenades.push_back(n);
	}
}
void grenadehandler::bounce()
{
	int k = grenades.size();
	{
		for(int i=0;i<k;i++)
		{
			grenade g = grenades[0];
			grenades.erase(grenades.begin());
			if((g.x<picw)||(g.x>(width-picw))||(g.y<pich)||(g.y>(height-pich)))
			{
				g.bounce=1;
				g.dx=-g.dx;
				g.dy=-g.dy;
			}
			grenades.push_back(g);
		}
	}
}
void grenadehandler::checkhit(collarea other)
{
	int k = grenades.size();
	{
		for(int i=0;i<k;i++)
		{
			grenade g = grenades[0];
			grenades.erase(grenades.begin());
			area.setarea(drf(g.x),drf(g.y),0);
			if(area.didhit(other))
			{
				g.bounce=1;
				g.dx=-g.dx;
				g.dy=-g.dy;
			}
			grenades.push_back(g);
		}
	}
}
float grenadehandler::drf(float& i)
{
	return i;
}
void grenadehandler::move(collarea other)
{
	checkhit(other);
	bounce();
	int k = grenades.size();
	{
		for(int i=0;i<k;i++)
		{
			grenade g = grenades[0];
			grenades.erase(grenades.begin());
			if(clock()<g.blowup)
			{
				if(!g.bounce)
				{
					g.theta+=g.dtheta;
					g.dx = speed * cos(g.theta);
					g.dy = speed * sin(g.theta);
				}
				g.x+=g.dx;
				g.y+=g.dy;
				grenades.push_back(g);
			}
			else if(!g.seq)
			{
				h->createexplosion(exptype,g.x,g.y);
				g.seq++;
			}
			//grenades.push_back(g);
		}
	}
}
void grenadehandler::draw(ALLEGRO_BITMAP* screen)
{
	float x,y,theta;
	int k = grenades.size();
	{
		for(int i=0;i<k;i++)
		{
			if(!grenades.at(i).seq)
			{
				x = grenades.at(i).x;
				y = grenades.at(i).y;
				theta = grenades.at(i).theta;
				al_draw_rotated_bitmap(gre,picw/2,pich/2,x,y,theta,0);
			}
		}
	}
}
void grenadehandler::setlimit(int l,int fuse)
{
	limit=l;
	fired=0;
	if(fuse>0)
	{
		delay = (unsigned long)(fuse) * CLOCKS_PER_SEC;
	}
}
line 124 looks wrong.

clock() returns the # of clock ticks since the program was launched. To have a meaningful comparison u should store the value returned by clock() when the grenade is created and then compare the difference against new calls to clock(). When that difference is sufficiently large - BOOM !
Last edited on
OK so here is the revised 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
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
//http://www.cplusplus.com/forum/beginner/317/
#include "grenadehandler.h"
#include <math.h>
#include <time.h>
grenadehandler::grenadehandler(float w,float h,float s)
{
	exptype=-1;
	width=w;
	height=h;
	speed=s;
	limit=0;
	fired=0;
	delay=5*CLOCKS_PER_SEC;
	incline=PI/4;
	decline=PI/32;
}
grenadehandler::~grenadehandler()
{
	free(h);
}
void grenadehandler::setgrenade(ALLEGRO_BITMAP*& a, ALLEGRO_BITMAP*& b, explosionhandler*& handler)
{
	gre = a;
	picw = al_get_bitmap_width(a);
	pich = al_get_bitmap_height(a);
	area.sethitboundaries(a);
	h = handler;
	h->registerexplosion(exptype,b,5,30,15,3);
}
void grenadehandler::launch(float x, float y, float angle)
{
	if(fired<limit)
	{
		fired++;
		grenade n;
		n.x=x;
		n.y=y;
		if(angle<(PI/2))
		{
			n.theta = angle+incline;
			n.dtheta = -decline;
		}
		else if(angle<PI)
		{
			n.theta = angle-incline;
			n.dtheta = decline;
		}
		else if(angle<(3*PI/2))
		{
			n.theta=angle-incline;
			n.dtheta=decline;
		}
		else {
			n.theta=angle+incline;
			n.dtheta=-decline;
		}
		if(n.theta>(2*PI))
		{
			n.theta-=2*PI;
		}
		else if(n.theta<0)
		{
			n.theta+=2*PI;
		}
		n.dx= speed*cos(n.theta);
		n.dy= speed*sin(n.theta);
		n.bounce=0;
		n.starttime=clock();
		n.seq=0;
		grenades.push_back(n);
	}
}
void grenadehandler::bounce()
{
	int k = grenades.size();
	{
		for(int i=0;i<k;i++)
		{
			grenade g = grenades[0];
			grenades.erase(grenades.begin());
			if((g.x<picw)||(g.x>(width-picw))||(g.y<pich)||(g.y>(height-pich)))
			{
				g.bounce=1;
				g.dx=-g.dx;
				g.dy=-g.dy;
			}
			grenades.push_back(g);
		}
	}
}
void grenadehandler::checkhit(collarea other)
{
	int k = grenades.size();
	{
		for(int i=0;i<k;i++)
		{
			grenade g = grenades[0];
			grenades.erase(grenades.begin());
			area.setarea(drf(g.x),drf(g.y),0);
			if(area.didhit(other))
			{
				g.bounce=1;
				g.dx=-g.dx;
				g.dy=-g.dy;
			}
			grenades.push_back(g);
		}
	}
}
float grenadehandler::drf(float& i)
{
	return i;
}
void grenadehandler::move(collarea other)
{
	checkhit(other);
	bounce();
	int k = grenades.size();
	{
		for(int i=0;i<k;i++)
		{
			grenade g = grenades[0];
			grenades.erase(grenades.begin());
			fprintf(stdout,"clock: %lu, starttime: %lu, delay: %lu\n",(unsigned long)clock(),g.starttime,delay);
			if((clock()-g.starttime)<delay)
			{
				if(!g.bounce)
				{
					g.theta+=g.dtheta;
					g.dx = speed * cos(g.theta);
					g.dy = speed * sin(g.theta);
				}
				g.x+=g.dx;
				g.y+=g.dy;
				grenades.push_back(g);
			}
			else if(!g.seq)
			{
				h->createexplosion(exptype,g.x,g.y);
				//g.seq++;
			}
			//grenades.push_back(g);
		}
	}
}
void grenadehandler::draw(ALLEGRO_BITMAP* screen)
{
	float x,y,theta;
	int k = grenades.size();
	{
		for(int i=0;i<k;i++)
		{
			if(!grenades.at(i).seq)
			{
				x = grenades.at(i).x;
				y = grenades.at(i).y;
				theta = grenades.at(i).theta;
				al_draw_rotated_bitmap(gre,picw/2,pich/2,x,y,theta,0);
			}
		}
	}
}
void grenadehandler::setlimit(int l,int fuse)
{
	limit=l;
	fired=0;
	if(fuse>0)
	{
		delay = (unsigned long)(fuse) * CLOCKS_PER_SEC;
	}
}


here is an excerpt from terminal:
1
2
3
4
clock: 673403, starttime: 255396, delay: 3000000
clock: 673428, starttime: 278061, delay: 3000000
clock: 673435, starttime: 341965, delay: 3000000
clock: 673446, starttime: 346448, delay: 3000000

(4 grenades)
so yeah there is something bigger going on here. I think it has to do with the unsigned long data type. I've never used long until today. Let alone anything "unsigned"
you know what I answered my own question:

(673446-346448)<3000000

hurr durr.

Thanks soranz
Last edited on
:D
this looks really interesting. are you planning on making this open source?
Of course. Right now its a really simple, kinda boring game. Needs a lot of work. I myself am a beginner and I would be honored if other newbies learned from my work.
Topic archived. No new replies allowed.