Legacy GM Drag and Drop movement

D

Darth Raven

Guest
Hello! Two problems are presented on this post.
#1
I'm having a issue with a drag and drop movement, which is the object is not returning to the place it should be. I'm using "distance to point" which is maybe the problem. It never returns to the exact point I want, it goes near the point.
In resume, I want to achieve a better Drag and Drop movement.

Let's assume the first object called " ThisO " .
I've this:

Create event:
Code:
x=160
y=160
alpha =0;
drag = false;

Step:
//Image Alpha
image_alpha = alpha;
alpha +=0.01;
if alpha >= 1
{alpha = 1
}

//Button
if alpha=1 and mouse_check_button_pressed(mb_left)
{drag = true;}

if alpha= 1 and mouse_check_button_released(mb_left)
{drag = false;}



//Drag movement
if drag = true and alpha = 1
{
x = mouse_x;
y = mouse_y;
}

if distance_to_point(160,160)>0 and drag = false
{move_towards_point(160,160,5)
}
else
speed =0

//Code that solved
if speed =0 and drag = false
{x=160
y=160}

[/CODE]



#2
A bit out of the context of the tittle... I'm using a object with the text " This " . I know how to create a "draw text", however I'm not able to work with the draw as a object ( to drag and drop ). Or is it possible to do it?

Thanks and good night!

ED1: I've edited the code. I still dont know how to drag it to the original place.
ED2: I've solved the problem of Drag and Drop. However question number 2 has not bee answered yet.
 
Last edited by a moderator:

KurtBlissZ

Member
#2
A bit out of the context of the tittle... I'm using a object with the text " This " . I know how to create a "draw text", however I'm not able to work with the draw as a object ( to drag and drop ). Or is it possible to do it?
You want to use another object's variable containing a string to draw some text?

Code:
var str = string(object_name_here.text);
draw_text(0, 0, str);
 

Xor

@XorDev
Hello Darth Raven! You were the guy that made that hotdog game right?
I decided to write the code I would use. Here it is:
Code:
///Create event
x = 160;
y = 160;
image_alpha = 0;
drag = 0;

///Step
image_alpha = min(image_alpha+0.01,1);

drag = (alpha==1)&&mouse_check_button(mb_left);

if drag
{
x = mouse_x;
y = mouse_y;
}
else
{
move_towards_point(160,160,min(distance_to_point(160,160),5))
}
That should fix it. That is because move_towards_point() jumps 5 units (pixels probably) at a time which if it is 2 units away, it will over shoot 3 units.
You can try this too (as a replacement for that last part):
Code:
{
x = x*0.9+16;
y = y*0.9+16;
}
That should give a smoother look. It may need some adjustments though.
As for the second question I'm not sure what you are asking. Do you want to draw text from a variable? Please explain.
I hope this helps
 
R

rui.rosario

Guest
A bit out of the context of the tittle... I'm using a object with the text " This " . I know how to create a "draw text", however I'm not able to work with the draw as a object ( to drag and drop ). Or is it possible to do it?
I'm not sure I understood, but you want an object that represents text and that can be dragged?

If so, then what I would do is calculate the size of the text (textWid and textHei) and then when the mouse was pressed I would check if the mouse was pressed in an area of textWid * textHei around the midpoint of the text being drawn (or the top left, bottom right, .... depends on how you draw the text). You can then reuse the drag code since you already identified the object as being dragged.
 
D

Darth Raven

Guest
Hii! Thanks for the answer!
And yes Xor, it's me! Good to know you still develop games ahah.
As for the second question I created other topic with the question, but I'll try to explain here.
When you create a text on the "draw" event, with no sprite related, any interaction is denied ( example: left button pressed ). Is there a way to transform the letters into "sprites"? Because the way I'm thinking to solve this is to create a single .png image for each word.

Rui, someone on the other topic already told me that. However that way seems to painfull to do for each word.
 
R

rui.rosario

Guest
Well... you could draw the text to a surface and convert the surface to a sprite... but with many words I believe that would take a massive amount of processing (I think each sprite created that way gets a new texture page, but don't quote me on that I'm speaking out of memory). Personally I would go with the manual checking in the step event, and if that was still not performant you could then apply more complex algorithms probably to map the coordinate of the mouse press to the object selected (none come to mind, but I'm imagining some stuff in my head that could work, but I won't talk about it since I would need to test it if it was a feasible solution, and that won't happen soon).
 

Xor

@XorDev
Here is a simplified version of dragging a text object. I didn't test it but it should work.
Create event:
Code:
Text = "This";
//Set font here
Step event:
Code:
if mouse_check_button_pressed(mb_left)
{
var W,H;
W = string_width(Text)/2;
H= string_width(Text)/2;
drag = point_in_rectangle(mouse_x,mouse_y,x-W,y-H,x+W,y+H);
}
else
if mouse_check_button_released(mb_left)
{
drag = 0;
}
if drag
{
x = mouse_x;
y = mouse_y;
}
Draw event:
Code:
draw_set_halign(fa_center);
draw_set_valign(fa_middle);
draw_text(x,y,Text);
 
D

Darth Raven

Guest
Thanks you both.
I've implemented and changed some details of the cod, Xor. However, if I drag from the left the word will vibrate a bit when returning to the start position.
 
R

rui.rosario

Guest
However, if I drag from the left the word will vibrate a bit when returning to the start position.
I believe it is because you set the text x and y position to the mouse coordinates, however you should set it the mouse coordinates plus the offset from where you clicked.

Imagining the center of the text is (0, 0) and you clicked at (5, 7). Then you should set the x position to mouse_x + 5 and the y position to mouse_y + 7

EDIT: Actually it should be mouse_x - 5 and mouse_y - 7 since you want to compensate the clicked offset
 
Last edited by a moderator:
  • Like
Reactions: Xor
D

Darth Raven

Guest
How do I record the last coordinate of x and y when mouse button has released?
At the moment I'm testing this code, and I'm having the issue that wherever I click on the screen it moves the word as well. It's not locking the drag effect only to the word.
 

Xor

@XorDev
rui.rosario is right. You need to add an offset. Something like:
Create event:
Code:
ox = 0;
oy = 0;
Step event:
Code:
if mouse_check_button_pressed(mb_left)
{
var W,H;
W = string_width(Text)/2;
H= string_width(Text)/2;
drag = point_in_rectangle(mouse_x,mouse_y,x-W,y-H,x+W,y+H);

ox = mouse_x-x-W;
oy = mouse_y-y-H;
}
else
if mouse_check_button_released(mb_left)
{
drag = 0;
}
if drag
{
x = mouse_x+ox;
y = mouse_y+oy;
}
 
R

rui.rosario

Guest
rui.rosario is right. You need to add an offset
Not completely right, I only just edited the post but my example was wrong. If you clicked the point (5, 7) and (0, 0) is the center of the text, then you need to apply the opposite vector to correct it (so it would be mouse_x - 5, mouse_y - 7)
 
D

Darth Raven

Guest
Well, the main issue at the moment is the fact that wherever I click it follows up my mouse. It should only response if I click in the text..
 
R

rui.rosario

Guest
Did you use the
drag = point_in_rectangle(mouse_x,mouse_y,x-W,y-H,x+W,y+H);

Because this line should make sure the text is only dragged when the mouse is in the text area.
 
D

Darth Raven

Guest
Yes I did. This all the code I do have at the moment:
Code:
drag = (image_alpha==1)&&mouse_check_button(mb_left);
image_alpha = min(image_alpha+0.01,1)

if mouse_check_button_pressed(mb_left)
{
var W,H;
W = string_width(Text)/2;
H= string_height(Text)/2;
drag = point_in_rectangle(mouse_x,mouse_y,x-W,y-H,x+W,y+H);
ox = mouse_x-x-W;
oy = mouse_y-y-H;
}
else
if mouse_check_button_released(mb_left)
{
drag = 0;
}

if drag
{
x = mouse_x+ox;
y = mouse_y+oy;
}
else
{
move_towards_point(160,160,min(distance_to_point(160,160),5))
}
I changed var H to Height, since he had width. I suppose it's heigth.
 
R

rui.rosario

Guest
I think your problem is here
drag = (image_alpha==1)&&mouse_check_button(mb_left);
You're saying that as long as the image_alpha is 1 and the mouse is held then the text should be dragged.

Only when the mouse button is pressed do you validate if it is inside the text area.
 
D

Darth Raven

Guest
I also tried that before. If I do that it moves for 0.5sec and then stops, and returns to the original place.
 
D

Darth Raven

Guest
Well, I want it to follow only when I click the text. At the momet it is following even if I click in the black screen (it insta pops-up )
 
R

rui.rosario

Guest
Try removing the else clause in this block of code then (if I understood correctly).
if drag { x = mouse_x+ox; y = mouse_y+oy; } else { move_towards_point(160,160,min(distance_to_point(160,160),5)) }
If this is not what you want could you then describe precisely what the behavior should be? In order to understand exactly what in the code is preventing it
 
Last edited by a moderator:
D

Darth Raven

Guest
That behavior it's okay.
What I'm struggling with is that I want it to be dragged only when I click over the text, not when I'm clicking 200 pixels away from the text and it pop's-up next to me.
I think it's because the text has no " collision " surface.
I want it to only be dragged when I click over the text. This is what is happening:
https://gyazo.com/31892463ad2d24cbcda286c14dd42663
 

Yal

šŸ§ *penguin noises*
GMC Elder
AFAIK, distance_to_point() and distance_to_object() take the object's whole bounding box into account, so the object will move until it borders to its original point from any side. You should use point_distance() instead, and supply x and y as the "second point" argument to it.
 
R

rui.rosario

Guest
If I understood the problem correctly, I think the culprit is:
Code:
drag = (image_alpha==1)&&mouse_check_button(mb_left);
Because when the mouse is held but not pressed or released it will be true.

To avoid many code changes to the current code, try changing
Code:
if mouse_check_button_pressed(mb_left)
To:
Code:
if mouse_check_button(mb_left)
 
D

Darth Raven

Guest
I've done the following:
Changed W and H var to:
Code:
W = string_width(Text);
H= string_width(Text);
And as you said:
Code:
if mouse_check_button_released(mb_left)
{
drag = 0;
}
This solved a part of the problem. Now if I move my mouse to fast, the object wont follow up ( I guess because it's not pressing it ). Altough this is not a problem to the gameplay itself, I'm wondering why it's not following up perfectly the mouse. Is it because "engine reaction" (step event) is not fast enough to follow up the mouse?
I also want to thank you guys for helping me out at this problem.
 
R

rui.rosario

Guest
Now if I move my mouse to fast, the object wont follow up ( I guess because it's not pressing it )
Yes, since now you've restricted it to only move if the mouse is over it the second the mouse moves so fast it advances more than the distance a single step can cover the drag will stop.

For example, if you have a Room Speed of 1, the game will only check the mouse position once per second, so it'll most likely not follow up. If you have a Room Speed of 60, it'll follow up more smoothly because it'll be able to catch up with the mouse position change more often. However, this isn't a problem that is fixed just by increasing the Room Speed. It is a problem that will happen regardless of Room Speed, because people can always move the mouse too fast.
 
D

Darth Raven

Guest
Yeah, I know. But I'm just making a introduction so I guess 80% of the players wont try to move the mouse to fast. So I'll jus change the speed of the room and it will cover most of the cases.
So this is already fixed and I really loved your help guys!
 
Top