1
\$\begingroup\$

I have some serious trouble with pixel-collision in my game. I am using the Matrix Scale parameter in Spritebatch.Begin method, to scale the content for each device's resolution correctly.

SpriteBatch.Begin(
  SpriteSortMode.Deferred, 
  null, 
  null, 
  null, 
  null, 
  null, 
  Managers.ResolutionManager.ScaleMatrix );

I am using Per Pixel Collision detection, because I have transparent textures, and I want to make the exact collision between moving textures. On the resolution, that the game was initially, made for: 800 x 480 the per/pixel collision is working perfectly, but when I am testing on a real device, with resolution 1080 x 1920 (lumia 930) or on any bigger resolutions than the initial one, the per pixel collision doesn't work properly. I, as a player, can pass through moving textures without colliding, at the good point.

I have made the adjustments for moving texture's rectangles, if the game is playing on bigger resolutions, but still, any difference.

Here is my Per pixel collision function:

public bool CheckCollision(
  Rectangle rect1, 
  Rectangle rect2, 
  Color[] textureData1, 
  Color[] textureData2)
{
  if (rect1.Intersects(rect2))
  {
    int top     = Math.Max(rect1.Top, rect2.Top);
    int bottom  = Math.Min(rect1.Bottom, rect2.Bottom);
    int left    = Math.Max(rect1.Left, rect2.Left);
    int right   = Math.Min(rect1.Right, rect2.Right);

    for (int y = top; y < bottom; y++)
    {
      for (int x = left; x < right; x++)
      {
        Color color1 = textureData1[(x - rect1.Left) + (y - rect1.Top) * rect1.Width];
        Color color2 = textureData2[(x - rect2.Left) + (y - rect2.Top) * rect2.Width];

        if (color1.A != 0 && color2.A != 0)
        {
          return true;
        }
      }
    }
  }
  return false;
}

Here are the rectangles, this player's rectangle

TextureData = new Color[(int)(
  Texture.Width * 
  Managers.ResolutionManager.MatrixX * 
  Texture.Height * 
  Managers.ResolutionManager.MatrixY)];

Texture.GetData<Color>(
  0, 
  new Rectangle(0, 0, frameWidth, frameHeight), 
  TextureData, 
  0, 
  TextureData.Length);

Bound = new Rectangle(
  (int)((Position.X - frameWidth / 2) * Managers.ResolutionManager.MatrixX), 
  (int)((Position.Y - frameHeight / 2) * Managers.ResolutionManager.MatrixY), 
  (int)(frameWidth * scale * Managers.ResolutionManager.MatrixX), 
  (int)(frameHeight * scale * Managers.ResolutionManager.MatrixY));

And this is obstacle's:

TextureData = new Color[(int)(
  Texture.Width * 
  Managers.ResolutionManager.MatrixX * 
  Texture.Height * 
  Managers.ResolutionManager.MatrixY)];

Texture.GetData<Color>(TextureData, 0, TextureData.Length);

Bounds = new Rectangle(
  (int)(Position.X * Managers.ResolutionManager.MatrixX),
  (int)(Position.Y * Managers.ResolutionManager.MatrixY),
  (int)(Texture.Width * Managers.ResolutionManager.MatrixX),
  (int)(Texture.Height * Managers.ResolutionManager.MatrixY));

Basically, it is almost the same code.

In my opinion it has to be something in CheckCollision function, because I checked the collision only with rectangles and it worked.

I'm out of ideas; any solution?

\$\endgroup\$
1
\$\begingroup\$

The basic idea for resolution scaling, is that it only happens on the draw phase. Your internal logic should use the fixed resolution your game is designed for. So remove the resolution logic from your game logic- that should do the trick.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Lol, it is working perfectly! Such a simple fix, lol ... Thank you so much! \$\endgroup\$ – Edvin Sep 25 '15 at 11:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.