/// <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> /// Detects OBB on OBB collision /// </summary> /// <param name="w1">This Collision data's world object</param> /// <param name="c1">OBB to check</param> /// <param name="w2">Other collision data's world object</param> /// <param name="o">AABB circle which to check</param> /// <returns>Whether a collision occurred</returns> internal static bool DetectCollision(WorldObject w1, Collision_OBB c1, WorldObject w2, Collision_AABB o) { //so, we've got to project the faces onto eachother and look for intersections //these values are values along the projected axis. Vector2 Corner1 = new Vector2(o.TL.X, o.BR.Y); var temp = c1.xAxis; var dot = 1;//Vector2.Dot(temp, temp); var a = (Vector2.Dot((c1.Corner1 + w1.Pos), temp) / dot); var b = (Vector2.Dot((c1.Corner2 + w1.Pos), temp) / dot); var c = (Vector2.Dot((Corner1 + w2.Pos), temp) / dot); var d = (Vector2.Dot((o.TL + w2.Pos), temp) / dot); if ( !(//check if they intersect, if they don't we're not colliding. a <= b ? //is c or d between a b? (a <= c && c <= b) || (a <= d && d <= b) : (b <= c && c <= a) || (b <= d && d <= a) ) ) { return(false); } temp = c1.yAxis; dot = 1;//Vector2.Dot(temp, temp); a = (Vector2.Dot((c1.Corner1 + w1.Pos), temp) / dot); b = (Vector2.Dot((c1.Corner3 + w1.Pos), temp) / dot); c = (Vector2.Dot((Corner1 + w2.Pos), temp) / dot); d = (Vector2.Dot((o.BR + w2.Pos), temp) / dot); if ( !(//check if they intersect, if they don't we're not colliding. a <= b ? //is c or d between a b? (a <= c && c <= b) || (a <= d && d <= b) : (b <= c && c <= a) || (b <= d && d <= a) ) ) { return(false); } return(true); }
/// <summary> /// Detects OBB on OBB collision /// </summary> /// <param name="w1">This Collision data's world object</param> /// <param name="c1">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 c1, WorldObject w2, Collision_OBB o) { return false; }
/// <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> /// 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> /// Detects OBB on OBB collision /// </summary> /// <param name="w1">This Collision data's world object</param> /// <param name="c1">AABB to check</param> /// <param name="w2">Other collision data's world object</param> /// <param name="o">OBB circle which to check</param> /// <returns>Whether a collision occurred</returns> internal static bool DetectCollision(WorldObject w1, Collision_AABB c1, WorldObject w2, Collision_OBB o) { return(DetectCollision(w2, o, w1, c1)); }
/// <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> /// Detects OBB on OBB collision /// </summary> /// <param name="w1">This Collision data's world object</param> /// <param name="c1">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 c1, WorldObject w2, Collision_OBB o) { //so, we've got to project the faces onto eachother and look for intersections //these values are values along the projected axis. var temp = c1.xAxis; var dot = 1;//Vector2.Dot(temp, temp); var a = (Vector2.Dot((c1.Corner1 + w1.Pos), temp) / dot); var b = (Vector2.Dot((c1.Corner2 + w1.Pos), temp) / dot); var c = (Vector2.Dot((o.Corner1 + w2.Pos), temp) / dot); var d = (Vector2.Dot((o.Corner2 + w2.Pos), temp) / dot); if ( !(//check if they intersect, if they don't we're not colliding. a <= b ? //is c or d between a b? (a <= c && c <= b) || (a <= d && d <= b) : (b <= c && c <= a) || (b <= d && d <= a) ) ) return false; temp = c1.yAxis; dot = 1;//Vector2.Dot(temp, temp); a = (Vector2.Dot((c1.Corner1 + w1.Pos), temp) / dot); b = (Vector2.Dot((c1.Corner3 + w1.Pos), temp) / dot); c = (Vector2.Dot((o.Corner1 + w2.Pos), temp) / dot); d = (Vector2.Dot((o.Corner3 + w2.Pos), temp) / dot); if ( !(//check if they intersect, if they don't we're not colliding. a <= b ? //is c or d between a b? (a <= c && c <= b) || (a <= d && d <= b) : (b <= c && c <= a) || (b <= d && d <= a) ) ) return false; temp = o.xAxis; dot = 1;//Vector2.Dot(temp, temp); a = (Vector2.Dot((c1.Corner1 + w1.Pos), temp) / dot); b = (Vector2.Dot((c1.Corner2 + w1.Pos), temp) / dot); c = (Vector2.Dot((o.Corner1 + w2.Pos), temp) / dot); d = (Vector2.Dot((o.Corner2 + w2.Pos), temp) / dot); if ( !(//check if they intersect, if they don't we're not colliding. a <= b ? //is c or d between a b? (a <= c && c <= b) || (a <= d && d <= b) : (b <= c && c <= a) || (b <= d && d <= a) ) ) return false; temp = o.yAxis; dot = 1;//Vector2.Dot(temp, temp); a = (Vector2.Dot((c1.Corner1 + w1.Pos), temp) / dot); b = (Vector2.Dot((c1.Corner3 + w1.Pos), temp) / dot); c = (Vector2.Dot((o.Corner1 + w2.Pos), temp) / dot); d = (Vector2.Dot((o.Corner3 + w2.Pos), temp) / dot); if ( !(//check if they intersect, if they don't we're not colliding. a <= b ? //is c or d between a b? (a <= c && c <= b) || (a <= d && d <= b) : (b <= c && c <= a) || (b <= d && d <= a) ) ) return false; return true; }
/// <summary> /// Detects OBB on OBB collision /// </summary> /// <param name="w1">This Collision data's world object</param> /// <param name="c1">AABB to check</param> /// <param name="w2">Other collision data's world object</param> /// <param name="o">OBB circle which to check</param> /// <returns>Whether a collision occurred</returns> internal static bool DetectCollision(WorldObject w1, Collision_AABB c1, WorldObject w2, Collision_OBB o) { return DetectCollision(w2, o, w1, c1); }