Jump to content

  • Log In with Google      Sign In   
  • Create Account


#ActualXanather

Posted 21 October 2012 - 02:52 AM

I have been seriously trying at this for just about a day now. Such as simple thing is creating big problems.

I am trying to implement 2D tile based collision. All have failed. Should I create a algorithm that calculates the velocity to apply to the position (the velocity calculated by the algorithm will insure that the non-static (moving) entity will not hit solid tiles) or create a algorithm that calculates the position of the entity after the velocity has been applied to it (resulting in directly changing the position to ensure that it will not collide with another tile). All in all this is a generic question, how can this be done properly? (A real example of what I want to do is terraria's character movement).

All replies are appriciated.
Thanks, Xanather.

Edit: One of the algorithms ive tried to implemented checks each velocity axis negativity/positivity and works along that. Edit 2: Entities have the same axis scale as the tiles (1, 1) would mean the player would be drawn at (16, 16) on the screen).

[source lang="csharp"] Vector2 result = position + velocity; Vector2 nposition = new Vector2(position.X + velocity.X, position.Y); Vector2 topleft = new Vector2(nposition.X - (width / 2), nposition.Y - (height / 2)); Vector2 topright = new Vector2(nposition.X + (width / 2), nposition.Y - (height / 2)); Vector2 bottomleft = new Vector2(nposition.X - (width / 2), nposition.Y + (height / 2)); Vector2 bottomright = new Vector2(nposition.X + (width / 2), nposition.Y + (height / 2)); if (velocity.X > 0) { for (int y = (int)topright.Y; y < (int)bottomright.Y + 1; y++) { if (engine.main.tiles[(int)topright.X, y].solid) { result.X = (int)topright.X - (width / 2); break; } } } else if (velocity.X < 0) { for (int y = (int)topleft.Y; y < (int)bottomleft.Y + 1; y++) { if (engine.main.tiles[(int)topleft.X, y].solid) { result.X = (int)topleft.X + 1 + (width / 2); break; } } } nposition = new Vector2(position.X, position.Y + velocity.Y); topleft = new Vector2(nposition.X - (width / 2), nposition.Y - (height / 2)); topright = new Vector2(nposition.X + (width / 2), nposition.Y - (height / 2)); bottomleft = new Vector2(nposition.X - (width / 2), nposition.Y + (height / 2)); bottomright = new Vector2(nposition.X + (width / 2), nposition.Y + (height / 2)); if (velocity.Y > 0) { for (int x = (int)bottomleft.X; x < bottomright.X + 1; x++) { if (engine.main.tiles[x, (int)bottomleft.Y].solid) { result.Y = (int)bottomleft.Y - (height / 2); } } } else if (velocity.Y < 0) { for (int x = (int)topleft.X; x < topright.X + 1; x++) { if (engine.main.tiles[x, (int)topleft.Y].solid) { result.Y = (int)topleft.Y + 1 + (height / 2); } } } return result;[/source]

#3Xanather

Posted 21 October 2012 - 02:38 AM

I have been seriously trying at this for just about a day now. Such as simple thing is creating big problems.

I am trying to implement 2D tile based collision. All have failed. Should I create a algorithm that calculates the velocity to apply to the position (the velocity calculated by the algorithm will insure that the non-static (moving) entity will not hit solid tiles) or create a algorithm that calculates the position of the entity after the velocity has been applied to it (resulting in directly changing the position to ensure that it will not collide with another tile). All in all this is a generic question, how can this be done properly? (A real example of what I want to do is terraria's character movement).

All replies are appriciated.
Thanks, Xanather.

Edit: One of the algorithms ive tried to implemented checks each velocity axis negativity/positivity and works along that. Edit 2: Entities are the same scale as the tiles (1, 1) would mean the player would be drawn at (16, 16) on the screen).

[source lang="csharp"] Vector2 result = position + velocity; Vector2 nposition = new Vector2(position.X + velocity.X, position.Y); Vector2 topleft = new Vector2(nposition.X - (width / 2), nposition.Y - (height / 2)); Vector2 topright = new Vector2(nposition.X + (width / 2), nposition.Y - (height / 2)); Vector2 bottomleft = new Vector2(nposition.X - (width / 2), nposition.Y + (height / 2)); Vector2 bottomright = new Vector2(nposition.X + (width / 2), nposition.Y + (height / 2)); if (velocity.X > 0) { for (int y = (int)topright.Y; y < (int)bottomright.Y + 1; y++) { if (engine.main.tiles[(int)topright.X, y].solid) { result.X = (int)topright.X - (width / 2); break; } } } else if (velocity.X < 0) { for (int y = (int)topleft.Y; y < (int)bottomleft.Y + 1; y++) { if (engine.main.tiles[(int)topleft.X, y].solid) { result.X = (int)topleft.X + 1 + (width / 2); break; } } } nposition = new Vector2(position.X, position.Y + velocity.Y); topleft = new Vector2(nposition.X - (width / 2), nposition.Y - (height / 2)); topright = new Vector2(nposition.X + (width / 2), nposition.Y - (height / 2)); bottomleft = new Vector2(nposition.X - (width / 2), nposition.Y + (height / 2)); bottomright = new Vector2(nposition.X + (width / 2), nposition.Y + (height / 2)); if (velocity.Y > 0) { for (int x = (int)bottomleft.X; x < bottomright.X + 1; x++) { if (engine.main.tiles[x, (int)bottomleft.Y].solid) { result.Y = (int)bottomleft.Y - (height / 2); } } } else if (velocity.Y < 0) { for (int x = (int)topleft.X; x < topright.X + 1; x++) { if (engine.main.tiles[x, (int)topleft.Y].solid) { result.Y = (int)topleft.Y + 1 + (height / 2); } } } return result;[/source]

#2Xanather

Posted 21 October 2012 - 02:36 AM

I have been seriously trying at this for just about a day now. Such as simple thing is creating big problems.

I am trying to implement 2D tile based collision. All have failed. Should I create a algorithm that calculates the velocity to apply to the position (the velocity calculated by the algorithm will insure that the non-static (moving) entity will not hit solid tiles) or create a algorithm that calculates the position of the entity after the velocity has been applied to it (resulting in directly changing the position to ensure that it will not collide with another tile). All in all this is a generic question, how can this be done properly? (A real example of what I want to do is terraria's character movement).

All replies are appriciated.
Thanks, Xanather.

Edit: One of the algorithms ive tried to implemented checks each velocity axis negativity/positivity and works along that.

[source lang="csharp"] Vector2 result = position + velocity; Vector2 nposition = new Vector2(position.X + velocity.X, position.Y); Vector2 topleft = new Vector2(nposition.X - (width / 2), nposition.Y - (height / 2)); Vector2 topright = new Vector2(nposition.X + (width / 2), nposition.Y - (height / 2)); Vector2 bottomleft = new Vector2(nposition.X - (width / 2), nposition.Y + (height / 2)); Vector2 bottomright = new Vector2(nposition.X + (width / 2), nposition.Y + (height / 2)); if (velocity.X > 0) { for (int y = (int)topright.Y; y < (int)bottomright.Y + 1; y++) { if (engine.main.tiles[(int)topright.X, y].solid) { result.X = (int)topright.X - (width / 2); break; } } } else if (velocity.X < 0) { for (int y = (int)topleft.Y; y < (int)bottomleft.Y + 1; y++) { if (engine.main.tiles[(int)topleft.X, y].solid) { result.X = (int)topleft.X + 1 + (width / 2); break; } } } nposition = new Vector2(position.X, position.Y + velocity.Y); topleft = new Vector2(nposition.X - (width / 2), nposition.Y - (height / 2)); topright = new Vector2(nposition.X + (width / 2), nposition.Y - (height / 2)); bottomleft = new Vector2(nposition.X - (width / 2), nposition.Y + (height / 2)); bottomright = new Vector2(nposition.X + (width / 2), nposition.Y + (height / 2)); if (velocity.Y > 0) { for (int x = (int)bottomleft.X; x < bottomright.X + 1; x++) { if (engine.main.tiles[x, (int)bottomleft.Y].solid) { result.Y = (int)bottomleft.Y - (height / 2); } } } else if (velocity.Y < 0) { for (int x = (int)topleft.X; x < topright.X + 1; x++) { if (engine.main.tiles[x, (int)topleft.Y].solid) { result.Y = (int)topleft.Y + 1 + (height / 2); } } } return result;[/source]

#1Xanather

Posted 21 October 2012 - 02:29 AM

I have been seriously trying at this for just about a day now. Such as simple thing is creating big problems.

I am trying to implement 2D tile based collision. All have failed. Should I create a algorithm that calculates the velocity to apply to the position (the velocity calculated by the algorithm will insure that the non-static (moving) entity will not hit solid tiles) or create a algorithm that calculates the position of the entity after the velocity has been applied to it (resulting in directly changing the position to ensure that it will not collide with another tile). All in all this is a generic question, how can this be done properly? (A real example of what I want to do is terraria's character movement).

All replies are appriciated.
Thanks, Xanather.

PARTNERS