|
Vivace extra points. Its there a better way of doing this one. |
AceBlkwell
Member #13,038
July 2011
|
I am working through the Vivace tutorial. I am at the point of animation, or moving things around the screen. At the end of the lesson it states extra points for preventing the randomly bouncing objects from drifting off screen. 1#include <stdio.h>
2#include <stdlib.h>
3#include <allegro5/allegro5.h>
4#include <allegro5/allegro_font.h>
5#include <allegro5/allegro_image.h>
6#include <allegro5/allegro_primitives.h>
7
8void must_init(bool test, const char *description)
9{
10 if(test) return;
11
12 printf("couldn't initialize %s\n", description);
13 exit(1);
14}
15
16enum BOUNCER_TYPE {
17 BT_HELLO = 0,
18 BT_MYSHA,
19 BT_TRIANGLE,
20 BT_RECTANGLE_1,
21 BT_RECTANGLE_2,
22 BT_CIRCLE,
23 BT_LINE1,
24 BT_LINE2,
25 BT_N
26};
27
28typedef struct BOUNCER
29{
30 float x, y;
31 float dx, dy;
32 float sx, sy; // Lower right corner of object square
33 int type;
34} BOUNCER;
35
36int main()
37{
38 float limit_x; //Offset limits to prevent going off screen
39 float limit_y;
40
41 must_init(al_init(), "allegro");
42 must_init(al_install_keyboard(), "keyboard");
43
44 ALLEGRO_TIMER* timer = al_create_timer(1.0 / 30.0);
45 must_init(timer, "timer");
46
47 ALLEGRO_EVENT_QUEUE* queue = al_create_event_queue();
48 must_init(queue, "queue");
49
50 al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_SUGGEST);
51 al_set_new_display_option(ALLEGRO_SAMPLES, 8, ALLEGRO_SUGGEST);
52 al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR);
53
54 ALLEGRO_DISPLAY* disp = al_create_display(640, 480);
55 must_init(disp, "display");
56
57 ALLEGRO_FONT* font = al_create_builtin_font();
58 must_init(font, "font");
59
60 must_init(al_init_image_addon(), "image addon");
61 ALLEGRO_BITMAP* mysha = al_load_bitmap("mysha.png");
62 must_init(mysha, "mysha");
63
64 must_init(al_init_primitives_addon(), "primitives");
65
66 al_register_event_source(queue, al_get_keyboard_event_source());
67 al_register_event_source(queue, al_get_display_event_source(disp));
68 al_register_event_source(queue, al_get_timer_event_source(timer));
69
70 bool done = false;
71 bool redraw = true;
72 ALLEGRO_EVENT event;
73
74 BOUNCER obj[BT_N];
75
76 obj[0].sx = 100; obj[0].sy = 10; // used with X and Y, SX and SY create a square to encompass the shapes
77 obj[1].sx = 318; obj[1].sy = 200; // took them from the draw commands below
78 obj[2].sx = 50; obj[2].sy = 50;
79 obj[3].sx = 100; obj[3].sy = 80;
80 obj[4].sx = 120; obj[4].sy = 100;
81 obj[5].sx = 30; obj[5].sy = 30;
82 obj[6].sx = 20; obj[6].sy = 100;
83 obj[7].sx = 70; obj[7].sy = 0;
84
85 for(int i = 0; i < BT_N; i++)
86 {
87 BOUNCER* b = &obj[i];
88 b->x = rand() % 320; // Changed from 640x480, Once outer limits were established I had to prevent the first draw to be out of bounds. It would lock the
89 b->y = rand() % 250; // the shape in the out of bound condition. Used the largest shape for the difference. (Mysha = 320x200)
90 b->dx = ((((float)rand()) / RAND_MAX) - 0.5) * 2 * 4;
91 b->dy = ((((float)rand()) / RAND_MAX) - 0.5) * 2 * 4;
92 b->type = i;
93 }
94
95 al_start_timer(timer);
96 while(1)
97 {
98 al_wait_for_event(queue, &event);
99
100 switch(event.type)
101 {
102 case ALLEGRO_EVENT_TIMER:
103 for(int i = 0; i < BT_N; i++)
104 {
105 BOUNCER* b = &obj[i];
106 b->x += b->dx;
107 b->y += b->dy;
108
109 limit_x = 640-b->sx; // Limit isn't 640x480. limit x and y takes in consideration the lower square point of the shape.
110 limit_y = 480-b->sy;
111
112 if(i==5 && b->x < 30) //Created for Circle to prevent X and Y from going below the R30
113 {
114 b->dx *= -1;
115 }
116 if(i==5 && b->y < 30) //Created for Circle to prevent X and Y from going below the R30
117 {
118 b->dy *= -1;
119 }
120 if(i==7 && b->y < 20) //Created for Line 2 prevent Y from getting in less than 20 which is the second point location (-20)
121 {
122 b->dy *= -1;
123 }
124 if(b->x < 0)
125 {
126 b->x *= -1;
127 b->dx *= -1;
128 }
129
130 if(b->x > limit_x)
131 {
132 b->dx *= -1;
133 }
134 if(b->y < 0)
135 {
136 b->y *= -1;
137 b->dy *= -1;
138 }
139 if(b->y > limit_y)
140 {
141
142 b->dy *= -1;
143 }
144 }
145
146 redraw = true;
147 break;
148
149 case ALLEGRO_EVENT_KEY_DOWN:
150 case ALLEGRO_EVENT_DISPLAY_CLOSE:
151 done = true;
152 break;
153 }
154
155 if(done)
156 break;
157
158 if(redraw && al_is_event_queue_empty(queue))
159 {
160 ALLEGRO_VERTEX v[4];
161 al_clear_to_color(al_map_rgb(0, 0, 0));
162
163 for(int i = 0; i < BT_N; i++)
164 {
165 BOUNCER* b = &obj[i];
166 switch(b->type)
167 {
168 case BT_HELLO:
169 al_draw_text(font, al_map_rgb(255, 255, 255), b->x, b->y, 0, "Hello world!");
170 break;
171
172 case BT_MYSHA:
173 al_draw_bitmap(mysha, b->x, b->y, 0);
174 break;
175
176 case BT_TRIANGLE:
177 al_draw_filled_triangle(b->x, b->y, b->x + 50, b->y + 25, b->x, b->y + 50, al_map_rgb_f(0, 1, 0));
178 break;
179
180 case BT_RECTANGLE_1:
181 al_draw_filled_rectangle(b->x, b->y, b->x + 100, b->y + 80, al_map_rgba_f(0, 0, 0.5, 0.5));
182 break;
183
184 case BT_RECTANGLE_2:
185 v[0].x = b->x; v[0].y = b->y; v[0].z = 0; v[0].color = al_map_rgb_f(1, 0, 0);
186 v[1].x = b->x + 120; v[1].y = b->y; v[1].z = 0; v[1].color = al_map_rgb_f(0, 1, 0);
187 v[2].x = b->x; v[2].y = b->y + 100; v[2].z = 0; v[2].color = al_map_rgb_f(0, 0, 1);
188 v[3].x = b->x + 120; v[3].y = b->y + 100; v[3].z = 0; v[3].color = al_map_rgb_f(1, 1, 0);
189
190 al_draw_prim(v, NULL, NULL, 0, 4, ALLEGRO_PRIM_TRIANGLE_STRIP);
191 break;
192
193 case BT_CIRCLE:
194 al_draw_circle(b->x, b->y, 30, al_map_rgb_f(1, 0, 1), 2);
195 break;
196
197 case BT_LINE1:
198 al_draw_line(b->x, b->y, b->x + 20, b->y + 100, al_map_rgb_f(1, 0, 0), 1);
199 break;
200
201 case BT_LINE2:
202 al_draw_line(b->x, b->y, b->x + 70, b->y - 20, al_map_rgb_f(1, 1, 0), 1);
203 break;
204 }
205 }
206
207 al_flip_display();
208 redraw = false;
209 }
210 }
211
212 al_destroy_bitmap(mysha);
213 al_destroy_font(font);
214 al_destroy_display(disp);
215 al_destroy_timer(timer);
216 al_destroy_event_queue(queue);
217
218 return 0;
219}
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
Since you're using objects, you can try OOP. Give Each object a GetLeft, SetLeft, GetRight, SetRight, GetTop, SetTop, GetBottom, and SetBottom function. Now you can easily constrain any object to the boundaries of the screen. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
AceBlkwell
Member #13,038
July 2011
|
Sounds good. I was thinking there was a more systemic way than using a line by line deviation. Thanks. |
|