/// <summary> /// Gets all tiles that interesect with a rotated rectangle /// </summary> /// <param name="rectangle">The rectangle to check for inteserctions with.</param> /// <returns>An array of adjacent interesetcing tiles.</returns> public CollisionTile[] GetAdjacentTilesFromIntersection(RotatedRectangle rectangle) { // list of tiles List<CollisionTile> adjTiles = new List<CollisionTile>(); // the 8 cases, also checking to make sure that the 8 cases exist! int up = this.GridY - 1; int down = this.GridY + 1; int left = this.GridX - 1; int right = this.GridX + 1; if (up >= 0) if (rectangle.Intersects(grid[GridX, up].loc)) adjTiles.Add(grid[GridX, up]); if (down < grid.GetLength(1)) if (rectangle.Intersects(grid[GridX, down].loc)) adjTiles.Add(grid[GridX, down]); if (up >= 0 && left >= 0) if (rectangle.Intersects(grid[left, up].loc)) adjTiles.Add(grid[left, up]); if (down < grid.GetLength(1) && left >= 0) if (rectangle.Intersects(grid[left, down].loc)) adjTiles.Add(grid[left, down]); if (up >= 0 && right < grid.GetLength(0)) if (rectangle.Intersects(grid[right, up].loc)) adjTiles.Add(grid[right, up]); if (down < grid.GetLength(1) && right < grid.GetLength(0)) if (rectangle.Intersects(grid[right, down].loc)) adjTiles.Add(grid[right, down]); if (left >= 0) if (rectangle.Intersects(grid[left, GridY].loc)) adjTiles.Add(grid[left, GridY]); if (right < grid.GetLength(0)) if (rectangle.Intersects(grid[right, GridY].loc)) adjTiles.Add(grid[right, GridY]); if (rectangle.Intersects(this.loc)) adjTiles.Add(this); return adjTiles.ToArray(); }
/* * To-do * - throw a rectangle in the direction entity is facing (faceDirection) * - check to see if this invis rectangle or the player intersects with anything * - use collision manager to get surrounding tiles from where this entity is. * - speedup: only check tiles that are in the same direction as the player (math here . 3.) * - once another ENTITY is found, call its action method (pass this entity as a param.) (NOT SURE ABOUT THIS...) * - closest to the player or first to find? */ // Douglas Gliner // spending too much time on making this versatile, this can only be 32 units away from player. public void Interact() { // ray cast RotatedRectangle rayCast = new RotatedRectangle(new FloatRectangle((location.Center.X + (((sprite.Texture.Width) * (float)Math.Cos(faceDirection - Math.PI / 2))) - (sprite.Texture.Width / 2)), (location.Center.Y + (((sprite.Texture.Height) * (float)Math.Sin(faceDirection - Math.PI / 2))) - (interactRange / 2)), sprite.Texture.Width, interactRange), faceDirection); //FloatRectangle rectangleToRotate = new FloatRectangle(location.X + 5 + (sprite.Texture.Width * (float)Math.Cos(faceDirection - Math.PI / 2)), location.Y + 5 + (sprite.Texture.Height * (float)Math.Sin(faceDirection - Math.PI / 2)), sprite.Texture.Width, interactRange); //FloatRectangle rectangleToRotate = new FloatRectangle(location.Center.X - sprite.Texture.Width / 2, location.Center.Y - interactRange / 2, sprite.Texture.Width, interactRange); //RotatedRectangle rayCast = new RotatedRectangle(rectangleToRotate, faceDirection); //Console.WriteLine("Radius: {0}", Vector2.Distance(location.Location, rayCast.UpperLeftCorner())); //Console.WriteLine("X: {0}, Y: {1} Theta: {2}", rayCast.X - location.X, rayCast.Y - location.Y, faceDirection); //Console.Write("ThisX: {0}, ThisY: {1}", location.X, locat) // tiles to do a check for entities CollisionTile[] intersectingTiles = CurrentCollisionTile.GetAdjacentTilesFromIntersection(rayCast); // foreach through each tile, foreach through each ent list and find ent closest to this ent. // starts with distance from edge midpoint closest to player to top left corner. // the closer items are to player, that item will be acted upon. //float shortestDistance = (float)Math.Sqrt((rayCast.Height * rayCast.Height) + ((rayCast.Width * rayCast.Width) / 4)); // start with longest distance possible which in this case is from center of player to a corner of raycast float shortestDistance = Vector2.Distance(this.location.Center, rayCast.UpperLeftCorner()); Entity entityToInteract = null; foreach (CollisionTile tile in intersectingTiles) { // only look at entities that interset with raycast bounds!! foreach (Entity ent in tile.EntitiesInTile.Where(ent => rayCast.Intersects(ent.location))) { if (ent == this) { continue; } // want to make sure ATLEAST more than the center is inside the check box!! float tmpDist = Vector2.Distance(ent.location.Center, this.location.Center); if (tmpDist < shortestDistance && ent.interactData != null) { entityToInteract = ent; shortestDistance = tmpDist; } } } // debug // if entity is null, return if (entityToInteract == null) { return; } //We need to fix this. entityToInteract.Action(this, ""); // do interact method here... (events or method?) Game1.Instance.renderManager.EmitParticle(new RectangleOutline(new RotatedRectangle(entityToInteract.location, 0), Color.Purple, 1)); Game1.Instance.renderManager.EmitParticle(new RectangleOutline(rayCast, Color.White, 1)); foreach (CollisionTile t in intersectingTiles) { Game1.Instance.renderManager.EmitParticle(new RectangleOutline(new RotatedRectangle(t.Rectangle, 0), Color.Red, 1)); } }
/// <summary> /// Will find the next obstacle in the beam's way /// </summary> /// <param name="obstacles">the array where to look for objects</param> /// <param name="start">the starting point of the beam</param> /// <param name="direction">the way in which we go on the direction</param> /// <param name="angle">the angle of the path to look for an object</param> /// <returns>the closest obstacle on the given path</returns> private Obstacle FindObject(Obstacle[] obstacles, Vector2 start, short direction, float angle) { //update 1300 with MaxWidth //the beam of light RotatedRectangle beam = new RotatedRectangle(new Rectangle((int)start.X, (int)start.Y, 1300, 2), angle); beam.Origin = new Vector2(beam.X, beam.Y); float dmin = 1300; float distance; Obstacle colidedObstacle = null; foreach (var obstacle in obstacles) { distance = Vector2.Distance(start, obstacle.Center); if (beam.Intersects(obstacle) && distance < dmin && distance > 0) { dmin = Vector2.Distance(start, obstacle.Center); colidedObstacle = obstacle; } } return colidedObstacle; }
/* * To-do * - throw a rectangle in the direction entity is facing (faceDirection) * - check to see if this invis rectangle or the player intersects with anything * - use collision manager to get surrounding tiles from where this entity is. * - speedup: only check tiles that are in the same direction as the player (math here . 3.) * - once another ENTITY is found, call its action method (pass this entity as a param.) (NOT SURE ABOUT THIS...) * - closest to the player or first to find? */ // Douglas Gliner // spending too much time on making this versatile, this can only be 32 units away from player. public void Interact() { // ray cast RotatedRectangle rayCast = new RotatedRectangle(new FloatRectangle((location.Center.X + (((sprite.Texture.Width) * (float)Math.Cos(faceDirection - Math.PI / 2))) - (sprite.Texture.Width / 2)), (location.Center.Y + (((sprite.Texture.Height) * (float)Math.Sin(faceDirection - Math.PI / 2))) - (interactRange / 2)), sprite.Texture.Width, interactRange), faceDirection); //FloatRectangle rectangleToRotate = new FloatRectangle(location.X + 5 + (sprite.Texture.Width * (float)Math.Cos(faceDirection - Math.PI / 2)), location.Y + 5 + (sprite.Texture.Height * (float)Math.Sin(faceDirection - Math.PI / 2)), sprite.Texture.Width, interactRange); //FloatRectangle rectangleToRotate = new FloatRectangle(location.Center.X - sprite.Texture.Width / 2, location.Center.Y - interactRange / 2, sprite.Texture.Width, interactRange); //RotatedRectangle rayCast = new RotatedRectangle(rectangleToRotate, faceDirection); //Console.WriteLine("Radius: {0}", Vector2.Distance(location.Location, rayCast.UpperLeftCorner())); //Console.WriteLine("X: {0}, Y: {1} Theta: {2}", rayCast.X - location.X, rayCast.Y - location.Y, faceDirection); //Console.Write("ThisX: {0}, ThisY: {1}", location.X, locat) // tiles to do a check for entities CollisionTile[] intersectingTiles = CurrentCollisionTile.GetAdjacentTilesFromIntersection(rayCast); // foreach through each tile, foreach through each ent list and find ent closest to this ent. // starts with distance from edge midpoint closest to player to top left corner. // the closer items are to player, that item will be acted upon. //float shortestDistance = (float)Math.Sqrt((rayCast.Height * rayCast.Height) + ((rayCast.Width * rayCast.Width) / 4)); // start with longest distance possible which in this case is from center of player to a corner of raycast float shortestDistance = Vector2.Distance(this.location.Center, rayCast.UpperLeftCorner()); Entity entityToInteract = null; foreach (CollisionTile tile in intersectingTiles) { // only look at entities that interset with raycast bounds!! foreach (Entity ent in tile.EntitiesInTile.Where(ent => rayCast.Intersects(ent.location))) { if (ent == this) continue; // want to make sure ATLEAST more than the center is inside the check box!! float tmpDist = Vector2.Distance(ent.location.Center, this.location.Center); if (tmpDist < shortestDistance && ent.interactData != null) { entityToInteract = ent; shortestDistance = tmpDist; } } } // debug // if entity is null, return if (entityToInteract == null) return; //We need to fix this. entityToInteract.Action(this, ""); // do interact method here... (events or method?) Game1.Instance.renderManager.EmitParticle(new RectangleOutline(new RotatedRectangle(entityToInteract.location, 0), Color.Purple, 1)); Game1.Instance.renderManager.EmitParticle(new RectangleOutline(rayCast, Color.White, 1)); foreach (CollisionTile t in intersectingTiles) Game1.Instance.renderManager.EmitParticle(new RectangleOutline(new RotatedRectangle(t.Rectangle, 0), Color.Red, 1)); }
/// <summary> /// Gets all tiles that interesect with a rotated rectangle /// </summary> /// <param name="rectangle">The rectangle to check for inteserctions with.</param> /// <returns>An array of adjacent interesetcing tiles.</returns> public CollisionTile[] GetAdjacentTilesFromIntersection(RotatedRectangle rectangle) { // list of tiles List <CollisionTile> adjTiles = new List <CollisionTile>(); // the 8 cases, also checking to make sure that the 8 cases exist! int up = this.GridY - 1; int down = this.GridY + 1; int left = this.GridX - 1; int right = this.GridX + 1; if (up >= 0) { if (rectangle.Intersects(grid[GridX, up].loc)) { adjTiles.Add(grid[GridX, up]); } } if (down < grid.GetLength(1)) { if (rectangle.Intersects(grid[GridX, down].loc)) { adjTiles.Add(grid[GridX, down]); } } if (up >= 0 && left >= 0) { if (rectangle.Intersects(grid[left, up].loc)) { adjTiles.Add(grid[left, up]); } } if (down < grid.GetLength(1) && left >= 0) { if (rectangle.Intersects(grid[left, down].loc)) { adjTiles.Add(grid[left, down]); } } if (up >= 0 && right < grid.GetLength(0)) { if (rectangle.Intersects(grid[right, up].loc)) { adjTiles.Add(grid[right, up]); } } if (down < grid.GetLength(1) && right < grid.GetLength(0)) { if (rectangle.Intersects(grid[right, down].loc)) { adjTiles.Add(grid[right, down]); } } if (left >= 0) { if (rectangle.Intersects(grid[left, GridY].loc)) { adjTiles.Add(grid[left, GridY]); } } if (right < grid.GetLength(0)) { if (rectangle.Intersects(grid[right, GridY].loc)) { adjTiles.Add(grid[right, GridY]); } } if (rectangle.Intersects(this.loc)) { adjTiles.Add(this); } return(adjTiles.ToArray()); }