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

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: