GMS 2 Check vspeed of instance

Discussion in 'Programming' started by MissingNo., Feb 11, 2019.

  1. MissingNo.

    MissingNo. Member

    Joined:
    Jun 25, 2018
    Posts:
    63
    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;
        }
    }
     
  2. FrostyCat

    FrostyCat Member

    Joined:
    Jun 26, 2016
    Posts:
    3,858
    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. likes this.
  3. MissingNo.

    MissingNo. Member

    Joined:
    Jun 25, 2018
    Posts:
    63
    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.
     
  4. Bentley

    Bentley Member

    Joined:
    Jun 18, 2017
    Posts:
    653
    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: Feb 11, 2019
    MissingNo. likes this.
  5. MissingNo.

    MissingNo. Member

    Joined:
    Jun 25, 2018
    Posts:
    63
    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: Feb 11, 2019
  6. FrostyCat

    FrostyCat Member

    Joined:
    Jun 26, 2016
    Posts:
    3,858
    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. likes this.
  7. MissingNo.

    MissingNo. Member

    Joined:
    Jun 25, 2018
    Posts:
    63
    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?
     
  8. FrostyCat

    FrostyCat Member

    Joined:
    Jun 26, 2016
    Posts:
    3,858
    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. likes this.
  9. MissingNo.

    MissingNo. Member

    Joined:
    Jun 25, 2018
    Posts:
    63
    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?
     
  10. FrostyCat

    FrostyCat Member

    Joined:
    Jun 26, 2016
    Posts:
    3,858
    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. likes this.
  11. MissingNo.

    MissingNo. Member

    Joined:
    Jun 25, 2018
    Posts:
    63
    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?
     
  12. FrostyCat

    FrostyCat Member

    Joined:
    Jun 26, 2016
    Posts:
    3,858
    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. likes this.
  13. MissingNo.

    MissingNo. Member

    Joined:
    Jun 25, 2018
    Posts:
    63
    Yeah that makes a lot of sense, I'm checking a VERY specific position so it's understandable why it fails sometimes.

    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?
     
  14. Bentley

    Bentley Member

    Joined:
    Jun 18, 2017
    Posts:
    653
    edit: nm.
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice