|
Problem with al_draw_filled_circle() |
Francis Langlais
Member #15,985
June 2015
|
I'm trying to use al_draw_filled_circle() to draw a shield around a robot but every time I use it, my game crash. I managed to use it once in a test I made just to make myself comfortable with the function but when I try it in my game it doesn't work. Here is how I use it : 1 robot = al_load_bitmap("ressources//images//basic_robot.bmp");
2 al_convert_mask_to_alpha(robot, al_map_rgb(255, 0, 255));
3 shield = al_create_bitmap(SHIELD_R, SHIELD_R);
4 al_set_target_bitmap(shield);
5 al_draw_filled_circle(SHIELD_R - 5, SHIELD_R - 5, SHIELD_R / 2, al_map_rgb(255, 0, 255));
6 character = al_create_bitmap(SHIELD_R, SHIELD_R);
7 al_set_target_bitmap(character);
8 al_draw_tinted_bitmap(shield, al_map_rgba_f(1*alpha, 1*alpha, 1*alpha, alpha), 0, 0, 0);
9 al_draw_bitmap(robot, SHIELD_R / 2 - al_get_bitmap_width(robot) / 2, SHIELD_R / 2 - al_get_bitmap_height(robot) / 2, 0);
The way I want to do it is to draw the shield on the character bitmap then draw the robot over it so the whole robot is visible. In this code my game crash and I use al_clear_to_color(al_map_rgb(255, 0, 255); instead everything is fine except I have a square instead of a circle. I don't have the code where the function is working with me at the moment but I will update this post tomorrow as soon as I get it. |
Elias
Member #358
May 2000
|
Paths can be separated with / instead of // btw. -- |
Francis Langlais
Member #15,985
June 2015
|
@Edgar Reynaldo @Elias Here is the code when al_draw_filled_circle() work : character = al_create_bitmap(SQUARE, SQUARE); al_set_target_bitmap(character); al_clear_to_color(al_map_rgb(0, 0, 255)); al_draw_filled_circle(SQUARE / 2, SQUARE / 2, SQUARE / 2, al_map_rgb(255, 0, 255)); al_convert_mask_to_alpha(character, al_map_rgb(0, 0, 255));
Here I was trying to use al_convert_mask_to_alpha() so I know I'm filling my bitmap and creating a alpha for nothing. |
RPG Hacker
Member #12,492
January 2011
|
Francis Langlais said: I thought so but when I use / it's not working so to be safe I use //. Maybe you're confusing / with \? \ wouldn't work because \ starts an escape sequence. \\ will work on Windows as path seperator. / should work on all systems, though.
|
Francis Langlais
Member #15,985
June 2015
|
So to comeback to my initial question about al_draw_filled_circle, here is the code that is bugging me right now. 1void DrawSensorBitmaps(t_LL listOfRobots) {
2 double startAngle, endAngle, oppositeAngle, radians, radiansL1, radiansL2;
3 int j, x, y, x1, x2, y1, y2, range;
4 int xMin, yMin, left, top;
5 ROBOT *robot;
6
7 al_init_primitives_addon();
8
9 ForeachLL_M(listOfRobots, robot)
10 {
11 for (j = 0; j < MAX_SENSORS; j++)
12 switch (robot->sensorArray[j].type) {
13 case SENSOR_RADAR:
14 //The algorithm for drawing the radar bitmap is:
15 //1: Clear the bitmap to transparent.
16 //2: Draw a colored circle to the radar range.
17 //3: Draw lines in transparency bounding the arc on either side
18 //4: Directly opposite to the arc, 10 pixels out, fill the remainder
19 // of the circle with the transparent color.
20 //5: Now the job is to copy just the sensor graphic to the bitmap
21 // associated with the radar.
22 //6: Find the three x,y points that define the arc and find the min
23 // and max each of x/y.
24 //7: Min/max doesn't work if the arc is pointing with its curve left/
25 // right or up/down because the curve is further away than any of
26 // the defining arc points. To compensate, do a test to see if the
27 // round part of the arc is left/right or up/down, and if so,
28 // bound the box so the arc fits.
29 //8: Pick x/y points for the final image for where the sensor should
30 // be drawn. Sadly, although there is math behind it, due to
31 // rounding of odd pixels, the value had to be adjusted with +1
32 // with no proof...just empirical tests.
33 al_set_target_bitmap(sensorPic);
34 al_clear_to_color(
35 al_map_rgb(COLOR_TRANS_RED, COLOR_TRANS_GREEN,
36 COLOR_TRANS_BLUE)); //1
37
38 range = robot->sensorArray[j].range * PX_PER_CM;
39
40 startAngle = -robot->sensorArray[j].angle + robot->heading;
41 endAngle = startAngle - robot->sensorArray[j].width;
42 oppositeAngle = startAngle - robot->sensorArray[j].width / 2
43 + 180;
44 al_set_target_bitmap(sensorPic);
45 al_draw_filled_circle(al_get_bitmap_width(sensorPic) / 2, //***************************************************
46 al_get_bitmap_height(sensorPic) / 2, //2
47 range, robot->color);
48
49 radiansL1 = startAngle * DEG_PER_RAD;
50 x1 = RADAR_WRKIMG_PX / 2 * cos(radiansL1);
51 y1 = RADAR_WRKIMG_PX / 2 * sin(radiansL1);
52 al_set_target_bitmap(sensorPic); //3a
53 al_draw_line(al_get_bitmap_width(sensorPic) / 2,
54 al_get_bitmap_height(sensorPic) / 2,
55 al_get_bitmap_width(sensorPic) / 2 + x1,
56 al_get_bitmap_height(sensorPic) / 2 - y1,
57 al_map_rgb(COLOR_TRANS_RED, COLOR_TRANS_GREEN,
58 COLOR_TRANS_BLUE), 1);
59 radiansL2 = endAngle * DEG_PER_RAD;
60 x2 = RADAR_WRKIMG_PX / 2 * cos(radiansL2);
61 y2 = RADAR_WRKIMG_PX / 2 * sin(radiansL2);
62 al_set_target_bitmap(sensorPic);
63 al_draw_line(al_get_bitmap_width(sensorPic) / 2,
64 al_get_bitmap_height(sensorPic) / 2, //3b
65 al_get_bitmap_width(sensorPic) / 2 + x2,
66 al_get_bitmap_height(sensorPic) / 2 - y2,
67 al_map_rgb(COLOR_TRANS_RED, COLOR_TRANS_GREEN,
68 COLOR_TRANS_BLUE), 1);
69
70 radians = oppositeAngle * DEG_PER_RAD;
71 x = 10 * cos(radians);
72 y = 10 * sin(radians);
73 floodfill(sensorPic, al_get_bitmap_width(sensorPic) / 2 + x, //4
74 al_get_bitmap_height(sensorPic) / 2 - y, al_map_rgb(COLOR_TRANS_RED, COLOR_TRANS_GREEN,
75 COLOR_TRANS_BLUE));
76
77 //OK, now the *big* bitmap is drawn. Now we just have to take the
78 //section we need and copy it to the radar sensor's bitmap. //5
79 x1 = RADAR_WRKIMG_PX / 2 + range * cos(radiansL1); //6
80 y1 = RADAR_WRKIMG_PX / 2 - range * sin(radiansL1);
81 x2 = RADAR_WRKIMG_PX / 2 + range * cos(radiansL2);
82 y2 = RADAR_WRKIMG_PX / 2 - range * sin(radiansL2);
83
84 xMin = al_get_bitmap_width(sensorPic) / 2; //6
85 if (x1 < xMin)
86 xMin = x1;
87 if (x2 < xMin)
88 xMin = x2;
89
90 yMin = al_get_bitmap_height(sensorPic) / 2; //6
91 if (y1 < yMin)
92 yMin = y1;
93 if (y2 < yMin)
94 yMin = y2;
95
96 while (startAngle < 0) //Due to earlier calc,
97 startAngle += 360; //startAngle could be -ve.
98
99 if (startAngle > 180 && startAngle < 225) //7
100 left = 1;
101 else
102 left = xMin + 1;
103
104 if (startAngle > 90 && startAngle < 135) //7
105 top = 1;
106 else
107 top = yMin + 1;
108
109 al_set_target_bitmap(robot->sensorArray[j].image);
110 al_draw_bitmap_region(sensorPic, left, top, RADAR_IMAGE_PX,
111 RADAR_IMAGE_PX, 0, 0, 0);
112
113 robot->sensorArray[j].drawX = RADAR_IMAGE_PX - left + 1;
114 ; //8
115 robot->sensorArray[j].drawY = RADAR_IMAGE_PX - top + 1;
116
117 break;
118 case SENSOR_RANGE:
119 break;
120 case SENSOR_NONE:
121 default:
122 break;
123 }
124 }
125}
I have put al_init_primitives_addon(); on line 7 in the function just to be sure it is initialised before using it (it is initialised earlier but just to be sure). Also, sensorPic is initialised and the bitmap is created like this: static ALLEGRO_BITMAP *sensorPic; sensorPic = al_create_bitmap(RADAR_WRKIMG_PX, RADAR_WRKIMG_PX); Note : static ALLEGRO_BITMAP *sensorPic; is a global for this file. I don't know if this is the right way of doing things but since it's not my code I left it like this. The part that crash my program is at line 45 to 47. When commented the program run but if that part is in the code the program crashes. I do use al_draw_filled_circle at other place in my code and it works perfectly but this one can't seems to work. I tried to draw a circle bigger than the bitmap on an other program and it work. Also drawing the circle with the centre outside of the bitmap works fine too. I tried using hard value instead of al_get_bitmap_width and al_get_bitmap_height but the result is the same. I honestly have no idea why this doesn't work. If you guys need, I can give you the whole code. |
|