• 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!

Legacy GM move value towards value without lerp

S

Shadowblitz16

Guest
can someone help me I'm looking for a way to slowly move a value towards another value at a set speed
I would prefer to use something that uses one line of code if that is possible
I do not want to use lerp because it has problems reaching the target value(please do not argue with me on this)

something along the lines of move_towards_value(value, target)

Edit: here is my current code
Code:
///Update vars

//get axis input
var h = keyboard_check(vk_right) - keyboard_check(vk_left);
var v = keyboard_check(vk_down)  - keyboard_check(vk_up);

//move ship
x += h * hsp;
y += v * vsp;

//animate ship

tilt = clamp((tilt + h*0.2), -1, 1)
image_index = tilt+1;
I am aiming to make it slowly rotate the ship towards the input but when it is released it slowly turns back to 0 or frame 1
 
S

Shadowblitz16

Guest
no its not direction its more of a 3D tilt effect with sprites

I have frame as followed
so left = 0; idle = 1; right = 2;
and I'm getting the input as
left = -1; none = 0; right = 1;

tilt is the variable I slowly adjust when my h input is -1 or 1 and assign it to my image_index
I want to slowly rotate back to 0 when horizontal input is none

also I think I just found a bug in game maker with the tilting to the edges part
 
T

TimothyAllen

Guest
You can use median for something like this.
Code:
tilt = median(h, tilt + 0.2, tilt - 0.2);
Lerp has no problem reaching its target!
 
L

L0v3

Guest
I have just the thing from my engine. Use this to approach an upper value for true or lower value for false following parameters of given tween.

Here's an example of usage:
Code:
var condition = //something random like mouseover, keypress or whatever.
tilt = animation_tween_step(id, condition, tween_linear, tilt, room_speed * 2, 0, 1);

Here's the script and object it uses.

Code:
///animation_tween_step(id, boolean, tween, value, duration, lower, upper);

// Returns a value between the given start and final value depending on boolean.
// This value is then acheived by following a tween over the given amount of steps, slowly
// approaching either the upper value for True or lower value for False.

// Note: Use within a step event.

// id               = Unique identifier used to retrive object that stores tweening data.
// boolean          = Boolean value to determine if should approach upper or lower.
// tween            = Tween script for effect to be used.
// value            = Current value of the tween.
// duration         = Total number of steps for the tween to complete.
// lower            = Lower value of the tween. Value reached when False.
// upper            = Upper value of the tween. Value reached when True.

// Dependencies: eng_animation_tween_step, tween script used.

// @Return: Value for tween at current step, between start and end value.

//Converts arguments to locals.
var identifier = argument0;
var boolean = argument1;
var tween = argument2;
var value = argument3;
var duration = argument4;
var lower = argument5;
var upper = argument6;

//Retrives the instance from the identifier.

//Singleton Identifier Arguments.
var xx = 0;
var yy = 0;
var obj = eng_animation_tween_step;

//Creates variables.
var instance = noone;
var check = noone;
var found = false;
var i;

//Checks for existing instance with id.
for (i = 0; i < instance_number(obj); i++)
{
    check = instance_find(obj, i);   
    if (check.eng_singleton_identifier = identifier)
    {
        found = true;
        break;
    }
}

//Checks if instance was found.
if (found)
{
    //Sets instance to existing.
    instance = check;
}
else
{
    //Creates new instance.
    instance = instance_create(xx, yy, obj);
    instance.eng_singleton_identifier = identifier;
}

//Sets object to instance.
obj = instance;

//Sends over variables.
with (obj)
{
    //Data variables.
    self.obj = other.id;
    self.boolean = boolean;
    self.tween = tween;
    self.duration = duration;
    self.lower = lower;
    self.upper = upper;
    self.value = value;
}

//Delayed Creation Code
if (!found)
{
    with (obj)
    {
        event_user(1);
    }
}

//Executes a single step of the tween.
with (obj)
{
    event_user(0);
}

//Retrives and returns value.
return obj.value;
Code:
Information about object: eng_animation_tween_step
Sprite:
Solid: false
Visible: true
Depth: 0
Persistent: false
Parent:
Children:
Mask:
No Physics Object
Create Event:
execute code:

///Creation Code

//Data Variables
boolean = noone;
tween = noone;
duration = noone;
lower = noone;
upper = noone;

//The Return Value
value = noone;

//Instance Variables
done = true;
previous = noone;
interupt = false;

//Interuption Variables
interupt_duration = noone;
interupt_lower = noone;
interupt_upper = noone;

Step Event:
execute code:

//Check if parent is still alive.
if (!instance_exists(obj))
{
    instance_destroy();
}

Other Event: User Defined 0:
execute code:

///Handles Tweening

//Checks for change.
if (boolean)
{
    //Checks for interuption
    if (previous = "false" and !done)
    {
        //Updates interupt values.
        interupt = true;
        interupt_duration = duration;
        interupt_lower = value;
        interupt_upper = upper;
        step = 0;
    }
    else if (previous = "false")
    {
        step = 0;
    }
}
else
{
    //Checks for interuption
    if (previous = "true" and !done)
    {
        //Updates interupt values.
        interupt = true;
        interupt_duration = duration;
        interupt_lower = lower;
        interupt_upper = value;
        step = 0;
    }
    else if (previous = "true")
    {
        step = 0;
    }
}

//Checks for boolean.
if (boolean)
{
    //Updates variables.
    done = false;
    previous = "true";
    step++;

    //Checks for interuption
    if (!interupt)
    {
        //Normal tweening.
        value = script_execute(tween, step, duration, lower, upper);
  
        //Check if complete.
        if (step > duration)
        {
            step = duration;
            interupt = false;
            done = true;
        }
    }
    else
    {
        //Interupt tweening.
        value = script_execute(tween, step, interupt_duration, interupt_lower, interupt_upper);
  
        //Check if complete.
        if (step > interupt_duration)
        {
            step = duration;
            interupt = false;
            done = true;
        }
    }
}
else
{
    //Updates variables.
    done = false;
    previous = "false";
    step++;

    //Checks for interuption
    if (!interupt)
    {
        //Normal tweening.
        value = script_execute(tween, step, duration, upper, lower);

        //Check if complete.
        if (step > duration)
        {
            step = duration;
            interupt = false;
            done = true;
        }
    }
    else
    {
        //Interupt tweening.
        value = script_execute(tween, step, interupt_duration, interupt_upper, interupt_lower);
  
        //Check if complete.
        if (step > interupt_duration)
        {
            step = duration;
            interupt = false;
            done = true;
        }
    }
}

Other Event: User Defined 1:
execute code:

///Delayed Creation Code

//Determines inital step value.
if (boolean)
{
    step = 0;
}
else
{
    step = duration;
}

Here's a linear tween to go with it:

Code:
///tween_linear(step, total, start, final);

// Finds the given tween value following tween parameters at the current step.
// Note: Use within a step event and have an iterative variable for the argument step.

// This tweening is linear with with constant velocity at all times.

// step             = Current step for the tween. Use an iterative variable for current step.
// total            = Total number of steps for the tween to complete.
// start            = Start value of the tween.
// final            = Final value of the tween.

// @Return: Value for tween at current step, between start and end value.

//Converts arguments to locals.
var step = argument0;
var total = argument1;
var start = argument2;
var final = argument3;

//Calculates delta for value.
var delta = final - start;

//Tweening Math.
var result = delta * step / total + start;

//Returns result.
return result;
 
Last edited by a moderator:

Yal

🐧 *penguin noises*
GMC Elder
How about this?
Code:
///interpolate(source,target,maxchange)
//Returns the new value, update the variable with it.
if(argument0 < argument1){
  return min(argument1,argument0 + argument2)
}
else{
  return max(argument1,argument0 - argument2)
}
 
S

Shadowblitz16

Guest
Thankyou guys for your reply I am probably going to go with either Yal's or Strawbry_jam's code

Edit: there still seems to be a bug with speed tilting left and speed tilting right
they do it at different speeds when I add 1 to tilt

Edit2: this is the code that seems to be returning the wrong value
Code:
image_index = round((tilt+1)/0.1)*0.1;
 
Last edited by a moderator:
T

TimothyAllen

Guest
Your problem is that when the sprite is drawn, it is drawn with the image_index floored. So simply add 1 if h < tilt:
Code:
image_index = tilt + 1 + (h < tilt);
 
Top