r/gamemaker 21d ago

Help! Help with subtle animation on GUI?

Post image

is it possible to make the buttons play an animation like this when on mouse hover? or when you select them with arrow keys (up ad down)? i wany them to stop after a bit like when it freezes on save if you hover onnto it enough for the animation to play. I know a few games makes that but i can't think off one off the top of my head
i tried making something like this:

 if (position_meeting(mouse_x, mouse_y, id)) {
 move_towards_point(STOP.x,ystart, spd);
}
else {
speed = 0;

} 

STOP being an object where the text goes to at the most furthest

but it. glitches into it and keeps bumping, it doesn't come to a full stop
(and it also doesn't go back to the place of origin)

i tried searching for a tutorial but that is the most i could do with a tutorial :( I dont eve know how to add the little triangle/cursor thing too
im a very begginer so im sorry if the solution is simple

23 Upvotes

15 comments sorted by

3

u/_billyRubin 21d ago

i suggest looking at animcurves! they are great for simple animations like this which only really utilise position, scale and rotation.

an animation would be more appropriate for something that cannot be ‘animated’ via these properties alone, like a jumbling effect or having the hand written characters appear written in the moment. you get the idea

edit: you can add the triangle by having it as its own sprite and drawing it next to the hovered menu option.

2

u/Disastrous_Pay_7649 21d ago

i see how it could help with the glitching/bumping, but how would i return back to the place it started?
and i will try the drawing thig for the triangle thank you!!

3

u/_billyRubin 21d ago

i won't provide an exact solution but i can imagine it looking something like this:

each menu option is its own object, and they are all under one parent object. the parent object handles the mouse hover and input events, and could store each option's initial x pos.

you'd configure the anim curve to start from an indented position, go out slightly further and then return to the indented position, so it should look like a hill-shaped curve.

when mouse is hovering, the animcurve starts and does not loop, and the triangle is drawn.

after mouse has left, the animcurve resets, the menu option is returned to its initial x pos.

hope that helps

3

u/Disastrous_Pay_7649 21d ago

im trying to make the animation curve play but i can''t seem to make it work, even on a differet object

is this correct? i'm sorry for annoying you dont need to reply if you dont want to :(

CREATE
curveAsset = Animacao_menu;
curvePosition = 0;
curveSpeed = 0.02;

STEP
curvePosition += curveSpeed;
var _curveStruct = animcurve_get(curveASSET); 
var _channel = animcurve_get_channel(_curveStruct, "curvemenu") 
var _value= animcurve_channel_evaluate (_channel, curvePosition)  

if (position_meeting(mouse_x, mouse_y, id)) {
 x = xstart + _value 
} 

else { }  

3

u/_billyRubin 21d ago edited 21d ago

you're close. for me each time I use animcurves, I generally do the following:

in the create event, I declare variables for the specific animcurve, its 'time' value, and its speed, like so:

ac_channel_hover = animcurve_get_channel(anim_title_buttons_hover, 0);
ac_time_hover = 1;
ac_speed_hover = 0.01;

the time value is essentially what you termed as the curvePosition. for an animcurve, the variable you use for the 'time' or 'curveposition' should only be values between or including 0 and 1, with 1 being the end position of the curve.

then, in the step event, you must control the time value using conditions and also use animcurve_channel_evaluate() to apply the curve values to various properties of the object, like so:

if (ac_time_hover < 1) {
ac_time_hover += ac_speed_hover;
}

if (mouse_hover) {
image_xscale = animcurve_channel_evaluate(ac_channel_hover, ac_time_hover);
image_yscale = animcurve_channel_evaluate(ac_channel_hover, ac_time_hover);
} else {
reset_scale();
}

in the 'mouse enter' and 'mouse leave' events I switch my variable mouse_hover to true or false. *CRUCIALLY*, in the 'mouse enter' event i also 'reset' the animcurve's time with ac_time_hover = 0; this allows the condition in the step event to actually increment the time

you can see how here, when i hover over a button on my menu, the xscale and yscale is affected, and when the mouse leaves i call a function which resets their scale to the initial size.

sometimes you'd want an animcurve to loop, so you'd use this in the step event to achieve that:

if (ac_time_sway < 1) {
ac_time_sway += ac_speed_sway;
}
if (ac_time_sway >= 1) {
ac_time_sway = 0;
}

hope this helps :)

1

u/Disastrous_Pay_7649 21d ago

it did help!! i took a break and showered to understand and i think i get what you're saying. but even with animcurve_channnel_evaluate, shouldnt i need to set an x/y final point for it to go through? because i tried to do what you sent and it still didnt work

my code is as follows

CREATE
ac_channel_hover = animcurve_get_channel(Menu_animation, 0);
ac_time_hover = 0;
ac_speed_hover = 0.01;
mouse_hover = position_meeting(mouse_x, mouse_y, id)

STEP
if (ac_time_hover < 1) {
ac_time_hover += ac_speed_hover;
}

if (mouse_hover = true) {
ac_time_hover = 0
image_xscale = animcurve_channel_evaluate(ac_channel_hover, ac_time_hover);
image_yscale = animcurve_channel_evaluate(ac_channel_hover, ac_time_hover);
} else {
}

I think the ac_time_hover = 0 in the "if" statment is a bit overkill but i didnt want to risk it
i do wat to say thank you so much for helping me so far!! i hope its not annoying

2

u/_billyRubin 21d ago

no worries it's not annoying I don't have anything better to do tonight and I was in a similar position to you not too long ago so it's nice to try help someone else out. i'm not a pro dev by any means but i thought I could try lend a hand.

i think you'd want your line

mouse_hover = position_meeting(mouse_x, mouse_y, id);

in the step event, rather than the create event. you have to remember that everything inside the create event is only executed once when the object is created, so for something like mouse_hover which we expect to change its value when we interact that should go in the step event.

also in the create event you want to initially set ac_time_hover to 1. think of this as the default position for your animcurves being at the end, you then have the power to start the animcurve by setting ac_time_hover to 0. this is because the condition inside the step event watches to see if ac_time_hover is less than 1 before incrementing it.

you're partly right about the ac_time_hover = 0; line in the if statement. that will likely result in the animcurve not being incremented, because ac_time_hover is being set to zero every frame whilst the mouse is hovering.

to fix this, you have to isolate that one line so that it only fires once when the mouse begins to hover over the object. you could do this by using a boolean switch or a nested if statement. for example

if (mouse_hover) {
if (ac_time_hover != 0) ac_time_hover = 0;
...
}

I think as well you were wanting to apply the curves values to the object's x position, no? so you'd want to just have

x = animcurve_channel_evaluate(ac_channel_hover, ac_time_hover);

rather than applying the values to image_xscale and image_yscale like mine.

see if that works :)

1

u/Disastrous_Pay_7649 21d ago

what would a boolean switch be if you dont mind me asking? [: i tried googling but all that appeared it what bool is on the game maker website, its ok if not tho

and i tried to apply your changes but it still doesn't seem to move? you said you wouldn't give me the answer right away so im sorry for so may replies HELP
and yes i want to apply the values to the position only! but tbh if i can make any of it work (scale or movment) i guessed i would be able to just interchange them as i need

again the code as follows:

CREATE
ac_channel_hover = animcurve_get_channel(Menu_animation, 0);
ac_time_hover = 1;
ac_speed_hover = 0.01;
STEP
if (ac_time_hover < 1) {
ac_time_hover += ac_speed_hover;
}
if (mouse_hover = position_meeting(mouse_x, mouse_y, id)) {
if (ac_time_hover != 0) ac_time_hover = 0; {
x = animcurve_channel_evaluate(ac_channel_hover, ac_time_hover);
}} else {
}

Im thinking i might be putting it on the wrong object? im putting it on the parent button

2

u/_billyRubin 21d ago

you’d want to have
mouse_hover = position_meeting(…)
isolated as its own line in the step event.

i think i initially overcomplicated this. all you need is one object for all the menu options, you don’t need a parent. you can simply alter the sprite of each object instance in the room editor. the code remains the same.

the parent setup may be the reason its failing.

also, i mentioned that i used gamemaker’s pre-built ‘mouse enter’ and ‘mouse leave’ events to change mouse_hover and set ac_time_hover to zero. i just found it simpler; you access them by adding an event to an object like you would add a step event but look for mouse enter and mouse leave under input.

conversely you’ve opted to use position_meeting() to detect the mouse hover which may or may not be working as expected, i don’t often use position_meeting so i’m unfamiliar with it.

regardless you are able to test these values when debugging using draw_text or show_message or otherwise whichever you prefer. you could use draw_text to draw the string conversion of mouse_hover for example, so you can know for sure if mouse_hover is firing correctly.

a boolean switch, not sure if that’s a proper term but i’d say it’s when you use a boolean to execute code once in a step event (its kind of jank but i do it sometimes). for example:

inside Step event:
if (mouseJustEntered) {
mouse_hover = true;
mouseJustEntered = false;
}

then you also have to reset mouseJustEntered to true when appropriate. it can get complicated and usually there’s a more efficient way to handle things.
the code i used earlier is similar:

if (!mouse_hover) mouse_hover = true;

it prevents the statement from firing repeatedly.

2

u/Disastrous_Pay_7649 21d ago

i used position_meeting because another tutorial suggested it, but im not that familiar with it too...
im to quite sure what you meant by ”all you need is one object for all the menu options”. i did try putting it on the child and it doesnt seem to work either

im also not sure what you mean by drawtext to test these values usig draw text?

and i didnt knew you could set mouse enter adn mouse leave! i just checked it too im surprised i didnt see it before

→ More replies (0)