0
\$\begingroup\$

In oGirlTest object I have a Create and Step event.

Create:

///PLAYER OBJECT CREATE EVENT

//Maximum speed
spd = 4;

//Current movement speed
hspd = 0;
vspd = 0;

//Initialize basic properties
sprite_index = sPlayerDown;
image_speed = 0.5;

//Initialize basic movement state
state = move_state;

/*

Directions for top-down spritework.

0 = down
1 = left
2 = up
3 = right

*/

dir = 0;

Step:

///PLAYER OBJECT STEP EVENT

//Get input (keyboard/controller)
get_input();

//Execute the state (in the basic case, this calls the move_state script)
script_execute(state);

And 3 scripts that I've found and which I'm trying to understand in order to replicate the Undertale movement

get_input

///get_input()

left = keyboard_check(vk_left);
right = keyboard_check(vk_right);
up = keyboard_check(vk_up);
down = keyboard_check(vk_down);

move_state

///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 = sPlayerLeft;

if(hspd > 0) sprite_index = sPlayerRight;

if(vspd < 0) sprite_index = sPlayerUp;

if(vspd > 0) sprite_index = sPlayerDown;

//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 = sPlayerLeft;

if(hspd > 0 && dir == 3 && right) sprite_index = sPlayerRight;

if(vspd < 0 && dir = 2 && up) sprite_index = sPlayerUp;

if(vspd > 0 && dir = 0 && down) sprite_index = sPlayerDown;

//Special checks when you're up against a wall trying to move against or along it

if(sprite_index == sPlayerLeft)
{
    if(place_meeting(x-1,y,Solid))
{
   if(vspd > 0 && !place_meeting(x,y+1,Solid))
   {
       sprite_index = sPlayerDown;
       dir = 3;
   }
   else if(vspd < 0 && !place_meeting(x,y-1,Solid))
   {
       sprite_index = sPlayerUp;
       dir = 1;
   }
   else
   {
       hspd = 0;
       vspd = 0;
   }
}
     else dir = 1;
}

    if(sprite_index == sPlayerRight)
    {
    if(place_meeting(x+1,y,Solid))
    {
        if(vspd > 0 && !place_meeting(x,y+1,Solid))
    {
        sprite_index = sPlayerDown;
       dir = 3;
    }
       else if(vspd < 0 && !place_meeting(x,y-1,Solid))
   {
       sprite_index = sPlayerUp;
       dir = 1;
   }
   else
   {
       hspd = 0;
       vspd = 0;
   }
 }
else dir = 3;
}

    if(sprite_index == sPlayerUp)
 {
    if(place_meeting(x,y-1,Solid))
 {
   if(hspd > 0 && !place_meeting(x+1,y,Solid))
   {
       sprite_index = sPlayerRight;
       dir = 3;
   }
   else if(hspd < 0 && !place_meeting(x-1,y,Solid))
   {
       sprite_index = sPlayerLeft;
       dir = 1;
   }
   else
   {
       hspd = 0;
       vspd = 0;
   }
 }
else dir = 2;
    }

    if(sprite_index == sPlayerDown)
    {
 if(place_meeting(x,y+1,Solid))
 {
   if(hspd > 0 && !place_meeting(x+1,y,Solid))
   {
       sprite_index = sPlayerRight;
       dir = 3;
   }
   else if(hspd < 0 && !place_meeting(x-1,y,Solid))
   {
       sprite_index = sPlayerLeft;
       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 = sPlayerDown;
image_speed = 0.5;
}

//Actually move the player

move(Solid);

move

///move(collision_object)

var collision_object = argument0;

//Horizontal collisions

if(place_meeting(x+hspd,y,collision_object))
{
  while(!place_meeting(x+sign(hspd),y,collision_object))
 {
    x += sign(hspd);
 }
hspd = 0;
}

x += hspd;

//Vertical collisions

if(place_meeting(x,y+vspd,collision_object))
{
while(!place_meeting(x,y+sign(vspd),collision_object))
{
       y += sign(vspd);
}
  vspd = 0;
}

y += vspd;

And I'm getting the following error, for another person this script worked so I'm not sure what I'm doing wrong, I apologize for the wall of text, just trying to understand.

___________________________________________
############################################################################################
FATAL ERROR in
action number 1
of  Step Event0
for object oGirlTest:

Variable oGirlTest.Solid(100008, -2147483648) not set before reading it.
at gml_Script_move_state (line 150) -      if(place_meeting(x,y+1,Solid))
############################################################################################
--------------------------------------------------------------------------------------------
stack frame is
gml_Script_move_state (line 150)
called from - gml_Object_oGirlTest_StepNormalEvent_1 (line 7) -     script_execute(state);
\$\endgroup\$
2
\$\begingroup\$

As far I can tell, Solid is not set before reading it.

Your move_state is likely a script, so it's unrelated directly to an object. The error is that it tries to reach a variable that's not defined. technically a nullreference exception.

I assume Solid is a custom variable and not standard build-in. oGirlTest doesn't have a definition for Solid in the Create event, but is able to reach move_state, move_state assumes it can reach Solid through the oGirlTest. that's where the error comes from.

One possible solution is to define Solid in the Create event of oGirlTest. But that depends on your game situation if it should be there.

EDIT: Reading it again, I think I've misunderstood it. Place_meeting is used to reach a different instance, so Solid should be the name of that instance it's colliding with. Your Gamemaker cannot recognise an instance named Solid(it's Case-sensitive), so it assumes that Solid is a custom variable from oGirlTest.

So you need to create an instance that's called Solid, and use that as the walls you're colliding with. Once it can recognise an instance correctly, the text should be turn dark red.

\$\endgroup\$
  • \$\begingroup\$ I've revisited it and noticed that I've probably misunderstood it, please read my EDIT message in case you havn't figured it out yet. \$\endgroup\$ – Steven Nov 12 '18 at 7:58

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.