3
\$\begingroup\$

I'm a little confused about the integration between collision and graphics. They both need to share the same position in the world. The most obvious choice is the center of the entity, which is good for bounding volumes and fixed sized sprites. However, for characters with variable height size sprites like this:

http://gamemedia.wcgame.ru/data/2011-07-17/game-sprite-sheet.jpg

This is no longer good. The character won't align to the ground if I'll draw it from the center. I can just make the sprites the same height, but it will be a waste of memory (the largest sprite is 4 times larger then the smallest one). Even then, this is not an option at all with skeletal sprites like this one:

http://user-generated-content.java-gaming.org/img-vault/212a171fc1ebb27ab77608fb9b2dd9bd9205361ce6300b21a7f8d06d025fbbd8.png

It seems that the graphics need to be drawn from the ground for characters, but not for other images such as scenery and obstacles. The only solution I could think of was having another position called draw-position, which is the entity center for images, and is the the bottom of the collision volume for characters. Then when I draw relative to that position, it should work properly.

I haven't found any references for something like that, so I'm kinda insecure about it. Does anyone knows of a better approach for this problem?

Thanks

\$\endgroup\$
0

3 Answers 3

1
\$\begingroup\$

My solution to this problem may be a bit overkill, but essentially I break things up like this:

Collision

  • Entities have a bounding box, which is essentially just a rectangle with an additional point called the "origin". The origin does not have to be the top-left corner or the rectangle. All edges of the box are calculated relative to the box's origin.
  • Collisions are checked against this bounding box's edges (which are relative to the origin).

Rendering

  • Every frame of an animation has a "source rectangle" that describes the region of the image that should be drawn.
  • Each frame also has a coordinate called an "origin". This is similar to the origin of a bounding box described above.

When an entity is rendered, its animation is drawn relative to the origin of its bounding box, offset by the current animation's current frame's origin.

Why?

Using a method like this allows:

  • each animation frame to be a different shape and size
  • allows the bounding box of the character to be independent from the animation
  • allows the bounding box to change in size without affecting the animation
  • allows you to make the "origin" of a character at its feet or its head or its center or wherever you want it to be, and you can position an animation appropriately
\$\endgroup\$
0
\$\begingroup\$

Your idea for a draw-position and drawing relative to that is the correct one.

When using collision and physics, you often want a proxy shape that is much simpler than your graphics shape. For example, a box or capsule could be the collision proxy. The graphics/drawing shape is attached (drawn relative to) the collision/proxy shape.

Equally important to drawing, a simple convex proxy shape doesn't get stuck on the terrain is collisions are easy to compute.

\$\endgroup\$
0
\$\begingroup\$

They don't need to integrate, you can do a bounding box check and give it the position vector and the texture object as parameters, and the bounding box method can use texture2.Width/Height to determine the dimensions.

It just really depends on how you go about implementing it. When using Bounding Box, you can implement a callback on your sprite object to react to a collision, or you can simply call a method that returns a boolean type on whether the 2 objects collided.

In most physics engines you have to create objects in the graphics engines and the physics engine separately. These objects should have the same position, and dimensions.

The problem you're probably facing is the anchor point in which graphics are drawn, and the anchor point in which collisions are check are different. Perhaps you're anchoring your graphics from the top left, and the AABB(bounding box) check anchors from the center. An easy fix for this is to find the center of your texture in reference to the screen, and submit that to the AABB method rather than your x/y which is anchored at the top left.

Example:

bool AABB(Texture2 tex, Vector2 xy){...}
...
Texture2 image;
Vector2 pos=new Vector2(50,50);
Vector2 origin=new Vector2(image.Width/2, image.Height/2); //center of the image in reference to the image
...
bool isColliding=AABB(image, Vector2.Add(pos,origin)); //pos+origin=center of the image in reference to the screen coordinate system.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .