1. Hello Guest! It's with a heavy heart that we must announce the removal of the Legacy GMC Archive. If you wish to save anything from it, now's the time! Please see this topic for more information.
    Dismiss Notice

GML [HELP] Floating player

Discussion in 'Programming' started by deathwish, Mar 23, 2018.

  1. deathwish

    deathwish Guest

    So I have an enemy object set up with the classic platformer movements (WASD, double jump etc;) with collision set up so that the player has to be touching the ground in order to jump; and stops moving when stuck at a wall. Now that I've figured out what I want my character to be like and actually made sprites for him rather than using place holders I figured I want my player to be floating in the air above the tiles a little bit; I figured out a way to get the objects to float for example when one of the enemies (floating eyeball) is in idle it will float around basically until it detects the players present (which works perfectly) using this code:

    Code:
    
    CREATE EVENT:
    
    //floating
    anchorY = ystart; //anchor that object will float around
    frequency = 0.1; //speed of floating
    amplitude = 20; //amount they float
    timer = 0; //process of sin wave
    
    STEP EVENT:
    y = anchorY + sin(timer*frequency)*amplitude;
            timer++;
    
    Now I wanted to do the same to this guy:
    [​IMG]

    And it basically works - I can move horizontally fine with it - BUT I can no longer jump I assume because of the collision code I have; I'm curious what I'd have to change up with the collision code to make it so he still floats but can jump if he's 'technically' on the ground (or close enough to it).

    Here's the code for it:

    Code:
    
    CREATE EVENT:
    
    //Variables
    hsp = 0;
    vsp = 0;
    grv = 0.1;
    walksp = 2;
    sprint = walksp + 2;
    jumpspeed = -5
    hascontrol = true
    jumps = 0;
    jumpsmax = 2;
    hp = 3;
    hitfrom = 0;
    
    //floating
    anchorY = ystart;
    frequency = 0.1;
    amplitude = 2.5;
    timer = 0;
    
    STEP EVENT:
    
    // Variables for moving
    if (hascontrol)
    {
    W = keyboard_check_pressed(ord("W"));
    A = keyboard_check(ord("A"));
    S = keyboard_check(ord("S"));
    D = keyboard_check(ord("D"));
    Cntrl = keyboard_check(vk_control);
    Shift = keyboard_check(vk_shift);
    doublejump = keyboard_check_pressed(W);
    // Getting player movement ^
    
    //floating
    y = anchorY + sin(timer*frequency)*amplitude;
    timer++;
    
    //moving
    
    if (Shift) walksp = sprint; // Makes you go faster
    var move = D - A;
    hsp = move * walksp;
    vsp = vsp + grv;
    
    if (place_meeting(x,y+1,obj_wall)) and (W)
    {
    jumps = jumpsmax;
    vsp = jumpspeed;
        }
    
    if (W) and (jumps > 0)
    {
    jumps -= 1;
    vsp = jumpspeed;
    }
    
    else {
       
        w = false
        a = false
        s = false
        d = false
        cntrl = false
        shift = false
    }
    }
    
    
    
    //Calculate movement ^
    //-------------------------------
    
    //-------------------------------
    //Code for moving
    
    //Horizontal Collision:
    if (place_meeting(x+hsp,y,obj_wall))
    {
        while (!place_meeting(x + sign(hsp),y,obj_wall))
        {
            x = x + sign(hsp);
        }
        hsp = 0;
    }
    x = x + hsp
    
    //Vertical Collision:
    if (place_meeting(x,y+vsp,obj_wall))
    {
        while (!place_meeting(x,y + sign(vsp),obj_wall))
        {
            y = y + sign(vsp);
        }
        vsp = 0;
    }
    y = y + vsp;
    
    If any more info is needed let me know!

    Thanks
     
  2. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,143
    See the y+1? Change the 1 to however high off the ground the reaper is.
     
    deathwish likes this.
  3. Frozen Stick

    Frozen Stick Member

    Joined:
    Jun 20, 2016
    Posts:
    21
    Perhaps you should increase the height of the sprite's hitbox or you can set it to
    (place_meeting(x,y+4,obj_wall)) for example.
     
    deathwish likes this.
  4. deathwish

    deathwish Guest

    I tried raising both and it didn't work;

    I then realised that setting the vertical speed to vsp + grv had an effect on the floating and was pushing the object down toward the collision causing it to freak out
    Getting rid of the gravity allowed me to jump BUT no longer would come back down

    Would reprogramming the collision to a tile based one maybe help with this? - I'm not sure what to do to fix it

    EDIT:

    I also wrapped the floating code in an if statement which allowed me to jump but not come down:

    Code:
    if (vsp =  0)
    {
    y = anchorY + sin(timer*frequency)*amplitude;
    timer++;
    }
    
     
  5. deathwish

    deathwish Guest

    So as far as I'm aware from all the changes I've made the problem is due to gravity

    The floating effect works without gravity fine and the jump does too except there's no way for the object to go back down to starting position now

    When I put the if statement around it it was jumping but as soon as the vertical speed reached 0 it would make the player go back to the starting position instantly

    I managed to fix this by adding this:

    Code:
    if (vsp = 0) and (place_meeting(x,y+16,obj_wall))
    {
    y = anchorY + sin(timer*frequency)*amplitude;
    timer++;
    }
    This allowed the player to jump but would stay up forever

    So everything works as I intended now except that when I add gravity to the game it ruins it and if I don't have gravity there's no way for the player to come back down to the ground - is there any possible way to allow the player to fall back down?
     
  6. deathwish

    deathwish Guest

    Changing the floating code to this and adding an else statement setting the gravity:

    Code:
    if (vsp = 0) and (place_meeting(x,y+16,obj_wall))
    {
    y = anchorY + sin(timer*frequency)*amplitude;
    timer++;
    }
    
    else vsp = vsp + grv
    
    This fixed my problem with jumping!!
    BUT I have another problem now which is when I land I get stuck in the floor now - I'm guessing it has something to do with the fact that i have anchorY = y setup in the create event and when I land somewhere with a different vertical axis it then sends the character to the axis? Or it may have something to do with my collision code?

    Code:
    [CODE]//Horizontal Collision:
    if (place_meeting(x+hsp,y,obj_wall))
    {
        while (!place_meeting(x + sign(hsp),y,obj_wall))
        {
            x = x + sign(hsp);
        }
        hsp = 0;
    }
    x = x + hsp
    
    //Vertical Collision:
    if (place_meeting(x,y,obj_wall))
    {
        while (!place_meeting(x,y + sign(vsp),obj_wall))
        {
            y = y + sign(vsp);
        }
        vsp = 0;
    }
    y = y + vsp;
    
    I'm sort of just fixing it through trial and error and I'm getting somewhat close to a good result; there's just something off about this

    Any ideas would be appreciated :-]
     
  7. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,143
    Code:
    if (place_meeting(x,y+vsp,obj_wall))
    {
       while (!place_meeting(x,y + sign(vsp),obj_wall))
       {
           y = y + sign(vsp);
       }
       vsp = 0;
    }
    y = y + vsp;
    Try changing this to

    Code:
    if (place_meeting(x,y+vsp+16*(vsp>0),obj_wall))
    {
       while (!place_meeting(x,y + 16*(vsp>0) + sign(vsp),obj_wall))
       {
           y = y + sign(vsp);
       }
       vsp = 0;
    }
    y = y + vsp;
     
    deathwish likes this.
  8. deathwish

    deathwish Guest

    ooooh this almost worked perfectly I got really excited hahaha - It works great at first but when the player lands the floating stops :(
     
  9. deathwish

    deathwish Guest

    bump - I can't seem to get this to work it's really frustrating

    i know the answer is probably staring me right in the face
     
  10. JFitch

    JFitch Member

    Joined:
    Sep 28, 2016
    Posts:
    428
    What about using a different sprite for floating, so it appears to be floating but the bounding box is still touching the ground, so the collision with ground event still triggers?
     
    deathwish likes this.
  11. deathwish

    deathwish Guest

    good idea - that's probably the only fix I can think of
     
  12. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,143
    I am just going to ask to see the full updated code again. Only thing I can think of right now is maybe the rest of the code conflicts with the new the code somehow.
     
  13. deathwish

    deathwish Guest

    I’ve scrapped the floating idea for now because I was spending too much time trying to figure it out - in the mean time ive set up state machines for the player etc organizational stuff

    Here’s the last updated code w/ floating:

    Code:
    
     //-------------------------------
    
    // Variables for moving
    if (hascontrol)
    {
    W = keyboard_check_pressed(ord("W"));
    A = keyboard_check(ord("A"));
    S = keyboard_check(ord("S"));
    D = keyboard_check(ord("D"));
    Cntrl = keyboard_check(vk_control);
    Shift = keyboard_check(vk_shift);
    doublejump = keyboard_check_pressed(W);
    // Getting player movement ^
    
    //floating
    if (vsp = 0) and (place_meeting(x,y+16,obj_wall))
    {
    y = anchorY + sin(timer*frequency)*amplitude;
    timer++;
    }
    else vsp = vsp + grv
    
    //moving
    
    if (Shift) walksp = sprint; // Makes you go faster
    var move = D - A;
    hsp = move * walksp;
    
    
    if (place_meeting(x,y+16,obj_wall)) and (W)
    {
    jumps = jumpsmax;
    vsp = jumpspeed;
        }
    
    if (W) and (jumps > 0)
    {
    jumps -= 1;
    vsp = jumpspeed;
    }
    
    else {
       
        w = false
        a = false
        s = false
        d = false
        cntrl = false
        shift = false
    }
    }
    
    
    
    //Calculate movement ^
    //-------------------------------
    
    //-------------------------------
    //Code for moving
    
    //Horizontal Collision:
    if (place_meeting(x+hsp,y,obj_wall))
    {
        while (!place_meeting(x + sign(hsp),y,obj_wall))
        {
            x = x + sign(hsp);
        }
        hsp = 0;
    }
    x = x + hsp
    
    //Vertical Collision:
    if (place_meeting(x,y+vsp+16*(vsp>0),obj_wall))
    {
       while (!place_meeting(x,y + 16*(vsp>0) + sign(vsp),obj_wall))
       {
           y = y + sign(vsp);
       }
       vsp = 0;
    }
    y = y + vsp;
    //Animation:
    
    if (!place_meeting(x,y+1,(obj_wall)))
    { 
        sprite_index = spr_grim;
        image_speed = 0;
        if (sign(vsp) > 0) image_index = 1; else image_index = 0;       
    } // If player is jumping or falling it will use relevant animation
    
    else
    {
        image_speed = 1;
        if (hsp == 0)
        {
            sprite_index = spr_grim;
        }
        else
            {
                sprite_index = spr_grim;
            }
    }  //if player is NOT running then the original sprite will be used; if is running running sprite will
    
    
    
    
    //if facing left player will flip left
    
    if (point_direction(x,y,mouse_x,mouse_y) > 90) and (point_direction(x,y,mouse_x,mouse_y) < 270)
    {
        image_xscale = -1;
    
    }
    
    else {
        image_xscale = 1;
    }//if mouse/gun pointing left side char will face left vice versa
    
       
            if place_meeting (x,y,obj_enemy) // if player + enemy collide
        {
            var colliding_enemy = instance_place(x,y, obj_enemy); //instance_place will kill only the enemy u jump on
           
        if (colliding_enemy.y < y+48)
        {
            vsp = -4;
            with (colliding_enemy) hp = 0;
        }
    else 
    {
        with (obj_gun) instance_destroy();
        instance_change(obj_player_dead,true);
        direction = point_direction(other.x,other.y,x,y);
        hsp = lengthdir_x(6,direction);
        vsp = lengthdir_y(4,direction)-2;
        if (sign(hsp) !=0) image_xscale = sign(hsp)
    }
    }
    

    Cheers
     
  14. bbbower

    bbbower Member

    Joined:
    Sep 11, 2016
    Posts:
    58
    Simply keep your existing movement, and instead of draw_self() in the draw event or using the default draw event make a custom draw event.

    draw_sprite_ext( sprite, subimg, x+float_x, y + float_y, xscale, yscale, rot, colour, alpha );

    and change the float_x/y around to simulate floating. If you are not floating much higher than a few pixels you shouldn't have to change your bounding boxes much if at all.
     

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