/// <summary> /// Get the intersection point of two lines /// </summary> /// <param name="line">Line to intersect</param> /// <returns>The intersection point</returns> public Vector2 intersection(LineSegment line) { if (isParallel(line)) return Vector2.Zero; float denom = A * line.B - B * line.A; float pX = (B * line.C - line.B * C) / denom; float pY = (A * line.C - line.A * C) / denom; return new Vector2(pX, pY); }
protected virtual bool testWallCollide() { Vector2 dir = physics.Velocity; if (dir.Length() > 0) { dir.Normalize(); dir *= RAY_LENGTH; } Vector2 endPoint = pos + dir; LineSegment ray = new LineSegment(pos, endPoint); // Check the grid for walls int startX = (int)Math.Round(Math.Min(Position.X, endPoint.X) / World.gridLength); int startY = (int)Math.Round(Math.Min(Position.Y, endPoint.Y) / World.gridLength); int endX = (int)Math.Round(Math.Max(Position.X, endPoint.X) / World.gridLength); int endY = (int)Math.Round(Math.Max(Position.Y, endPoint.Y) / World.gridLength); bool collides = false; try { for (int k = startY; k != endY + 1; ++k) { for (int l = startX; l != endX + 1; ++l) { for (int j = 0; j != Game1.world.grid[k, l].Count; ++j) { if (ray.IntersectsBox(Game1.world.grid[k, l][j].BoundingRectangle)) { collides = true; } } } } } catch (IndexOutOfRangeException e) { } if (collides) { wallAvoidance(); return true; } return false; }
private float? closestWallCollide(LineSegment line) { int startX = (int)Math.Round(Math.Min(line.start.X, line.end.X) / World.gridLength); int startY = (int)Math.Round(Math.Min(line.start.Y, line.end.Y) / World.gridLength); int endX = (int)Math.Round(Math.Max(line.start.X, line.end.X) / World.gridLength); int endY = (int)Math.Round(Math.Max(line.start.Y, line.end.Y) / World.gridLength); List<float> collidingDistances = new List<float>(); for (int k = startY; k != endY + 1; ++k) { for (int l = startX; l != endX + 1; ++l) { for (int j = 0; j != Game1.world.grid[k, l].Count; ++j) { BoundingRectangle currRect = Game1.world.grid[k, l][j].BoundingRectangle; if (line.IntersectsBox(currRect)) { float? dist = line.intersectionDistance(currRect); if (dist != null && !collidingDistances.Contains(dist.Value)) { collidingDistances.Add(dist.Value); } } } } } if (collidingDistances.Count == 0) { return null; } else { float s = collidingDistances.Min(); return s; } }
public virtual void IsVisible(Vector2 position, out bool canSee, out bool canReach) { LineSegment lineTest = new LineSegment(Position, position); bool obstacle; bool isSeeThrough; canReach = true; canSee = true; // Check the grid for walls int startX = (int)Math.Round(Math.Min(Position.X, position.X) / World.gridLength); int startY = (int)Math.Round(Math.Min(Position.Y, position.Y) / World.gridLength); int endX = (int)Math.Round(Math.Max(Position.X, position.X) / World.gridLength); int endY = (int)Math.Round(Math.Max(Position.Y, position.Y) / World.gridLength); try { for (int k = startY; k != endY + 1; ++k) { for (int l = startX; l != endX + 1; ++l) { for (int j = 0; j != Game1.world.grid[k, l].Count; ++j) { obstacle = lineTest.IntersectsBox(Game1.world.grid[k, l][j].BoundingRectangle); isSeeThrough = Game1.world.grid[k, l][j].IsSeeThrough; if (obstacle && isSeeThrough) { canReach = false; } else if (obstacle && !isSeeThrough) { canReach = false; canSee = false; } if (!canReach && !canSee) { return; } } } } } catch (IndexOutOfRangeException e) { //Console.WriteLine("BAD POSITION: " + physics.Position.X + ", " + physics.Position.Y); } }
private void superFlash() { int victimCount = 0; foreach (EntityMoveable entity in Game1.world.moveableObjectsX) { if (entity is Streaker) { continue; } if ((entity.Position - Position).Length() > SUPER_FLASH_DISTANCE) { continue; } bool canBeHit = true; LineSegment test = new LineSegment(Position, entity.Position); // Check the grid for walls int startX = (int)Math.Round(Math.Min(Position.X, entity.Position.X) / World.gridLength); int startY = (int)Math.Round(Math.Min(Position.Y, entity.Position.Y) / World.gridLength); int endX = (int)Math.Round(Math.Max(Position.X, entity.Position.X) / World.gridLength); int endY = (int)Math.Round(Math.Max(Position.Y, entity.Position.Y) / World.gridLength); try { for (int k = startY; k != endY + 1; ++k) { for (int l = startX; l != endX + 1; ++l) { for (int j = 0; j != Game1.world.grid[k, l].Count; ++j) { if (Game1.world.grid[k, l][j].IsSeeThrough) { continue; } if (test.IntersectsBox(Game1.world.grid[k, l][j].BoundingRectangle)) { canBeHit = false; break; } } if (!canBeHit) { break; } } if (!canBeHit) { break; } } if (canBeHit) { entity.Fall(true); if (!(entity is RoboCop)) { ++victimCount; DataManager.GetInstance().IncreaseScore(DataManager.Points.SuperFlashKnockDown, true, entity.ComponentPhysics.Position.X, entity.ComponentPhysics.Position.Y - 64); } } } catch (IndexOutOfRangeException e) { } } DataManager dataMan = DataManager.GetInstance(); dataMan.SuperflashVictims += victimCount; if (dataMan.biggestSuperflash < victimCount) dataMan.biggestSuperflash = victimCount; dataMan.numberofSuperFlash++; }
public float? intersectionDistance(BoundingRectangle rect) { LineSegment[] side = new LineSegment[4]; side[0] = new LineSegment(rect.Bounds.Left, rect.Bounds.Top, rect.Bounds.Right, rect.Bounds.Top); side[1] = new LineSegment(rect.Bounds.Left, rect.Bounds.Bottom, rect.Bounds.Right, rect.Bounds.Bottom); side[2] = new LineSegment(rect.Bounds.Left, rect.Bounds.Top, rect.Bounds.Left, rect.Bounds.Bottom); side[3] = new LineSegment(rect.Bounds.Right, rect.Bounds.Top, rect.Bounds.Right, rect.Bounds.Bottom); Vector2 intersectPt = Vector2.Zero; float? shortestDist = null; float currDist; for (int i = 0; i < 4; i++) { intersectPt = intersection(side[i]); currDist = distance(intersectPt); if (!intersectPt.Equals(Vector2.Zero) && (shortestDist == null || currDist < shortestDist)) { shortestDist = currDist; } } return shortestDist; }
/// <summary> /// Check if two lines are parallel /// </summary> /// <param name="line">Line to check against</param> /// <returns>True if the lines are parallel</returns> public bool isParallel(LineSegment line) { return (A * line.B == B * line.A); }