{RESOLVED} Drag an object or GUI control

Started by Joacim Andersson, Sun 22/12/2024 18:12:36

Previous topic - Next topic

Joacim Andersson

I'm currently developing a game that includes a few mini-games as part of the puzzles. I've already created one, but I had the idea of another that is like the Unblock Me game, except instead of a red block, you would unblock a key.

I wanted to do this in a GUI, but I'm OK with it being its own room if I can't use GUI controls. The thing is that I want to have buttons (or Objects) that you can drag & drop, but if you're familiar with the Unblock Me game, you can either drag a block horizontally or vertically, not in both directions.

A GUI control has a very limited number of events, so is there a way to implement this?

Crimson Wizard

#1
Here's a Drag and Drop module that I wrote:
https://www.adventuregamestudio.co.uk/forums/modules-plugins-tools/module-dragdrop-1-1-0-helps-to-drag-things-around-your-ags-game!/

May be used as-is, or as a hint to how code this.

The quick summary for writing your own code:
- keep track of the mouse state in rep-exec or rep-exec-always; remember last position and button state each time, compare with new ones;
- if mouse button gets down, find if any control is under: if there's then remember it being "dragged" in a variable (GUIControl* pointer variable);
- if mouse changes position and control is dragged, then move the object relatively; adjust the movement if needed (clamp to certain range, ignore certain axis, and so on);
- if mouse button gets up, and there was a control dragged, then reset the GUIControl* variable to null.

Rik_Vargard

Not as Pro and fancy as CW, but here's my noob version:

- When you select the object, make it disappear , and make the mouse cursor that object's image.
- When you click on the hotspot/object, verify if the mouse graphic is that image.
- Restore your mouse image.

 :P

Joacim Andersson

Quote from: Crimson Wizard on Sun 22/12/2024 18:19:01Here's a Drag and Drop module that I wrote:
https://www.adventuregamestudio.co.uk/forums/modules-plugins-tools/module-dragdrop-1-1-0-helps-to-drag-things-around-your-ags-game!/
I will have a look on that, and probably get back to you on it.
Quote from: Crimson WizardThe quick summary for writing your own code:
- keep track of the mouse state in rep-exec or rep-exec-always; remember last position and button state each time, compare with new ones;
- if mouse button gets down, find if any control is under: if there's then remember it being "dragged" in a variable (GUIControl* pointer variable);
- if mouse changes position and control is dragged, then move the object relatively; adjust the movement if needed (clamp to certain range, ignore certain axis, and so on);
- if mouse button gets up, and there was a control dragged, then reset the GUIControl* variable to null.
That sounds easy enough. Can I cast from a GUIControl to a Button? Also, I'm guessing that if there's only a mouse.IsButtonDown method I have to keep track if it was just pressed or not myself?

Quote from: Rik_Vargard on Sun 22/12/2024 21:52:57- When you select the object, make it disappear, and make the mouse cursor that object's image.
Thank you for your idea, but unfortunately, that won't work since you should only be able to drag the object horizontally or vertically, depending on its original orientation. Also, there might be blocks stopping you from dragging the block altogether.

Khris

There's a GUIControl.AsButton property.
There's also a Mouse.SetBounds() command which should allow implementing the limited block movement, at least in theory.

Joacim Andersson

Quote from: Khris on Mon 23/12/2024 11:40:57There's a GUIControl.AsButton property.
There's also a Mouse.SetBounds() command which should allow implementing the limited block movement, at least in theory.
Thanks for the AsButton property, which is not documented in the help file that comes with AGS. That documentation is somewhat limited.

I don't think I will use the SetBounds method though, I just use either the X or the Y property depending on the block I want to move. I also have to figure out how to stop the dragging of a block (I will most likely use GUI Buttons for this) if there's another block in the way.


Joacim Andersson


Crimson Wizard

#8
Quote from: Joacim Andersson on Mon 23/12/2024 16:10:30Thanks for the AsButton property, which is not documented in the help file that comes with AGS. That documentation is somewhat limited.

What do you mean? This property has been documented in the manual for many years, and help file that comes with the editor is near exact match with the online one (may be bit older depending on the version that you have installed).

EDIT: It's labelled "GUIControl.AsType", maybe that is the problem.
It's in the list of GUIControl's properties, at the top of its page though.

Joacim Andersson

Quote from: Crimson Wizard on Mon 23/12/2024 18:05:00What do you mean? This property has been documented in the manual for many years, and help file that comes with the editor is near exact match with the online one (may be bit older depending on the version that you have installed).
Yes, I apologize, it was under AsType which is probably why I missed it. However, I didn't get a result in the index for AsButton.

Crimson Wizard

Quote from: Joacim Andersson on Mon 23/12/2024 18:10:50However, I didn't get a result in the index for AsButton.

Yes, this is the problem with the Index in the latest versions of the manual, it only lists full article names, i.e. it mentions "GUIControl.AsType" but not "AsType" nor "AsButton".

"Search" tab should find "AsButton" afaik.

Joacim Andersson

But of course, I didn't know that I should search for AsButton, I just assumed that I could cast it this way.
Code: ags
Button* btn = (Button) someGuiControl;
Which of course didn't work.

Crimson Wizard

Quote from: Joacim Andersson on Mon 23/12/2024 18:37:30But of course, I didn't know that I should search for AsButton, I just assumed that I could cast it this way.
Code: ags
Button* btn = (Button) someGuiControl;

Unfortunately, pointer downcasts (from base type to child type) are not supported by AGS at the moment.
This is one of the feature requests, which in theory could be implemented in AGS 4, where we have done the basic data reflection.

Upcast (from child to base) is supported though (fwiw).

Joacim Andersson

#13
I understand that downcasting would require an explicit cast (unlike upcasting which can be done implicitly), but I still think it should be available.

There are other quirks of the language I find strange, for example, why can't I do the following:
Code: ags
String s1 = "THis iS A stRIng";
String s2 = s1.Substring(0, 9).LowerCase();
Since the Substring method returns a String why can't I call the LowerCase() method directly on that?

eri0o

#14
What AGS version you are using?

I believe this works in ags4, but there may have been a regression that wasn't picked. The autocomplete hasn't been adjusted yet.

Joacim Andersson

I'm using the latest stable version 3.6.2

eri0o

Ah, this is only supported in ags4, using the new compiler, it briefly broke in a regression in alpha 15 and got fixed in alpha 16.

Khris

AGS is primarily a free tool to build adventure games, not a programming language. It's amazing that the script language is as powerful as it is, and AGS4 will make the compiler even better in a lot of ways.
Ten years ago, AGS was absolutely peerless in what it could do scripting-wise; the alternatives back then were dogshit.

What exactly is the expected answer when one asks why the compiler doesn't support feature X yet?
Why would one say "feature X should be available"? Why should it be available? Because you paid $0 for the product?
I will never understand this mindset. Especially if it's a "problem" that is extremely easy to work around.

Joacim Andersson

Quote from: Khris on Tue 24/12/2024 11:49:51Why would one say "feature X should be available"? Why should it be available? Because you paid $0 for the product?
I will never understand this mindset. Especially if it's a "problem" that is extremely easy to work around.
I don't think I've asked for any new features, unless you count my comment on downcasting as a request.

My comment on why I can't call a String method directly on a function that returns a String wasn't a request it was just something I found weired.

Crimson Wizard

#19
Quote from: Joacim Andersson on Tue 24/12/2024 08:02:33There are other quirks of the language I find strange, for example, why can't I do the following:
Code: ags
String s1 = "THis iS A stRIng";
String s2 = s1.Substring(0, 9).LowerCase();
Since the Substring method returns a String why can't I call the LowerCase() method directly on that?

That is not a quirk of a language per se, but rather a limitation of an old script compiler that could not handle parsing composite expressions well.
This problem has been dealt with in AGS 4 where a new compiler can do that.

The old compiler is written in a old and dirty code, thus it's difficult to change. That's why I try not to meddle with it much and only fix the mistakes that are easy to fix.

SMF spam blocked by CleanTalk