• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

SOLVED Selecting an object with mouse

CodET

Member
If clicking on the object I want to select the object. For this, I check whether the object is clicked or not, and make the selected variable the opposite of its current state (selected =! selected). And if it is selected, I outline the object in draw GUI. The moment I click on the object, selected is correct, but then it turns false, what is the reason for this?
GML:
//code(in step event):
if (held) {
selected =! selected;
}

//In create
hover = button_hover ();
msClick = mouse_click ();
held = hover && msClick;

//button_hover script:
var _mouseX = device_mouse_x_to_gui (0);
var _mouseY = device_mouse_y_to_gui (0);
return point_in_rectangle (_mouseX, _mouseY, x - (buttonWidth / 2), y - (buttonHeight / 2), x + (buttonWidth / 2), y + (buttonHeight / 2));

//mouse_click script:
return mouse_check_button_pressed (mb_left);
 

Nidoking

Member
//In create
This comment suggests to me that you're defining these variables in the Create event of this object. That tells me that they are defined one time, based on whether the mouse is inside the instance or the button is pressed in the exact step that the instance is created. They will never change their values again. I have no idea how it could ever be selected for even a single step. You cannot store a closure in a variable in GML. If you want to know whether hover or msClick is true in a given step, you must evaluate them during that step.

Given that you're saying it works for one step, I suspect that the comment I quoted is incorrect, and you've worked out that you need to move those lines into a different event. I also notice that you're calling
return mouse_check_button_pressed (mb_left);
which only returns true for one frame when the button is pressed. If you want to know whether the button is being held down, you would need to use mouse_check_button or watch for the mouse_check_button_released and use that to set held to false.
 

CodET

Member
This comment suggests to me that you're defining these variables in the Create event of this object. That tells me that they are defined one time, based on whether the mouse is inside the instance or the button is pressed in the exact step that the instance is created. They will never change their values again. I have no idea how it could ever be selected for even a single step. You cannot store a closure in a variable in GML. If you want to know whether hover or msClick is true in a given step, you must evaluate them during that step.

Given that you're saying it works for one step, I suspect that the comment I quoted is incorrect, and you've worked out that you need to move those lines into a different event. I also notice that you're calling

which only returns true for one frame when the button is pressed. If you want to know whether the button is being held down, you would need to use mouse_check_button or watch for the mouse_check_button_released and use that to set held to false.
I'm defining them in begin step too
 

NightFrost

Member
I'm defining them in begin step too
You should post the code as it is written, so we don't need to guess from fragments how it is organized. If the code indeed is as you explain, it should just flip the state of selected variable. Although you could write it more shortly by just doing:
GML:
if(button_hover() && mouse_click()){
    selected != selected;
}
and drop the intermediary variables. (Unless they have more use we're not seeing here.)
 

CodET

Member
(Meanwhile I changed some things)
create:
GML:
event_inherited();
enoughItem = false;
selected = false;
slotID = 0;
mouseX = device_mouse_x_to_gui(0);
mouseY = device_mouse_y_to_gui(0);
hover = point_in_rectangle(mouseX, mouseY, x - (buttonWidth/2), y - (buttonHeight/2), x + (buttonWidth/2), y + (buttonHeight/2));
lClick = mouse_check_button_pressed(mb_left);
begin step:
GML:
hover = point_in_rectangle(mouseX, mouseY, x - (buttonWidth/2), y - (buttonHeight/2), x + (buttonWidth/2), y + (buttonHeight/2));
rClick = mouse_check_button_pressed(mb_right);
lClick = mouse_check_button_pressed(mb_left);
step:
GML:
var held = hover && lClick;
if(held){
    event_user(0);   
}
and user event:
GML:
selected = !selected;
// Get recipe
var _recipe = global.itemRecipe[item];
var _recipeSize = array_length_1d(_recipe);
    
// Check ingredients
var _canCraft = true;
enoughItem = true;
    
for (var i = 0; i < _recipeSize; i++) {
    // Get ingredient data
    var _ingr = _recipe[i];
    var _item = _ingr[0];
    var _count = _ingr[1];
        
    // Get item array
    var _arr = inv_get_item_array(_item);
        
    if (!is_array(_arr)) {
        _canCraft = false;
        enoughItem = false;
        break;
    }
        
    // Check count
    var _arrCount = _arr[1];
        
    if (_arrCount < _count) {
        _canCraft = false;
        enoughItem = false;
        break;
    }
}
 

Nidoking

Member
Okay, so now it should select when you click it and remain selected until you click it a second time. And also do a bunch of stuff that isn't relevant to your question.
 

woods

Member
i have a side question..
hover = point_in_rectangle(mouseX, mouseY, x - (buttonWidth/2), y - (buttonHeight/2), x + (buttonWidth/2), y + (buttonHeight/2));
this is EXACTLY CENTER of the button you are trying to click?
seems like a small target to be clicking on ;o)

wouldnt it be better to check for mouse IN the rectangle instead of exactly centered in the rectangle?
...i mean off by 1px in any direction would make it fail right?

hover = point_in_rectangle(mouseX, mouseY, button.x, button.y,, (button_Width), (button_Height)); //assuming button is drawn at top left
 
Last edited:

woods

Member
i guess what im saying is
x - (buttonWidth/2), y - (buttonHeight/2), x + (buttonWidth/2), y + (buttonHeight/2));

is a very small target to hit with your mouse to select your button ;o)
 
Last edited:

woods

Member
ok .. got a couple cups of coffee in me and realized i missed the sign of your x-button width
//makes alot more sense now that im awake... shutting up now ;o)


im still on about this tho...
hover = point_in_rectangle(mouseX, mouseY, x - (buttonWidth/2), y - (buttonHeight/2), x + (buttonWidth/2), y + (buttonHeight/2));

mouseX and mouseY are set to the GUI scope. i see that..
but is the rest of it set to the room coords or the button(GUI) coords?

it's not working
it looks to me that they are set to room coords ..which would explain why things aren't working
 

Nidoking

Member
So, what IS it doing? "Not working" doesn't help. Is it not selecting at all? Is it selecting for only one frame? Is it turning your monitor into a humidifier? How are you determining that the hover is working? If you want specific answers, you need to learn to ask specific questions.
 

CodET

Member
I can understand whether hovering with the mouse is working here if it has hovered on it with the mouse in draw GUI, I outline:

GML:
if(hover and !selected){
    draw_sprite(sCraftUISlotOutlined, 0, x, y);
}

If I use mouse_check_button () it selects until I release the mouse and if I use mouse_check_button_pressed () it selects when I click and then it goes wrong.
 

CodET

Member
When I click on the object, I want it to remain selected until I click again. But the moment I press it, it gets selected, then its selection disappears.
 

4i4in

Member
The moment I click on the object, selected is correct, but then it turns false, what is the reason for this?
io_clear and timer for checking next mouse event.
You are checking inn very fast loops (fps/fps_real). You propably click and uncklick it several times.
It is reasonable to make it like
if timer1 mod delay_mouse = 0
so chack will be performed only sometimes not every time.
 

Nidoking

Member
Okay, so the question is, where is it setting selected to false again? Is it in the User Event 0, or somewhere else? This is where you do some debugging and put some messages so you can see what happens when you click. How many times does the event run? What is the value of selected in each event? What is the value of lClick? These things will help you figure out the problem. I believe there is something at fault that you haven't posted here.
 

CodET

Member
This is (attachment) held's and selected's value when I click. I just use selected in create, draw GUI and step event.
GML:
if(hover and !selected){
    draw_sprite(sCraftUISlotOutlined, 0, x, y);
}

if(selected and enoughItem){
    draw_sprite(sCraftUISlotOutlinedGreen, 0, x, y);
}

if(selected and !enoughItem){
    draw_sprite(sCraftUISlotOutlinedRed, 0, x, y);  
}
this is draw GUI code but I'm not setting a value or something. I'm creating 6 instances of this object. Its values look the same as held...
 

Attachments

Nidoking

Member
I see four numbers. They're not meaningful to me without the context of what messages produced them. A good practice is to put a debug message at the top of each event where the variable you're concerned with could be set. Then, you'll know in which event it changed, and you can start figuring out why.
 

CodET

Member
io_clear and timer for checking next mouse event.
You are checking inn very fast loops (fps/fps_real). You propably click and uncklick it several times.
It is reasonable to make it like
if timer1 mod delay_mouse = 0
so chack will be performed only sometimes not every time.
I didn't understand this.
---
I debugged but couldn't find anything.
 
Top