///move_state
//Set animation speed for movement
image_speed = 1;
//Set default speed if there is no input
hspd = 0;
vspd = 0;
//Set speed to the direction you are pressing as long as there isn't a wall there
//Left and up take precedence
if(right && !place_meeting(x+1,y,Solid)) hspd = spd;
if(left && !place_meeting(x-1,y,Solid)) hspd = -spd;
if(down && !place_meeting(x,y+1,Solid)) vspd = spd;
if(up && !place_meeting(x,y-1,Solid)) vspd = -spd;
//Prevent stuttering if against a wall pressing opposite directional buttons
/*
SPECIAL NOTE: The following two lines of uncommented code deviate from Undertale.
In Undertale if you hold both UP & DOWN at the same time and run into a wall,
your character will stutter against it. Also if you hold LEFT & RIGHT and run into a wall,
your character will stop in its tracks. I fixed those issues in the next two lines of uncommented code.
if you truly wanted an exact replica of Undertale, replace them with this instead:
if(left && right && place_meeting(x-1,y,Solid))
{
hspd = 0;
vspd = 0;
}
This will replicate the stuttering effect and the freeze effect you encounter in Undertale.
*/
if(left && right && place_meeting(x-1,y,Solid)) hspd = 0;
if(up && down && place_meeting(x,y-1,Solid)) vspd = 0;
//Set the sprite to the appropriate direction
if(hspd < 0) sprite_index = spr_testleft;
if(hspd > 0) sprite_index = spr_testright;
if(vspd < 0) sprite_index = spr_testup;
if(vspd > 0) sprite_index = spr_testdown;
//Sprite direction correction in special cases of multiple button press combinations
if((right && down && left && !up) || (right && down && !left && !up && dir == 1) || (left && down && !right && !up && dir == 3)) dir = 0;
if((down && left && up && !right) || (down && left && !up && !right && dir == 2) || (up && left && !right && !down && dir == 0)) dir = 1;
if((left && up && right && !down) || (left && up && !right && !down && dir == 3) || (right && up && !down && !left && dir == 1)) dir = 2;
if((up && right && down && !left) || (up && right && !down && !left && dir == 0) || (down && right && !up && !left && dir == 2)) dir = 3;
//Maintain sprite momentum by checking the previous sprite direction
if(hspd < 0 && dir == 1 && left) sprite_index = spr_testleft;
if(hspd > 0 && dir == 3 && right) sprite_index = spr_testright;
if(vspd < 0 && dir = 2 && up) sprite_index = spr_testup;
if(vspd > 0 && dir = 0 && down) sprite_index = spr_testdown;
//Special checks when you're up against a wall trying to move against or along it
if(sprite_index == spr_testleft)
{
if(place_meeting(x-1,y,Solid))
{
if(vspd > 0 && !place_meeting(x,y+1,Solid))
{
sprite_index = spr_testdown;
dir = 3;
}
else if(vspd < 0 && !place_meeting(x,y-1,Solid))
{
sprite_index = spr_testup;
dir = 1;
}
else
{
hspd = 0;
vspd = 0;
}
}
else dir = 1;
}
if(sprite_index == spr_testright)
{
if(place_meeting(x+1,y,Solid))
{
if(vspd > 0 && !place_meeting(x,y+1,Solid))
{
sprite_index = spr_testdown;
dir = 3;
}
else if(vspd < 0 && !place_meeting(x,y-1,Solid))
{
sprite_index = spr_testup;
dir = 1;
}
else
{
hspd = 0;
vspd = 0;
}
}
else dir = 3;
}
if(sprite_index == spr_testup)
{
if(place_meeting(x,y-1,Solid))
{
if(hspd > 0 && !place_meeting(x+1,y,Solid))
{
sprite_index = spr_testright;
dir = 3;
}
else if(hspd < 0 && !place_meeting(x-1,y,Solid))
{
sprite_index = spr_testleft;
dir = 1;
}
else
{
hspd = 0;
vspd = 0;
}
}
else dir = 2;
}
if(sprite_index == spr_testdown)
{
if(place_meeting(x,y+1,Solid))
{
if(hspd > 0 && !place_meeting(x+1,y,Solid))
{
sprite_index = spr_testright;
dir = 3;
}
else if(hspd < 0 && !place_meeting(x-1,y,Solid))
{
sprite_index = spr_testleft;
dir = 1;
}
else
{
hspd = 0;
vspd = 0;
}
}
else dir = 0;
}
//If there is no input, default to the idle state
if(hspd == 0 && vspd == 0)
{
sprite_index = spr_testidle;
image_speed = 0.5;
}
//Actually move the player
move(Solid);