Allegro.cc Forums » Game Design & Concepts » Rotating square with mouse

 Rotating square with mouse
 AleX-G Squadron Member #13,593 October 2011 I wanted to ask, how can i make a square rotate in base of event.mouse.xevent.mouse.yThe square is al_draw_rectangle(x-15,y-15,x+15,y+15,al_map_rgb(0,0,255),3.0);Is there any way to do that? The square cannot move with mouse, only with keyboard. www.anothergames.com
 SiegeLord Member #7,827 October 2006 Your question is a bit incomplete... let me use my A5 mind reading addon and guess what you actually want.You can do that using transformations:```ALLEGRO_TRANSFORM trans; al_identity_transform(&trans); al_translate_transform(&trans, -cx, -cy); //cx,cy are set to the mouse coordinates in the mouse event al_rotate_transform(&trans, theta); al_translate_transform(&trans, cx, cy); al_use_transform(&trans); al_draw_rectangle(x - 15, y - 15, x + 15, y + 15, al_map_rgb(0, 0, 255), 3.0); /* Reset transform */ al_identity_transform(&trans); al_use_transform(&trans); ``` "For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]
 AleX-G Squadron Member #13,593 October 2011 Your code works perfect. But i need to rotate the square.Here is what i want to do:The square must be at the center and wont move. If i move the mouse, it wont move again.It will only rotate in base of the mouse e.mouse.x and e.mouse.y www.anothergames.com
 Edgar Reynaldo Member #8,592 May 2007 Sorry, what? You need to be clearer.What I gather so far :1) The square is centered on the center of the screen.2?) You want to rotate the square according to the direction from the center of the square to the mouse position?```double theta_radians = atan2(event.mouse.y - square_center_y , event.mouse.x - square_center_x); ``` Then use a transform to center on the center of the square, then add in a rotate transform to rotate by theta_radians, then draw the square.
 AleX-G Squadron Member #13,593 October 2011 I have used the AMCerasoli video of networking, because it is clearer.You see the player rotates when he moves the mouse?I want to make the same thing, just with a square.Also, the code of siege worked, but the center was not the square, but the top left corner of the screen. How to change the center? www.anothergames.com
 SiegeLord Member #7,827 October 2006 How about this:```ALLEGRO_TRANSFORM trans; al_identity_transform(&trans); al_rotate_transform(&trans, theta); al_translate_transform(&trans, x, y); al_use_transform(&trans); al_draw_rectangle(-15, -15, 15, 15, al_map_rgb(0, 0, 255), 3.0); /* Reset transform */ al_identity_transform(&trans); al_use_transform(&trans); ``` You'd compute the theta using the formula Edgar posted. "For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]
 AleX-G Squadron Member #13,593 October 2011 Same thing again, it just moved a littleWho in the world understands this from the manual"Apply a translation to a transformation."Also, i tried scale transform and it didnt work at all with the mouse.atan2 is wrong in my configuration after including math.h which wasnt even mentioned to use:double theta_radians = atan2(e.mouse.y - (x + 15) , e.mouse.x - (y - 15)); www.anothergames.com
 SiegeLord Member #7,827 October 2006 AleX-G Squadron said: Same thing again, it just moved a little Then you're doing something wrong, as this example shows that it works fine:#SelectExpand 1#include 2#include 3#include 4#include 5int main() 6{ 7 al_init(); 8 ALLEGRO_DISPLAY* d = al_create_display(800, 600); 9 al_init_primitives_addon(); 10 al_install_mouse(); 11 al_install_keyboard(); 12 ALLEGRO_TIMER* t = al_create_timer(1.0 / 60); 13 ALLEGRO_EVENT_QUEUE* q = al_create_event_queue(); 14 al_register_event_source(q, al_get_mouse_event_source()); 15 al_register_event_source(q, al_get_keyboard_event_source()); 16 al_register_event_source(q, al_get_timer_event_source(t)); 17 18 int x = 200; 19 int y = 200; 20 int vx = 0; 21 int vy = 0; 22 int mx = 0; 23 int my = 0; 24 float theta = 0; 25 26 al_start_timer(t); 27 bool quit = false; 28 bool redraw = true; 29 while(!quit) 30 { 31 ALLEGRO_EVENT e; 32 al_wait_for_event(q, &e); 33 switch(e.type) 34 { 35 case ALLEGRO_EVENT_MOUSE_AXES: 36 mx = e.mouse.x; 37 my = e.mouse.y; 38 break; 39 case ALLEGRO_EVENT_KEY_DOWN: 40 switch(e.keyboard.keycode) 41 { 42 case ALLEGRO_KEY_ESCAPE: 43 quit = true; 44 break; 45 case ALLEGRO_KEY_RIGHT: 46 vx += 1; 47 break; 48 case ALLEGRO_KEY_LEFT: 49 vx -= 1; 50 break; 51 case ALLEGRO_KEY_UP: 52 vy -= 1; 53 break; 54 case ALLEGRO_KEY_DOWN: 55 vy += 1; 56 break; 57 } 58 break; 59 case ALLEGRO_EVENT_KEY_UP: 60 switch(e.keyboard.keycode) 61 { 62 case ALLEGRO_KEY_RIGHT: 63 vx -= 1; 64 break; 65 case ALLEGRO_KEY_LEFT: 66 vx += 1; 67 break; 68 case ALLEGRO_KEY_UP: 69 vy += 1; 70 break; 71 case ALLEGRO_KEY_DOWN: 72 vy -= 1; 73 break; 74 } 75 break; 76 case ALLEGRO_EVENT_TIMER: 77 x += vx; 78 y += vy; 79 theta = atan2(my - y, mx - x); 80 redraw = true; 81 break; 82 } 83 84 if(al_is_event_queue_empty(q) && redraw) 85 { 86 al_clear_to_color(al_map_rgb_f(0, 0, 0)); 87 88 ALLEGRO_TRANSFORM trans; 89 al_identity_transform(&trans); 90 al_rotate_transform(&trans, theta); 91 al_translate_transform(&trans, x, y); 92 al_use_transform(&trans); 93 al_draw_rectangle(-15, -15, 15, 15, al_map_rgb(0, 0, 255), 3.0); 94 /* Reset transform */ 95 al_identity_transform(&trans); 96 al_use_transform(&trans); 97 98 al_flip_display(); 99 } 100 } 101 102 return 0; 103} "For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]
 AleX-G Squadron Member #13,593 October 2011 atan2 doesnt work. I dont know why. I am using visual studio 2012I copy pasted your code and it doesnt work on my machine only because of atan2 www.anothergames.com
 Arthur Kalliokoski Second in Command February 2005 Are you linking with math.lib? “Throughout history, poverty is the normal condition of man. Advances which permit this norm to be exceeded — here and there, now and then — are the work of an extremely small minority, frequently despised, often condemned, and almost always opposed by all right-thinking people. Whenever this tiny minority is kept from creating, or (as sometimes happens) is driven out of a society, the people then slip back into abject poverty. This is known as "bad luck.”― Robert A. Heinlein
 AleX-G Squadron Member #13,593 October 2011 I added the math.lib in the Linker -> General -> Additional Library DependenciesUsed this pathC:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include;%(AdditionalLibraryDirectories)Then i tried this other oneC:\Program Files %28x86%29\Microsoft Visual Studio 11.0\VC\includeStill the same www.anothergames.com
 CodeStepper Member #14,495 August 2012 ``` theta = atan2(my - y, mx - x); ``` I have the same problem Try this ``` theta = atan2((float)(my - y), (float)(mx - x)); ``` Theta in this case must be float AleX-G Squadron said: I am using visual studio 2012 o.OVisual Studio for Windows 8?Is there Intelisense? I'm using 2008, because 2010 haven't got intelisense :/And I think, that this is better way to do rotate something: #SelectExpand 1#include 2#include 3#include 4#include 5#include 6 7int main( void ) 8{ 9 // Inicjalizacja bibliotek 10 al_init( ); 11 al_init_primitives_addon( ); 12 al_init_font_addon( ); 13 al_init_ttf_addon( ); 14 15 // Instalowanie kontrolerów 16 al_install_mouse( ); 17 al_install_keyboard( ); 18 al_install_joystick( ); 19 20 // Zmienne allegro 21 ALLEGRO_DISPLAY *display = al_create_display( 800, 600 ); 22 ALLEGRO_EVENT_QUEUE *queue = al_create_event_queue( ); 23 ALLEGRO_TIMER *timer = al_create_timer( 1.0 / 60 ); 24 25 // Rejestrowanie zdarzeń 26 al_register_event_source( queue, al_get_keyboard_event_source( ) ); 27 al_register_event_source( queue, al_get_mouse_event_source( ) ); 28 al_register_event_source( queue, al_get_joystick_event_source( ) ); 29 al_register_event_source( queue, al_get_display_event_source( display ) ); 30 al_register_event_source( queue, al_get_timer_event_source( timer ) ); 31 32/////////////////////////////////////////////////////////////////////////////// 33 // CREATE BITMAP 34/////////////////////////////////////////////////////////////////////////////// 35 ALLEGRO_BITMAP *bitmap = al_create_bitmap( 40, 40 ); 36 al_set_target_bitmap( bitmap ); 37 al_clear_to_color( al_map_rgb( 60, 80, 100 ) ); 38 al_set_target_bitmap( al_get_backbuffer( display ) ); 39 40 bool run = true; 41 bool render = true; 42 43 bool keys[4] = { false, false, false, false }; 44 45 int posx = 40; 46 int posy = 40; 47 float theta = 0; 48 49 al_start_timer( timer ); 50 while( run ) 51 { 52 ALLEGRO_EVENT event; 53 al_wait_for_event( queue, &event ); 54 55 switch( event.type ) 56 { 57 case ALLEGRO_EVENT_DISPLAY_CLOSE: 58 59 run = false; 60 61 break; 62 case ALLEGRO_EVENT_TIMER: 63 64 render = true; 65 66 break; 67 case ALLEGRO_EVENT_KEY_DOWN: 68 69 switch( event.keyboard.keycode ) 70 { 71 case ALLEGRO_KEY_UP: 72 keys[0] = true; 73 break; 74 case ALLEGRO_KEY_DOWN: 75 keys[1] = true; 76 break; 77 case ALLEGRO_KEY_LEFT: 78 keys[2] = true; 79 break; 80 case ALLEGRO_KEY_RIGHT: 81 keys[3] = true; 82 break; 83 } 84 85 break; 86 case ALLEGRO_EVENT_KEY_UP: 87 88 switch( event.keyboard.keycode ) 89 { 90 case ALLEGRO_KEY_UP: 91 keys[0] = false; 92 break; 93 case ALLEGRO_KEY_DOWN: 94 keys[1] = false; 95 break; 96 case ALLEGRO_KEY_LEFT: 97 keys[2] = false; 98 break; 99 case ALLEGRO_KEY_RIGHT: 100 keys[3] = false; 101 break; 102 case ALLEGRO_KEY_ESCAPE: 103 run = false; 104 break; 105 } 106 107 break; 108 case ALLEGRO_EVENT_MOUSE_AXES: 109 theta = atan2( (float)(event.mouse.y - posy + 10), (float)(event.mouse.x - posx + 10) ); 110 break; 111 } 112 113 if( render && al_is_event_queue_empty( queue ) ) 114 { 115 render = false; 116 al_clear_to_color( al_map_rgb( 250, 250, 250 ) ); 117 118 if( keys[0] ) posy -= 3; 119 else if( keys[1] ) posy += 3; 120 if( keys[2] ) posx -= 3; 121 else if( keys[3] ) posx += 3; 122 123/////////////////////////////////////////////////////////////////////////////// 124 // ROTATE BITMAP 125/////////////////////////////////////////////////////////////////////////////// 126 al_draw_rotated_bitmap( bitmap, 20, 20, posx, posy, theta, 0 ); 127 128 al_flip_display( ); 129 } 130 } 131 132 // Destruktory 133 al_destroy_display ( display ); 134 al_destroy_event_queue ( queue ); 135 al_destroy_timer ( timer ); 136 al_destroy_bitmap ( bitmap ); 137 138 return 0; 139}
 SiegeLord Member #7,827 October 2006 CodeStepper said: Theta in this case must be float There is no integer version of atan2, that's just nonsensical.What does this code print?```#include #include #include int main() { std::cout << typeid(atan2((int)0, int(0))).name() << std::endl; return 0; } ``` Quote: And I think, that this is better way to do rotate something: My way is better for primitives and in fact works for all drawables, while your way only works for bitmaps. "For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]
 CodeStepper Member #14,495 August 2012 Oh... but there is double, long dobule and float atan2 version!In fact, you can create bitmap from all drawable primitives and then rotate it While I compile your code, there is error: ```error C2668: 'atan2' : ambiguous call to overloaded function c:\program files\microsoft visual studio 9.0\vc\include\math.h(547): could be 'long double atan2(long double,long double)' c:\program files\microsoft visual studio 9.0\vc\include\math.h(499): or 'float atan2(float,float)' c:\program files\microsoft visual studio 9.0\vc\include\math.h(110): or 'double atan2(double,double)' while trying to match the argument list '(int, int)' ``` I must do cast to float.Sory, but my previous words are logical
 SiegeLord Member #7,827 October 2006 CodeStepper said: In fact, you can create bitmap from all drawable primitives and then rotate it Inefficient and unnecessary.Quote: While I compile your code, there is error: Well a compile error makes sense. It compiling without error and then not functioning does not. Either way, the original code is C not C++ . "For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]
 CodeStepper Member #14,495 August 2012 But if you using bitmaps in this case, application works better Processor has less to countAt least I think so...
 SiegeLord Member #7,827 October 2006 CodeStepper said: But if you using bitmaps in this case, application works better If you only need to rotate a single pre-existing bitmap, then yeah... no need for transformations. "For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]
 AMCerasoli Member #11,955 May 2010 Well, I'm currently not using transformations at all...
 AleX-G Squadron Member #13,593 October 2011 @codestepperWOW THANKS! It works perfect! Can you make some notes in english to the program so i can understand it better? I mean especially the transformation, because i dont understand it well.Visual Studio 2012 is the same as 2010, with some changes and it has intellisense. I have had 2010 and it had intellisense, i dont know what version you had. I have worked on both for Allegro 5. I recently moved a game from VC9 to VC10 and it was very easy and fast.I dont get it why it is a bad thing to do it like that, because it works 100%Also, if anyone can make a pacman which opens its mouth using the al_draw_pieslice that would be great as i was trying to do it today without any success.@cerasoliWhat is your method of doing it? www.anothergames.com
 CodeStepper Member #14,495 August 2012 Hmm... i think i don't make any bugs in comments If yes, sorry Sorry for variable names - some of them don't reflect their rolesSo, code for pac-man primitives version with comments: #SelectExpand 1#include 2#include 3#include 4#include 5#include 6int main() 7{ 8 const float framesPerSecond = 60; /////////////////// frames 9 10 al_init(); 11 ALLEGRO_DISPLAY* d = al_create_display(800, 600); 12 al_init_primitives_addon(); 13 al_install_mouse(); 14 al_install_keyboard(); 15 ALLEGRO_TIMER* t = al_create_timer(1.0 / framesPerSecond); 16 ALLEGRO_EVENT_QUEUE* q = al_create_event_queue(); 17 al_register_event_source(q, al_get_mouse_event_source()); 18 al_register_event_source(q, al_get_keyboard_event_source()); 19 al_register_event_source(q, al_get_timer_event_source(t)); 20 21 int x = 200; // position x 22 int y = 200; // position y 23 int vx = 0; // velocity x 24 int vy = 0; // velocity y 25 int mx = 0; // mouse x 26 int my = 0; // mouse y 27 float theta = 0; // theta ( atan2 ) 28 29 // Maximum radius ( 360 degress in radians ) - half is 3.14159, ( so, half it's PI ) 30 const float maxDelta = 6.28318; 31 // Minimum radius ( minimum radius of slice ( maxDelta - minDelta is real radius of slice ) ) 32 const float minDelta = 5.0; 33 34 // Automatic variables 35 float deltaFrame = ( maxDelta - minDelta ) / framesPerSecond; // value of delta adding in every frame per second 36 float currDelta = maxDelta; // start theta in 37 float currDelta2 = minDelta; // delta_theta 38 float halfDelta = ( maxDelta - minDelta ) / 2; // half of 39 40 // Decide, (TRUE) if currDelta is increasing and currDelta2 decreasing or vice versa (FALSE) 41 bool growing = false; 42 43 al_start_timer(t); 44 bool quit = false; 45 bool redraw = true; 46 while(!quit) 47 { 48 ALLEGRO_EVENT e; 49 al_wait_for_event(q, &e); 50 switch(e.type) 51 { 52 case ALLEGRO_EVENT_MOUSE_AXES: 53 mx = e.mouse.x; 54 my = e.mouse.y; 55 break; 56 case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: 57 al_rest( 1 ); 58 break; 59 case ALLEGRO_EVENT_KEY_DOWN: 60 switch(e.keyboard.keycode) 61 { 62 case ALLEGRO_KEY_ESCAPE: 63 quit = true; 64 break; 65 case ALLEGRO_KEY_RIGHT: 66 vx += 1; 67 break; 68 case ALLEGRO_KEY_LEFT: 69 vx -= 1; 70 break; 71 case ALLEGRO_KEY_UP: 72 vy -= 1; 73 break; 74 case ALLEGRO_KEY_DOWN: 75 vy += 1; 76 break; 77 } 78 break; 79 case ALLEGRO_EVENT_KEY_UP: 80 switch(e.keyboard.keycode) 81 { 82 case ALLEGRO_KEY_RIGHT: 83 vx -= 1; 84 break; 85 case ALLEGRO_KEY_LEFT: 86 vx += 1; 87 break; 88 case ALLEGRO_KEY_UP: 89 vy += 1; 90 break; 91 case ALLEGRO_KEY_DOWN: 92 vy -= 1; 93 break; 94 } 95 break; 96 case ALLEGRO_EVENT_TIMER: 97 x += vx; 98 y += vy; 99 theta = atan2((float)(my - y), (float)(mx - x)); 100 redraw = true; 101 break; 102 } 103 104 if(al_is_event_queue_empty(q) && redraw) 105 { 106 al_clear_to_color(al_map_rgb_f(0, 0, 0)); 107 108 // Transformation 109 ALLEGRO_TRANSFORM trans; 110 al_identity_transform(&trans); // creating transformation 111 al_rotate_transform(&trans, theta); // rotating display 112 al_translate_transform(&trans, x, y); // moving transformation ( display ) 113 al_use_transform(&trans); // using transformation 114 115 // Drawing pieslice 116 al_draw_pieslice( 0, 0, 20, currDelta + halfDelta, currDelta2, al_map_rgb( 255, 0, 0 ), 2 ); 117 118 /* Reset transform */ 119 al_identity_transform(&trans); 120 al_use_transform(&trans); 121 122 // Checking radius 123 if( currDelta >= maxDelta ) growing = false; 124 else if( currDelta <= minDelta + halfDelta ) growing = true; 125 126 // Decreasing or increasing 127 // In case variable currDelta2, value is multipled * 2, that the top line was moving 128 if( growing ) currDelta += deltaFrame, currDelta2 -= deltaFrame * 2; 129 else currDelta -= deltaFrame, currDelta2 += deltaFrame * 2; 130 131 al_flip_display(); 132 } 133 } 134 135 al_destroy_display( d ); 136 al_destroy_event_queue( q ); 137 al_destroy_timer( t ); 138 return 0; 139}
 AleX-G Squadron Member #13,593 October 2011 Wow, you are amazing! Thank you very much man, it worked perfect www.anothergames.com
 CodeStepper Member #14,495 August 2012 I forgot about this: ```redraw = false; ``` Paste this before: ```al_clear_to_color(al_map_rgb_f(0, 0, 0)); ``` And it will run better
 Go to: Allegro Development Installation, Setup & Configuration Allegro.cc Comments Off-Topic Ordeals The Depot Game Design & Concepts Programming Questions Recent Threads