Is there a collision detection function?


(Julian Nitzsche) #1

I’m in the process of making a game where, like Super Mario (It’s of course my own creation, but I want to clarify what it’s about.), you have to overcome obstacles and the like, and I need to know if there’s a feature that gives me a logical value, for example, that I can use to see if the player is standing on a block or not. Of course, I want to save the work of having to process every single coordinate in the game individually. I would be glad to hear from you if you know if there is such a function.

Greetings Julian


(Scott) #2

The Arduboy2 library includes Point and Rect (rectangle) structures. You can use these to create and map points or rectangular areas. The library’s two collide() functions can test if a point is colliding with a rectangle or a rectangle is colliding with another rectangle.


(Julian Nitzsche) #3

Thanks for your help i will try to do this.


(Julian Nitzsche) #4

Can you give an example how to use it?


(Scott) #5

Let’s say the player is a bitmap that is 8 x 8 pixels. You could track the player’s location using a Rect object.

constexpr uint8_t PlayerWidth = 8, PlayerHeight = 8;

Rect player(0, 0, PlayerWidth, PlayerHeight);

This creates a Rect object named player at location 0, 0 with size 8 x 8. To move the player, you change the x and y members.

player.x = 5;
player.y = 13;

moves the player to location x = 5, y = 13.
You could draw it there:

arduboy.drawBitmap(player.x, player.y, playerSprite, PlayerWidth, PlayerHeight);

Let’s say there’s a 16 x 12 block, with the top left corner at location 45, 37. You define this as another Rect object.

constexpr uint8_t BlockWidth = 16, BlockHeight = 12;

Rect block1(45, 37, BlockWidth, BlockHeight);

If you wanted the block to actually just be a rectangle you could draw it using the drawRect() function

arduboy.drawRect(block1.x, block1.y, BlockWidth, BlockHeight);

Now, to test if the player is in contact with the block (at least one pixel of their rectangular areas is overlapping), you can use the collide() function.

if (arduboy.collide(player, block1)) {
 arduboy.print("Player is touching the block");
}

Note that with the above example, the check is for overlapping areas. If you want to check for “touching” you may have to adjust the area or what is drawn, for one of the objects, by one pixel on each side.

arduboy.drawRect(block1.x + 1, block1.y + 1, BlockWidth - 2, BlockHeight - 2);

(Julian Nitzsche) #6

very helpful, thanks!


(Pharap) #7

Two small nitpicks…


Firstly, I recommend avoiding this form of initilisation:

Rect player(0, 0, PlayerWidth, PlayerHeight);

Prefer either:

Rect player = Rect(0, 0, PlayerWidth, PlayerHeight);

Or:

// Despite appearances, this does call the constructor
Rect player { 0, 0, PlayerWidth, PlayerHeight };

Because the first form can lead to the most vexing parse problem.
This is actually one of the reasons why C++11 introduced the third form (called “uniform initialisation syntax”).


Secondly, not so much a problem as a small addition…
I think it’s worth mentioning that you don’t need an instance of Arduboy2 to use collide (because collide is static).

E.g.

// static functions are inherited
// so Arduboy2, Arduboy2Core or Arduboy2Base can all be used
// on the left of the scope resolution operator (`::`)
if (Arduboy2::collide(player, block1))
{
    // Do something without 'arduboy' object
}

This can be useful if you need collision checking but don’t want to have to make sure that an arduboy object is ‘visible’ to the code.


Thank you for using constexpr by the way.
I’m glad to see constexpr getting some traction, I hope to see more people using it.