Skill Level: Experienced user (6)
Hey there. I’ve decided to write an article about why you shouldn’t use the built-in Game Maker solid variable. It’s common among many developers’ early games, and the reason is generally because it handles collision events for you decently well. However, though many developers use it, they generally don’t know how it actually works and therefore may run into problems with it that they can’t solve.
Solid, in case you don’t already know, is controlled by the little checkbox in the object properties next to visible (you can, however, control it through code by using the variable solid) Go to one of your objects which is solid, double click it, find the solid checkbox, and uncheck it now. Why should you do this? Because of wizardry.
(no, not really…)
So you want to know how solid really works? Well, it’s pretty simple actually. When actions or code is placed in a collision event for a solid object, the two objects cannot overlap. So if you have non-solid objPlayer, and solid objBlock, and you add a collision event in objPlayer for objBlock, then whenever objPlayer bumps into objBlock it will be kicked back to the last hopefully non-colliding position. Same thing with the block; if it happened to be moving and the player was stationary, the block still could not enter the player.
Now you may be wondering why I said, “hopefully” above. Well, if your object is moving and touches a solid object, it will be moved out of it. However, if the object starts there or gets placed overlapping the solid object, suddenly, you can’t move at all. And it’s not really your fault (aside from using solid) because you didn’t tell GM to do this; you just told GM to make the wall solid.
Actually, that is the very reason why you should get rid of it. Because you aren’t in control. What if at one point you want the object to go through walls? No good with solid; as long as there’s a collision event, the solid object will be un-passable. What are you to do?
If you turn solid off, all you have to do to keep a functional game is to program the collisions yourself. Take the more difficult path and collect the treasure at the end. Now, you can include conditionals, etc. in your collisions, without the omnipresent don’t-touch-the-wall-ever-mwahaha stuff. For a top-down maze game, you might use this code in the step event:
if (OkToHitWalls)
{
if (place_meeting(x+hspeed,y,objBlock1)) hspeed=0;
if (place_meeting(x,y+vspeed,objBlock1)) vspeed=0;
}
Notice we didn’t even have to use a collision event, at all.
One last thing that I feel I should mention. You can’t use the function place_free() when you aren’t using solid objects. Note, if you use actions, place_free() is equivalent to this one:
If a position is collision free
This is a small price to pay, as I will demonstrate, but I want to get it out there now that place_free()/the above action only returns true when there’s a collision with a solid object. If you never use solid, place_free() never returns true.
Anyways, the way to get around this small roadblock is by using place_meeting(), as I did in the code above. Action form:
If there is an object at a position
Anyways, place_meeting(), or the action shown above, is an alternate form of place_free() in that it also requires you to tell it the object to check for collisions with. But that means, if you have 15 different wall objects you have to use this function 15 different times, right? Right?!
Um, no. When have I ever steered you down such an annoying path? In fact, with a little creativity, you only have to use it once. The way you do this, is to make a new object, and call it objBlockParent.
You guessed it, this object will in fact be a dummy object with no code of its own, only to be used as the parent object of all block objects. Okay, maybe you didn’t guess that…
Once you’ve done that, you just plug that new object into place_meeting() as the final (third) argument (or into the action next to “object:”) and it checks for all objects which have objBlockParent as their parent. That is, a single function/action checks every single block object. Yay. The code example above could replace objBlock1 with objBlockParent and work in just this way.
You’ve just written your very own custom, functional wall collision code, and now you don’t have to worry that solid will mess you up later. Now that you have turned off solid, you can even make things like one-way platforms. I can’t possibly know how far you are in your current project, so it may or may not be feasible to go through and revamp your current wall collision engine to stop using solid. But be sure to remember this for future games.
Disagree with something? Post a comment! (but don’t make it solid!)
( =/ )
If you have a technical question, such as “How do I do this” or “this is not working right” (relative to something with your Game Maker game after reading this tutorial), please head over to the Game Maker Community and ask there. I can’t answer any such questions in this blog and the members at the GMC will be more than capable to help you. Unfortunately any technical-question-related comments will be deleted without a response. Any other comments, however, will be welcomed wholeheartedly. Thanks!
Filed under: Game Maker | Tagged: Game Maker, tutorial, yoyogames
Wow, I’ve been using GM for 3.5 years, and I never thought to do something like this. No wonder I’ve always had troublesome collisions. This article makes me glad I subscribed to your feed in the first place. Thanks, and keep up the good work!
I’ve found that, the larger my games become, the smaller my chances of being able to use a general function like place_free(), and the larger my chances of creating some very general parent objects.
Ah… Stupid solid collisions!!!one
Thanks for the tip, man.
My friend on Orkut shared this link and I’m not dissapointed that I came to your blog.
I would love some advice on creating a platformer without using solid objects. I attempted to use what was discussed here in my game, but I couldn’t get it to work. Any idea where I should look?
Thanks
Hey facelifter,
Try looking at my “SoulHow to make a platform game” article. The example there ends up with a fully-functional platform game with perfect collisions without using solid. It’s usually my most popular tutorial, so you should be able to find a link quickly in the “Popular articles” section of the righthand column.
Hello Soulred12,
I am currently creating a platform game for a school assignment on water conservation, i have a few pipe objects. I have used your “SoulHow to make a platform game” for the blocks although i cannot get ObjPlayer to stand on them and jump off them etc.
If you could help me out it would be great ^^
CHeers Naturalistic
Edit:: sorry, just read through and it didnt make sense lol. Standing on the blocks are fine, its the pipes that i;m having trouble with.
Set the pipe’s parent to the block object that the player can stand on. Then the pipes will work exactly the same as the blocks.
Good luck.
Thank you so much, it was messing with my head for a while. props to you :)