Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ...
- private Vector2 ApplyTileCollision(Vector2 velocity)
- {
- Vector2 nextPosition = this.position + velocity;
- Int32 startx = (Int32)(((Single)position.X) / Tile.Size) - 1;
- Int32 endx = (Int32)(((Single)position.X + this.Width - 0.0001f) / Tile.Size) + 1; // because of float imprecision, we subtract 0.0001f.
- Int32 starty = (Int32)(((Single)position.Y) / Tile.Size) - 1;
- Int32 endy = (Int32)(((Single)position.Y + this.Height - 0.0001f) / Tile.Size) + 1; // because of float imprecision, we subtract 0.0001f.
- // these variables are filled with only solid tiles
- List<Point> horizontalWall = new List<Point>();
- List<Point> verticalWall = new List<Point>();
- Point ?corner = null;
- if (this.IsMovingRight)
- {
- // we use starty + 1 to remove the corner
- for (Int32 y = starty + 1; y < endy; y += 1)
- if (realm.TileAt(endx, y).IsSolid)
- verticalWall.Add(new Point(endx, y));
- }
- else if (this.IsMovingLeft)
- {
- // we use starty + 1 to remove the corner
- for (Int32 y = starty + 1; y < endy; y += 1)
- if (realm.TileAt(startx, y).IsSolid)
- verticalWall.Add(new Point(startx, y));
- }
- if (this.IsMovingDown)
- {
- // we use startx + 1 to remove the corner
- for (Int32 x = startx + 1; x < endx; x += 1)
- if (realm.TileAt(x, endy).IsSolid)
- horizontalWall.Add(new Point(x, endy));
- }
- else if (this.IsMovingUp)
- {
- // we use startx + 1 to remove the corner
- for (Int32 x = startx + 1; x < endx; x += 1)
- if (realm.TileAt(x, starty).IsSolid)
- horizontalWall.Add(new Point(x, starty));
- }
- if (this.IsMovingLeft && this.IsMovingUp)
- {
- if (realm.TileAt(startx, starty).IsSolid)
- corner = new Point(startx, starty);
- }
- else if (this.IsMovingRight && this.IsMovingUp)
- {
- if (realm.TileAt(endx, starty).IsSolid)
- corner = new Point(endx, starty);
- }
- else if (this.IsMovingLeft && this.IsMovingDown)
- {
- if (realm.TileAt(startx, endy).IsSolid)
- corner = new Point(startx, endy);
- }
- else if (this.IsMovingRight && this.IsMovingDown)
- {
- if (realm.TileAt(endx, endy).IsSolid)
- corner = new Point(endx, endy);
- }
- this.IsPushingLeft = false;
- this.IsPushingRight = false;
- foreach (Point point in verticalWall)
- {
- // if our next position would collide with the tile, we fix velocity.
- if (nextPosition.X + this.Width > point.X * Tile.Size &&
- nextPosition.X < point.X * Tile.Size + Tile.Size)
- {
- if (this.IsMovingRight)
- {
- this.IsPushingRight = true;
- velocity.X = point.X * Tile.Size - (position.X + this.Width);
- }
- else if (this.IsMovingLeft)
- {
- this.IsPushingLeft = true;
- velocity.X = (point.X * Tile.Size + Tile.Size) - position.X;
- }
- }
- }
- this.IsOnGround = false;
- this.IsPushingUp = false;
- Single oldFriction = this.friction;
- this.friction = Single.NegativeInfinity;
- foreach (Point point in horizontalWall)
- {
- // if our next position would collide with the tile, we fix velocity.
- if (nextPosition.Y + this.Height > point.Y * Tile.Size &&
- nextPosition.Y < point.Y * Tile.Size + Tile.Size)
- {
- this.friction = Math.Max(this.friction, realm.TileAt(point.X, point.Y).Friction);
- if (this.IsMovingDown)
- {
- this.IsOnGround = true;
- velocity.Y = point.Y * Tile.Size - (position.Y + this.Height);
- }
- else if (this.IsMovingUp)
- {
- this.IsPushingUp = true;
- velocity.Y = (point.Y * Tile.Size + Tile.Size) - position.Y;
- }
- }
- }
- // in case we only have a corner to consider, we rule that we land on top of it, or hit the bottom of it.
- if (corner.HasValue && verticalWall.Count == 0 && horizontalWall.Count == 0)
- {
- // if our next position would collide with the tile, we fix velocity.
- if (nextPosition.Y + this.Height > corner.Value.Y * Tile.Size &&
- nextPosition.Y < corner.Value.Y * Tile.Size + Tile.Size &&
- nextPosition.X + this.Width > corner.Value.X * Tile.Size &&
- nextPosition.X < corner.Value.X * Tile.Size + Tile.Size)
- {
- this.friction = Math.Max(this.friction, realm.TileAt(corner.Value.X, corner.Value.Y).Friction);
- if (this.IsMovingDown)
- {
- this.IsOnGround = true;
- velocity.Y = corner.Value.Y * Tile.Size - (position.Y + this.Height);
- }
- else if (this.IsMovingUp)
- {
- this.IsPushingUp = true;
- velocity.Y = (corner.Value.Y * Tile.Size + Tile.Size) - position.Y;
- }
- }
- }
- if (this.friction == Single.NegativeInfinity)
- this.friction = oldFriction;
- return velocity;
- }
- ...
Advertisement
Add Comment
Please, Sign In to add comment