GML Visual How to jump through an object but land on it too

H

homeyworkey

Guest
Hi,

I want to just make it clear I'm very amateur at this and I'm not sure what I'm going to ask for you guys to help me out with is way out of my reach or if it's a possibility that you could help me while I can understand it all.

I want platforms I can jump through if under, but if above it will stop. I want to make it also so if I press S or down arrow key while on it, you will fall through it. I don't even know where to start with this idea, so I have no code, and I don't know what to even google for this sort of specific "platform" Thanks!
 
D

dindow

Guest
Every object has a so-called collision mask. If you use a place_meeting(); function, you don't check for collisions with the pixels of the sprite, but with its collision mask. What you want to achieve is turning off this collision mask when you are underneath the platform.
There is a built-in variable called "mask_index", so you can use it simply like this:

mask_index = noone; //This turns off the mask
mask_index = sprite_index; //This returns the mask index to its original form.

So the final code should look something like this:

if(obj_player.y < y || keyboard_check_pressed(ord("S"))){ //If the player is above the platform or pressing S
mask_index = noone;
}else{
mask_index = sprite_index;
}
 

Rob

Member
Every object has a so-called collision mask. If you use a place_meeting(); function, you don't check for collisions with the pixels of the sprite, but with its collision mask. What you want to achieve is turning off this collision mask when you are underneath the platform.
There is a built-in variable called "mask_index", so you can use it simply like this:

mask_index = noone; //This turns off the mask
mask_index = sprite_index; //This returns the mask index to its original form.

So the final code should look something like this:

if(obj_player.y < y || keyboard_check_pressed(ord("S"))){ //If the player is above the platform or pressing S
mask_index = noone;
}else{
mask_index = sprite_index;
}
That actually sounds like a very easy and straightforward way of going about it, and not one that I would of thought of. The only potential issue might be if enemies were also using the sprite for collision?
 
T

trialuser

Guest
@homeyworkey google for "one-way platform". But I'm pretty sure you should use GML.
Here is one tutorial, made by... never mind.
 
Last edited by a moderator:
G

Gillen82

Guest
That actually sounds like a very easy and straightforward way of going about it, and not one that I would of thought of. The only potential issue might be if enemies were also using the sprite for collision?
Turn your own mask off while jumping through the platform, then turn it back on when you have passed through it
 
  • Like
Reactions: Rob

DesArts

Member
I'd check the platforms manually (loop through nearby ones), and check if you are above or below them via code for each specific one, and pick or choose which ones to collide with, then you don't need to remove any masks which will mess up other objects collision.

Bit more complex but tasty results.
 

TheouAegis

Member
Removing the mask is a horrible idea - it's never been a good idea and it never will be a good idea. How the hell would anything else collide with the platform if you remove the platform's collision mask? How would anything collide with the player if you remove the player's mask?

When you collide with the platform, is your vspeed or vspd or vsp greater than 0? Is your bbox_bottom-vspeed (or whatever) less than the platform's bbox-top? If both are true, collide with it.
 
Last edited:
H

homeyworkey

Guest
Some of you have raised good points on how collision masks isn't the way to go- but when it comes to doing it the right way, I still have no clue how to do it. I don't want to do it in code (or GMS2??) because we've been creating it in class in D&D only. I just want to know, is it possible to do this with D&D, and how exactly? (This is my first ever game, and even then I haven't done much, so as I've said I'm very amateur, most of what you guys say completely flies over my head). Thanks, I'll keep researching ;)
 

TheouAegis

Member
Collision event with platform:

Check if variable vspeed is greater than 0
Check if variable (or expression, but variable should work) bbox_bottom-vspeed is less than other.bbox_bottom
Start block
Set variable y to other.bbox_top-bbox_bottom relative
Set variable vspeed to 0
end block
 

poliver

Member
For collisions:
set a collision LINE from your characters bbox_bottom left to right
(this is to avoid weird behavior like being able to jump out of the platforms while falling through them)
check for collisions only on the way down

And if you want to have one-way platforms of any thickness(mask as thin as 1 px) and not fall through them if your speed is greater than one:
Do a pixel perfect collision checking on the way down every step using while loop/if it hits the platform use break
 
Last edited:

TheouAegis

Member
I agree. I know people around here just love love LOVE Shaun's tutorials, but they have so many flaws in them. From his occasional typo and logic error due to brain farts (I understand these, but dude should have done some post-editing to get rid of them), to his downright horrible advise like setting mask_index to -1 (which stemmed from the archaic advice to set solid=false, which has the exact same flaws as mask_index=-1), Shaun's videos are hardly the answer to every question. Some videos are good to direct people to, I'll give him that; videos like his One-Way Platforms tutorial, though, are just trash.
 
H

homeyworkey

Guest
I tried what TheouAegis told me to do- and I probably did it wrong (When I tried in game, it just acted like a block but you got stuck on it if you got on it). I don't know what you mean by "start block" and "end block" but oh well tell me what needs to be changed. Thanks a bunch!
 

Attachments

I

icuurd12b42

Guest
PLEASE STOP!!!
I agree. I know people around here just love love LOVE Shaun's tutorials, but they have so many flaws in them. From his occasional typo and logic error due to brain farts (I understand these, but dude should have done some post-editing to get rid of them), to his downright horrible advise like setting mask_index to -1 (which stemmed from the archaic advice to set solid=false, which has the exact same flaws as mask_index=-1), Shaun's videos are hardly the answer to every question. Some videos are good to direct people to, I'll give him that; videos like his One-Way Platforms tutorial, though, are just trash.
Yeah mask fiddling is horrible and that particular tut is horrible.

I tried what TheouAegis told me to do- and I probably did it wrong (When I tried in game, it just acted like a block but you got stuck on it if you got on it). I don't know what you mean by "start block" and "end block" but oh well tell me what needs to be changed. Thanks a bunch!
Did you set the object to be a solid, is that still a (unfortunate) thing in gms2?

I dont think startblock endblock is a gms2 D&D thing.

And OMG doing GM in D&D is horrible. they still don't have proper copy paste (outside of program) to help paste code.

upload_2018-7-2_22-27-52.png

I simplified the code to assume you origins of the sprite of the player is the feet of the character, which it should be for platformers
 

TheouAegis

Member
Oh yeah, it's just a tree diagram now, isn't it? Drag an action to a conditional and it assumes that action and anything attached to that action is part of the conditional now, right?

Start Block and End Block were how DnD knew when one set of actions should be the result of a conditional and when another set shouldn't.

Test Variable species equals cat
Start Block
Set Sprite to spr_feline frame 0 with speed 1
Set Alarm 0 to 60 without Start and End Block, this line would run all the time
End Block


When you start using GML inside scripts or code actions, the Start Block and End Block actions are the same as { and }.

if species==cat
{
sprite_index = spr_feline;
image_index = 0;
image_speed = 1;
alarm[0] = 60;
}
 
I

icuurd12b42

Guest
Obviously it's still a thing, because it's in your screenshot! :p
I typed before I dove in gm to make the example...

Is there any way to paste gml d&d on the forum. I know someone made something for gm14 a while back

Also, your post above, it's really hard to grasp/associate gml with d&d now since you really cant merge the methods now


Oh I guess you can with right click...

Oh, and right clicking back to gml makes a code box...

Code:
if(vspeed > 0)
{
    if(y-vspeed < other.bbox_top)
    {
        y = other.bbox_top;
   
        vspeed = 0;
    }
}
 
Last edited by a moderator:
T

trialuser

Guest
@Roman P. @TheouAegis @homeyworkey
Hahaha, is it as serious as that? Don't worry I'll stop that.
And anyway, I didn't love love LOVE in shaun's, all I want is to do fast-reply on what to google and give him an example 'on search'.
So I google for "gml one way platform", and I thought the most top result was the most useful, then I gave it a caption (that really sounds like 'recommending' to watch.)
I don't even watch that video, but I know one way platform is one of 'what to google', which (if I didn't miss) no one has talk about it before.
I thougt I should practice my fast-reply? ;)
 

poliver

Member
one way platforms have been a thing that's been plaguing beginners with no good tutorials out there. same questions popping up every week or so.

that's shauns tutorial is infamous. i guess it's the first thing people stumble upon but it suggests to remove the collsion mask of the platforms causing everything thats standing on the platform to fall through.
 

Niels

Member
I have a pretty solid one-way platform system for my project.

What is your current collision code?
 
H

homeyworkey

Guest
Yeah mask fiddling is horrible and that particular tut is horrible.



Did you set the object to be a solid, is that still a (unfortunate) thing in gms2?

I dont think startblock endblock is a gms2 D&D thing.

And OMG doing GM in D&D is horrible. they still don't have proper copy paste (outside of program) to help paste code.

View attachment 19359

I simplified the code to assume you origins of the sprite of the player is the feet of the character, which it should be for platformers
So, I tried what you did and it comes with the same problem... the character can't move up, left or right.
 

Niels

Member
What is your collision code atm?
Myself I made a variable in the obj_solid called one_way (which set to false or true). When true, my player won't be blocked horizontally with it and is ONLY blocked if vspd is 0 or more and it currently isn't colliding with it.
 
H

homeyworkey

Guest
My code at the moment is provided in the image attached to this post. Also, I don't necessarily understand all of it either, I'm just copying what someone said.

This code doesn't work, it acts like a solid block but you can't move when you jump on it.
 

Niels

Member
Not sure if it helps (especially since you seem to be doing D&D(, but this is my collision code, which works perfect for 1-way platform:

Code:
_Solid = argument0   
//horizontal collision
    var _solidh = instance_place(x+hspd,y,_Solid);
        if _solidh != noone {
            if _solidh.one_way = false { //<=only collide horizontally when one_way = false
            while (!place_meeting(x+sign(hspd),y,_Solid)) {
        x += sign(hspd);
    }
    hspd = 0; 
            }
}
    
x += hspd;

//vertical collision
var _solidv = instance_place(x,y + vspd,_Solid);
        if _solidv != noone {
            if _solidv.one_way = false { //<=if _Solid's one_way variable = false then do the below)
                
            while (!place_meeting(x,y+sign(vspd),_Solid)) {
                y += sign(vspd);
                }
                
            vspd = 0; 
                }else if _solidv.one_way && _solidv.bbox_top > bbox_bottom { //<= if true then do this
        while (!place_meeting(x,y+sign(vspd),obj_solid_oneway)) {
            y += sign(vspd);
        }
        vspd = 0;
    }
}
                
y += vspd;
 

TheouAegis

Member
are you sure you put his code in the right spot? In his code, object0 is the player and object1, which is what the Collision is for, is the platform.

Platformers are quite difficult for beginners to make well. He want to make sure that the origin of all of your Sprites are at the very bottom of the Sprites. In a platformer, the majority of collisions actually occur below the feet, so it makes sense to have the origin of the Sprite below the feet as well. this also makes it very easy to maintain proper ratios between the bounding box and the origin - if you change Sprite and the distance between the origin of one Sprite and the bottom of its bounding box is different than the distance between the origin of the other Sprite and its bounding box, then you will alter the collision state when changing sprites.

Also as icuurd said, you should make sure you do not have the solid attribute marked on any of your platforms. Some people here like solid, most of us hate it.

Icuurd and to some extent myself offer code that set the y position of the player to the top of the bounding box of the platform. You could try setting y to other.bbox_top-1 and see if that works.
 
H

homeyworkey

Guest
are you sure you put his code in the right spot? In his code, object0 is the player and object1, which is what the Collision is for, is the platform.

Platformers are quite difficult for beginners to make well. He want to make sure that the origin of all of your Sprites are at the very bottom of the Sprites. In a platformer, the majority of collisions actually occur below the feet, so it makes sense to have the origin of the Sprite below the feet as well. this also makes it very easy to maintain proper ratios between the bounding box and the origin - if you change Sprite and the distance between the origin of one Sprite and the bottom of its bounding box is different than the distance between the origin of the other Sprite and its bounding box, then you will alter the collision state when changing sprites.

Also as icuurd said, you should make sure you do not have the solid attribute marked on any of your platforms. Some people here like solid, most of us hate it.

Icuurd and to some extent myself offer code that set the y position of the player to the top of the bounding box of the platform. You could try setting y to other.bbox_top-1 and see if that works.
This didn't work either, I changed it accordingly and got rid of it being solid but it still gets you stuck.
 
Top