• Hello [name]! Thanks for joining the GMC. Before making any posts in the Tech Support forum, can we suggest you read the forum rules? These are simple guidelines that we ask you to follow so that you can get the best help possible for your issue.

Discussion Efficiency of rectangle in rectangle

I

inkBot

Guest
I've been contemplating how to approach detecting connecting attacks in my game, and the usual method I see in tutorials on the matter is to use a second player object that acts as a hitbox. While skimming through the GML reference, I noticed rectangle_in_rectangle. From a cursory reading it seems perfect to use to replicate the hitbox/hurtbox mechanics from fighting games.

I can see many upsides to use rectangle_in_rectangle but I've been wondering, would using it be more or less efficient than the previously mentioned additional object method?
 

Perseus

Not Medusa
Forum Staff
Moderator
The "hitbox object" approach is primarily for simplifying things, not for optimization. Creating instances usually does the polar opposite of that.

Whether using rectangle_in_rectangle in its place would be more efficient or not depends on how you're doing things currently. If you're using precise collisions, then you're certainly causing a performance hit. Here's a a tech blog article explaining why and also providing a nice way to handle rectangle-to-rectangle collisions.

From what I can tell, rectangle_in_rectangle should technically be faster than built-in collision checking due to how simple the internal calculations for it are. Try using the profiler to see how well it works on a massive scale. But you shouldn't really go for it at the cost of overcomplicating things, which in turn will outweigh the benefits.
 

kburkhart84

Firehammer Games
I'm understanding that using code for directly checking(rectangle-in-rectangle for example) will be faster...but, will it be better for your use case? One advantage of creating a sort of second invisible instance for this purpose is so you can more easily visualize the actual collision boxes. Most of the time, precise collision checking is slow, but if it works better for your game, and is fast enough, who cares? If you are making a fighting game with few characters going at a time, it shouldn't bog the system down at all. And it would let you draw sprites that correspond to animations of your character. Say you are doing a punching attack, and you only want the fist to actually do damage, you draw a second equally sized sprite, and just alpha out everything that isn't the fist. You then have a second instance "overlaying" your player that is what actually tracks the collisions. Typically this would be invisible, but if you wanted to, you could implement a system where it draws it if you set a "debug" variable or something.

One thing to consider, there is a such thing as premature optimization. In general, if you are using Gamemaker, you are already trading developement ease and speed for final product performance. The engine won't be able to catch up with a natively coded specialized engine, but of course it would take much longer to develop a game in such a system, which is where Gamemaker wins for many people. This applies not only to the game engine, but to other aspects. Is it easier to simply draw over/alpha out the fists for your fighters, or easier to make out coordinates frame by frame for rectangles in order to code it so it could be faster. Honestly, if the easy way to do it is fast enough, leave it alone. Only if things get bogged down, and something specific is the cause, do you then go and change it to a harder to work with but faster version.
 
I

inkBot

Guest
The main thing that got me interested in using rectangle_in_rectangle is the flexibility it gives. For example: for any given attack I can check if the hitbox rectangle overlaps or is inside the hurtbox rectangle. If instead I would want to do a grab, I can check specifically if the hitbox rectangle is completely inside the hurtbox rectangle and only then execute the grab.

This is how I judged each method.

Additional object method: This is how I would've done it in other software/engines I've worked with, so it's a familiar approach. However, for each character on screen, there will now be an equivalent-sized texture taking up space in VRAM (unless setting it to be invisible clears it from VRAM, which sounds reasonable to assume, but I'm honestly unclear on whether or not it does). That may be negligible in the end, but is probably worth keeping in mind.

Rectangle in rectangle method: The most obvious benefit here is that there's no need for additional objects. On the other hand, every time an attack is made, the rectangles are changed on a frame by frame basis. This is the part of it that I thought may be slow or inefficient when there are many things happening at once. But if it's not noticeable for the player, then it doesn't really matter if it is slower.

My biggest concern about optimization here was if there was any obvious drawbacks to rectangle_in_rectangle that I may be ignorant to, being still new to working with GML. From your responses so far, it seems there really isn't.

Thanks for the responses. Obviously if anyone else has input to add, I'd be glad to read it.
 
Last edited by a moderator:

Mike

nobody important
GMC Elder
The built in collisions now use an R-Tree, so will not test things that aren't close to each other, but doing a bounding box test yourself won't give you this speed up. The built in collision tests using bounding boxes should be the fastest way to do collisions - although this may not always be the best for your game, depending on your needs.
 

Ribhu

Member
upload_2018-12-14_20-17-49.png
upload_2018-12-14_20-22-40.png
this is my player with two movement tiles and the current code im using that works , it allows the dark green box (collision box of my player) to move within a the movement objects/tiles(dull green blocks). Was hoping someone could help me with the following questions :
1) seem like i can achieve this by rectangle_in_rectangle [so as to limit the movement in such a way that only full collisions are allowed and not partial collision. i dont quite know how to go about it
2) any other suggestions would be much appreciated
 

Attachments

I'm using GM 8 and i have not the rectangle_in_rectangle command, so i need to create a script to define it. How do you reccommend me do it?
 

gnysek

Member
I'm using GM 8 and i have not the rectangle_in_rectangle command, so i need to create a script to define it. How do you reccommend me do it?
As GameMaker Studio was released in May 2012, GM 8 was discontinued, and it's support ended in 2015: https://www.yoyogames.com/blog/358/farewell-gamemaker-8-1 .

You should be able to easily write it by searching same function in another langages, for example : https://stackoverflow.com/a/2752369 - just convert it to GM (remove Math., and set variable names for left/right/top/bottom of each).
 

Xer0botXer0

Senpai
Doesn't GMS come with three modes of collision detection of a sprite.

You also just use distance_to_object or distance_to_point, and use a rectangular based bounding box.

Let me try to elaborate on this.

bullet step event 0:
custom movement and persona code

bullet step event 1:
awareness code
Code:
attack_dir = point_direction(x,y,obj_player.x,obj_player.y)

if attack_dir <= 45 && attack_dir >= 315
{
angle_of_attack = "right";
}
..repeat for all directions

bullet step event 2:
hitbox code

Code:
switch(angle_of_attack)
{
case left:

if distance_to_object(obj_player) < bbleft
then
{
obj_player.hp -= 5;
instance_destroy()
}
break;

case right:
if distance_to_object(obj_player) < bbright
then
{
obj_player.hp -= 5;
instance_destroy()
}
break;

case_up:
if distance_to_object(obj_player) < bbup
then
{
obj_player.hp -= 5;
instance_destroy()
}
break;

case_down:
if distance_to_object(obj_player) < bbdown
then
{
obj_player.hp -= 5;
instance_destroy()
}
break;
 }
obj_player step event
Code:
bbleft = x - get_sprite_width(spr_player) - xleftoffset
bbright= x + get_sprite_width(spr_player) - xrightoffset
bbleft = y - get_sprite_width(spr_player) - xupoffset
bbleft = y + get_sprite_width(spr_player) - xdownoffset


So you've pretty much got a basic bounding box here, which should or may work in GM8.
Thoughts and error checks ?
 
Top