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

Turn collisions on and off

I

Intergalakti

Guest
Hi,

I am just creating a platformer and I've got a small problem: The objects do all have a parent I called wall_main, which prevents the player from walking or falling through them, just an ordinary collision code. Everything works fine, but there are some objects (like e.g. doors) which should sometimes let the player pass and sometimes not. So I had the idea to give them a variable s so if s=true, they are solid, and if s=false, they are passable. I didn't want to use the built-in variable solid because that would cause other problems. I also gave them a parent door_main. But how should I make the player collide with them only if their s=true ? Thanks for your help!

PS: Here is my collision code (simplified), in case it helps:
Code:
if place_meeting(x+hspeed,y,beton)
{
        while(!place_meeting(x+sign(hspeed),y,beton))
        {
            x += sign(hspeed);
        }
    hspeed = 0;
    }
}
And something similar for the vertical collision checking
 

jo-thijs

Member
There are a couple of ways to do this.
One way is to deactivate every active instance of type door_main with s false (if colliding with any door_main),
perform the collision event and reactivate them all afterwards.

Alternatively, you could also leave them activated, but change their mask to an empty sprite and reset it afterwards.
In your case this might be best.

You could also iterate over every single instance of door_main and perform a check with "other" if s is true.

It might also be a good idea to create a new script for performing this collision check.

If you want more explenation, feel free to ask.
 
I

Intergalakti

Guest
Thank you!

I think I'll try that one with the empty mask. What do you mean with activating? And how would you do that thing with other, I thought that was only possible in a collision event?

I'll let you know if it works!
 

jo-thijs

Member
You can deactivate instances using instance_deactivate_object.
Deactivated instances don't execute events and aren't concidered in collision checking.

In GameMaker, you can also use "with".
Code:
with obj_enemy
{
    // code here
    x += 4;
}
The above code will execute whatever is in the block, between the curley brackets { }
for every active instance of type obj_enemy.
In this case, it will move every obj_enemy 4 pixels to the right.

If you use "other" inside a with block, it will refer the instance that called the with block.
Code:
with obj_wall
    if x < other.x
        instance_destroy();
The above destroys every obj_wall left from the executing instance (usable in a sidescroller that always goes to the right).

As an extra, you can think of a collision event in object obj1 with object obj2 as though they are executed using this code, just after speeds are applied after the step event:
Code:
with obj2
    if place_meeting(x, y, other) {
        if solid {
            other.x = other.xprevious;
            other.y = other.yprevious;
        }
        with other
            event_perform(ev_collision, obj2);
    }
Using other in the collision event would be interpreted exactly the same as using other in a with structure this way.
 
I

Intergalakti

Guest
Ok, so now I finished rewriting the code and it pretty much works that way. But I've got two problems:
- The doors should be clickable, so if you right-click them, they open. But I've they havent got a collision mask, you cant click them... But no big deal, because I can make a key like L open them
- There are objects which should be hit by bullets, but now by the player, except when they stand still. That's the major problem.
Deactivating the objects does not work because they still have to do something, so I'll try the other code.

A very big thank you for the effort you put in your explanation!
 
I

Intergalakti

Guest
I resolved it the following way:
When the object stands still, it is getting destroyed and a new object is created with the same properties, but wall_main as a parent. It's not very elegant, but it works well and doesnt need a lot of code.
 

jo-thijs

Member
No, that's not a good solution.
It is almost guaranteed to throw more and more problems in the future.

I'd suggest you first try using the "with" structure to solve the issue.
 

RangerX

Member
Let's say "blocking" is the name of your variable as to know if the collision should occur or not... Why not simply...

Code:
if place_meeting(x+hspeed,y,beton) && blocking==true)
{
        while(!place_meeting(x+sign(hspeed),y,beton))
        {
            x += sign(hspeed);
        }
    hspeed = 0;
    }
}
So basically you don't need to change any code, change any event, just keep your collision event. Its just that it will do something only when "blocking" is true.
 

RangerX

Member
Depends the complexity of his game yeah. I personally would manage that problem with the obj_door itself and if there's multiple doors or door-like objects in behavior, they could have a common parent just the like the general collision objects would.
 
Top