public override void InitData() { type = ShapeType.arc; arcRadius = ToolMethod.Config2Logic(arcRadiusCon); arcCenter = ToolGameVector.ChangeGameVectorConToGameVector2(arcCenterCon) + basePosition; }
void OnDrawGizmos() { if (closeLine) { return; } Gizmos.color = lineColor; if (Application.isPlaying) { Gizmos.DrawWireSphere(ToolGameVector.ChangeGameVectorToVector3(basePosition), ToolMethod.Config2Render(baseRadiusCon)); } else { Gizmos.DrawWireSphere(ToolGameVector.ChangeGameVectorConToVector3(baseCenter), ToolMethod.Config2Render(baseRadiusCon)); } if (fixPosition) { int _posX = (int)ToolMethod.Render2Config(transform.position.x) + 25; int _posY = (int)ToolMethod.Render2Config(transform.position.z) + 25; _posX = _posX - _posX % 50; _posY = _posY - _posY % 50; baseCenter.x = _posX; baseCenter.y = _posY; transform.position = ToolGameVector.ChangeGameVectorConToVector3(baseCenter); fixPosition = false; } }
//圆和多边形碰撞 public static bool CollideCircleAndPolygon(GameVector2 _c1, int _radius1, GameVec2Con[] vectexs, int[] normalDir) { Vector3 _circleCenter = ToolGameVector.ChangeGameVectorToVector3(_c1); bool isAllIn = true;//是否都在多边形线段的右侧 for (int i = 0; i < vectexs.Length; i++) { Vector3 lineBegin = ToolGameVector.ChangeGameVectorConToVector3(vectexs [i]); int endIndex = (i + 1) % vectexs.Length; Vector3 lineEnd = ToolGameVector.ChangeGameVectorConToVector3(vectexs [endIndex]); Vector3 _circleVec = _circleCenter - lineBegin; Vector3 _line = lineEnd - lineBegin; Vector3 _cross = Vector3.Cross(_circleVec, _line); if (_cross.z < 0) { isAllIn = false; //在线段的左侧,即多边形的外侧 Vector3 vecProj = Vector3.Project(_circleVec, _line); //投影点 float disLine = _line.magnitude; float proj_begin = vecProj.magnitude; float proj_end = (vecProj - _line).magnitude; float projlengh = proj_begin + proj_end; if ((disLine + 1) >= projlengh) { //投影在线段上 int dis = (int)Mathf.Sqrt(_circleVec.sqrMagnitude - vecProj.sqrMagnitude); int disRadius = _radius1 / 100; if (dis < disRadius) { return(true); } else { return(false); } } else { //投影不在当前线段上 if (CollidePointAndCircle(ChangeGameVectorConToGameVector2(vectexs [i]), _c1, _radius1)) { return(true); } else { return(CollidePointAndCircle(ChangeGameVectorConToGameVector2(vectexs [endIndex]), _c1, _radius1)); } } } } if (isAllIn) { //全在内侧,圆心在多边形内 return(true); } return(false); }
public void InitSelf(ObjectType _objType, int _objID) { isInDestory = false; objUid = new ObjectUid(_objType, _objID); basePosition = ToolGameVector.ChangeGameVectorConToGameVector2(baseCenter); baseRadius = ToolMethod.Config2Logic(baseRadiusCon); InitData(); }
public virtual void Logic_UpdateMoveDir(int _dir) { if (_dir > 120) { logicSpeed = GameVector2.zero; } else { roleDirection = _dir * 3; logicSpeed = moveSpeed * BattleData.Instance.GetSpeed(roleDirection); Vector3 _renderDir = ToolGameVector.ChangeGameVectorToVector3(logicSpeed); renderDir = Quaternion.LookRotation(_renderDir); } }
// 圆和正圆弧的碰撞,不带位置修正 public static bool CollideCircleAndArc(GameVector2 _c1, int _radius1, GameVector2 _arcCen, int _arcRadius, int _arcAngle, int _arcAngleSize) { int radiusSum = _radius1 + _arcRadius; long sqrRadiusSum = radiusSum * radiusSum; long sqrDistance = _c1.sqrMagnitude(_arcCen); if (sqrDistance >= sqrRadiusSum) { return(false); } int radiusDel = _radius1 - _arcRadius; long sqrRadiusDel = radiusDel * radiusDel; if (sqrDistance <= sqrRadiusDel) { return(false); } int _angle = (_c1 - _arcCen).Angle(); if (Mathf.Abs(_angle - _arcAngle) <= _arcAngleSize) { return(true); } int _point1Angle = (int)Mathf.Repeat(_arcAngle + _arcAngleSize, 360); GameVector2 _point1 = _arcCen + (_arcRadius / 100) * BattleData.Instance.GetSpeed(_point1Angle); bool _result1 = ToolGameVector.CollidePointAndCircle(_c1, _point1, _radius1); if (_result1) { return(_result1); } int _point2Angle = (int)Mathf.Repeat(_arcAngle - _arcAngleSize, 360); GameVector2 _point2 = _arcCen + (_arcRadius / 100) * BattleData.Instance.GetSpeed(_point2Angle); bool _result2 = ToolGameVector.CollidePointAndCircle(_c1, _point2, _radius1); if (_result2) { return(_result2); } return(false); }
//获取渲染坐标 public Vector3 GetPositionVec3(float _y = 0f) { return(ToolGameVector.ChangeGameVectorToVector3(basePosition, _y)); }
public override bool IsCollisionCircleCorrection(GameVector2 _pos, int _radius, out GameVector2 _amend) { return(ToolGameVector.CollideCircleAndArc(_pos, _radius, arcCenter, arcRadius, arcAngle, arcAngleSize, out _amend)); }
void OnDrawGizmos() { if (closeLine) { return; } Gizmos.color = lineColor; Vector3 baseVec3 = ToolGameVector.ChangeGameVectorConToVector3(baseCenter); Gizmos.DrawWireSphere(baseVec3, baseRadiusCon); Vector3 arcCenter = baseVec3 + ToolGameVector.ChangeGameVectorConToVector3(arcCenterCon); if (showArcCircle) { Gizmos.DrawWireSphere(arcCenter, arcRadiusCon); } int vectNumber = arcAngleSize / 3; Vector3 firstVect1 = arcCenter + new Vector3(Mathf.Cos(Mathf.Deg2Rad * arcAngle) * arcRadiusCon, Mathf.Sin(Mathf.Deg2Rad * arcAngle) * arcRadiusCon, 0); Vector3 firstVect2 = firstVect1; // Gizmos.color = Color.blue; for (int i = 1; i <= vectNumber; i++) { int angle1 = arcAngle + 3 * i; int angle2 = arcAngle - 3 * i; if (i == vectNumber) { angle1 = arcAngle + arcAngleSize; angle2 = arcAngle - arcAngleSize; } float fAngle1 = Mathf.Deg2Rad * angle1; float fAngle2 = Mathf.Deg2Rad * angle2; Vector3 vectPos1 = arcCenter + new Vector3(Mathf.Cos(fAngle1) * arcRadiusCon, Mathf.Sin(fAngle1) * arcRadiusCon, 0); Gizmos.DrawLine(firstVect1, vectPos1); firstVect1 = vectPos1; Vector3 vectPos2 = arcCenter + new Vector3(Mathf.Cos(fAngle2) * arcRadiusCon, Mathf.Sin(fAngle2) * arcRadiusCon, 0); Gizmos.DrawLine(firstVect2, vectPos2); firstVect2 = vectPos2; } if (fixPosition) { int _posX = (int)transform.position.x + 25; int _posY = (int)transform.position.y + 25; _posX = _posX - _posX % 50; _posY = _posY - _posY % 50; baseCenter.x = _posX; baseCenter.y = _posY; transform.position = new Vector3(_posX * 1.0f, _posY * 1.0f); fixPosition = false; } }
//距离检测 public virtual bool IsInBaseCircleDistance(GameVector2 _pos, int _radius) { return(ToolGameVector.CollideCircleAndCircle(_pos, basePosition, _radius, baseRadius)); }
public override bool IsCollisionCircle(GameVector2 _pos, int _radius) { return(ToolGameVector.CollideCircleAndArc(_pos, _radius, arcCenter, arcRadius, arcAngle, arcAngleSize)); }
/// <summary> /// 圆和矩形的修正碰撞 /// </summary> /// <returns><c>true</c>, 产生碰撞, <c>false</c> 没有碰撞.</returns> /// <param name="_c1">圆心.</param> /// <param name="_radius1">圆半径.</param> /// <param name="_rCenter">矩形中心.</param> /// <param name="_half_w">矩形宽度的一半.</param> /// <param name="_half_h">矩形高度的一半.</param> /// <param name="_amend">修正值.</param> public static bool CollideCircleAndRect(GameVector2 _c1, int _radius1, GameVector2 _rCenter, int _half_w, int _half_h, out GameVector2 _amend) { /* * l:左 * r:右 * t:上/顶 * b:下/底 */ int llx = _rCenter.x - _half_w - _radius1; if (_c1.x <= llx) { _amend = GameVector2.zero; return(false); } int bby = _rCenter.y - _half_h - _radius1; if (_c1.y <= bby) { _amend = GameVector2.zero; return(false); } int rrx = _rCenter.x + _half_w + _radius1; if (_c1.x >= rrx) { _amend = GameVector2.zero; return(false); } int tty = _rCenter.y + _half_h + _radius1; if (_c1.y >= tty) { _amend = GameVector2.zero; return(false); } int lx = _rCenter.x - _half_w; int by = _rCenter.y - _half_h; int rx = _rCenter.x + _half_w; int ty = _rCenter.y + _half_h; if (_c1.x <= lx) { if (_c1.y > ty) { //左上角的顶点矩形里 GameVector2 _ltPoint = new GameVector2(lx, ty); return(ToolGameVector.CollidePointAndCircle(_c1, _ltPoint, _radius1, out _amend)); } else if (_c1.y < by) { //左下角的顶点矩形里 GameVector2 _lbPoint = new GameVector2(lx, by); return(ToolGameVector.CollidePointAndCircle(_c1, _lbPoint, _radius1, out _amend)); } else { //左侧矩形 _amend = new GameVector2(llx - _c1.x, 0); } } else if (_c1.x >= rx) { if (_c1.y > ty) { //右上角的顶点矩形里 GameVector2 _rtPoint = new GameVector2(rx, ty); return(ToolGameVector.CollidePointAndCircle(_c1, _rtPoint, _radius1, out _amend)); } else if (_c1.y < by) { //右下角的顶点矩形里 GameVector2 _rbPoint = new GameVector2(rx, by); return(ToolGameVector.CollidePointAndCircle(_c1, _rbPoint, _radius1, out _amend)); } else { //右侧矩形 _amend = new GameVector2(rrx - _c1.x, 0); } } else { if (_c1.y > ty) { //中上矩形 _amend = new GameVector2(0, tty - _c1.y); } else if (_c1.y < by) { //中下矩形 _amend = new GameVector2(0, bby - _c1.y); } else { //矩形内 GameVector2 _rtPoint = new GameVector2(rx, ty); int _rtAngle = (_rtPoint - _rCenter).Angle(); int _ltAngle = 180 - _rtAngle; int _lbAngle = 180 + _rtAngle; int _rbAngel = 360 - _rtAngle; int circleAngle = (_c1 - _rCenter).Angle(); //圆心和矩形中心的角度 if (circleAngle > _rbAngel) { _amend = new GameVector2(rrx - _c1.x, 0); } else if (circleAngle > _lbAngle) { _amend = new GameVector2(0, bby - _c1.y); } else if (circleAngle > _ltAngle) { _amend = new GameVector2(llx - _c1.x, 0); } else if (circleAngle > _rtAngle) { _amend = new GameVector2(0, tty - _c1.y); } else { _amend = new GameVector2(rrx - _c1.x, 0); } } } return(true); }
void OnDrawGizmos() { if (closeLine) { return; } if (!hideCircle) { Gizmos.color = Color.blue; if (Application.isPlaying) { Gizmos.DrawWireSphere(ToolGameVector.ChangeGameVectorToVector3(basePosition), baseRadiusCon); Gizmos.DrawWireSphere(ToolGameVector.ChangeGameVectorToVector3(basePosition), colliRadiusCon); } else { Gizmos.DrawWireSphere(ToolGameVector.ChangeGameVectorConToVector3(baseCenter), baseRadiusCon); Gizmos.DrawWireSphere(ToolGameVector.ChangeGameVectorConToVector3(baseCenter), colliRadiusCon); } } if (updateVertexs || fixPosition) { vertexsCon = new GameVec2Con[vertexs_delta.Length]; normalDir = new int[vertexs_delta.Length]; float radius = 0; for (int i = 0; i < vertexs_delta.Length; i++) { vertexsCon [i].x = baseCenter.x + vertexs_delta [i].x; vertexsCon [i].y = baseCenter.y + vertexs_delta [i].y; Vector3 _dv = ToolGameVector.ChangeGameVectorConToVector3(vertexs_delta [i]); radius = Mathf.Max(radius, _dv.magnitude); //法向 Vector3 _dir; if (i == vertexs_delta.Length - 1) { _dir = ToolGameVector.ChangeGameVectorConToVector3(vertexs_delta [0]); } else { _dir = ToolGameVector.ChangeGameVectorConToVector3(vertexs_delta [i + 1]); } Vector3 _line = _dir - _dv; int _linedir = (int)Mathf.Sign(_line.y) * Mathf.RoundToInt(Vector3.Angle(_line, new Vector3(1f, 0f, 0f))); normalDir [i] = (int)Mathf.Repeat(_linedir + 90, 360); } baseRadiusCon = (int)radius + 1; } Gizmos.color = lineColor; for (int i = 0; i < vertexsCon.Length; i++) { Vector3 lineBegin; Vector3 lineEnd; if (i == vertexsCon.Length - 1) { lineBegin = ToolGameVector.ChangeGameVectorConToVector3(vertexsCon [i]); lineEnd = ToolGameVector.ChangeGameVectorConToVector3(vertexsCon [0]); } else { lineBegin = ToolGameVector.ChangeGameVectorConToVector3(vertexsCon [i]); lineEnd = ToolGameVector.ChangeGameVectorConToVector3(vertexsCon [i + 1]); } Gizmos.DrawLine(lineBegin, lineEnd); Vector3 _normalBegin = (lineBegin + lineEnd) * 0.5f; Vector3 _normalEnd = _normalBegin + new Vector3(100f * Mathf.Cos(Mathf.Deg2Rad * normalDir [i]), 100f * Mathf.Sin(Mathf.Deg2Rad * normalDir [i])); Gizmos.DrawLine(_normalBegin, _normalEnd); } if (fixPosition) { int _posX = (int)transform.position.x + 25; int _posY = (int)transform.position.y + 25; _posX = _posX - _posX % 50; _posY = _posY - _posY % 50; baseCenter.x = _posX; baseCenter.y = _posY; transform.position = new Vector3(_posX * 1.0f, _posY * 1.0f); fixPosition = false; } }
//是否碰撞,带位置修正 public virtual bool IsCollisionCircleCorrection(GameVector2 _pos, int _radius, out GameVector2 _amend) { return(ToolGameVector.CollideCircleAndCircle(_pos, basePosition, _radius, baseRadius, out _amend)); }
public override bool IsCollisionCircle(GameVector2 _pos, int _radius) { return(ToolGameVector.CollideCircleAndPolygon(_pos, _radius, vertexsCon, normalDir)); }
/// <summary> /// 圆和正圆弧的碰撞,带位置修正 /// </summary> /// <returns><c>true</c>, if circle and arc was collided, <c>false</c> otherwise.</returns> /// <param name="_c1">圆心.</param> /// <param name="_radius1">圆半径.</param> /// <param name="_arcCen">圆弧圆心.</param> /// <param name="_arcRadius">圆弧所在圆半径.</param> /// <param name="_arcAngle">角度.</param> /// <param name="_arcAngleSize">角度范围.</param> /// <param name="_amend">修正值.</param> public static bool CollideCircleAndArc(GameVector2 _c1, int _radius1, GameVector2 _arcCen, int _arcRadius, int _arcAngle, int _arcAngleSize, out GameVector2 _amend) { _amend = GameVector2.zero; int radiusSum = _radius1 + _arcRadius; long sqrRadiusSum = radiusSum * radiusSum; long sqrDistance = _c1.sqrMagnitude(_arcCen); if (sqrDistance >= sqrRadiusSum) { return(false); } int radiusDel = _radius1 - _arcRadius; long sqrRadiusDel = radiusDel * radiusDel; if (sqrDistance <= sqrRadiusDel) { return(false); } int _angle = (_c1 - _arcCen).Angle(); int _point1Angle = _arcAngle + _arcAngleSize; int _point2Angle = _arcAngle - _arcAngleSize; bool inArc; if (_point2Angle < 0) { int _angle1 = (int)Mathf.Repeat(_angle - _point2Angle, 360f); if (_angle1 >= 0 && _angle1 <= (_point1Angle - _point2Angle)) { inArc = true; } else { inArc = false; } } else if (_point1Angle > 360) { int _delA = _point1Angle - 360; int _angle1 = (int)Mathf.Repeat(_angle - _delA, 360f); if (_angle1 >= (_point2Angle - _delA) && _angle1 <= 360) { inArc = true; } else { inArc = false; } } else { if (_angle >= _point2Angle && _angle <= _point1Angle) { inArc = true; } else { inArc = false; } } if (inArc) { //在圆弧内,需要修正 long _arcRadiusSqr = _arcRadius * _arcRadius; int distance = (int)Mathf.Sqrt(sqrDistance); int amendDis; int amendAngle; if (sqrDistance >= _arcRadiusSqr) { //向外修正 amendDis = 1 + (int)(radiusSum - distance) / 100; amendAngle = _angle; } else { amendDis = 1 + (int)(distance - Mathf.Abs(radiusDel)) / 100; amendAngle = (_arcCen - _c1).Angle(); } _amend = amendDis * BattleData.Instance.GetSpeed(amendAngle); return(true); } _point1Angle = (int)Mathf.Repeat(_point1Angle, 360); GameVector2 _point1 = _arcCen + (_arcRadius / 100) * BattleData.Instance.GetSpeed(_point1Angle); GameVector2 _outAmend1; bool _result1 = ToolGameVector.CollidePointAndCircle(_c1, _point1, _radius1, out _outAmend1); if (_result1) { _amend = _outAmend1; return(_result1); } _point2Angle = (int)Mathf.Repeat(_point2Angle, 360); GameVector2 _point2 = _arcCen + (_arcRadius / 100) * BattleData.Instance.GetSpeed(_point2Angle); GameVector2 _outAmend2; bool _result2 = ToolGameVector.CollidePointAndCircle(_c1, _point2, _radius1, out _outAmend2); if (_result2) { _amend = _outAmend2; return(_result2); } return(false); }
void OnDrawGizmos() { if (closeLine) { return; } Vector3 _center; if (Application.isPlaying) { _center = ToolGameVector.ChangeGameVectorToVector3(basePosition); } else { _center = ToolGameVector.ChangeGameVectorConToVector3(baseCenter); } if (!hideCircle) { Gizmos.color = Color.blue; Gizmos.DrawWireSphere(_center, ToolMethod.Config2Render(baseRadiusCon)); } Gizmos.color = lineColor; float _width = ToolMethod.Config2Render(halfWidthCon); float _heigh = ToolMethod.Config2Render(halfHeightCon); Vector3[] topVec = new Vector3[4]; topVec [0] = _center + new Vector3(-_width, 0, -_heigh); topVec [1] = _center + new Vector3(-_width, 0, _heigh); topVec [2] = _center + new Vector3(_width, 0, _heigh); topVec [3] = _center + new Vector3(_width, 0, -_heigh); Gizmos.DrawLine(topVec[0], topVec[1]); Gizmos.DrawLine(topVec[1], topVec[2]); Gizmos.DrawLine(topVec[2], topVec[3]); Gizmos.DrawLine(topVec[3], topVec[0]); if (updateRadius) { baseRadiusCon = (int)Mathf.Sqrt(halfWidthCon * halfWidthCon + halfHeightCon * halfHeightCon) + 1; updateRadius = false; } if (fixPosition) { int _posX = (int)ToolMethod.Render2Config(transform.position.x) + 25; int _posY = (int)ToolMethod.Render2Config(transform.position.z) + 25; _posX = _posX - _posX % 50; _posY = _posY - _posY % 50; baseCenter.x = _posX; baseCenter.y = _posY; transform.position = ToolGameVector.ChangeGameVectorConToVector3(baseCenter); fixPosition = false; } }
/// <summary> /// 圆和圆的碰撞,圆2不动,修正是的是圆1的位置 /// </summary> /// <returns><c>true</c>, if circle and circle was collided, <c>false</c> otherwise.</returns> /// <param name="_c1">圆1的圆心.</param> /// <param name="_c2">圆2的圆心.</param> /// <param name="_radius1">圆1的半径.</param> /// <param name="_radius2">圆2的半径.</param> /// <param name="_amend">修正值.</param> public static bool CollideCircleAndCircle(GameVector2 _c1, GameVector2 _c2, int _radius1, int _radius2, out GameVector2 _amend) { return(ToolGameVector.CollidePointAndCircle(_c1, _c2, (_radius1 + _radius2), out _amend)); }
/// <summary> /// 圆和多边形的碰撞 /// </summary> /// <returns><c>true</c>, if circle and polygon was collided, <c>false</c> otherwise.</returns> /// <param name="_c1">圆心.</param> /// <param name="_radius1">圆半径.</param> /// <param name="vectexs">多边形顶点.</param> /// <param name="normalDir">多边形每条边的法向量.</param> /// <param name="_amend">位置修正.</param> public static bool CollideCircleAndPolygon(GameVector2 _c1, int _radius1, GameVec2Con[] vectexs, int[] normalDir, out GameVector2 _amend) { _amend = GameVector2.zero; Vector3 _circleCenter = ToolGameVector.ChangeGameVectorToVector3(_c1); for (int i = 0; i < vectexs.Length; i++) { Vector3 lineBegin = ToolGameVector.ChangeGameVectorConToVector3(vectexs [i]); int endIndex = (i + 1) % vectexs.Length; Vector3 lineEnd = ToolGameVector.ChangeGameVectorConToVector3(vectexs [endIndex]); Vector3 _circleVec = _circleCenter - lineBegin; Vector3 _line = lineEnd - lineBegin; Vector3 _cross = Vector3.Cross(_circleVec, _line); if (_cross.z < 0) { //在线段的左侧,即多边形的外侧 Vector3 vecProj = Vector3.Project(_circleVec, _line); //投影点 float disLine = _line.magnitude; float proj_begin = vecProj.magnitude; float proj_end = (vecProj - _line).magnitude; float projlengh = proj_begin + proj_end; if ((disLine + 1) >= projlengh) { //投影在线段上 int dis = (int)Mathf.Sqrt(_circleVec.sqrMagnitude - vecProj.sqrMagnitude); int disRadius = _radius1 / 100; if (dis < disRadius) { int amendDis = 1 + (int)(_radius1 / 100 - dis); _amend = amendDis * BattleData.Instance.GetSpeed(normalDir [i]); return(true); } else { return(false); } } else { Vector3 newLineBegin; Vector3 newLineEnd; //投影不在当前线段上 bool isSameDir = Vector3.Dot(vecProj, _line) > 0f ? true : false; //为0的时候是垂直,不会出现该情况 int normalIndex; int linePointIndex; //2条线段的交点 if (isSameDir) { //同向 newLineBegin = lineEnd; int newEndIndex = (i + 2) % vectexs.Length; newLineEnd = ToolGameVector.ChangeGameVectorConToVector3(vectexs [newEndIndex]); normalIndex = endIndex; linePointIndex = endIndex; } else { //反向 if (i == 0) { newLineBegin = ToolGameVector.ChangeGameVectorConToVector3(vectexs [vectexs.Length - 1]); } else { newLineBegin = ToolGameVector.ChangeGameVectorConToVector3(vectexs [i - 1]); } newLineEnd = lineBegin; normalIndex = vectexs.Length - 1; linePointIndex = i; } Vector3 newCircleVec = _circleCenter - newLineBegin; Vector3 _newline = newLineEnd - newLineBegin; Vector3 newVecProj = Vector3.Project(newCircleVec, _newline); //投影点 float newdisLine = _newline.magnitude; float newproj_begin = newVecProj.magnitude; float newproj_end = (newVecProj - _newline).magnitude; float newprojlengh = newproj_begin + newproj_end; if ((newdisLine + 1) >= newprojlengh) { //投影在线段上 int dis = (int)Mathf.Sqrt(newCircleVec.sqrMagnitude - newVecProj.sqrMagnitude); int disRadius = _radius1 / 100; if (dis < disRadius) { int amendDis = 1 + (int)(_radius1 / 100 - dis); _amend = amendDis * BattleData.Instance.GetSpeed(normalDir [normalIndex]); return(true); } else { return(false); } } else { bool isNewSameDir = Vector3.Dot(newVecProj, _newline) > 0f ? true : false; if (isNewSameDir != isSameDir) { //夹角处 GameVector2 _point = ToolGameVector.ChangeGameVectorConToGameVector2(vectexs [linePointIndex]); GameVector2 _outAmend; bool _result = ToolGameVector.CollidePointAndCircle(_c1, _point, _radius1, out _outAmend); _amend = _outAmend; return(_result); } } } } } return(false); }
/// <summary> /// 把坐标往绝对值大取整到百位,主要用于碰撞后的位置修正 /// </summary> public static void RoundGameVector2(ref GameVector2 _vec2) { _vec2.x = ToolGameVector.RoundInt(_vec2.x); _vec2.y = ToolGameVector.RoundInt(_vec2.y); }
public override bool IsCollisionCircle(GameVector2 _pos, int _radius) { return(ToolGameVector.CollideCircleAndRect(_pos, _radius, basePosition, halfWidth, halfHeight)); }
public override bool IsCollisionCircleCorrection(GameVector2 _pos, int _radius, out GameVector2 _amend) { return(ToolGameVector.CollideCircleAndPolygon(_pos, _radius, vertexsCon, normalDir, out _amend)); }
public override bool IsCollisionCircleCorrection(GameVector2 _pos, int _radius, out GameVector2 _amend) { return(ToolGameVector.CollideCircleAndRect(_pos, _radius, basePosition, halfWidth, halfHeight, out _amend)); }
//圆和矩形碰撞 public static bool CollideCircleAndRect(GameVector2 _c1, int _radius1, GameVector2 _rCenter, int _half_w, int _half_h) { if (_radius1 <= 100) { //半径足够小,当成点来处理 if (_c1.x <= _rCenter.x - _half_w) { return(false); } if (_c1.y <= _rCenter.y - _half_h) { return(false); } if (_c1.x >= _rCenter.x + _half_w) { return(false); } if (_c1.y >= _rCenter.y + _half_h) { return(false); } return(true); } int llx = _rCenter.x - _half_w - _radius1; if (_c1.x <= llx) { return(false); } int bby = _rCenter.y - _half_h - _radius1; if (_c1.y <= bby) { return(false); } int rrx = _rCenter.x + _half_w + _radius1; if (_c1.x >= rrx) { return(false); } int tty = _rCenter.y + _half_h + _radius1; if (_c1.y >= tty) { return(false); } int lx = _rCenter.x - _half_w; int by = _rCenter.y - _half_h; int rx = _rCenter.x + _half_w; int ty = _rCenter.y + _half_h; if (_c1.x <= lx) { if (_c1.y > ty) { //左上角的顶点矩形里 GameVector2 _ltPoint = new GameVector2(lx, ty); return(ToolGameVector.CollidePointAndCircle(_c1, _ltPoint, _radius1)); } else if (_c1.y < by) { //左下角的顶点矩形里 GameVector2 _lbPoint = new GameVector2(lx, by); return(ToolGameVector.CollidePointAndCircle(_c1, _lbPoint, _radius1)); } else { return(true); } } else if (_c1.x >= rx) { if (_c1.y > ty) { //右上角的顶点矩形里 GameVector2 _rtPoint = new GameVector2(rx, ty); return(ToolGameVector.CollidePointAndCircle(_c1, _rtPoint, _radius1)); } else if (_c1.y < by) { //右下角的顶点矩形里 GameVector2 _rbPoint = new GameVector2(rx, by); return(ToolGameVector.CollidePointAndCircle(_c1, _rbPoint, _radius1)); } else { return(true); } } return(true); }
/// <summary> /// 圆和正圆扇面的碰撞,带位置修正 /// </summary> /// <returns><c>true</c>, if circle and arc was collided, <c>false</c> otherwise.</returns> /// <param name="_c1">圆心.</param> /// <param name="_radius1">圆半径.</param> /// <param name="_arcCen">扇面圆心.</param> /// <param name="_arcRadius">扇面所在圆半径.</param> /// <param name="_arcAngle">角度.</param> /// <param name="_arcAngleSize">角度范围.</param> /// <param name="_amend">修正值.</param> public static bool CollideCircleAndArcArea(GameVector2 _c1, int _radius1, GameVector2 _arcCen, int _arcRadius, int _arcAngle, int _arcAngleSize, out GameVector2 _amend) { _amend = GameVector2.zero; int radiusSum = _radius1 + _arcRadius; long sqrRadiusSum = radiusSum * radiusSum; long sqrDistance = _c1.sqrMagnitude(_arcCen); if (sqrDistance >= sqrRadiusSum) { return(false); } int _angle = (_c1 - _arcCen).Angle(); int _point1Angle = _arcAngle + _arcAngleSize; int _point2Angle = _arcAngle - _arcAngleSize; bool inArc; if (_point2Angle < 0) { int _angle1 = (int)Mathf.Repeat(_angle - _point2Angle, 360f); if (_angle1 >= 0 && _angle1 <= (_point1Angle - _point2Angle)) { inArc = true; } else { inArc = false; } } else if (_point1Angle > 360) { int _delA = _point1Angle - 360; int _angle1 = (int)Mathf.Repeat(_angle - _delA, 360f); if (_angle1 >= (_point2Angle - _delA) && _angle1 <= 360) { inArc = true; } else { inArc = false; } } else { if (_angle >= _point2Angle && _angle <= _point1Angle) { inArc = true; } else { inArc = false; } } if (inArc) { //在圆弧内,需要修正 int distance = (int)Mathf.Sqrt(sqrDistance); int amendDis = 1 + (int)(radiusSum - distance) / 100; _amend = amendDis * BattleData.Instance.GetSpeed(_angle); return(true); } //线段修正 Vector3 _circleCenter = ToolGameVector.ChangeGameVectorToVector3(_c1); Vector3 _arcAreaCenter = ToolGameVector.ChangeGameVectorToVector3(_arcCen); _point1Angle = (int)Mathf.Repeat(_point1Angle, 360); GameVector2 _point1 = _arcCen + (_arcRadius / 100) * BattleData.Instance.GetSpeed(_point1Angle); _point2Angle = (int)Mathf.Repeat(_point2Angle, 360); GameVector2 _point2 = _arcCen + (_arcRadius / 100) * BattleData.Instance.GetSpeed(_point2Angle); Vector3 _line1Point = ToolGameVector.ChangeGameVectorToVector3(_point1); Vector3 _line2Point = ToolGameVector.ChangeGameVectorToVector3(_point2); //线段1修正 bool amendline1 = false; GameVector2 amendLine1P = GameVector2.zero; Vector3 _circleVec = _circleCenter - _arcAreaCenter; Vector3 _line = _line1Point - _arcAreaCenter; Vector3 _cross = Vector3.Cross(_circleVec, _line); if (_cross.z <= 0) { //在线段的左侧,即多边形的外侧 Vector3 vecProj = Vector3.Project(_circleVec, _line); //投影点 float disLine = _line.magnitude; float proj_begin = vecProj.magnitude; float proj_end = (vecProj - _line).magnitude; float projlengh = proj_begin + proj_end; if ((disLine + 1) >= projlengh) { //投影在线段上 int dis = (int)Mathf.Sqrt(_circleVec.sqrMagnitude - vecProj.sqrMagnitude); int disRadius = _radius1 / 100; if (dis < disRadius) { //需要修正 amendline1 = true; int amendDis = 1 + (int)(_radius1 / 100 - dis); Vector3 angelVec = _circleVec - vecProj; float angle1 = Mathf.Atan2(angelVec.y, angelVec.x) * Mathf.Rad2Deg; int amendAngle = (int)Mathf.Repeat(angle1, 360f); amendLine1P = amendDis * BattleData.Instance.GetSpeed(amendAngle); } } else { //投影不在当前线段上 } } //线段2修正 bool amendline2 = false; GameVector2 amendLine2P = GameVector2.zero; Vector3 _circleVec2 = _circleCenter - _line2Point; Vector3 _line2 = _arcAreaCenter - _line2Point; Vector3 _cross2 = Vector3.Cross(_circleVec2, _line2); if (_cross2.z <= 0) { //在线段的左侧,即多边形的外侧 Vector3 vecProj = Vector3.Project(_circleVec2, _line2); //投影点 float disLine = _line2.magnitude; float proj_begin = vecProj.magnitude; float proj_end = (vecProj - _line2).magnitude; float projlengh = proj_begin + proj_end; if ((disLine + 1) >= projlengh) { //投影在线段上 int dis = (int)Mathf.Sqrt(_circleVec2.sqrMagnitude - vecProj.sqrMagnitude); int disRadius = _radius1 / 100; if (dis < disRadius) { //需要修正 amendline2 = true; int amendDis = 1 + (int)(_radius1 / 100 - dis); Vector3 angelVec = _circleVec2 - vecProj; float angle1 = Mathf.Atan2(angelVec.y, angelVec.x) * Mathf.Rad2Deg; int amendAngle = (int)Mathf.Repeat(angle1, 360f); amendLine2P = amendDis * BattleData.Instance.GetSpeed(amendAngle); } } else { //投影不在当前线段上 } } if (amendline1 || amendline2) { _amend = amendLine1P + amendLine2P; return(true); } //对点修正 GameVector2 _outAmend1; bool _result1 = ToolGameVector.CollidePointAndCircle(_c1, _arcCen, _radius1, out _outAmend1); if (_result1) { _amend = _outAmend1; return(true); } GameVector2 _outAmend2; bool _result2 = ToolGameVector.CollidePointAndCircle(_c1, _point1, _radius1, out _outAmend2); GameVector2 _outAmend3; bool _result3 = ToolGameVector.CollidePointAndCircle(_c1, _point2, _radius1, out _outAmend3); if (_result2 || _result3) { _amend = _outAmend2 + _outAmend3; return(true); } return(false); }
//距离检测,out距离平方 public virtual bool IsInBaseCircleDistanceOutDistance(GameVector2 _pos, int _radius, out long _dis) { int newRange = _radius + baseRadius; return(ToolGameVector.IsInDistance(_pos, basePosition, newRange, out _dis)); }