/// <summary> /// Determine if BoundingCircle and BoundingCircle collide /// </summary> /// /// <param name="w1">This Collision data's world object</param> /// /// <param name="c1">Circle to check</param> /// <param name="w2">Other collision data's world object</param> /// <param name="o">Collision circle which to check</param> /// <returns>Whether a collision occurred</returns> internal static bool DetectCollision(WorldObject w1, Collision_BoundingCircle c1, WorldObject w2, Collision_BoundingCircle o) { float ds = Collision.DistanceSquared(w1.Pos + c1.Center, w2.Pos + o.Center); float r = c1.Radius + o.Radius; return(ds <= r * r); }
/// <summary> /// Determine if BoundingCircle and BoundingCircle collide /// </summary> /// /// <param name="w1">This Collision data's world object</param> /// /// <param name="c1">Circle to check</param> /// <param name="w2">Other collision data's world object</param> /// <param name="o">Collision circle which to check</param> /// <returns>Whether a collision occurred</returns> internal static bool detectCollision(WorldObject w1, Collision_BoundingCircle c1, WorldObject w2, Collision_BoundingCircle o) { float ds = Collision.distanceSquared(w1.Pos + c1.centerPointOffset, w2.Pos + o.centerPointOffset); float r = c1.radius + o.radius; return (ds <= r*r); }
/// <summary> /// Detect of a Collision circle and OBB collide /// </summary> /// <param name="w1">This Collision data's world object</param> /// <param name="o1">OBB to check</param> /// <param name="w2">Other collision data's world object</param> /// <param name="o">Collision circle which to check</param> /// <returns>Whether a collision occurred</returns> internal static bool detectCollision(WorldObject w1, Collision_OBB o1, WorldObject w2, Collision_BoundingCircle o) { Vector2 c1Center = o.centerPointOffset + w2.Pos; Vector2 o1Anchor = new Vector2(w1.Pos.X, w1.Pos.Y); Vector2 drawPoint0 = new Vector2(o1.drawPoints[0].Position.X + o1Anchor.X, o1.drawPoints[0].Position.Y + o1Anchor.Y); Vector2 drawPoint1 = new Vector2(o1.drawPoints[1].Position.X + o1Anchor.X, o1.drawPoints[1].Position.Y + o1Anchor.Y); Vector2 drawPoint2 = new Vector2(o1.drawPoints[2].Position.X + o1Anchor.X, o1.drawPoints[2].Position.Y + o1Anchor.Y); Vector2 drawPoint3 = new Vector2(o1.drawPoints[3].Position.X + o1Anchor.X, o1.drawPoints[3].Position.Y + o1Anchor.Y); Vector2 C = drawPoint1 + Vector2.Dot(c1Center - drawPoint1, Vector2.Normalize(drawPoint1 - drawPoint0)) * Vector2.Normalize(drawPoint1 - drawPoint0); Vector2 D = drawPoint1 + Vector2.Dot(c1Center - drawPoint1, Vector2.Normalize(drawPoint1 - drawPoint2)) * Vector2.Normalize(drawPoint1 - drawPoint2); float CtoDP1 = Vector2.DistanceSquared(C, drawPoint1); float CtoDP0 = Vector2.DistanceSquared(C, drawPoint0); float DP0toDP1 = Vector2.DistanceSquared(drawPoint1, drawPoint0); float DtoDP1 = Vector2.DistanceSquared(D, drawPoint1); float DtoDP2 = Vector2.DistanceSquared(D, drawPoint2); float DP2toDP1 = Vector2.DistanceSquared(drawPoint1, drawPoint2); float CentertoDP0 = Vector2.DistanceSquared(c1Center, drawPoint0); float CentertoDP1 = Vector2.DistanceSquared(c1Center, drawPoint1); float CentertoDP2 = Vector2.DistanceSquared(c1Center, drawPoint2); float CentertoDP3 = Vector2.DistanceSquared(c1Center, drawPoint3); if (((DP0toDP1 + (o.radius * 2) * (o.radius * 2) + 100 >= CtoDP0 + CtoDP1) && (DP2toDP1 + (o.radius * 2) * (o.radius * 2) + 100 >= DtoDP2 + DtoDP1)) || (CentertoDP0 <= o.radius * o.radius) || (CentertoDP1 <= o.radius * o.radius) || (CentertoDP2 <= o.radius * o.radius) || (CentertoDP3 <= o.radius * o.radius)) return true; return false; }
/// <summary> /// Determine if OBB and BoundingCircle collide /// </summary> /// /// <param name="w1">This Collision data's world object</param> /// <param name="c1">Cricle to check</param> /// <param name="w2">Other collision data's world object</param> /// <param name="o">OBB which to check</param> /// <returns>Whether a collision occurred</returns> internal static bool detectCollision(WorldObject w1, Collision_BoundingCircle c1, WorldObject w2, Collision_OBB o) { return detectCollision(w2, o, w1, c1); }
/// <summary> /// Determine whether an AABB and Collision circle collide /// </summary> /// <param name="w1">This Collision data's world object</param> /// <param name="a1">Collision AABB</param> /// <param name="w2">Other collision data's world object</param> /// <param name="o">Collision circle which to check</param> /// <returns>Whether a collision occurred</returns> internal static bool detectCollision(WorldObject w1, Collision_AABB a1, WorldObject w2, Collision_BoundingCircle o) { Vector2 centerPoint = o.centerPointOffset + w2.Pos; Vector2 topLeftPoint = a1.topLeftPointOffset + w1.Pos; Vector2 bottomRightPoint = a1.bottomRightPointOffset + w1.Pos; int regionCode = 0; if (centerPoint.X < topLeftPoint.X) regionCode += 1; // 0001 if (centerPoint.X > bottomRightPoint.X) regionCode += 2; // 0010 if (centerPoint.Y > topLeftPoint.Y) regionCode += 4; // 0100 if (centerPoint.Y < bottomRightPoint.Y) regionCode += 8; float radius = o.radius; switch (regionCode) { case 0: //0000 return true; case 1: //0001 if (Math.Abs(topLeftPoint.X - centerPoint.X) <= radius) return true; break; case 2: //0010 if (Math.Abs(centerPoint.X - bottomRightPoint.X) <= radius) return true; break; case 4: //0100 if (Math.Abs(centerPoint.Y - topLeftPoint.Y) <= radius) return true; break; case 8: //1000 if (Math.Abs(bottomRightPoint.Y - centerPoint.Y) <= radius) return true; break; case 5: //0101 case 9: //1001 if (Collision.distanceSquared(centerPoint, topLeftPoint) <= radius * radius) return true; break; case 6: //0110 case 10: //1010 if (Collision.distanceSquared(centerPoint, bottomRightPoint) <= radius * radius) return true; break; } return false; }
/// <summary> /// Loads the animations from a file. /// </summary> /// <param name="filename">Name of animfile</param> /// <param name="contentSubfolder">Folder where content is stored</param> private void LoadAnimation(string filename, string contentSubfolder) { filename = String.Format("Content/{0}/{1}", contentSubfolder, filename); if (!File.Exists(filename)) { throw new Exception(String.Format("Animation file {0} does not exist.", filename)); } XDocument doc = XDocument.Load(filename); foreach (var frame in doc.Descendants("Frame")) { SpriteFrame sf = new SpriteFrame(); string[] sp = frame.Attribute("TLPos").Value.Split(','); sf.StartPos = new Vector2(float.Parse(sp[0]), float.Parse(sp[1])); ///image string file = frame.Attribute("SpriteSheet").Value; sf.Image = This.Game.Content.Load<Texture2D>(String.Format("{0}/{1}", contentSubfolder, file)); /** sets frame delay */ sf.Pause = int.Parse(frame.Attribute("FrameDelay").Value); //Image's width and height sf.Width = int.Parse(frame.Attribute("Width").Value); sf.Height = int.Parse(frame.Attribute("Height").Value); var point = frame.Attribute("AnimationPeg").Value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); float pegX = float.Parse(point.First()); float pegY = float.Parse(point.Last()); /** Set the animation Peg*/ sf.AnimationPeg = new Vector2(pegX + (float)sf.Width / 2, pegY + (float)sf.Height / 2); Frames.Add(sf); } //add collision data int idCount = 0; foreach (var collision in doc.Descendants("Collision")) { if (collision.Attribute("Type").Value == "Circle") { string[] pt = collision.Attribute("Pos").Value.Split(','); var col = new Collision_BoundingCircle( idCount++, new Vector2(float.Parse(pt[0]), float.Parse(pt[1])), float.Parse(collision.Attribute("Radius").Value)); CollisionData.Add(col); objects.Add(new Background_Collision(col)); } else if (collision.Attribute("Type").Value == "Rectangle") { string[] tl = collision.Attribute("TLPos").Value.Split(','); float tlx = float.Parse(tl[0]); float tly = float.Parse(tl[1]); string[] br = collision.Attribute("BRPos").Value.Split(','); float brx = float.Parse(br[0]); float bry = float.Parse(br[1]); var col = new Collision_AABB( idCount++, new Vector2(tlx, tly), new Vector2(brx, bry) ); CollisionData.Add(col); objects.Add(new Background_Collision(col)); } else if (collision.Attribute("Type").Value == "OBB") { string[] c1 = collision.Attribute("Corner1").Value.Split(','); float c1x = float.Parse(c1[0]); float c1y = float.Parse(c1[1]); string[] c2 = collision.Attribute("Corner2").Value.Split(','); float c2x = float.Parse(c2[0]); float c2y = float.Parse(c2[1]); float thickness = float.Parse(collision.Attribute("Thickness").Value.ToString()); var col = new Collision_OBB( idCount++, new Vector2(c1x, c1y), new Vector2(c2x, c2y), thickness ); CollisionData.Add(col); objects.Add(new Background_Collision(col)); } } }
/// <summary> /// Loads the animations from a file. /// </summary> /// <param name="filename">Name of animfile</param> /// <param name="contentSubfolder">Folder where content is stored</param> private void LoadAnimation(string filename, string contentSubfolder) { filename = String.Format("Content/{0}/{1}", contentSubfolder, filename); if (!File.Exists(filename)) { throw new Exception(String.Format("Animation file {0} does not exist.", filename)); } XDocument doc = XDocument.Load(filename); foreach (var frame in doc.Descendants("Frame")) { SpriteFrame sf = new SpriteFrame(); string[] sp = frame.Attribute("TLPos").Value.Split(','); sf.StartPos = new Vector2(float.Parse(sp[0]), float.Parse(sp[1])); ///image string file = frame.Attribute("SpriteSheet").Value; sf.Image = This.Game.Content.Load <Texture2D>(String.Format("{0}/{1}", contentSubfolder, file)); /** sets frame delay */ sf.Pause = int.Parse(frame.Attribute("FrameDelay").Value); //Image's width and height sf.Width = int.Parse(frame.Attribute("Width").Value); sf.Height = int.Parse(frame.Attribute("Height").Value); var point = frame.Attribute("AnimationPeg").Value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); float pegX = float.Parse(point.First()); float pegY = float.Parse(point.Last()); /** Set the animation Peg*/ sf.AnimationPeg = new Vector2(pegX + (float)sf.Width / 2, pegY + (float)sf.Height / 2); Frames.Add(sf); } //add collision data int idCount = 0; foreach (var collision in doc.Descendants("Collision")) { if (collision.Attribute("Type").Value == "Circle") { string[] pt = collision.Attribute("Pos").Value.Split(','); var col = new Collision_BoundingCircle( idCount++, new Vector2(float.Parse(pt[0]), float.Parse(pt[1])), float.Parse(collision.Attribute("Radius").Value)); CollisionData.Add(col); objects.Add(new Background_Collision(col)); } else if (collision.Attribute("Type").Value == "Rectangle") { string[] tl = collision.Attribute("TLPos").Value.Split(','); float tlx = float.Parse(tl[0]); float tly = float.Parse(tl[1]); string[] br = collision.Attribute("BRPos").Value.Split(','); float brx = float.Parse(br[0]); float bry = float.Parse(br[1]); var col = new Collision_AABB( idCount++, new Vector2(tlx, tly), new Vector2(brx, bry) ); CollisionData.Add(col); objects.Add(new Background_Collision(col)); } else if (collision.Attribute("Type").Value == "OBB") { string[] c1 = collision.Attribute("Corner1").Value.Split(','); float c1x = float.Parse(c1[0]); float c1y = float.Parse(c1[1]); string[] c2 = collision.Attribute("Corner2").Value.Split(','); float c2x = float.Parse(c2[0]); float c2y = float.Parse(c2[1]); float thickness = float.Parse(collision.Attribute("Thickness").Value.ToString()); var col = new Collision_OBB( idCount++, new Vector2(c1x, c1y), new Vector2(c2x, c2y), thickness ); CollisionData.Add(col); objects.Add(new Background_Collision(col)); } } }
/// <summary> /// Detect of a Collision circle and OBB collide /// </summary> /// <param name="w1">This Collision data's world object</param> /// <param name="o1">OBB to check</param> /// <param name="w2">Other collision data's world object</param> /// <param name="o">Collision circle which to check</param> /// <returns>Whether a collision occurred</returns> internal static bool DetectCollision(WorldObject w1, Collision_OBB o1, WorldObject w2, Collision_BoundingCircle o) { Vector2 c1Center = o.Center + w2.Pos; Vector2 o1Anchor = new Vector2(w1.Pos.X, w1.Pos.Y); Vector2 drawPoint0 = new Vector2(o1.drawPoints[0].Position.X + o1Anchor.X, o1.drawPoints[0].Position.Y + o1Anchor.Y); Vector2 drawPoint1 = new Vector2(o1.drawPoints[1].Position.X + o1Anchor.X, o1.drawPoints[1].Position.Y + o1Anchor.Y); Vector2 drawPoint2 = new Vector2(o1.drawPoints[2].Position.X + o1Anchor.X, o1.drawPoints[2].Position.Y + o1Anchor.Y); Vector2 drawPoint3 = new Vector2(o1.drawPoints[3].Position.X + o1Anchor.X, o1.drawPoints[3].Position.Y + o1Anchor.Y); Vector2 C = drawPoint1 + Vector2.Dot(c1Center - drawPoint1, Vector2.Normalize(drawPoint1 - drawPoint0)) * Vector2.Normalize(drawPoint1 - drawPoint0); Vector2 D = drawPoint1 + Vector2.Dot(c1Center - drawPoint1, Vector2.Normalize(drawPoint1 - drawPoint2)) * Vector2.Normalize(drawPoint1 - drawPoint2); float CtoDP1 = Vector2.DistanceSquared(C, drawPoint1); float CtoDP0 = Vector2.DistanceSquared(C, drawPoint0); float DP0toDP1 = Vector2.DistanceSquared(drawPoint1, drawPoint0); float DtoDP1 = Vector2.DistanceSquared(D, drawPoint1); float DtoDP2 = Vector2.DistanceSquared(D, drawPoint2); float DP2toDP1 = Vector2.DistanceSquared(drawPoint1, drawPoint2); float CentertoDP0 = Vector2.DistanceSquared(c1Center, drawPoint0); float CentertoDP1 = Vector2.DistanceSquared(c1Center, drawPoint1); float CentertoDP2 = Vector2.DistanceSquared(c1Center, drawPoint2); float CentertoDP3 = Vector2.DistanceSquared(c1Center, drawPoint3); if (((DP0toDP1 + (o.Radius * 2) * (o.Radius * 2) + 100 >= CtoDP0 + CtoDP1) && (DP2toDP1 + (o.Radius * 2) * (o.Radius * 2) + 100 >= DtoDP2 + DtoDP1)) || (CentertoDP0 <= o.Radius * o.Radius) || (CentertoDP1 <= o.Radius * o.Radius) || (CentertoDP2 <= o.Radius * o.Radius) || (CentertoDP3 <= o.Radius * o.Radius)) { return(true); } return(false); }
/// <summary> /// Determine if OBB and BoundingCircle collide /// </summary> /// /// <param name="w1">This Collision data's world object</param> /// <param name="c1">Cricle to check</param> /// <param name="w2">Other collision data's world object</param> /// <param name="o">OBB which to check</param> /// <returns>Whether a collision occurred</returns> internal static bool DetectCollision(WorldObject w1, Collision_BoundingCircle c1, WorldObject w2, Collision_OBB o) { return(DetectCollision(w2, o, w1, c1)); }
/// <summary> /// Determine whether an AABB and Collision circle collide /// </summary> /// <param name="w1">This Collision data's world object</param> /// <param name="a1">Collision AABB</param> /// <param name="w2">Other collision data's world object</param> /// <param name="o">Collision circle which to check</param> /// <returns>Whether a collision occurred</returns> internal static bool DetectCollision(WorldObject w1, Collision_AABB a1, WorldObject w2, Collision_BoundingCircle o) { Vector2 centerPoint = o.Center + w2.Pos; Vector2 topLeftPoint = a1.TL + w1.Pos; Vector2 bottomRightPoint = a1.BR + w1.Pos; int regionCode = 0; if (centerPoint.X < topLeftPoint.X) { regionCode += 1; // 0001 } if (centerPoint.X > bottomRightPoint.X) { regionCode += 2; // 0010 } if (centerPoint.Y < topLeftPoint.Y) { regionCode += 4; // 0100 } if (centerPoint.Y > bottomRightPoint.Y) { regionCode += 8; } float radius = o.Radius; switch (regionCode) { case 0: //0000 return(true); case 1: //0001 if (Math.Abs(topLeftPoint.X - centerPoint.X) <= radius) { return(true); } break; case 2: //0010 if (Math.Abs(centerPoint.X - bottomRightPoint.X) <= radius) { return(true); } break; case 4: //0100 if (Math.Abs(centerPoint.Y - topLeftPoint.Y) <= radius) { return(true); } break; case 8: //1000 if (Math.Abs(bottomRightPoint.Y - centerPoint.Y) <= radius) { return(true); } break; case 5: //0101 if (Collision.DistanceSquared(centerPoint, topLeftPoint) <= radius * radius) { return(true); } break; case 9: //1001 if (Collision.DistanceSquared(centerPoint, new Vector2(topLeftPoint.X, bottomRightPoint.Y)) <= radius * radius) { return(true); } break; case 6: //0110 if (Collision.DistanceSquared(centerPoint, new Vector2(bottomRightPoint.X, topLeftPoint.Y)) <= radius * radius) { return(true); } break; case 10: //1010 if (Collision.DistanceSquared(centerPoint, bottomRightPoint) <= radius * radius) { return(true); } break; } return(false); }
/// <summary> /// Determine if BoundingCircle and BoundingCircle collide /// </summary> /// /// <param name="w1">This Collision data's world object</param> /// /// <param name="c1">Circle to check</param> /// <param name="w2">Other collision data's world object</param> /// <param name="o">Collision circle which to check</param> /// <returns>Whether a collision occurred</returns> internal static bool DetectCollision(WorldObject w1, Collision_BoundingCircle c1, WorldObject w2, Collision_BoundingCircle o) { float ds = Collision.DistanceSquared(w1.Pos + c1.Center, w2.Pos + o.Center); float r = c1.Radius + o.Radius; return (ds <= r * r); }