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

GML [HELP] Floating player

D

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:


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
 
F

Frozen Stick

Guest
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.
 
D

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++;
}
 
D

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?
 
D

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 :-]
 

TheouAegis

Member
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;
 
D

deathwish

Guest
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;
ooooh this almost worked perfectly I got really excited hahaha - It works great at first but when the player lands the floating stops :(
 
D

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
 
J

JFitch

Guest
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?
 
D

deathwish

Guest
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?
good idea - that's probably the only fix I can think of
 

TheouAegis

Member
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.
 
D

deathwish

Guest
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.
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
 

bbbower

Member
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.
 
Top