Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Collision Detection with a rotating square.

Credits go to Edgar Reynaldo for helping out!
This thread is locked; no one can reply to it. rss feed Print
 1   2 
Collision Detection with a rotating square.
Darren Hoehna
Member #15,297
September 2013

I have tried the code yet I have not found out why it does that. I'm still wondering why doesn't the rectangle go flat when both x-coordinates are the same. But when I find it our I'll give you a hollar.

Here is the code I used to make the rotating square work. It doesn't have any functions or methods yet, but it works. :)

#SelectExpand
1#include <allegro5/allegro.h> 2#include <allegro5/allegro_image.h> 3#include <allegro5/allegro_native_dialog.h> 4#include <allegro5/allegro_primitives.h> 5#include <stdio.h> 6#include <math.h> 7#include <iostream> 8 9 10const int SCREEN_WIDTH = 640; 11const int SCREEN_HEIGTH = 640; 12 13const int SHIP_WIDTH = 32; 14const int SHIP_HEIGTH = 32; 15 16const double CHANGE_IN_ANGLE = 0.034906585; 17const double SPEED_OF_SHIP = 4.0; 18 19const double FRAMES_PER_SECOND = 60.0; 20 21const enum KEYS {UP, DOWN, LEFT, RIGHT}; 22 23//I keep track of the center and not a second point since the second point is never used. 24//To get the secodn point the program uses First_X_Position + SHIP_WIDTH 25 26//The Center_X_Position and Center_Y_Position is used in the redraw step near the end of the program. 27//The Center points are to make the square move around the center of the square. 28struct ShipStuff 29{ 30 float First_X_Position; 31 float First_Y_Position; 32 float Width; 33 float Heigth; 34 float Center_X_Position; 35 float Center_Y_Position; 36 float Angle; 37}; 38int main(int argc, char **argv) 39{ 40 ALLEGRO_DISPLAY *Display = NULL; 41 ALLEGRO_TIMER *Timer = NULL; 42 ALLEGRO_EVENT_QUEUE *EventQueue = NULL; 43 44 ShipStuff Ship; 45 Ship.First_X_Position = SCREEN_WIDTH / 2.0; 46 Ship.First_Y_Position = SCREEN_HEIGTH / 2.0; 47 Ship.Width = 0.0f; 48 Ship.Heigth = 0.0f; 49 Ship.Center_X_Position = Ship.First_X_Position + (SHIP_WIDTH / 2.0); 50 Ship.Center_Y_Position = Ship.First_Y_Position + (SHIP_HEIGTH / 2.0); 51 Ship.Angle = -ALLEGRO_PI/2; 52 if(!al_init()) 53 { 54 al_show_native_message_box(Display, "Bad Init", "Bad Init", "Can't initilize allegro", NULL, ALLEGRO_MESSAGEBOX_ERROR); 55 return -1; 56 } 57 58 al_init_primitives_addon(); 59 Display = al_create_display(SCREEN_WIDTH, SCREEN_HEIGTH); 60 if(!Display) 61 { 62 al_show_native_message_box(Display, "Bad Display", "Bad Display", "Sorry, can't make the display", NULL, ALLEGRO_MESSAGEBOX_ERROR); 63 return -1; 64 } 65 66 if(!al_install_keyboard()) 67 { 68 al_show_native_message_box(Display, "No Keyboard", "No Keyboard", "Sorry, can't install the keyboard", NULL, ALLEGRO_MESSAGEBOX_ERROR); 69 al_destroy_display(Display); 70 return -1; 71 } 72 73 Timer = al_create_timer(1.0/FRAMES_PER_SECOND); 74 if(!Timer) 75 { 76 al_show_native_message_box(Display, "Bad Timer", "Bad Timer", "Sorry, can't make the timer", NULL, ALLEGRO_MESSAGEBOX_ERROR); 77 al_destroy_display(Display); 78 return -1; 79 } 80 81 EventQueue = al_create_event_queue(); 82 if(!EventQueue) 83 { 84 al_show_native_message_box(Display, "Bad Queue", "Bad Queue", "Can't make the event queue.", NULL, ALLEGRO_MESSAGEBOX_ERROR); 85 al_destroy_display(Display); 86 al_destroy_timer(Timer); 87 return -1; 88 } 89 90 //UP, DOWN, LEFT, RIGHT 91 bool KeyPresses[] = {false, false, false, false}; 92 bool Redraw = true; 93 double Ships_X_Position = SCREEN_HEIGTH / 2.0; 94 double Ships_Y_Position = SCREEN_WIDTH / 2.0; 95 96 al_register_event_source(EventQueue, al_get_display_event_source(Display)); 97 al_register_event_source(EventQueue, al_get_timer_event_source(Timer)); 98 al_register_event_source(EventQueue, al_get_keyboard_event_source()); 99 al_draw_filled_rectangle(Ship.First_X_Position, Ship.First_Y_Position, Ship.First_X_Position + SHIP_WIDTH, Ship.First_Y_Position + SHIP_HEIGTH, al_map_rgb(255, 124, 68)); 100 al_flip_display(); 101 al_start_timer(Timer); 102 float AngleInRadians = 0.0f; 103 bool DoExit = false; 104 while (!DoExit) 105 { 106 ALLEGRO_EVENT Event; 107 al_wait_for_event(EventQueue, &Event); 108 109 if(Event.type == ALLEGRO_EVENT_TIMER) 110 { 111 if(KeyPresses[UP]) 112 { 113 Ship.First_X_Position += cos(Ship.Angle) * SPEED_OF_SHIP; 114 Ship.Center_X_Position += cos(Ship.Angle) * SPEED_OF_SHIP; 115 116 Ship.First_Y_Position += sin(Ship.Angle) * SPEED_OF_SHIP; 117 Ship.Center_Y_Position += sin(Ship.Angle) * SPEED_OF_SHIP; 118 } 119 if (KeyPresses[DOWN]) 120 { 121 Ship.First_X_Position -= (cos(Ship.Angle) * SPEED_OF_SHIP); 122 Ship.Center_X_Position -= cos(Ship.Angle) * SPEED_OF_SHIP; 123 124 Ship.First_Y_Position -= (sin(Ship.Angle) * SPEED_OF_SHIP); 125 Ship.Center_Y_Position -= sin(Ship.Angle) * SPEED_OF_SHIP; 126 127 } 128 if(KeyPresses[LEFT]) 129 { 130 Ship.Angle -= CHANGE_IN_ANGLE; 131 if( Ship.Angle > (2 * 3.1415)) 132 { 133 Ship.Angle = 0; 134 } 135 136 } 137 if(KeyPresses[RIGHT]) 138 { 139 Ship.Angle += CHANGE_IN_ANGLE; 140 if(Ship.Angle > (2 * 3.1415)) 141 { 142 Ship.Angle = 0; 143 } 144 145 } 146 Redraw = true; 147 } 148 else if (Event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) 149 { 150 break; 151 } 152 else if (Event.type == ALLEGRO_EVENT_KEY_DOWN) 153 { 154 switch (Event.keyboard.keycode) 155 { 156 case ALLEGRO_KEY_UP: 157 KeyPresses[UP] = true; 158 break; 159 case ALLEGRO_KEY_DOWN: 160 KeyPresses[DOWN] = true; 161 break; 162 case ALLEGRO_KEY_LEFT: 163 KeyPresses[LEFT] = true; 164 break; 165 case ALLEGRO_KEY_RIGHT: 166 KeyPresses[RIGHT] = true; 167 break; 168 } 169 } 170 else if (Event.type == ALLEGRO_EVENT_KEY_UP) 171 { 172 switch(Event.keyboard.keycode) 173 { 174 case ALLEGRO_KEY_UP: 175 KeyPresses[UP] = false; 176 break; 177 case ALLEGRO_KEY_DOWN: 178 KeyPresses[DOWN] = false; 179 break; 180 case ALLEGRO_KEY_LEFT: 181 KeyPresses[LEFT] = false; 182 break; 183 case ALLEGRO_KEY_RIGHT: 184 KeyPresses[RIGHT] = false; 185 break; 186 case ALLEGRO_KEY_ESCAPE: 187 DoExit = true; 188 break; 189 } 190 } 191 192 if(Redraw && al_is_event_queue_empty(EventQueue)) 193 { 194 195 Redraw = false; 196 al_clear_to_color(al_map_rgb(0, 0, 0)); 197 ALLEGRO_TRANSFORM ShipTransformation, Old; 198 al_identity_transform(&ShipTransformation); 199 al_translate_transform(&ShipTransformation, -(SCREEN_WIDTH - (SCREEN_WIDTH - Ship.Center_X_Position)), 200 -(SCREEN_HEIGTH - (SCREEN_HEIGTH - Ship.Center_Y_Position))); 201 al_rotate_transform(&ShipTransformation, Ship.Angle); 202 al_translate_transform(&ShipTransformation, (Ship.Center_X_Position), (Ship.Center_Y_Position)); 203 al_translate_transform(&ShipTransformation, 0.0, 0.0); 204 al_use_transform(&ShipTransformation); 205 al_draw_filled_rectangle(Ship.First_X_Position, Ship.First_Y_Position, Ship.First_X_Position + SHIP_WIDTH, Ship.First_Y_Position + SHIP_HEIGTH, al_map_rgb(255,127,0)); 206 al_use_transform(&Old); 207 al_flip_display(); 208 } 209 } 210 al_destroy_timer(Timer); 211 al_destroy_event_queue(EventQueue); 212 al_destroy_display(Display); 213 214 return 0; 215}

Also, I found this very interesting.

Let's say you have these variables:
Upper_Left_X
Upper_Left_y
Lower_Right_X
Lower_RIght_Y

and you make a square by doing this
al_draw_filled_rectangle(Upper_Left_X, Upper_Left_y, Lower_Right_X, Lower_Right_Y,
al_map_rgb(255, 10, 13))

Than the square contorts and will become a straight line whenever the two X coordinates are the same.

But if you draw a rectangle like this.
al_draw_filled_rectangle(Upper_Left_X, Upper_Left_Y, SHIP_WIDTH, SHIP_HEIGTH,
al_map_rgb(255, 10, 13)) then the rectangle will always stay the same shape.

Edgar Reynaldo
Member #8,592
May 2007
avatar

Hey, you can post your code now Darren.

And if you click on the pen and paper icon at the top of your post you can edit it and then send to top.

Darren Hoehna
Member #15,297
September 2013

The transformations are done with the center of the square. That way the square will rotate around the center. Because of that I don't know who to the stop the square from moving if one point touches the border.

I'm looking into this as well. I just can't figure it out yet.

 1   2 


Go to: