private bool DetectCollisionWithPlayerBullet(PlayerBulletBase bullet) { int nextColliderIndex = 0; int curColliderIndex; bool isCollided = false; do { CollisionDetectParas collParas = bullet.GetCollisionDetectParas(nextColliderIndex); curColliderIndex = nextColliderIndex; nextColliderIndex = collParas.nextIndex; if (collParas.type == CollisionDetectType.Circle) { // 子弹为圆形判定,先检测外切正方形 float dx = Mathf.Abs(_curPos.x - collParas.centerPos.x); float dy = Mathf.Abs(_curPos.y - collParas.centerPos.y); // 两圆的半径和 float sumOfRadius = _radius + collParas.radius; if (dx <= sumOfRadius && dy <= sumOfRadius) { if (dx * dx + dy * dy <= sumOfRadius * sumOfRadius) { bullet.CollidedByObject(curColliderIndex); isCollided = true; } } } } while (nextColliderIndex != -1); return(isCollided); }
/// <summary> /// 碰撞检测 /// </summary> /// <param name="collParas"></param> /// <returns></returns> private bool DetectCollisionWithEnemyBullet(EnemyBulletBase bullet) { if (bullet.Type == BulletType.Enemy_Laser) { return(false); } CollisionDetectParas collParas; switch (bullet.Type) { case BulletType.Enemy_Simple: collParas = bullet.GetCollisionDetectParas(0); break; case BulletType.Enemy_LinearLaser: case BulletType.Enemy_CurveLaser: collParas = bullet.GetCollisionDetectParas(-1); break; default: collParas = new CollisionDetectParas(); break; } if (DetectCollisionWithCollisionParas(collParas)) { CollidedByObject(bullet); return(true); } return(false); }
public override CollisionDetectParas GetCollisionDetectParas(int index = 0) { if (_collisionHalfWidth == _collisionHalfHeight) { CollisionDetectParas paras = new CollisionDetectParas { type = CollisionDetectType.Circle, centerPos = _curPos, radius = _collisionHalfWidth, nextIndex = -1, }; return(paras); } else { CollisionDetectParas paras = new CollisionDetectParas { type = CollisionDetectType.ItalicRect, centerPos = _curPos, halfWidth = _collisionHalfWidth, halfHeight = _collisionHalfHeight, angle = _curVAngle, nextIndex = -1, }; return(paras); } }
private bool DetectCollisionWithPlayerBullet(PlayerBulletBase bullet) { int nextColliderIndex = 0; int curColliderIndex; bool isCollided = false; do { CollisionDetectParas collParas = bullet.GetCollisionDetectParas(nextColliderIndex); curColliderIndex = nextColliderIndex; nextColliderIndex = collParas.nextIndex; if (collParas.type == CollisionDetectType.Circle) { // 子弹为圆形判定,方形判定来检测 float dx = Mathf.Abs(_curPos.x - collParas.centerPos.x); float dy = Mathf.Abs(_curPos.y - collParas.centerPos.y); // 检测该碰撞矩形与方形是否相交 if (dx <= _halfWidth + collParas.radius && dy <= _halfHeight + collParas.radius) { CollidedByPlayerBullet(bullet, curColliderIndex); isCollided = true; } } } while (nextColliderIndex != -1); return(isCollided); }
public override bool DetectCollisionWithCollisionParas(CollisionDetectParas collParas) { if (collParas.type == CollisionDetectType.Circle) { if (MathUtil.DetectCollisionBetweenCircleAndOBB(collParas.centerPos, collParas.radius, _curPos, _halfWidth, _halfHeight, _curRotation)) { return(true); } } else if (collParas.type == CollisionDetectType.Rect || collParas.type == CollisionDetectType.ItalicRect) { // 计算rect1的分离轴向量 float angle0 = 0; float angle1 = collParas.angle; float cos0 = Mathf.Cos(Mathf.Deg2Rad * angle0); float sin0 = Mathf.Sin(Mathf.Deg2Rad * angle0); float cos1 = Mathf.Cos(Mathf.Deg2Rad * angle1); float sin1 = Mathf.Sin(Mathf.Deg2Rad * angle1); //rect0分离轴 Vector2 rect0Vec0 = new Vector2(cos0, sin0); Vector2 rect0Vec1 = new Vector2(-sin0, cos0); // rect1分离轴 Vector2 rect1Vec0 = new Vector2(cos1, sin1); Vector2 rect1Vec1 = new Vector2(-sin1, cos1); List <Vector2> rectVecList = new List <Vector2> { rect0Vec0, rect0Vec1, rect1Vec0, rect1Vec1 }; // 两矩形中心的向量 Vector2 centerVec = new Vector2(collParas.centerPos.x - _curPos.x, collParas.centerPos.y - _curPos.y); bool rectIsCollided = true; for (int i = 0; i < rectVecList.Count; i++) { // 投影轴 Vector2 vec = rectVecList[i]; // rect0的投影半径对于该投影轴的投影 float projectionRadius0 = Mathf.Abs(Vector2.Dot(rect0Vec0, vec) * _halfWidth) + Mathf.Abs(Vector2.Dot(rect0Vec1, vec) * _halfHeight); projectionRadius0 = Mathf.Abs(projectionRadius0); // rect1的投影半径对于投影轴的投影 float projectionRadius1 = Mathf.Abs(Vector2.Dot(rect1Vec0, vec) * collParas.halfWidth) + Mathf.Abs(Vector2.Dot(rect1Vec1, vec) * collParas.halfHeight); projectionRadius1 = Mathf.Abs(projectionRadius1); // 连线对于投影轴的投影 float centerVecProjection = Vector2.Dot(centerVec, vec); centerVecProjection = Mathf.Abs(centerVecProjection); // 投影的和小于轴半径的长度,说明没有碰撞 if (projectionRadius0 + projectionRadius1 <= centerVecProjection) { rectIsCollided = false; break; } } if (rectIsCollided) { return(true); } } return(false); }
public override CollisionDetectParas GetCollisionDetectParas(int index = 0) { if (!_isCachedCollisionSegment) { CacheCollisionPoints(); } CollisionDetectParas paras; if (index == 0) { if (_pathCount <= _laserLen && !_isSourceEliminated) { paras = new CollisionDetectParas() { type = CollisionDetectType.Circle, radius = DefaultCollisionHalfHeight, nextIndex = 1, }; } else { paras = new CollisionDetectParas() { type = CollisionDetectType.Null, nextIndex = 1, }; } } else if (_collisionSegmentCount < index) { paras = new CollisionDetectParas() { type = CollisionDetectType.Null, nextIndex = -1, }; } else { index = index > 0 ? index : _collisionSegmentCount + index + 1; int segmentIndex = index - 1; Vector2 segment = _collisionSegmentList[segmentIndex]; Vector2 lineVec = _pathList[(int)segment.y] - _pathList[(int)segment.x]; float segmentLen = lineVec.magnitude; paras = new CollisionDetectParas() { type = CollisionDetectType.ItalicRect, centerPos = (_pathList[(int)segment.x] + _pathList[(int)segment.y]) / 2, nextIndex = segmentIndex + 1 >= _collisionSegmentCount ? -1 : index + 1, halfWidth = segmentLen / 2, halfHeight = DefaultCollisionHalfHeight, angle = _curRotation, }; } return(paras); }
public override CollisionDetectParas GetCollisionDetectParas(int index = 0) { CollisionDetectParas para = new CollisionDetectParas { type = CollisionDetectType.Circle, centerPos = _curPos, radius = _radius, }; return(para); }
public override bool DetectCollisionWithCollisionParas(CollisionDetectParas collParas) { if (collParas.type == CollisionDetectType.Circle) { // 子弹为圆形判定,先检测外切正方形 float dx = Mathf.Abs(_curPos.x - collParas.centerPos.x); float dy = Mathf.Abs(_curPos.y - collParas.centerPos.y); // 两圆的半径和 float sumOfRadius = _radius + collParas.radius; if (dx <= sumOfRadius && dy <= sumOfRadius) { if (dx * dx + dy * dy <= sumOfRadius * sumOfRadius) { return(true); } } } else if (collParas.type == CollisionDetectType.Rect || collParas.type == CollisionDetectType.ItalicRect) { if (_radius == 0) { return(false); } // 子弹为矩形判定 return(MathUtil.DetectCollisionBetweenCircleAndOBB(_curPos, _radius, collParas.centerPos, collParas.halfWidth, collParas.halfHeight, collParas.angle)); //// 以子弹中心点为圆心,将B的判定中心旋转angle的角度计算判定 //Vector2 vec = new Vector2(_curPosX - collParas.centerPos.x, _curPosY - collParas.centerPos.y); //float cos = Mathf.Cos(collParas.angle * Mathf.Deg2Rad); //float sin = Mathf.Sin(collParas.angle * Mathf.Deg2Rad); //Vector2 relativeVec = new Vector2(); //// 向量顺时针旋转laserAngle的度数 //relativeVec.x = cos * vec.x + sin * vec.y; //relativeVec.y = -sin * vec.x + cos * vec.y; //// 计算圆和矩形的碰撞 //float len = relativeVec.magnitude; //float dLen = len - _radius; //// 若圆心和矩形中心的连线长度小于圆的半径,说明矩形肯定有一部分在圆内 //// 因此直接认定为碰撞 //if (dLen <= 0) //{ // return true; //} //else //{ // float rate = dLen / len; // relativeVec *= rate; // if (Mathf.Abs(relativeVec.x) < collParas.halfHeight && Mathf.Abs(relativeVec.y) < collParas.halfWidth) // { // return true; // } //} } return(false); }
public override CollisionDetectParas GetCollisionDetectParas(int index = 0) { CollisionDetectParas para = new CollisionDetectParas { type = CollisionDetectType.Rect, centerPos = _curPos, halfWidth = _halfWidth, halfHeight = _halfHeight, }; return(para); }
/// <summary> /// 获取碰撞检测的参数 /// </summary> /// <param name="index">对应的第n个碰撞盒的参数</param> /// <returns></returns> public virtual CollisionDetectParas GetCollisionDetectParas(int index = 0) { CollisionDetectParas paras = new CollisionDetectParas { type = CollisionDetectType.Circle, centerPos = _curPos, radius = _collisionRadius, nextIndex = -1, angle = 0, }; return(paras); }
public static int SetLaserCollisionDetectParas(ILuaState luaState) { Logger.LogError("Try to call unused Method LuaLib:SetLaserCollisionDetectParas"); EnemyLaser laser = luaState.ToUserData(-3) as EnemyLaser; CollisionDetectParas detectParas = new CollisionDetectParas() { type = CollisionDetectType.Rect, halfWidth = (float)luaState.ToNumber(-2), halfHeight = (float)luaState.ToNumber(-1), }; luaState.Pop(3); //laser.SetCollisionDetectParas(detectParas); return(0); }
/// <summary> /// 获取碰撞检测的参数 /// </summary> /// <param name="index">对应的第n个碰撞盒的参数</param> /// <returns></returns> public virtual CollisionDetectParas GetCollisionDetectParas(int index = 0) { CollisionDetectParas paras = new CollisionDetectParas { type = CollisionDetectType.Rect, centerPos = _curPos, halfWidth = _collisionHalfWidth, halfHeight = _collisionHalfHeight, radius = Mathf.Min(_collisionHalfWidth, _collisionHalfHeight), nextIndex = -1, angle = 0, }; return(paras); }
private void RenderEnemy() { Color col = new Color(255f / 255, 255f / 255, 128f / 255); List <EnemyBase> list = EnemyManager.GetInstance().GetEnemyList(); //int count = list.Count; foreach (var enemy in list) { if (enemy != null && enemy.DetectCollision()) { CollisionDetectParas para = enemy.GetCollisionDetectParas(); RenderCollisionGraphic(para, col); } } }
private void RenderCollisionGraphic(CollisionDetectParas para, Color col) { if (para.type == CollisionDetectType.Circle) { RenderCircle(para.centerPos, para.radius, col); } else if (para.type == CollisionDetectType.Rect) { RenderAABB(para.centerPos, para.halfWidth, para.halfHeight, col); } else if (para.type == CollisionDetectType.ItalicRect) { RenderOBB(para.centerPos, para.halfWidth, para.halfHeight, para.angle, col); } }
/// <summary> /// 获取子弹的碰撞参数 /// <para>bullet</para> /// <para>collisionIndex 第n个碰撞体</para> /// </summary> /// <param name="luaState"></param> /// <returns></returns> public static int GetBulletCollisionDetectParas(ILuaState luaState) { EnemyBulletBase bullet = luaState.ToUserData(-2) as EnemyBulletBase; int index = luaState.ToInteger(-1); luaState.Pop(2); CollisionDetectParas collParas = bullet.GetCollisionDetectParas(index); luaState.PushInteger((int)collParas.type); luaState.PushNumber(collParas.centerPos.x); luaState.PushNumber(collParas.centerPos.y); luaState.PushNumber(collParas.radius); luaState.PushNumber(collParas.halfWidth); luaState.PushNumber(collParas.halfHeight); luaState.PushNumber(collParas.angle); return(7); }
/// <summary> /// 碰撞检测 /// </summary> /// <param name="collParas"></param> /// <returns></returns> private bool DetectCollisionWithEnemyBullet(EnemyBulletBase bullet) { int nextColliderIndex = 0; int curColliderIndex; bool isCollided = false; do { CollisionDetectParas collParas = bullet.GetCollisionDetectParas(nextColliderIndex); curColliderIndex = nextColliderIndex; nextColliderIndex = collParas.nextIndex; if (DetectCollisionWithCollisionParas(collParas)) { bullet.CollidedByObject(curColliderIndex, _eliminateType); isCollided = true; } } while (nextColliderIndex != -1); return(isCollided); }
public override CollisionDetectParas GetCollisionDetectParas(int index=0) { CollisionDetectParas paras = new CollisionDetectParas(); paras.nextIndex = -1; paras.type = CollisionDetectType.ItalicRect; //paras.halfWidth = _laserHalfWidth * _collisionFactor; //paras.halfHeight = _laserHalfLength; paras.halfWidth = _laserHalfLength; paras.halfHeight = _laserHalfWidth * _collisionFactor; paras.angle = _curRotation; // 计算矩形中心坐标 Vector2 center = new Vector2(); float cos = Mathf.Cos(_curRotation * Mathf.Deg2Rad); float sin = Mathf.Sin(_curRotation * Mathf.Deg2Rad); // 矩形中心坐标 center.x = _laserHalfLength * cos + _curPos.x; center.y = _laserHalfLength * sin + _curPos.y; paras.centerPos = center; return paras; }
private void RenderPlayerBullet() { Color col = new Color(127f / 255, 127f / 255, 192f / 255); List <PlayerBulletBase> list = BulletsManager.GetInstance().GetPlayerBulletList(); //int count = list.Count; foreach (var bullet in list) { if (bullet != null && bullet.DetectCollision()) { int nextIndex = 0; do { CollisionDetectParas para = bullet.GetCollisionDetectParas(nextIndex); RenderCollisionGraphic(para, col); nextIndex = para.nextIndex; } while (nextIndex != -1); } } }
private bool DetectCollisionWithPlayerBullet(PlayerBulletBase bullet) { int nextColliderIndex = 0; int curColliderIndex; bool isCollided = false; do { CollisionDetectParas collParas = bullet.GetCollisionDetectParas(nextColliderIndex); curColliderIndex = nextColliderIndex; nextColliderIndex = collParas.nextIndex; if (collParas.type == CollisionDetectType.Circle) { if (MathUtil.DetectCollisionBetweenCircleAndOBB(collParas.centerPos, collParas.radius, _curPos, _halfWidth, _halfHeight, _curRotation)) { CollidedByPlayerBullet(bullet, curColliderIndex); isCollided = true; } } } while (nextColliderIndex != -1); return(isCollided); }
public override CollisionDetectParas GetCollisionDetectParas(int index = 0) { if (!_isCachedCollisionSegments) { CacheCollisionSegments(); } CollisionDetectParas paras = new CollisionDetectParas(); if (index >= _collisionSegmentsCount) { paras.type = CollisionDetectType.Null; paras.nextIndex = -1; } else { int nextIndex = index + 1 >= _collisionSegmentsCount ? -1 : index + 1; paras.type = CollisionDetectType.Circle; paras.radius = CollisionSegmentRadius; paras.centerPos = _collisionSegments[index]; paras.nextIndex = nextIndex; } return(paras); }
public override void Update() { for (int i = 0; i < _triggerDataCount; i++) { TriggerData data = _triggerDatas[i]; if (data.triggerGroup == 0) { continue; } int listCount; List <ObjectColliderBase> colliderList = ColliderManager.GetInstance().GetColliderList(out listCount); ObjectColliderBase collider; for (int j = 0; j < listCount; j++) { collider = colliderList[j]; // 非空,且满足触发条件 if (collider != null && ((int)collider.GetColliderGroup() & data.triggerGroup) != 0) { int nextColliderIndex = 0; int curColliderIndex; do { CollisionDetectParas collParas = _bullet.GetCollisionDetectParas(nextColliderIndex); curColliderIndex = nextColliderIndex; nextColliderIndex = collParas.nextIndex; if (collider.DetectCollisionWithCollisionParas(collParas)) { //InterpreterManager.GetInstance().AddPara(_bullet, LuaParaType.LightUserData); InterpreterManager.GetInstance().AddPara(collider, LuaParaType.LightUserData); InterpreterManager.GetInstance().AddPara(curColliderIndex, LuaParaType.Int); InterpreterManager.GetInstance().CallLuaFunction(data.triggerFuncRef, 2, 0); } } while (nextColliderIndex != -1); } } } }
public void CheckHitEnemy() { List <EnemyBase> enemyList = EnemyManager.GetInstance().GetEnemyList(); int enemyCount = enemyList.Count; EnemyBase enemy; for (int i = 0; i < enemyCount; i++) { enemy = enemyList[i]; // 自机子弹与敌机使用方形检测 if (enemy != null && enemy.isAvailable && enemy.CanHit()) { CollisionDetectParas paras = enemy.GetCollisionDetectParas(); if (Mathf.Abs(_curPos.x - paras.centerPos.x) <= _collisionRadius + paras.halfWidth && Mathf.Abs(_curPos.y - paras.centerPos.y) <= _collisionRadius + paras.halfHeight) { enemy.TakeDamage(GetDamage()); _hitPos = _curPos; BeginEliminating(); break; } } } }
public virtual bool DetectCollisionWithCollisionParas(CollisionDetectParas collParas) { throw new System.NotImplementedException(); }