If statement never executes???

I am making a game using Allegro game programming library. Basically its the same one that I asked help with a year ago. I gave up and came back to it this summer, updated to A5, and its nearly complete. Just a few bugs to work out. Like this one:

I have 2 objects: tank and bulletholder bulletholder managed a linked list of the bullets fired by its respective tank:

running through the game loop, (Its event oriented) it goes something like this:
in main:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if(event.type == KEY_PRESS_UP)
{
    tank1.shoot();
}
...
in draw():
if(tank1.fire==1) //this never executes.
{
   bullet1.shoot(tank1.x,tank1.y,tank1.dir);
   tank1.fired();
}
if(tank2.fire==1)
{
   bullet2.shoot(tank2.x,tank2.y,tank2.dir);
   tank2.fired();
}

in tank: global variable int fire indicating that the tank intends to shoot
1
2
3
4
5
6
7
8
void tank::shoot()
{
   fire=1;
}
void tank::fired()
{
   fire=0;
}


I have something similar for the AI tank, they both are tank objects, but being AI fire is set internally in a private function and reset in the main. AI tank works perfectly. player 1 tank doesn't work at all.

if you guys want I can post the entire code (The relevant parts anyway) but its long and might be confusing. Basically, I need some tutoring on how make object communicate with each other properly, and what to look out for.
maybe you could make sure the "fired()" function isn't called anywhere else.. or just make sure the KEY_PRESS_UP event is happening... the info you gave is not enough to completely help you
I for one would like to see more code, but if I had to guess I'd say it's because immediately after you fire your bullet you set the "fire" variable to 0 so your application is only drawing the bullet sprite at that one iteration. It could be any number of other things though.
I can guess that maybe you pass your object by value from one function to another and a used copy constructor (or other constructor) resets the value of the fire.
Last edited on
Here is main.cpp code in its entirety: Again, its kinda complex do to the game programming code. I do admit I have some unused variables as artifacts from previous attempts.
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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
#include "image.h"
#include "program9handler.h"
#include "bulletholder.h"
#include <allegro5/allegro.h>
#include <allegro5/allegro_image.h>
#include <stdio.h>
#include <cstdlib>
int height=480;
int width=640;
int margin=40;
int delay=50;
int speed=10;
int bullet_speed=5;
int it = 8;
ALLEGRO_COLOR wallcolor;

ALLEGRO_DISPLAY* display;
//ALLEGRO_BITMAP* scc;
ALLEGRO_BITMAP* back;
ALLEGRO_BITMAP* t1 = 0;
ALLEGRO_BITMAP* t2 = 0;
ALLEGRO_BITMAP* bul = 0;
ALLEGRO_BITMAP* dt = 0;

ALLEGRO_TIMER *timer;
const float FPS = 24;

//pics
int t1len=0;
int t2len=0;
int dtlen = 0;
int bullen = 0;
int fact1 = 0;
int fact2 = 0;
int facdt = 0;
int facb = 0;
int dly = 200;
int count;

image imagemaker;

bulletholder bt1;
bulletholder bt2;

program9handler tank1, tank2;
void draw();
int setup();
void initializetanks();
void initializebullets();
...
void initializebullets()
{
	bt1.initialize(width,height,bullet_speed,it);
	bt2.initialize(width,height,bullet_speed,it);
	char bb[256];
	char td[256];
	for(int i=0;i<it;i++)
	{
		bt1.sethitboundaries(al_create_sub_bitmap(bul,i*bullen,0,bullen,al_get_bitmap_height(bul)),i);
		bt2.sethitboundaries(al_create_sub_bitmap(bul,i*bullen,0,bullen,al_get_bitmap_height(bul)),i);
	}
}
void draw()
{
	al_set_target_bitmap(al_get_backbuffer(display));
	al_clear_to_color(wallcolor);
	if(bt1.checkkill(tank2))
	{
		tank2.kill();
	}
	if(bt2.checkkill(tank1))
	{
		fprintf(stdout,"Its a hit tank 1 should be dead\n");
		tank1.kill();
	}
	bt1.move();
	bt2.move();
	tank1.move(tank2);
	tank2.move(tank1);
	//al_draw_bitmap(t1,0,0,0);
	//al_draw_bitmap(t2,0,200,0);
	if(tank2.fire==1)
	{
		bt2.shoot(tank2.x,tank2.y,tank2.dir);
		tank2.fired();
	}
	if(tank1.fire==1)
	{
		fprintf(stdout,"Tank 1 In if statement\n");
		bt1.shoot(tank1.x,tank1.y,tank1.dir);
		tank1.fired();
	}
	if(tank1.isdead==0)
	{
		//fact1,al_get_bitmap_width(t1)/it
		al_draw_bitmap(al_create_sub_bitmap(t1,t1len*tank1.dir,0,t1len,t1len),(float)tank1.x,(float)tank1.y,0);
	}
	else 
	{
		//facdt
		al_draw_bitmap(al_create_sub_bitmap(dt,dtlen*tank1.dir,0,dtlen,dtlen),(float)tank1.x,(float)tank1.y,0);
	}
	if(tank2.isdead==0)
	{
		//fact2
		al_draw_bitmap(al_create_sub_bitmap(t2,t2len*tank2.dir,0,t2len,t2len),(float)tank2.x,(float)tank2.y,0);
	}
	else 
	{
		//facdt
		al_draw_bitmap(al_create_sub_bitmap(dt,dtlen*tank2.dir,0,dtlen,dtlen),(float)tank2.x,(float)tank2.y,0);
	}
	int a = bt2.getnumbullets();
	for(int i=0;i<a;i++)
	{
		//facb
		al_draw_bitmap(al_create_sub_bitmap(bul,bullen*bt2.getdir(i),0,al_get_bitmap_width(bul)/it,al_get_bitmap_height(bul)),(float)bt2.getx(i),(float)bt2.gety(i),0);
	}
	a = bt1.getnumbullets();
	for(int i=0;i<a;i++)
	{
		//facb
		al_draw_bitmap(al_create_sub_bitmap(bul,bullen*bt1.getdir(i),0,al_get_bitmap_width(bul)/it,al_get_bitmap_height(bul)),(float)bt1.getx(i),(float)bt1.gety(i),0);
	}
	al_flip_display();
}
int main(int argc, char **argv)
{
	int i = setup();
	initializetanks();
	initializebullets();
	wallcolor = al_map_rgb(50,230,10);
	if(i != 0)
	{
		return i;
	}
	else
	{
	ALLEGRO_EVENT_QUEUE *queue;
	queue = al_create_event_queue();
	if(!queue) {
		fprintf(stderr, "failed to create event queue!\n");
		al_destroy_display(display);
		return -1;
	}
	al_register_event_source(queue, al_get_display_event_source(display));
	al_register_event_source(queue, al_get_keyboard_event_source());
	al_register_event_source(queue, al_get_mouse_event_source());
	al_register_event_source(queue, al_get_timer_event_source(timer));
	al_start_timer(timer);
	int quit = 0;
	int redraw = 0;
		while (!quit)
		{
					ALLEGRO_EVENT ev;
					al_wait_for_event(queue, &ev);
					if (ev.type == ALLEGRO_EVENT_KEY_DOWN)
					{
						if(ev.keyboard.keycode==ALLEGRO_KEY_LEFT)
						{
							tank1.changedirection(-1);
						}
						else if(ev.keyboard.keycode==ALLEGRO_KEY_RIGHT)
						{
							tank1.changedirection(1);
						}
						else if(ev.keyboard.keycode==ALLEGRO_KEY_DOWN)
						{
							tank1.goback();
						}
						else if(ev.keyboard.keycode==ALLEGRO_KEY_SPACE)
						{
							tank1.startstop();
						}
						else if(ev.keyboard.keycode==ALLEGRO_KEY_UP)
						{
							tank1.shoot();
						}
						else if(ev.keyboard.keycode==ALLEGRO_KEY_ESCAPE)
						{
							quit=1;
						}
					}
					else if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
					{
						quit = 1;
					}
					else if(ev.type == ALLEGRO_EVENT_TIMER)
					{
						redraw = 1;
					}
					if(redraw && al_is_event_queue_empty(queue))
					{
						draw();
					}
		}
		al_destroy_event_queue(queue);
	}
	//al_destroy_event_queue(queue);
	al_destroy_bitmap(t1);
	al_destroy_bitmap(t2);
	al_destroy_bitmap(bul);
	al_destroy_bitmap(dt);
	al_destroy_display(display);
	al_destroy_timer(timer);
	fprintf(stdout,"made it to last line\n");
	return 0;
}

Tank.cpp (Program9handler.cpp again from previous 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
#include "program9handler.h"
#include <cmath>
#include <stdio.h>
#include <cstdlib>
#include <exception>
#include <allegro5/allegro.h>
#include <allegro5/allegro_image.h>
void program9handler::setbitmap(int w,int h)
{
	WIDTH = w;
	HEIGHT = h;
}
void program9handler::setAI()
{
	isAI=true;
	x=350;
	y=150;
	dir = 4;
}
//it only tests to see if i is - or +. 0 does nothing. increasing the value does nothing.
// + : turn right, - : turn left
void program9handler::chooseDirection(program9handler other)
{
	if (isAI)
	{
		if (other.getx() > x)
		{
			changedirection(-1); //+ = right
		}
		else
		{
			changedirection(1); //- = left
		}
	}
	setDirection();
}
void program9handler::move(program9handler other)
{
	if(!isdead)
	{
		fire=0;
		if(stop==0)
		{
			if((isAI)&&(cycledelay>=5))
			{
				chooseDirection(other);
			}
			if(isAI)
			{
				aim(other);
			}
			cycledelay = (cycledelay+1)%6;
			checkhitwall();
			checkcollision(other);
			x+=dx;
			y+=dy;
		}
		setDirection();
	}
}

void program9handler::aim(program9handler other)
{
	int good = false;
	if((other.x<x)&&(other.y<y)&&(dir>5))
	{
		fire=1;
	}
	else if((other.x>x)&&(other.y<y)&&(dir>=0)&&(dir<3))
	{
		fire=1;
	}
	else if((other.x>x)&&(other.y>y)&&(dir>1)&&(dir<5))
	{
		fire=1;
	}
	else if((other.x<x)&&(other.y>y)&&(dir>3)&&(dir<7))
	{
		fire=1;
	}
}
void program9handler::shoot()
{
	if(!isdead)
	{
		fprintf(stdout,"fire has been changed to 1\n");
		fire=1;
	}
}
void program9handler::fired()
{
	fire=0;
	fprintf(stdout,"fire has been changed to 0\n");
}
void program9handler::kill()
{
	fprintf(stdout,"isdead has been changed\n");
	isdead = (isdead+1)%2;
}

I'll double post the bulletholder code.
Last edited on
bulletholder.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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
#include "bulletholder.h"
#include <math.h>
#include <cstdlib>
#include <stdio.h>
bulletholder::bulletholder()
{
}
void bulletholder::initialize(int w, int h, int sp, int it)
{
	width = w;
	height = h;
	max_bullets=20;
	bullet_speed=sp;
	iterations = it;
	idd=0;
	table.initialize(sp,it);
	top = 0;
	mr = 255;
	mg = 0;
	mb = 255;
}
void bulletholder::shoot(int x, int y, int dir)
{
	fprintf(stdout,"In bulletholder, shoot\n");
	add(top, x, y, dir,idd);
	setspeed();
	idd++;
}
void bulletholder::add(bullet*& a, int x, int y, int dir, int idd)
{
	if(a!=0)
	{
		bullet *nnew = new bullet;
		nnew->x=x;
		nnew->y=y;
		nnew->dir=dir;
		nnew->idd=idd;
		nnew->next=a;
		a=nnew;
	}
	else {
		a = new bullet;
		a->x=x;
		a->y=y;
		a->dir=dir;
		a->idd=idd;
		a->next=0;
	}
}
void bulletholder::deepcopy(bullet*& a, bullet* b) //REMEMBER a is being deep copied to b
{
	b->x=a->x;
	b->y=a->y;
	b->dx=a->dx;
	b->dy=a->dy;
	b->dir=a->dir;
	b->idd=a->idd;
}
void bulletholder::push(bullet*& a, bullet* b)
{
	/*b->x=a->x;
	b->y=a->y;
	b->dx=a->dx;
	b->dy=a->dy;
	b->dir=a->dir;
	b->idd=a->idd;
	b->next = a;
	a = b;*/
	b->next=a;
	a = b;
}
void bulletholder::setspeed()
{
	top->dx = table.spx(top->dir);
	top->dy = table.spy(top->dir);
}
void bulletholder::update(bullet*& a)
{
	bullet* b = a;
	while (b!=0)
	{
		b->x+=b->dx;
		b->y+=b->dy;
		b=b->next;
	}
}
void bulletholder::renew(bullet*& a)
{
	bullet *nnew;
	while(a!=0)
	{
		if(!((a->x<=0)||(a->x>=width)||(a->y<=0)||(a->y>=height)))
		{
			bullet *b = new bullet;
			deepcopy(a,b);
			push(nnew,b);
		}
		pop(a);
	}
	a = nnew;
}
void bulletholder::move()
{
	update(top);
	renew(top);
}
void bulletholder::sethitboundaries(ALLEGRO_BITMAP* sprite,int z) //might be right here
{
	float r,g,b;
	int inc = (height/30);
	int w = al_get_bitmap_width(sprite);
	int h = al_get_bitmap_height(sprite);
	for(int i=0;i<w/2;i++)
	{
		tl = inc*i;
		if(areas[z].tl.set==0)
		{
			//getpixel(b,tl,tl)
			al_unmap_rgb_f(al_get_pixel(sprite,tl,tl),&r,&g,&b);
			//if(magicpink!=getpixel(sprite,tl,tl))
			if((mr!=r)||(mg!=g)||(mb!=b))
			{
				areas[z].tl.set=1;
				areas[z].tl.x=tl;
				areas[z].tl.y=tl;
			}
		}
		int tr = width-tl;
		if(areas[z].tr.set==0)
		{
			//getpixel(b,tr,tl)
			al_unmap_rgb_f(al_get_pixel(sprite,tr,tl),&r,&g,&b);
			//if(magicpink!=getpixel(sprite,tr,tl))
			if((mr!=r)||(mg!=g)||(mb!=b))
			{
				areas[z].tr.set=1;
				areas[z].tr.x=tr;
				areas[z].tr.y=tl;
			}
		}
		if(areas[z].bl.set==0)
		{
			//getpixel(b,tl,tr)
			al_unmap_rgb_f(al_get_pixel(sprite,tl,tr),&r,&g,&b);
			//if(magicpink!=getpixel(sprite,tl,tr))
			if((mr!=r)||(mg!=g)||(mb!=b))
			{
				areas[z].bl.set=1;
				areas[z].bl.x=tl;
				areas[z].bl.y=tr;
			}
		}
		if(areas[z].br.set==0)
		{
			//getpixel(b,tr,tr)
			al_unmap_rgb_f(al_get_pixel(sprite,tr,tr),&r,&g,&b);
			//if(magicpink!=getpixel(sprite,tr,tr))
			if((mr!=r)||(mg!=g)||(mb!=b))
			{
				areas[z].br.set=1;
				areas[z].br.x=tr;
				areas[z].br.y=tr;
			}
		}
	}
}
int bulletholder::checkkill(program9handler& other)
{
	int ishit = 0;
	area dg = other.areas[other.dir];
	int ror = (int)(sqrt((float)(other.width*other.width+other.height*other.height)));
	bullet *c = new bullet;
	c = top;
	int g = getnumbullets();
	for(int i=0;i<g;i++)
	{
		int ox = other.x;
		int bx = c->x;
		int xx = ox - bx;
		int oy = other.y;
		int by = c->y;
		int yy = oy-by;
		int dd = c->dir;
		int dis = (int)(sqrt((float)(xx*xx)+(yy*yy)));
		if(dis<ror)
		{
			if(ox<bx)
			{
				if(oy<by)
				{
					//top left, so test bottom right of tank
					//if tankx > bulletx and tanky > bullety
					if((dg.br.y>areas[dd].tl.y)&&(dg.br.x>areas[dd].tl.x))
					{
						//its a hit
						killbullet(top,c->idd);
						ishit=1;
					}
				}
				else
				{
					//top right, so test bottom left of tank
					//if tankx < bulletx and tanky > bullety
					if((dg.bl.x<areas[dd].tr.x)&&(dg.bl.y>areas[dd].tr.y))
					{
						//its a hit
						killbullet(top,c->idd);
						ishit=1;
					}
				}
			}
			else
			{
				if(oy<by)
				{
					//bottom left, test top right of tank
					//if tankx > bulletx and tanky < bullety
					if((dg.tr.x>areas[dd].bl.x)&&(dg.tr.y<areas[dd].bl.y))
					{
						killbullet(top,c->idd);
						ishit=1;
					}
				}
				else
				{
					//bottom right, test top left of tank
					//if tankx < bulletx and tanky < bullety
					if((dg.tl.x<areas[dd].br.x)&&(dg.tl.y<areas[dd].br.y))
					{
						killbullet(top,c->idd);
						ishit=1;
					}
				}
			}
		}
	c = c->next;
	}
	free(c);
	return ishit;
}
void bulletholder::pop(bullet*& a)
{
	bullet *c = a;
	a=a->next;
	free(c);
}
void bulletholder::killbullet(bullet*& a, int idd)
{
	bullet *nnew;
	while (a!=0)
	{
		if(a->idd!=idd)
		{
			bullet *b = new bullet;
			deepcopy(a,b);
			push(nnew,b);
		}
		pop(a);
	}
	a = nnew;
}
int bulletholder::getx(int i)
{
	bullet *c = top;
	int j=0;
	while(j<i)
	{
		c = c->next;
		j++;
	}
	int aa = c->x;
	return aa;
}
int bulletholder::gety(int i)
{
	bullet *c = top;
	int j=0;
	while(j<i)
	{
		c = c->next;
		j++;
	}
	int aa = c->y;
	return aa;
}
int bulletholder::getdir(int i)
{
	bullet *c = top;
	int j=0;
	while(j<i)
	{
		c = c->next;
		j++;
	}
	int aa = c->dir;
	return aa;	
}
int bulletholder::getnumbullets()
{
	int c = 0;
	for(bullet *b = top;b!=0;b=b->next)
	{
		c++;
	}
	return c;
}
bulletholder::~bulletholder()
{
	free(top);
}
so I noticed:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
	al_set_target_bitmap(al_get_backbuffer(display));
	al_clear_to_color(wallcolor);
	if(bt1.checkkill(tank2))
	{
		tank2.kill();
	}
	if(bt2.checkkill(tank1))
	{
		fprintf(stdout,"Its a hit tank 1 should be dead\n");
		tank1.kill();
	}
	bt1.move();
	bt2.move();
	tank1.move(tank2);
	tank2.move(tank1);

and move():
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void program9handler::move(program9handler other)
{
	if(!isdead)
	{
		fire=0; /************************** */
		if(stop==0)
		{
			if((isAI)&&(cycledelay>=5))
			{
				chooseDirection(other);
			}
			if(isAI)
			{
				aim(other);
			}
			cycledelay = (cycledelay+1)%6;
			checkhitwall();
			checkcollision(other);
			x+=dx;
			y+=dy;
		}
		setDirection();
	}
}


So I switched tank1.move(tank2)
to after the if statement in question. No help

something curious: commenting out fire=0 in move doesn't appear to have any effect. However: If I'm quick enough when the program starts I'm able to fire 1 bullet and thats it. AI tank's behavior doesn't seem effected. Also, when I repeated press fire (up). The game gets a little choppy.
Last edited on
Topic archived. No new replies allowed.