public bool GetHit(LiteCollision target) { switch (Type) { case CollisionType.Circle: switch (target.Type) { case CollisionType.Circle: return HitCircleCircle(this, target); case CollisionType.Rect: return HitCircleRect(this, target); case CollisionType.ChainCircle: return HitCircleChain(this, target); default: break; } break; case CollisionType.Rect: switch (target.Type) { case CollisionType.Circle: return HitCircleRect(target, this); case CollisionType.Rect: return HitRectRect(this, target); default: break; } break; case CollisionType.ChainCircle: switch (target.Type) { case CollisionType.Circle: return HitCircleChain(target, this); case CollisionType.Rect: break; case CollisionType.ChainCircle: break; default: break; } break; default: break; } throw new NotImplementedException("未定義の当たり判定組 " + Type.ToString() + " * " + target.Type.ToString()); }
static bool HitCircleRect(LiteCollision circle, LiteCollision rect) { ///正確ではない return (rect.Left < circle.Position.X + circle.Radius) && (circle.Position.X - circle.Radius < rect.Right) && (rect.Top - circle.Radius < circle.Position.Y) && (circle.Position.Y < rect.Bottom + circle.Radius); }
static bool HitRectRect(LiteCollision rect1, LiteCollision rect2) { //(rect1.Position.X - rect1.Width / 2f < rect2.Position.X - rect2.Width / 2f) throw new NotImplementedException("じっそうめんどくさい"); }
static bool HitCircleCircle(LiteCollision circle1, LiteCollision circle2) { return HitCircleCircleHelper(circle1.Position, circle1.Radius, circle2.Position, circle2.Radius); }
static bool HitCircleChain(LiteCollision circle, LiteCollision chain) { for (int i = 0; i < chain.chainLength; i++) { if (HitCircleCircleHelper(circle.Position, circle.Radius, chain.Positions[i], chain.Radius)) { return true; } } return false; }
static Vector2 GetHitPointRectCircle(LiteCollision ccl, LiteCollision rct) { Vector2 c = ccl.Position; bool xin = rct.Left < c.X && c.X < rct.Right; bool yin = rct.Top < c.Y && c.Y < rct.Bottom; if (xin && yin)//円が中に入っている { return c; } if (xin) { if (c.Y > rct.Position.Y) { return new Vector2(c.X, rct.Bottom); } else { return new Vector2(c.X, rct.Top); } } else { if (c.X > rct.Position.X) { return new Vector2(rct.Right, c.Y); } else { return new Vector2(rct.Left, c.Y); } } }
static Vector2 GetHitPointCircleCircle(LiteCollision c1, LiteCollision c2) { LiteCollision sml, big; if (c1.Radius > c2.Radius) { sml = c2; big = c1; } else { sml = c1; big = c2; } Vector2 d = sml.Position - big.Position; float dis = d.LengthSquared(); if (dis > MathUtil.Pow2(c1.Radius + c2.Radius))///そもそも当たっていない { throw new Exception(); } if (MathUtil.Pow2(big.Radius - sml.Radius) > dis)///小さいほうが完全に内包されてる { return sml.Position; } //d.Normalize(); return big.Position + d * ((MathUtil.Pow2(big.Radius) - MathUtil.Pow2(sml.Radius) + dis) * .5f / dis); //return sml.Position + d * ((1 + (big.Radius * big.Radius - sml.Radius * sml.Radius) / dis) / 2f); //return sml.Position + d * ((1 + (sml.Radius * sml.Radius - big.Radius * big.Radius) / dis) / 2); }
public Vector2 GetHitPoint(LiteCollision target) { switch (target.Type) { case CollisionType.Circle: if (this.Type == CollisionType.Circle) { return GetHitPointCircleCircle(this, target); } else if (this.Type == CollisionType.Rect) { return GetHitPointRectCircle(target, this); } break; case CollisionType.Rect: if (this.Type == CollisionType.Circle) { return GetHitPointRectCircle(this, target); } break; case CollisionType.ChainCircle: break; default: break; } throw new NotImplementedException(); }