Ejemplo n.º 1
0
    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);
    }
Ejemplo n.º 2
0
    /// <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);
     }
 }
Ejemplo n.º 4
0
    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);
 }
Ejemplo n.º 6
0
    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);
    }
Ejemplo n.º 7
0
    public override CollisionDetectParas GetCollisionDetectParas(int index = 0)
    {
        CollisionDetectParas para = new CollisionDetectParas
        {
            type      = CollisionDetectType.Circle,
            centerPos = _curPos,
            radius    = _radius,
        };

        return(para);
    }
Ejemplo n.º 8
0
 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);
 }
Ejemplo n.º 9
0
    public override CollisionDetectParas GetCollisionDetectParas(int index = 0)
    {
        CollisionDetectParas para = new CollisionDetectParas
        {
            type       = CollisionDetectType.Rect,
            centerPos  = _curPos,
            halfWidth  = _halfWidth,
            halfHeight = _halfHeight,
        };

        return(para);
    }
Ejemplo n.º 10
0
    /// <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);
    }
Ejemplo n.º 11
0
    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);
    }
Ejemplo n.º 12
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);
    }
Ejemplo n.º 13
0
    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);
            }
        }
    }
Ejemplo n.º 14
0
 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);
     }
 }
Ejemplo n.º 15
0
    /// <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);
    }
Ejemplo n.º 16
0
    /// <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);
    }
Ejemplo n.º 17
0
 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;
 }
Ejemplo n.º 18
0
    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);
    }
Ejemplo n.º 20
0
    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);
    }
Ejemplo n.º 21
0
 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;
                }
            }
        }
    }
Ejemplo n.º 23
0
 public virtual bool DetectCollisionWithCollisionParas(CollisionDetectParas collParas)
 {
     throw new System.NotImplementedException();
 }