Castlevania Dungeon Forums

Off Topic => Off Topic => Topic started by: TheouAegis on December 02, 2011, 11:20:05 PM

Title: True Tile Collision Checking in GameMaker! (another Eureka)
Post by: TheouAegis on December 02, 2011, 11:20:05 PM
Well here y'all go (well, those of you that use Game Maker). I recommend starting a project from scratch if you want to use this script, because incorporating it into a customary object-driven game is a hair-pulling pain in the ass. The script itself is deceptively simple, but it works. Here is a very simple GMK file (http://www.mediafire.com/?6ph0e464j9t1e4m) to demonstrate it. And here is the script (http://castlevaniadungeon.net/forums/index.php/topic,4359.msg90843.html#msg90843).


I posted a question about this on the GMC forums and all I got was one reply from someone blindly quoting the Game Maker User Manual. Torigara hasn't replied to my post yet, so I'm asking the question here, hoping maybe someone here has more experience than those in the Novice forum on GMC.

Which is less processor-intensive and therefore the faster method of background collision detection: object-based collisions or tile-based collisions?

Object-based collision is the most popular method, but that doesn't mean it's the best. This is when you place invisible objects, which have a sprite that isn't rendered, over every tile in the room and then use the built-in collision events (e.g., place_meeting(), collision_line, etc.) to check for collisions with those invisible blocks. As some of you know, I have made a script which drastically reduces the number of objects.

Tile-based collision requires no additional objects, but may require a custom movement engine (not a problem for some people). An object checks for "solid" tiles around it using tile-based functions such as tile_layer_find(), tile_get_left() and tile_get_top() to determine if the tile is a solid one (as defined in a database script, as an example). Yes, this is a feasible method of collision detection. My Castlevania engine even uses it to a minor extent currently.

So is anyone here proficient enough with Game Maker to provide knowledgeable feedback on this matter?
Title: Re: (GMC Repost) Object-based collision vs Tile-based Collision
Post by: uzo on December 08, 2011, 04:48:04 AM
Not really a Game Maker exclusive concept. Truth is, tile collision is MUCH faster and way more efficient. Well, if you do it right at least. That said, since you mentioned it would need a custom movement code to work in GM, if done wrong it can be slower and less efficient.

I'm not sure how GM handles 'sprite' collisions exactly, but under typical circumstances you'd check the bounding box against every other active sprite, for each active sprite. If one of them intersects, do a more refined polygonal based collision check (if GM even does that, I don't know, I don't use it, but this is what I do). Then if they intersect we have a collision to process.

It can be handy for simple non-grid level layouts. I stress simple, because using this you want to minimize how much of these objects you use. The problem here is that the more that you use, the more checks it is forced to make, and the slower it gets. Very bad. A fighter game like Smash Bros, simple small one 'room' stages, would use something like this, especially if it has no 'grid' design to their stages and many many slope styles and angles that are irregular. Castlevania though? Eh. I wouldn't recommend it. You wouldn't need any of the advantages that it offers anyway.

With a tile based system, you don't have to check EVERY tile in existence. You can localize your collision checks to tiles within the object's bounding box only. Not only that, you can (and seemingly have to) code exactly how the check is performed, and how to handle it. It gives you the ability to really refine things.

Bottom Line: It has the potential to be much more efficient, if done right.
Title: Re: (GMC Repost) Object-based collision vs Tile-based Collision
Post by: TheouAegis on December 08, 2011, 07:06:13 AM
My thoughts exactly. ... Well, not exactly. But yes, GM seems to do that, from what I can see. I don't know about checking EVERY sprite's bounding boxes, but I'm almost dead certain it checks against entire bounding boxes. Although it seems like I can lag out GM more if I use line-based collision instead of the typical collision functions most GM users use. But yeah, like you said, I think the ability to localize collision with a tile should be faster and maybe it's just my computer that makes line-based collision so friggin' slow.

I'll work out a script for it today at work instead of playing OoE, then.
Title: Re: (GMC Repost) Object-based collision vs Tile-based Collision
Post by: uzo on December 08, 2011, 09:57:48 AM
I don't know about checking EVERY sprite's bounding boxes

Well, think about it. You have X amount of sprites, and you need to check their collisions. How else will you know if they're colliding? they could be in completely different locations, but you'll never know unless you check if they're touching. The bounding box is the least CPU cost form of checking for objects that can be any position and any size within your game space. But if you never perform it on every sprite, every frame, you'll never know if they are touching. That's why it gets costly and lags eventually.
Title: Tile Collision Checking Script COMPLETE
Post by: TheouAegis on December 08, 2011, 10:54:15 PM
I'll update the first post to include this and change the title.

Here ya go, for all you GM users who want to start a game from scratch. ... Cuz that's what you'll need to do, probably. Converting your current projects to work with this script will be a royal pain in the ass. Believe me... I'm trying to do that right now. I'll probably put it off for a later build, cuz it's such a buttsore. The script itself is deceptively simple.


GMK link: http://www.mediafire.com/?6ph0e464j9t1e4m (http://www.mediafire.com/?6ph0e464j9t1e4m)

Code: [Select]
switch argument1
{

case vk_left:
    for (tile=bbox_top;tile<=bbox_bottom;tile+=2)
        if tile_exists(tile_layer_find(argument0,bbox_left-1,tile))
            if tile_get_top(tile_layer_find(argument0,bbox_left-1,tile))=0
            {
                return 1;
                break;
            }
    break;

case vk_right:
    for (tile=bbox_top;tile<=bbox_bottom;tile+=2)
        if tile_exists(tile_layer_find(argument0,bbox_right+1,tile))
            if tile_get_top(tile_layer_find(argument0,bbox_right+1,tile))=0
            {
                return 1;
                break;
            }
    break;
           
case vk_up:
    for (tile=bbox_left;tile<=bbox_right;tile+=2)
        if tile_exists(tile_layer_find(argument0,tile,bbox_top-1))
            if tile_get_top(tile_layer_find(argument0,tile,bbox_top-1))=0
            {
                return 1;
                break;
            }
    break;

case vk_down:
    for (tile=bbox_left;tile<=bbox_right;tile+=2)
        if tile_exists(tile_layer_find(argument0,tile,bbox_bottom+1))
            if tile_get_top(tile_layer_find(argument0,tile,bbox_bottom+1))=0
            {
                return 1;
                break;
            }
    break;
}
Title: Re: True Tile Collision Checking in GameMaker! (another Eureka)
Post by: Esco on December 10, 2011, 03:51:35 PM
Nice work Theo; you should really put this up on the GM forums, as well as possibly the fan section here. I truly find it amazing how sooooooooooooo many people on the GM forums say something is un-doable, then a few days or weeks later you see someone come up with a way to do it with no problem.

Just so you know, I looked thru it and actually considered using it in my own project, but sadly due to the way I do my "tiling" (each room is one background image for the most part; if there is a foreground it is a separate image. These are externally loaded when the room starts) it wouldn't work for me. But honestly by using your tile layout script, my room uses very few collision objects already. So it isn't an issue at all for me.  In fact, right now my game only uses about 150-170k ram on average, and only about 30% cpu strength on average (I use a dual core processor). Not bad at all compared to using an emulator. 8)

Title: Re: True Tile Collision Checking in GameMaker! (another Eureka)
Post by: Inccubus on December 10, 2011, 04:45:27 PM
Nice! I'm totally grabbing this.

Esco is right. There's too much of that defeatist attitude on those forums at times.
You'll find that the more you work to refine your code the more efficient & smaller it'll become while being able to do more.
Title: Re: True Tile Collision Checking in GameMaker! (another Eureka)
Post by: TheouAegis on December 10, 2011, 05:10:35 PM
It's on GMC. Nocturne or icuurd12b42 moved it into the Tutorials And Examples forum.

As I'm adding in trap doors to my engine right now, I'm torn between switching to the tile framework or continuing with objects. The way traps are handled, it makes things trickier, since the traps and spikes are tiles, but the trapdoor itself is an object which is only active when it spins. And crumbling blocks will pose a minor issue with the tile framework, although there should be no issue with an object framework. I can already visualize how I'd do both methods, though.