Here's the source:
tank.cpp
#SelectExpand
1/********************
2 * Tank Source File *
3 ********************/
4
5#include <math.h>
6#include <allegro.h>
7#include "tank.h"
8
9CTank::CTank
()
10/* Sets up tank object */
11{
12 x
= (SCREEN_W/2); // init player
13 y
= SCREEN_H - (SCREEN_H/6);
14 health
= 100;
15 reload
= 0;
16 score
= 0;
17 speed
= TANK_SPEED
;
18
19 canx
= x
+ TANK_W
/2 - CANNON_W
/2;
20 cany
= y
- CANNON_H
+ (CANNON_H
/4);
21
22 tank
= create_bitmap(TANK_W, TANK_H
);
23 cannon
= create_bitmap(CANNON_W, CANNON_H
);
24
25 // draw tank to tank bitmap
26 clear_to_color(tank,
makecol(255,
0,
255));
27 rectfill(tank,
10,
0,
(TANK_W-10
), TANK_H-
(TANK_H
/4),
makecol(45,
200,
60));
28 rect(tank,
10,
0,
(TANK_W-10
), TANK_H-
(TANK_H
/4),
makecol(60,
230,
70));
29
30 ellipsefill(tank,
(TANK_W
/2), TANK_H-
(TANK_H
/4)-1,
(TANK_W
/2)-1,
31 (TANK_H
/4),
makecol(160,
160,
160));
32 ellipse(tank,
(TANK_W
/2), TANK_H-
(TANK_H
/4)-1,
(TANK_W
/2)-1,
33 (TANK_H
/4),
makecol(120,
120,
120));
34
35 // draw cannon to cannon bitmap
36 clear_to_color(cannon,
makecol(255,
0,
255));
37 rectfill(cannon,
0,
0, CANNON_W, CANNON_H,
makecol(45,
200,
60));
38 rect(cannon,
0,
0, CANNON_W-1, CANNON_H-1,
makecol(60,
230,
70));
39}
40//--------------------------------------------
41
42CTank::~CTank
()
43/* Deletes tank bmps */
44{
45 destroy_bitmap(tank
);
46 destroy_bitmap(cannon
);
47}
48//--------------------------------------------
49
50void CTank::MoveTank
()
51/* Moves tank */
52{
53
54 if((key[KEY_LEFT
]) && (x
> 0)){
55 x
-= speed
;
56 canx
-= speed
;
57 }
58
59 if((key[KEY_RIGHT
]) && ((x
+TANK_W
) < SCREEN_W)){
60 x
+= speed
;
61 canx
+= speed
;
62 }
63
64 angle
= atan((canx-
(CANNON_W
/2)-mouse_x)/(cany-
(CANNON_H
/2)-mouse_y))/(3.
1415/180);
65
66 return;
67}
68//--------------------------------------------
69
70void CTank::FireBullet
()
71{}
72//--------------------------------------------
73
74void CTank::DrawTank
(BITMAP *surface
)
75{
76 // blit tank to *surface
77 masked_blit(tank, surface,
0,
0, x, y, TANK_W, TANK_H
);
78 // blit cannon to *surface
79 rotate_sprite(surface, cannon,
int(canx
),
int(cany
),
ftofix(-angle
));
80 textprintf_ex(screen,
font,
0,
10,
makecol(255,
255,
255),
0,
81 "Angle = %f", angle
);
82}
83//--------------------------------------------
tank.h
#SelectExpand
1/********************
2 * Tank Class Header*
3 ********************/
4
5#ifndef _TANK_H
6#define _TANK_H
7
8#define MAX_BULLETS 10
9#define MOVE_LEFT 0
10#define MOVE_RIGHT 1
11
12#define TANK_W 100
13#define TANK_H 35
14
15#define TANK_SPEED 1
16
17#define CANNON_W 15
18#define CANNON_H 30
19
20class CTank
21{
22public:
23 CTank
();
24 ~CTank
();
25
26 int x, y
; // x and y coordinate of the player
27 int health
; // health of the player
28 int reload
; // reload time of the player
29 int speed
;
30
31 float canx
;
32 float cany
;
33 float angle
; // angle of cannon
34
35 int score
;
36
37 BITMAP *tank,
*cannon
; //bitmaps to hold the tank and cannon
38
39 void MoveTank
();
40 void FireBullet
();
41 void DrawTank
(BITMAP *surface
);
42};
43
44#endif
main.cpp
#SelectExpand
1/******************************
2 * Tank Defense v.0.1 *
3 * March 25 2007 *
4 * Kelly Crawford *
5 ******************************/
6
7#include <allegro.h>
8#include <time.h>
9#include "tank.h"
10
11#define WINDOW_W 640
12#define WINDOW_H 480
13
14#define MAX_CLOUDS 14
15#define MIN_CLOUDS 7
16
17int SetUp
()
18/* Initializes allegro and screen */
19{
20 allegro_init();
21
22 install_keyboard();
23 install_mouse();
24 install_timer();
25
26 set_color_depth(16);
27
28 if(set_gfx_mode(GFX_AUTODETECT_WINDOWED, WINDOW_W, WINDOW_H,
0,
0) != 0)
29 return 1;
30
31 srand(time(0));
32
33 show_mouse(screen);
34
35 return 0;
36}
37//--------------------------------------------
38
39void cloud_line
(BITMAP *bmp,
int x,
int y,
int color
)
40/* Function called by DoLine() */
41{
42 putpixel(bmp, x, y, color
);
43
44 return;
45}
46//--------------------------------------------
47
48void MakeCloud
(BITMAP *bmp
)
49/* Draws a cloud to bmp */
50{
51 int height
= 1 + (rand()%
50); // height of cloud
52 int width
= 100 + (rand()%
50); // general width of cloud
53
54 int x1
= (-30) + rand()%
(SCREEN_W-30
);
55 int x2
= x1
+ width
;
56 int y
= 10 + rand()%
(SCREEN_H-100
); // cloud coordinates
57
58 int col
= makecol(255,
255,
255); // cloud color information
59
60 for(int i
= 0; i
< height
; i
++) // loops until entire cloud is drawn
61 {
62 do_line(bmp, x1, y, x2, y, col,
*cloud_line
); // draw line of cloud
63 y
+= 1;
64
65 if(i
< (height
/2)){
66 x1
-= 3 + rand()%
5;
67 x2
+= 3 + rand()%
5;}
68 else{
69 x1
+= 3 + rand()%
5;
70 x2
-= 3 + rand()%
5;}
71 }
72
73 return;
74}
75//--------------------------------------------
76
77BITMAP* GenerateSky
(BITMAP *bmp
)
78/* Generates a sky on bitmap pointed
79 to by bmp */
80{
81 int r
= 140, g
= 150, b
= 225;
82 int col
= makecol(r, g, b
);
83
84
85 floodfill(bmp,
SCREEN_W/2,
SCREEN_H/2, col
); // fill screen w/ blue
86
87 int clouds
= (rand()%
(MAX_CLOUDS-MIN_CLOUDS
) + MIN_CLOUDS
);
88
89 for(int c
= 0; c
< clouds
; c
++)
90 MakeCloud
(bmp
);
91
92 return bmp
;
93}
94//--------------------------------------------
95
96int main
()
97{
98 if(SetUp
() != 0) return 1; // setup + error checking for allegro
99
100 BITMAP *bg_sky
= create_bitmap(SCREEN_W,
SCREEN_H); // create sky bitmap
101 BITMAP *buffer
= create_bitmap(SCREEN_W,
SCREEN_H); // create double buffer
102
103 bg_sky
= GenerateSky
(bg_sky
); // colour sky bitmap
104
105 CTank player
;
106
107 while(!key[KEY_ESC
]){
108
109 blit(bg_sky, buffer,
0,
0,
0,
0, bg_sky->w, bg_sky->h
);
110
111 player.MoveTank
();
112 player.DrawTank
(buffer
);
113
114 blit(buffer,
screen,
0,
0,
0,
0,
SCREEN_W,
SCREEN_H);
115 };
116
117 destroy_bitmap(bg_sky
);
118 destroy_bitmap(buffer
);
119
120 return(0);
121}END_OF_MAIN()
The problem lies in the tank.cpp file. In the MoveTank() function, there is a call to atan() to determine the angle of the mouse in degrees from the center of a bitmap of a cannon.
The cannon rotates to face the mouse, basically. But there are errors, it jumps around sometimes when you pass certain parts, and if you keep the mouse near the top of the window and drag it too far left or right, the cannon stops facing it (it faces too far down).
Is there any way I can improve upon the angle calculation?
]]>