Jump to content
  • Advertisement
Sign in to follow this  

Efficient pixelperfect collision with collision mask

This topic is 2667 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Heyho everybody!

I'm currently trying to make the collision working for a sidescrolling ( platformer ) game. It uses a collision mask ( like this one: http://dl.dropbox.co...lisionmask1.png BIG IMAGE!!! ).
My current code for this is this one:

override public void OnUpdate(GameTime gameTime)
//Input check
if (state != State.Jumping)
state = Player.State.Standing;
if (Keyboard.GetState().IsKeyDown(Keys.A))
Velocity = new Vector2(WalkSpeed*-1, Velocity.Y);
direction = Player.Direction.Left;
state = Player.State.Walking;
else if (Keyboard.GetState().IsKeyDown(Keys.D))
Velocity = new Vector2(WalkSpeed, Velocity.Y);
direction = Player.Direction.Right;
state = Player.State.Walking;
Velocity = new Vector2(0, Velocity.Y);

if (Keyboard.GetState().IsKeyDown(Keys.Space))
state = Player.State.Jumping;
Velocity = new Vector2(Velocity.X, JumpPower*-1);

//Position update
lastPosition = Position;
Velocity += Acceleration * (float)gameTime.ElapsedGameTime.TotalSeconds;
Position += Velocity;

switch (state)
case State.Walking: SetAnimation("Walk"); break;
case State.Jumping: SetAnimation("Jump"); break;
case State.Standing:
default:SetAnimation("Stand"); break;

//Collision check
int check = Level.GetCollisionMaskIndex(this);

//Check if player is already standing ( should mean that he collided the frame before )
if (state != State.Standing)
if (CheckCollision(check) != new Vector2(1.337f, 1.337f))
state = State.Standing;
Position = new Vector2(Position.X, Position.Y - (Size.Y / 2) - Vector2.Subtract(GetCenter(), CheckCollision(check)).Y + 5);
Velocity = new Vector2(Velocity.X, 0);
Position = new Vector2(Position.X, lastPosition.Y);


private void MoveToContact(int Index)
Vector2 beforeCollision = Position;
int direction = 0;

if (CheckCollision(Index) != new Vector2(1.337f, 1.337f))
direction = -1;
direction = 1;

while (CheckCollision(Index) != new Vector2(1.337f, 1.337f))
beforeCollision = Position;
Position += new Vector2(0, direction);

Position = beforeCollision;

private Vector2 CheckCollision(int Index)
Rectangle rectangleA, rectangleB;
rectangleA = new Rectangle((int)Position.X, (int)Position.Y, (int)Size.X, (int)Size.Y);
rectangleB = new Rectangle((int)Level.CollisionMasks[Index].Position.X, (int)Level.CollisionMasks[Index].Position.Y, Level.CollisionMasks[Index].Texture.Width, Level.CollisionMasks[Index].Texture.Height);
Color[] dataA, dataB;
dataA = colorData;
dataB = Level.CollisionMasks[Index].colorInfo;

// Find the bounds of the rectangle intersection
int top = Math.Max(rectangleA.Top, rectangleB.Top);
int bottom = Math.Min(rectangleA.Bottom, rectangleB.Bottom);
int left = Math.Max(rectangleA.Left, rectangleB.Left);
int right = Math.Min(rectangleA.Right, rectangleB.Right);

// Check every point within the intersection bounds
for (int y = top; y < bottom; y++)
for (int x = left; x < right; x++)
// Get the color of both pixels at this point
Color colorA = dataA[(x - rectangleA.Left) +
(y - rectangleA.Top) * rectangleA.Width];
Color colorB = dataB[(x - rectangleB.Left) +
(y - rectangleB.Top) * rectangleB.Width];

// If both pixels are not completely transparent,
if (colorA.A != 0 && colorB.A != 0)
// then an intersection has been found
return new Vector2(x, y);

// No intersection found
return new Vector2(1.337f, 1.337f);

This code has some bugs and behaviors that I actually don't want.
First of all its not very efficient. Its reducing the FPS when passing bigger slopes and when I'm changing to another window and go back the character just falls through the ground sometimes.
Also its possible to walk over any slope, I don't want it to move against a wall and appear on the top of the wall. My next point is the fact that it is currently only checking for vertical collision. I want it to check for all collision, so jumping against a platform over you makes you stopping and falling back.
I was google'ing and searching for the last days and didn't found any nice resource or examples for this. Are there any common ways to solve this?
( This is meant to be pixelperfect and big collision mask based, not rectangle and tiled collision masks )

I hope you can give me some hints or links.

Thank you!

Share this post

Link to post
Share on other sites
Does nobody have an idea or a hint for me? :P
I already changed the collision to test pixel ( mask ) to player ( rectangle ), but this didn't change the basic behaviour.

Share this post

Link to post
Share on other sites

i bet you re a novice game programmer,
so i hope my post helps u =)

first of all,
the idea of checking collision with pixels (with image) is not what a good game programmer should attempt to,
the reason is because the flipping of buffer (displaying image) would sometimes cause problems when u minimize ur windows or simply jump out of ur window,
the problems of your character falling down when u minimize ur window is probably becauase of this.

because the windows need to be repainted when you minimzie and resume your windows,
the moment you resume your window,
the graphic is not painted,
and hence no pixels are there,
that's the reason why your character is falling down.

so the best attempt is to,
construct a 2D array for your pixels and collision detection,
which is not for display purpose but for calculation purpose.

remember, image is for display,
the actual calculation should be done seperately.


Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!