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

GameMaker Check vspeed of instance

MissingNo.

Member
I want to check 2 pixels below the block for the enemyparent and then check that the vspeed of the specific
instance is smaller than -3. Then once both criteria are fulfilled then I want to execute the rest of the code.

The code works fine as is but the problem is I don't know how to check the vspeed of a specific instance rather than the object itself.

Code:
if(hit == 0)
{
    // If Object At Place
    var l5D388924_0 = instance_place(x + 0, y + 2, enemyparent);
    if ((l5D388924_0 > 0))
    {
        // Set Sprite
        sprite_index = emptyblock2;
        image_index = 0;
   
        // Assign Variable
        hit = 1;
    }
}
 

FrostyCat

Redemption Seeker
Who told you that only an object ID can be on the left side of a dot? An instance ID also has every right to be in the same position. If the instance ID is l5D388924_0, then its vspeed is l5D388924_0.vspeed.
 

MissingNo.

Member
Who told you that only an object ID can be on the left side of a dot?
Nobody, I'm just an idiot. But now I have a new problem, this new code is working but it only works if the enemy is heading straight upwards.
If it is traveling diagonally the vspeed check will fail and the rest of the code will refuse to trigger.

Code:
if(hit == 0)
{
    // If Object At Place
    var l5D388924_0 = instance_place(x + 0, y + 1, playerallparent);
    if ((l5D388924_0 > 0))
    {
        // If Variable
        with(l5D388924_0) var l26139CEE_0 = vspeed < -4;
        if(l26139CEE_0)
        {
            // Set Sprite
            sprite_index = emptyblock2;
            image_index = 0;
        
            // Assign Variable
            hit = 1;
        }
    }
}
Oh and just so everyone knows, I move the enemy with hspeed and vspeed.
 

Bentley

Member
It might be easier to use simpler variable names. For ex:
Code:
var inst = instance_place(x, y + 1, obj_something);

if (instance_exists(inst))
{
    with (inst)
    {
        if (vspeed < 4)
        {
            // Do stuff 
        }
    }
}
Every instance has an id. You don't need to create it for them. What you can do is get an instance's id and store it in a variable (like "inst" above). You can then change that instance using
Code:
with (inst)
{
    vspeed = 4;    
}

// or

inst.vspeed = 4;
 
Last edited:

MissingNo.

Member
It might be easier to use simpler variable names. For ex:
Thanks for the help but this made the problem worse:

Code:
if(hit == 0)
{
var inst = instance_place(x, y + 1, playerallparent);
if (instance_exists(inst))
{
    with (inst)
    {
        if (vspeed < -4)
        {
          sprite_index = emptyblock2;
          image_index = 0;
          hit = 1;
        }
    }
}
}
Now what happens is that it applies the sprite change to the player itself instead of to the empty block this code is running on.

Basically I want to check that the player or enemy is 1 pixel below the empty block and then I want to check that instance to make sure its vertical speed is smaller than -4
and then I want the block to then switch sprites once the instance below it meets both criteria.

I'm checking "vspeed < -4" to see if the instance is traveling upwards at a high enough speed
before triggering the empty block.

This code is to be run on the empty block, not on the instance I'm checking:
Code:
sprite_index = emptyblock2;
image_index = 0;
hit = 1;
 
Last edited:

FrostyCat

Redemption Seeker
What's with the needless avoidance of the dot syntax? When you use a with block, the code inside is executed from the perspective of the target, not the original instance. Since you only need this perspective change once for getting vspeed, just use the dot syntax.
Code:
var inst = instance_place(x, y + 1, playerallparent);
if (instance_exists(inst) && inst.vspeed < -4)
{
    sprite_index = emptyblock2;
    image_index = 0;
    hit = 1;
}
 

MissingNo.

Member
What's with the needless avoidance of the dot syntax? When you use a with block, the code inside is executed from the perspective of the target, not the original instance. Since you only need this perspective change once for getting vspeed, just use the dot syntax.
I think I was completely misunderstanding what you were saying, I get it now.

Code:
if(hit == 0)
{
var inst = instance_place(x, y + 3, playerallparent);
if (instance_exists(inst) && inst.vspeed < -4)
{
    sprite_index = emptyblock2;
    image_index = 0;
    hit = 1;
}
}
Now this code is having the same problem I was having before, it only seems to work if the player or enemy is jumping straight upwards. If the player is jumping diagonally the check will fail.

Why is this happening? The instance still has vspeed going upwards. Why does it seem like if any hspeed is applied at all then this check will fail?
 

FrostyCat

Redemption Seeker
Because if your jump is diagonal and you corrected for speed (e.g. having only a vertical speed of -0.707 for a speed of 1 at a direction of 135), the horizontal component will dilute the magnitude of the vertical component. It may still be negative, but not as far as -4 as you expect.
 

MissingNo.

Member
Because if your jump is diagonal and you corrected for speed (e.g. having only a vertical speed of -0.707 for a speed of 1 at a direction of 135), the horizontal component will dilute the magnitude of the vertical component. It may still be negative, but not as far as -4 as you expect.
I did think of this but the player is being forced upwards at a speed of -8 and I even did a quick test of changing the check to: "inst.vspeed < -0.1" and it still fails.
Only if the player is jumping straight upwards does the check work. I don't understand, the players vspeed can't be diluted that much.

I wonder what I am doing wrong?
 

FrostyCat

Redemption Seeker
If your "force upward" code is done by jumping positions, paths or any other means except for setting vspeed (e.g. setting vspeed or speed, using move_towards_point(), motion_set() or motion_add() etc.), it won't register in vspeed. Draw vspeed in real-time and see what its true value is.
 

MissingNo.

Member
If your "force upward" code is done by jumping positions, paths or any other means except for setting vspeed (e.g. setting vspeed or speed, using move_towards_point(), motion_set() or motion_add() etc.), it won't register in vspeed. Draw vspeed in real-time and see what its true value is.
Yeah I'm not doing anything like that in my code, which is why I am so confused.

But I think I narrowed down the issue, it seems checking 3 pixels below "var inst =instance_place(x, y + 3, playerallparent)" is not enough to detect the instance jumping below it.
It seems I need to be checking y + 6 or higher to detect the instance. I have no idea why I need to check so far below the block, but once I do everything works perfectly.

Have any idea why checking 3 pixels below is not enough? It's puzzling but I can live with it.
When we use instance_place are we checking from the origin point of the sprite or are we checking below the collision box of the sprite?
 

FrostyCat

Redemption Seeker
It's easy to see why once you start treating it as a discrete-time environment. When you set a speed of 8, between two consecutive steps you are only ever 0 away or 8 away, never any value in between. You end up either under- or over-stepping the paper-thin 1-pixel margin you set for yourself.

An expectation for an ideal, noiseless runtime environment is one of the worst beliefs a programmer can acquire.
 

MissingNo.

Member
It's easy to see why once you start treating it as a discrete-time environment. When you set a speed of 8, between two consecutive steps you are only ever 0 away or 8 away, never any value in between. You end up either under- or over-stepping the paper-thin 1-pixel margin you set for yourself.
Yeah that makes a lot of sense, I'm checking a VERY specific position so it's understandable why it fails sometimes.

An expectation for an ideal, noiseless runtime environment is one of the worst beliefs a programmer can acquire.
You sound like a Greek philosopher who decided to take up programming.:D But in all seriousness thanks for all your help, I have been using GameMaker for about 8 years
And in skill I'm still no better than a novice. Luckily I'm just doing this as a hobby.

I have another question though, when we use instance_place are we checking from the origin point of the sprite or outside the collision of the sprite?
 
Top