Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » ALLEGRO_RESIZABLE & Mouse Pointer Collision Detection

This thread is locked; no one can reply to it. rss feed Print
 1   2 
ALLEGRO_RESIZABLE & Mouse Pointer Collision Detection
GaryT
Member #14,875
January 2013

When using al_set_new_display_flags(ALLEGRO_RESIZABLE), is there a way to do the following:

1) Have a program detect the size of the window as it's being manually changed by the player using the mouse. I understand the actual created display size remains the same, but would like to change certain objects size and position for collision detection to work correctly between the mouse pointer and those objects after the window has been resized by the player, otherwise the collision detection between the mouse pointer and those objects remains in the same position relative to the initially created display, whilst the graphics change size and position as the display window size is manually adjusted. In other words the collision detection happens in the wrong visual place on screen.

2) After initializing al_set_new_display_flags(ALLEGRO_RESIZABLE) and creating the display, is there a way to program the window display size as opposed to the player adjusting it using the mouse. It's just that if a player adjusts the window size, then switches into fullscreen, and then back to resizable, I'd like to know what the previous resizable size was so I can set it back to that size, rather than it be initiated at the actual created display size.

Part of My Next Entry Quoted Below, Which I can't Edit Now, Is BALONEY

GaryT said:

which I guess is essential, as if a player manually changed the window size in this way during play and the created display al_create_display(WIDTH, HEIGHT) was to change also, then the game/programming would crash.

jmasterx
Member #11,410
October 2009

1. I'm not sure I quite understand, but when Allegro detects a resize, you are sent the event which has the new display size:

I do something like:

#SelectExpand
1 void SceneManager::defaultBeginEventHandler( ALLEGRO_EVENT*evt ) 2 { 3 4 m_currentScene->processGuiInputEvent(evt); 5 6 if(evt->type == ALLEGRO_EVENT_TIMER && evt->timer.source == m_gameTimer) 7 { 8 if(m_transitioning) 9 { 10 m_transitionOpacity -= m_transitionRate; 11 12 if(m_transitionOpacity <= 0) 13 { 14 m_transitionOpacity = 0; 15 m_transitioning = false; 16 } 17 } 18 m_needsRedraw = true; 19 m_devices->getAudioManager()->logic(); 20 m_currentScene->sceneLogic(); 21 m_currentScene->processGuiLogic(); 22 m_currentScene->logic(); 23 m_devices->getNetClient()->tick(); 24 } 25 else if(evt->type == ALLEGRO_EVENT_DISPLAY_RESIZE) 26 { 27 m_needsResize = true; 28 m_newScreenWidth = evt->display.width; 29 m_newScreenHeight = evt->display.height; 30 sendResizeMessage(m_newScreenWidth,m_newScreenHeight); 31 } 32 else if(m_needsResize) 33 { 34 m_needsResize = false; 35 36 } 37 } 38 39... 40 41 void SceneManager::sendResizeMessage( int w, int h ) 42 { 43 //this is a bug in Allegro 44 if(w == 0 && h == 0) 45 { 46 return; 47 } 48 49 al_acknowledge_resize(m_devices->getDisplay()->getContext()); 50 m_g.resizeBuffer(w,h); 51 //stop transition 52 m_transitioning = false; 53 m_transitionOpacity = 0.0f; 54 m_currentScene->processGuiResizeEvent(); 55 m_currentScene->resizeEvent( 56 w,h); 57 Log::write("Scene Manager","Resize Event: Width:" + StringUtil::toString(w) + 58 " Height:" + StringUtil::toString(h)); 59 }

So with that, you get the new display size and you can update your gui however you want.

2. To resize it yourself you do http://alleg.sourceforge.net/a5docs/refman/display.html#al_resize_display

GaryT
Member #14,875
January 2013

So far I've found resizing the window with the mouse (whilst playing the game) when using ALLEGRO_RESIZABLE only shrinks or expands the graphics, which I guess is essential, as if a player manually changed the window size in this way during play and the created display al_create_display(WIDTH, HEIGHT) was to change also, then the game/programming would crash.

So what I'm finding (during play) is that even though the graphics shrink and expand as they should when using the mouse to adjust the window size, the mouse pointer collision detection isn't aligned with the graphics because the mouse pointer still references the created display al_create_display(WIDTH, HEIGHT) which understandably doesn't change as the window is resized. To describe this, if the window gets smaller the collision detection happens to the right of the objects as graphically they are displayed more to the left (the window shrinks along with the displayed graphics within it, but al_create_display(WIDTH, HEIGHT) stays the same). Similarly if the window gets larger the collision detection happens to the left of the objects.

I'm guessing now the features which I'm after don't exist within ALLEGRO. Please note this does not stop my main game from playing at all, but just messes up the various stages where I need to have the mouse effectively click on certain button images.

If access to the ALLEGRO_RESIZABLE window were available as parameters Width and Height, then I guess there would be various ways to compensate. For example if the window was made smaller, the int x = al_get_mouse_state_axis(&state, 0) could be increased proportionally to the window getting smaller effectively making int x collision detect correctly relative to al_create_display(WIDTH, HEIGHT).

With regards to my initial post where I suggested changing the size and positions of various objects, I'm now thinking that would only work if there was a second copy of the objects, one unchanged for the graphics (ALLEGRO_RESIZABLE), and one which does change proportionally to the resized window.

I think the easiest way (because of less work to do) might be the first way, adding or subtracting to the x = al_get_mouse_state_axis(&state, 0) values.

So it seems that for my question 1) I need access to the ALLEGRO_RESIABLE manually adjusted window width and height in the form of parameters, to work with within my programming, and for my question 2) I guess this also is not possible for me to do.

jmasterx
Member #11,410
October 2009

I'm just a bit confused by some of this. I understand your problem, but I don't quite understand why it should happen.

My game dynamically resizes and repositions elements and my gui mouse stuff works fine.

What I find strange too is that you're saying changing the window size affects the mouse position returned, which should not be since mouse starts at top left (0,0).

Is there a way you could either send your game src or make an example that demonstrates the problem. There might just be something simple you need to do.

Also, are you just upscaling your content? Because in that case, the mouse and gui positions won't line up, you'd have to transform your mouse position. I have code for that in my gui api if you need it.

GaryT
Member #14,875
January 2013

Are you saying if you have an object exactly in the middle of the display which can be collision detected with the mouse pointer, that when in ALLEGRO_RESIZABLE if you manually resize the window (using the mouse) to approximately half the size whilst playing, that your object which is now half the size and still in the middle of the display (like it is for me), still has the collision detection with the mouse pointer working correctly, both being aligned.

For me changing the window size does not affect the mouse position returned. If it did so proportionally to the window size being changed as I've described, that might be the perfect solution.

I've rewritten some of my last post to try and make it a bit clearer, as some of it was not good.

Thank you jmasterx for helping with this :)

Edgar Reynaldo
Member #8,592
May 2007
avatar

It's not about changing the mouse position but changing the button position. When you scale your graphics your button rectangle changes. My GUI mouse stuff works fine with al_resize_display and with ALLEGRO_EVENT_DISPLAY_RESIZE. Try and show us example code that doesn't work. You can use <code></code> tags.

jmasterx
Member #11,410
October 2009

Right, so you are proportionally resizing your elements.

Whereas in my case, in my gui, I literally have an algorithm running that says:

onResize:
position = screen / 2; //center
size = screen * 0.25f;

And thus, my mouse coordinates make sense.

I suspect that regardless of the size of your screen, your elements just RENDER proportionally, so you do not actually change their location and size.

This is the class I made that can transform your mouse.

https://github.com/jmasterx/Agui/blob/master/src/Agui/Transform.cpp

My gui uses it like this:

#SelectExpand
1void Gui::_dispatchMouseEvents() 2{ 3if(isDelayingMouseDownEvents()) 4{ 5while(!queuedMouseDown.empty()) 6{ 7MouseInput mi = queuedMouseDown.back(); 8queuedMouseDown.pop(); 9if(mi.type == MouseEvent::MOUSE_DOWN) 10{ 11_dispatchMousePreview(mi,mi.type); 12if(!mouseEvent.isConsumed()) 13handleMouseDown(mi); 14} 15} 16} 17while(!input->isMouseQueueEmpty()) 18{ 19MouseInput mi = input->dequeueMouseInput(); 20if(isUsingTransform()) 21{ 22float x = (float)mi.x; 23float y = (float)mi.y; 24transform.transformPoint(&x,&y); 25mi.x = (int)x; 26mi.y = (int)y; 27}

So the idea is, whatever transformation is applied to upscale the rendering must be applied to your mouse position.

The alternative, as I had mentioned is to change the size and position of your gui elements so that the mouse coordinates are screen-relative rather than world-oriented.

GaryT
Member #14,875
January 2013

Thank you both :)

I'm not resizing the 'object graphics' or the 'created display' in the way that is perhaps being assumed. I'm not using any other resize() function/class other than the one below.

I'm using: al_set_new_display_flags(ALLEGRO_RESIZABLE), which only allows the display window to change size via use of the mouse whilst the game is running.

Please confirm that it's (ALLEGRO_RESIZABLE) to which you are referring :)

jmasterx
Member #11,410
October 2009

One important thing, do you call al_acknowledge_resize ?

If you do not you will get the issues you seem to be describing because the internal buffer might not resize itself if you do not acknowledge the resize event.

http://alleg.sourceforge.net/a5docs/refman/display.html#al_acknowledge_resize

GaryT
Member #14,875
January 2013

Ah flipping heck.

No I don't. Not yet anyway.

I have to ask in excitement before I try It :D, should this work with al_set_new_display_flags(ALLEGRO_RESIZABLE) as I've described.

I'll give it a try :)

jmasterx
Member #11,410
October 2009

It only works with that display flag ;)
in your event loop:

case ALLEGRO_EVENT_DISPLAY_RESIZE:
//call here
break;

http://alleg.sourceforge.net/a5docs/refman/events.html#allegro_event_display_resize

GaryT
Member #14,875
January 2013

I'm only doing the following so far. I must be missing something by the looks of it. It's doing something but I need to figure it out. I'm not yet using "ALLEGRO_EVENT_DISPLAY_RESIZE". Do I need to add that in. I'll keep at it.

#SelectExpand
1DestroyBitmaps(); 2DestroyFonts(); 3 4al_destroy_display(display); 5 6al_set_new_display_flags(ALLEGRO_RESIZABLE); 7 8display = al_create_display(WIDTH, HEIGHT); 9 10LoadBitmaps(); 11LoadFonts();

jmasterx
Member #11,410
October 2009

What does your main loop look like?

This is old and dated but might help https://www.allegro.cc/forums/thread/603224

#SelectExpand
1/*====================================== 2ALLEGRO 5 TEMPLATE 3======================================== */ 4 5#include <stdlib.h> //Standard library 6#include <string.h> //String functions 7#include <sstream> //More string functions 8 9#include <allegro5/allegro.h> 10#include <allegro5/allegro5.h> 11#include <allegro5/allegro_image.h> 12#include <allegro5/allegro_primitives.h> 13#include <allegro5/allegro_audio.h> 14#include <allegro5/allegro_font.h> 15#include <allegro5/allegro_ttf.h> 16#include <allegro5/allegro_vorbis.h> 17#include <allegro5/allegro_flac.h> 18#include <allegro5/allegro_opengl.h> 19#include <allegro5/allegro_physfs.h> 20#include <physfs.h> 21 22#include <vector> //Dynamic array data structure 23#include <queue> //Queue FIFO data structure 24#include <cmath> // C Math functions 25#include <ctime> // C Time functions 26 27#define FRAME_RATE 60 28 29//Declarations 30ALLEGRO_DISPLAY *display; 31ALLEGRO_MONITOR_INFO info; 32ALLEGRO_TIMER *timer; 33bool done; 34//color 35ALLEGRO_COLOR BLACK = al_map_rgb(0,0,0); 36 37//Keyboard 38bool key[256]; 39 40//Mouse 41int mX = 0; 42int mY = 0; 43 44void init() { 45 //Install event handlers 46 al_init(); 47 al_init_image_addon(); 48 al_init_font_addon(); 49 al_init_ttf_addon(); 50 al_install_mouse(); 51 al_install_keyboard(); 52 al_install_joystick(); 53 al_install_audio(ALLEGRO_AUDIO_DRIVER_AUTODETECT); 54 al_init_ogg_vorbis_addon(); 55 56 //For PhysFS 57 //PHYSFS_init(0); 58 //PHYSFS_addToSearchPath("",1); 59 60 // Start a timer to regulate speed 61 62 timer = al_install_timer(1.0/FRAME_RATE); 63 al_start_timer(timer); 64 65 //for audio.... 66 al_reserve_samples(64); 67 68 //for keyboard... 69 memset(key,0,sizeof(key)); 70 71 //show the mouse 72 al_show_mouse_cursor(); 73 74 //make the random function randomer 75 srand(time(NULL)); 76 77 78 //show screen 79 al_set_new_display_flags(ALLEGRO_RESIZABLE); 80 display = al_create_display(640, 480); 81 82 //For PhysFS 83 //al_set_physfs_file_interface(); 84 85 //Window Title 86 al_set_window_title("Allegro 5 Template"); 87 88 89 90 91} 92 93//Mouse_Down 94void mousedown(ALLEGRO_MOUSE_EVENT *mouse) { 95 96 } 97//Mouse Up 98void mouseup(ALLEGRO_MOUSE_EVENT *mouse) { 99 100 } 101 102// If a key is pressed down, add it to the key array 103void keydown(ALLEGRO_KEYBOARD_EVENT *kb) { 104 key[kb->keycode] = true; 105 106 107 if(kb->keycode == ALLEGRO_KEY_ESCAPE) { 108 109 done = true; 110 } 111} 112 113// If a key is released, mark it as unpressed 114void keyup(ALLEGRO_KEYBOARD_EVENT *kb) { 115 key[kb->keycode] = false; 116} 117 118// If an operating system repeat event comes in, set the flag 119void keyrepeat(ALLEGRO_KEYBOARD_EVENT *kb) { 120 121} 122 123//Mouse Move 124 125void mouseaxes(ALLEGRO_MOUSE_EVENT *mouse) { 126 mX = mouse->x; 127 mY = mouse->y; 128 129 } 130//RENDER CURRENT FRAME 131 void render() 132 { 133 //draw to the screen 134 135 al_clear_to_color(BLACK); 136 //code goes here 137 al_flip_display(); 138 139 140 141 } 142 143int main(int argc, char *argv[]) 144 145{ 146 //initialize game 147 init(); 148 bool need_redraw = true; 149 150 //Main Loop 151 152//***** Start Main Code Here ***** 153 154 // Start the event queue to handle keyboard input and our timer 155 ALLEGRO_EVENT_QUEUE *queue = al_create_event_queue(); 156 al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP); 157 al_register_event_source(queue, (ALLEGRO_EVENT_SOURCE*)al_get_keyboard_event_source()); 158 al_register_event_source(queue, (ALLEGRO_EVENT_SOURCE*)al_get_mouse_event_source()); 159 al_register_event_source(queue, (ALLEGRO_EVENT_SOURCE*)timer); 160 al_register_event_source(queue, (ALLEGRO_EVENT_SOURCE*)display); 161 ALLEGRO_EVENT event; 162 while(!done) { 163 164 // Block until an event enters the queue 165 if (need_redraw && al_event_queue_is_empty(queue)) { 166 render(); 167 need_redraw = false; 168 } 169 al_wait_for_event(queue, &event); 170 171 switch(event.type) { 172 case ALLEGRO_EVENT_MOUSE_AXES: 173 mouseaxes(&event.mouse); 174 break; 175 176 case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: 177 mousedown(&event.mouse); 178 break; 179 180 case ALLEGRO_EVENT_MOUSE_BUTTON_UP: 181 mouseup(&event.mouse); 182 break; 183 184 case ALLEGRO_EVENT_KEY_DOWN: 185 keydown(&event.keyboard); 186 break; 187 188 case ALLEGRO_EVENT_KEY_UP: 189 keyup(&event.keyboard); 190 break; 191 192 case ALLEGRO_EVENT_KEY_REPEAT: 193 keyrepeat(&event.keyboard); 194 break; 195 196 case ALLEGRO_EVENT_TIMER: 197 need_redraw = true; 198 break; 199 case ALLEGRO_EVENT_DISPLAY_RESIZE: 200 al_acknowledge_resize(event.display.source); 201 break; 202 case ALLEGRO_EVENT_DISPLAY_CLOSE: 203 return 0; 204 break; 205 } 206 207 208 } 209//***** End Main Code Here ***** 210 211 212 return 0; 213}

GaryT
Member #14,875
January 2013

Here's the entire routine. Most of this is relevant.

#SelectExpand
1{ 2 bool realevent; 3 4 bool wait = true; 5 6 bool isplaying = false; 7 8 string displaymode; // Used For Display Name In Buttons 9 10 vector<Buttons> mode(3); // Number Of Buttons To Display 11 12 int stdx= 100; // Amount To Shift Everything Left 13 int stdoffset = -27; // Vertical Pitch 14 for(unsigned int pos = 0; pos < mode.size(); ++pos, stdoffset += 40) // Set mode Button Parameters 15 { 16 mode[pos].x = WIDTH / 2 - stdx; 17 mode[pos].y = 250 + stdoffset; 18 mode[pos].boundx = mode[pos].x + 188; 19 mode[pos].boundy = mode[pos].y + 23; 20 } 21 22 int r = 20; 23 int g = 20; 24 int b = 20; 25 26 while(wait) 27 { 28 realevent = al_get_next_event(event_queue, &ev); 29 30 al_get_mouse_state(&state); 31 int x = al_get_mouse_state_axis(&state, 0); 32 int y = al_get_mouse_state_axis(&state, 1); 33 int z = al_get_mouse_state_axis(&state, 2); 34 35 al_clear_to_color(al_map_rgb(0,0,0)); 36 37 for(unsigned int pos = 0; pos < mode.size(); ++pos) 38 { 39 if(pos == 0) 40 displaymode = "Full Screen"; 41 if(pos == 1) 42 displaymode = "Windowed Normal"; 43 if(pos == 2) 44 displaymode = "Windowed Resizeable"; 45 46 if(x > mode[pos].x && x < mode[pos].boundx && y > mode[pos].y && y < mode[pos].boundy) // Collision Check For Mode Buttons 47 { 48 r = 120; 49 g = 120; 50 b = 120; 51 52 if(realevent) 53 if(ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) 54 if(ev.mouse.button == 1 && pos == 0) 55 { 56 DestroyBitmaps(); 57 DestroyFonts(); 58 59 al_destroy_display(display); // This Might Destroy Bitmaps And Fonts Anyway But Still Destroy Them Independently Just To Make Sure As Immediately Above 60 61 ALLEGRO_DISPLAY_MODE disp_data; 62 al_get_display_mode(al_get_num_display_modes() - 1, &disp_data); 63 al_set_new_display_flags(ALLEGRO_FULLSCREEN); 64 display = al_create_display(disp_data.width, disp_data.height); 65 66 fsx = (disp_data.width - WIDTH) / 2; 67 fsy = (disp_data.height - HEIGHT) / 2; 68 69 LoadBitmaps(); 70 LoadFonts(); 71 72 for(unsigned int pos = 0; pos < mode.size(); ++pos) // Move Buttons To The Right For Full Screen Mode 73 { 74 mode[pos].x += fsx; // Because fsx And fsy Are Used To Set Actual Button Postions Just Here This Means 75 mode[pos].y += fsy; // al_get_mouse_state_axis() And The al_draw Functions For The Buttons! Dont Need To 76 mode[pos].boundx += fsx; // Use fsx And fsy !!! 77 mode[pos].boundy += fsy; 78 } 79 } 80 81 if(ev.mouse.button == 1 && pos == 1) 82 { 83 DestroyBitmaps(); 84 DestroyFonts(); 85 86 al_destroy_display(display); // This Might Destroy Bitmaps And Fonts Anyway But Still Destroy Them Independently Just To Make Sure As Immediately Above 87 88 al_set_new_display_flags(ALLEGRO_WINDOWED); 89 90 display = al_create_display(WIDTH, HEIGHT); 91 92 LoadBitmaps(); 93 LoadFonts(); 94 95 for(unsigned int pos = 0; pos < mode.size(); ++pos) // Move Buttons Back To The Left For Windowed Mode 96 { 97 mode[pos].x -= fsx; 98 mode[pos].y -= fsy; 99 mode[pos].boundx -= fsx; 100 mode[pos].boundy -= fsy; 101 } 102 103 fsx = 0; // Reset offSet After Having Moved Buttons Back To The Left Just Above 104 fsy = 0; // Reset offSet After Having Moved Buttons Back To The Left Just Above 105 } 106 107 if(ev.mouse.button == 1 && pos == 2) 108 { 109 DestroyBitmaps(); 110 DestroyFonts(); 111 112 al_destroy_display(display); // This Might Destroy Bitmaps And Fonts Anyway But Still Destroy Them Independently Just To Make Sure As Immediately Above 113 114 al_set_new_display_flags(ALLEGRO_RESIZABLE); 115 116 display = al_create_display(WIDTH, HEIGHT); 117 118 LoadBitmaps(); 119 LoadFonts(); 120 121 for(unsigned int pos = 0; pos < mode.size(); ++pos) // Move Buttons Back To The Left For Windowed Mode 122 { 123 mode[pos].x -= fsx; 124 mode[pos].y -= fsy; 125 mode[pos].boundx -= fsx; 126 mode[pos].boundy -= fsy; 127 } 128 129 fsx = 0; // Reset offSet After Having Moved Buttons Back To The Left Just Above 130 fsy = 0; // Reset offSet After Having Moved Buttons Back To The Left Just Above 131 } 132 } 133 134 else 135 { 136 r = 40; 137 g = 40; 138 b = 40; 139 } 140 141 al_draw_filled_rectangle(mode[pos].x, mode[pos].y, mode[pos].boundx, mode[pos].boundy, al_map_rgb(r, g, b)); 142 al_draw_text(font18, al_map_rgb(130, 190, 130), mode[pos].x + 3, mode[pos].y, 0, displaymode.c_str()); 143 } 144 145 al_draw_text(font30, al_map_rgb(0, 200, 255), WIDTH / 2 + fsx, 350 + fsy, ALLEGRO_ALIGN_CENTRE, "Press 'M' To Begin Munching Or Press Space To Create A Maze"); 146 147 al_flip_display(); 148 149 //al_acknowledge_resize(display); // Obviously This Is Very Wrong Here 150 151 if(realevent) 152 if(ev.type == ALLEGRO_EVENT_KEY_DOWN) 153 { 154 if(ev.keyboard.keycode == ALLEGRO_KEY_M) 155 { 156 wait = false; 157 } 158 159 if(ev.keyboard.keycode == ALLEGRO_KEY_SPACE) 160 { 161 BonusLevel(isplaying); 162 } 163 } 164 } 165}

jmasterx
Member #11,410
October 2009

What if you tried:

if(ev.type == ALLEGRO_EVENT_DISPLAY_RESIZE)
{
   al_acknowledge_resize(display);
}

Also, you should really use al_wait_for_event()

That will make your game more robust, consume less cpu, and you'll know the event is real.

GaryT
Member #14,875
January 2013

I've tried it here and also immediately after al_flip_display(); and I'm still getting exactly the same behaviour. I'll keep investigating.

#SelectExpand
1if(ev.mouse.button == 1 && pos == 2) 2{ 3 DestroyBitmaps(); 4 DestroyFonts(); 5 6 al_destroy_display(display); // This Might Destroy Bitmaps And Fonts Anyway But Still Destroy Them Independently Just To Make Sure As Immediately Above 7 8 al_set_new_display_flags(ALLEGRO_RESIZABLE); 9 10 display = al_create_display(WIDTH, HEIGHT); 11 12 LoadBitmaps(); 13 LoadFonts(); 14 15 for(unsigned int pos = 0; pos < mode.size(); ++pos) // Move Buttons Back To The Left For Windowed Mode 16 { 17 mode[pos].x -= fsx; 18 mode[pos].y -= fsy; 19 mode[pos].boundx -= fsx; 20 mode[pos].boundy -= fsy; 21 } 22 23 fsx = 0; // Reset offSet After Having Moved Buttons Back To The Left Just Above 24 fsy = 0; // Reset offSet After Having Moved Buttons Back To The Left Just Above 25} 26 27if(ev.type == ALLEGRO_EVENT_DISPLAY_RESIZE) 28{ 29 al_acknowledge_resize(display); 30}

user1061
Member #15,774
October 2014

Thanks, think I just got a handle wich I asked for in my thread, something a NOOB to allegro 5 can understand. :D

GaryT
Member #14,875
January 2013

Now I'm thinking the internal buffer was luckily resizing itself anyway ("internal buffer might not resize itself") without calling the following, and that the buffer resizing hasn't actually been the problem.

#SelectExpand
1if(ev.type == ALLEGRO_EVENT_DISPLAY_RESIZE) 2{ 3 al_acknowledge_resize(display); 4}

And that my initial ideas/observations are unfortunately correct :-/

Damn. I really hope I'm wrong and talking total rubbish :D

Please help ???

I just want to point out once again for anybody new to this thread, that all graphics and all collision detection (apart from mouse), and so therefore the main part of my game all resize and work perfectly. It's only collision detection between the Mouse Pointer and the Various Objects as previously described that are the problem :-/

jmasterx
Member #11,410
October 2009

The way you've done your main loop is a bit chaotic and I can't spot the problem from just looking. I would have to run it through a debugger but I don't have time right now.

Could you try to use al_wait_for_event() and sort of try to make your loop a bit more like my template one. I know the template behaves correctly.

But right now you are making an infinite while loop and not waiting for events which might be causing problems.

GaryT
Member #14,875
January 2013

I've changed it to use al_wait_for_event() but it's still the same. A massive thank you for all your support. It's beer O'Clock for me now :)

EDIT: Just to clarify can somebody please comment/confirm on the following that I posted earlier in this post:

"Are you saying if you have an object exactly in the middle of the display which can be collision detected with the mouse pointer, that when in ALLEGRO_RESIZABLE if you manually resize the window (using the mouse) to approximately half the size whilst playing, that your object which is now half the size and still in the middle of the display (like it is for me), still has the collision detection with the mouse pointer working correctly, both being aligned." END OF EDIT

#SelectExpand
1{ 2 //bool realevent; 3 bool realevent = true; 4 5 bool wait = true; 6 7 bool isplaying = false; 8 9 string displaymode; // Used For Display Name In Buttons 10 11 vector<Buttons> mode(3); // Number Of Buttons To Display 12 13 int stdx= 100; // Amount To Shift Everything Left 14 int stdoffset = -27; // Vertical Pitch 15 for(unsigned int pos = 0; pos < mode.size(); ++pos, stdoffset += 40) // Set mode Button Parameters 16 { 17 mode[pos].x = WIDTH / 2 - stdx; 18 mode[pos].y = 250 + stdoffset; 19 mode[pos].boundx = mode[pos].x + 188; 20 mode[pos].boundy = mode[pos].y + 23; 21 } 22 23 int r = 20; 24 int g = 20; 25 int b = 20; 26 27 while(wait) 28 { 29 //realevent = al_get_next_event(event_queue, &ev); 30 al_wait_for_event(event_queue, &ev); 31 32 al_get_mouse_state(&state); 33 int x = al_get_mouse_state_axis(&state, 0); 34 int y = al_get_mouse_state_axis(&state, 1); 35 int z = al_get_mouse_state_axis(&state, 2); 36 37 al_clear_to_color(al_map_rgb(0,0,0)); 38 39 for(unsigned int pos = 0; pos < mode.size(); ++pos) 40 { 41 if(pos == 0) 42 displaymode = "Full Screen"; 43 if(pos == 1) 44 displaymode = "Windowed Normal"; 45 if(pos == 2) 46 displaymode = "Windowed Resizeable"; 47 48 if(x > mode[pos].x && x < mode[pos].boundx && y > mode[pos].y && y < mode[pos].boundy) // Collision Check For Mode Buttons 49 { 50 r = 120; 51 g = 120; 52 b = 120; 53 54 if(realevent) 55 if(ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) 56 if(ev.mouse.button == 1 && pos == 0) 57 { 58 DestroyBitmaps(); 59 DestroyFonts(); 60 61 al_destroy_display(display); // This Might Destroy Bitmaps And Fonts Anyway But Still Destroy Them Independently Just To Make Sure As Immediately Above 62 63 ALLEGRO_DISPLAY_MODE disp_data; 64 al_get_display_mode(al_get_num_display_modes() - 1, &disp_data); 65 al_set_new_display_flags(ALLEGRO_FULLSCREEN); 66 display = al_create_display(disp_data.width, disp_data.height); 67 68 fsx = (disp_data.width - WIDTH) / 2; 69 fsy = (disp_data.height - HEIGHT) / 2; 70 71 LoadBitmaps(); 72 LoadFonts(); 73 74 for(unsigned int pos = 0; pos < mode.size(); ++pos) // Move Buttons To The Right For Full Screen Mode 75 { 76 mode[pos].x += fsx; // Because fsx And fsy Are Used To Set Actual Button Postions Just Here This Means 77 mode[pos].y += fsy; // al_get_mouse_state_axis() And The al_draw Functions For The Buttons! Dont Need To 78 mode[pos].boundx += fsx; // Use fsx And fsy !!! 79 mode[pos].boundy += fsy; 80 } 81 } 82 83 if(ev.mouse.button == 1 && pos == 1) 84 { 85 DestroyBitmaps(); 86 DestroyFonts(); 87 88 al_destroy_display(display); // This Might Destroy Bitmaps And Fonts Anyway But Still Destroy Them Independently Just To Make Sure As Immediately Above 89 90 al_set_new_display_flags(ALLEGRO_WINDOWED); 91 92 display = al_create_display(WIDTH, HEIGHT); 93 94 LoadBitmaps(); 95 LoadFonts(); 96 97 for(unsigned int pos = 0; pos < mode.size(); ++pos) // Move Buttons Back To The Left For Windowed Mode 98 { 99 mode[pos].x -= fsx; 100 mode[pos].y -= fsy; 101 mode[pos].boundx -= fsx; 102 mode[pos].boundy -= fsy; 103 } 104 105 fsx = 0; // Reset offSet After Having Moved Buttons Back To The Left Just Above 106 fsy = 0; // Reset offSet After Having Moved Buttons Back To The Left Just Above 107 } 108 109 if(ev.mouse.button == 1 && pos == 2) 110 { 111 DestroyBitmaps(); 112 DestroyFonts(); 113 114 al_destroy_display(display); // This Might Destroy Bitmaps And Fonts Anyway But Still Destroy Them Independently Just To Make Sure As Immediately Above 115 116 al_set_new_display_flags(ALLEGRO_RESIZABLE); 117 118 display = al_create_display(WIDTH, HEIGHT); 119 120 LoadBitmaps(); 121 LoadFonts(); 122 123 for(unsigned int pos = 0; pos < mode.size(); ++pos) // Move Buttons Back To The Left For Windowed Mode 124 { 125 mode[pos].x -= fsx; 126 mode[pos].y -= fsy; 127 mode[pos].boundx -= fsx; 128 mode[pos].boundy -= fsy; 129 } 130 131 fsx = 0; // Reset offSet After Having Moved Buttons Back To The Left Just Above 132 fsy = 0; // Reset offSet After Having Moved Buttons Back To The Left Just Above 133 } 134 135 if(ev.type == ALLEGRO_EVENT_DISPLAY_RESIZE) 136 { 137 al_acknowledge_resize(display); 138 } 139 } 140 141 else 142 { 143 r = 40; 144 g = 40; 145 b = 40; 146 } 147 148 al_draw_filled_rectangle(mode[pos].x, mode[pos].y, mode[pos].boundx, mode[pos].boundy, al_map_rgb(r, g, b)); 149 al_draw_text(font18, al_map_rgb(130, 190, 130), mode[pos].x + 3, mode[pos].y, 0, displaymode.c_str()); 150 } 151 152 al_draw_text(font30, al_map_rgb(0, 200, 255), WIDTH / 2 + fsx, 350 + fsy, ALLEGRO_ALIGN_CENTRE, "Press 'M' To Begin Munching Or Press Space To Create A Maze"); 153 154 /*ALLEGRO_DISPLAY_MODE options; 155 int number = al_get_num_display_modes(); 156 for(int count = 0, int space = 0; count < number; ++count, space += 30) 157 { 158 al_get_display_mode(count, &options); 159 al_draw_textf(font40, al_map_rgb(0, 200, 255), WIDTH / 2 + fsx, 100 + space + fsy, ALLEGRO_ALIGN_CENTRE, "Width %i Height %i", options.width(), options.height()); 160 }*/ 161 162 al_flip_display(); 163 164 /*if(ev.type == ALLEGRO_EVENT_DISPLAY_RESIZE) 165 { 166 al_acknowledge_resize(display); 167 }*/ 168 169 if(realevent) 170 if(ev.type == ALLEGRO_EVENT_KEY_DOWN) 171 { 172 if(ev.keyboard.keycode == ALLEGRO_KEY_M) 173 { 174 wait = false; 175 } 176 177 if(ev.keyboard.keycode == ALLEGRO_KEY_SPACE) 178 { 179 BonusLevel(isplaying); 180 } 181 } 182 } 183}

jmasterx
Member #11,410
October 2009

When you resize to half the size, it should look like when closing one eye; objects should be same size/position, just you do not see as much of them as you decrease the size.

GaryT
Member #14,875
January 2013

I don't know why but that tickled me quite a lot :D another beer or two and I'll be cross eyed.

Seriously apart from the mouse collision detection problem, ALLEGRO_RESIZABLE works really great and I think it's a really cool feature. I can play my game perfectly, literally any size down to a large postage stamp size.

It's only on screens where the mouse is used to select objects that the issue arises. I could perhaps disable ALLEGRO_RESIZABLE for those screens, but I was hoping for a more complete solution.

EDIT: I'll upload a very short video clip when I get back from work in about 8 to 9 hours from now, showing how the game works perfectly in resizable mode apart from the mouse collision detection on certain screens.

Again thank you very much for all your support :)

EDIT: 2

Here's My Video Link: http://www.youtube.com/watch?v=Xhh4MTe-Q9A&list=UU2XSIT3tAf_-7ilWHAaiocA

Video Link Description: Mouse pointer collision detection misalignment which is not all that surprising, but is there a way to obtain the changing windows width and height to feed into my program so I can compensate.

pkrcel
Member #14,001
February 2012

GaryT said:

Video Link Description: Mouse pointer collision detection misalignment which is not all that surprising, but is there a way to obtain the changing windows width and height to feed into my program so I can compensate.

When you acknowledge the resize event, the al_get_display_* functions should return the actual size of the backbuffer if I am not mistaken, and jmasterx seems to confirm this (and he is a much more trustable source :P)

I guess you should use that to transfom mouse input accordingly.

It is unlikely that Google shares your distaste for capitalism. - Derezo
If one had the eternity of time, one would do things later. - Johan Halmén

GaryT
Member #14,875
January 2013

Excellent I understand now.

I'll give it a test later when I get back from work in about 7 to 8 hours.

Thanks again pkrcel :)

My apologies everyone for misunderstanding before. :-/

If the following is true then that's exactly what I've been looking for:

pkrcel said:

When you acknowledge the resize event, the al_get_display_* functions should return the actual size of the backbuffer if I am not mistaken

Arthur Kalliokoski
Second in Command
February 2005
avatar

IIRC, Edgar Reynaldo had a system where the button coordinates were a percentage of the screen dimensions.

And you'll get to do it all over again if you switch to OpenGL.

“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

 1   2 


Go to: