Guest User

Untitled

a guest
Sep 7th, 2011
18
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.65 KB | None | 0 0
  1. ...
  2.     private Vector2 ApplyTileCollision(Vector2 velocity)
  3.     {
  4.         Vector2 nextPosition = this.position + velocity;
  5.  
  6.         Int32 startx = (Int32)(((Single)position.X) / Tile.Size) - 1;
  7.         Int32 endx = (Int32)(((Single)position.X + this.Width - 0.0001f) / Tile.Size) + 1; // because of float imprecision, we subtract 0.0001f.
  8.         Int32 starty = (Int32)(((Single)position.Y) / Tile.Size) - 1;
  9.         Int32 endy = (Int32)(((Single)position.Y + this.Height - 0.0001f) / Tile.Size) + 1; // because of float imprecision, we subtract 0.0001f.
  10.  
  11.         // these variables are filled with only solid tiles
  12.         List<Point> horizontalWall = new List<Point>();
  13.         List<Point> verticalWall = new List<Point>();
  14.         Point ?corner = null;
  15.  
  16.         if (this.IsMovingRight)
  17.         {
  18.             // we use starty + 1 to remove the corner
  19.             for (Int32 y = starty + 1; y < endy; y += 1)
  20.                 if (realm.TileAt(endx, y).IsSolid)
  21.                     verticalWall.Add(new Point(endx, y));
  22.         }
  23.         else if (this.IsMovingLeft)
  24.         {
  25.             // we use starty + 1 to remove the corner
  26.             for (Int32 y = starty + 1; y < endy; y += 1)
  27.                 if (realm.TileAt(startx, y).IsSolid)
  28.                     verticalWall.Add(new Point(startx, y));
  29.         }
  30.  
  31.         if (this.IsMovingDown)
  32.         {
  33.             // we use startx + 1 to remove the corner
  34.             for (Int32 x = startx + 1; x < endx; x += 1)
  35.                 if (realm.TileAt(x, endy).IsSolid)
  36.                     horizontalWall.Add(new Point(x, endy));
  37.         }
  38.         else if (this.IsMovingUp)
  39.         {
  40.             // we use startx + 1 to remove the corner
  41.             for (Int32 x = startx + 1; x < endx; x += 1)
  42.                 if (realm.TileAt(x, starty).IsSolid)
  43.                     horizontalWall.Add(new Point(x, starty));
  44.         }
  45.  
  46.         if (this.IsMovingLeft && this.IsMovingUp)
  47.         {
  48.             if (realm.TileAt(startx, starty).IsSolid)
  49.                 corner = new Point(startx, starty);
  50.         }
  51.         else if (this.IsMovingRight && this.IsMovingUp)
  52.         {
  53.             if (realm.TileAt(endx, starty).IsSolid)
  54.                 corner = new Point(endx, starty);
  55.         }
  56.         else if (this.IsMovingLeft && this.IsMovingDown)
  57.         {
  58.             if (realm.TileAt(startx, endy).IsSolid)
  59.                 corner = new Point(startx, endy);
  60.         }
  61.         else if (this.IsMovingRight && this.IsMovingDown)
  62.         {
  63.             if (realm.TileAt(endx, endy).IsSolid)
  64.                 corner = new Point(endx, endy);
  65.         }
  66.  
  67.         this.IsPushingLeft = false;
  68.         this.IsPushingRight = false;
  69.         foreach (Point point in verticalWall)
  70.         {
  71.             // if our next position would collide with the tile, we fix velocity.
  72.             if (nextPosition.X + this.Width > point.X * Tile.Size &&
  73.                 nextPosition.X < point.X * Tile.Size + Tile.Size)
  74.             {
  75.                 if (this.IsMovingRight)
  76.                 {
  77.                     this.IsPushingRight = true;
  78.                     velocity.X = point.X * Tile.Size - (position.X + this.Width);
  79.                 }
  80.                 else if (this.IsMovingLeft)
  81.                 {
  82.                     this.IsPushingLeft = true;
  83.                     velocity.X = (point.X * Tile.Size + Tile.Size) - position.X;
  84.                 }
  85.             }
  86.         }
  87.  
  88.         this.IsOnGround = false;
  89.         this.IsPushingUp = false;
  90.         Single oldFriction = this.friction;
  91.         this.friction = Single.NegativeInfinity;
  92.         foreach (Point point in horizontalWall)
  93.         {
  94.             // if our next position would collide with the tile, we fix velocity.
  95.             if (nextPosition.Y + this.Height > point.Y * Tile.Size &&
  96.                 nextPosition.Y < point.Y * Tile.Size + Tile.Size)
  97.             {
  98.                 this.friction = Math.Max(this.friction, realm.TileAt(point.X, point.Y).Friction);
  99.                 if (this.IsMovingDown)
  100.                 {
  101.                     this.IsOnGround = true;
  102.                     velocity.Y = point.Y * Tile.Size - (position.Y + this.Height);
  103.                 }
  104.                 else if (this.IsMovingUp)
  105.                 {
  106.                     this.IsPushingUp = true;
  107.                     velocity.Y = (point.Y * Tile.Size + Tile.Size) - position.Y;
  108.                 }
  109.             }
  110.         }
  111.  
  112.         // in case we only have a corner to consider, we rule that we land on top of it, or hit the bottom of it.
  113.         if (corner.HasValue && verticalWall.Count == 0 && horizontalWall.Count == 0)
  114.         {
  115.             // if our next position would collide with the tile, we fix velocity.
  116.             if (nextPosition.Y + this.Height > corner.Value.Y * Tile.Size &&
  117.                 nextPosition.Y < corner.Value.Y * Tile.Size + Tile.Size &&
  118.                 nextPosition.X + this.Width > corner.Value.X * Tile.Size &&
  119.                 nextPosition.X < corner.Value.X * Tile.Size + Tile.Size)
  120.             {
  121.                 this.friction = Math.Max(this.friction, realm.TileAt(corner.Value.X, corner.Value.Y).Friction);
  122.                 if (this.IsMovingDown)
  123.                 {
  124.                     this.IsOnGround = true;
  125.                     velocity.Y = corner.Value.Y * Tile.Size - (position.Y + this.Height);
  126.                 }
  127.                 else if (this.IsMovingUp)
  128.                 {
  129.                     this.IsPushingUp = true;
  130.                     velocity.Y = (corner.Value.Y * Tile.Size + Tile.Size) - position.Y;
  131.                 }
  132.             }
  133.         }
  134.  
  135.         if (this.friction == Single.NegativeInfinity)
  136.             this.friction = oldFriction;
  137.  
  138.         return velocity;
  139.     }
  140. ...
Advertisement
Add Comment
Please, Sign In to add comment