예제 #1
0
    public SPoint ExitDist(int iInd, SPoint origin, float dir, Ninja plr, int ifGrab)
    {
        //plBox must contain 4 vertices!!!
        bool isHit = true;
        float rAng, distSq, projVal, moveDist;
        SPoint moveVec = new SPoint();
        moveVec.x = plr.GetPos().x - plr.GetLastPos().x;
        moveVec.y = plr.GetPos().y - plr.GetLastPos().y;
        SPoint[] plBox;
        int hbLen = 4;

            if (ifGrab < 0)
            {//implies groundCheck
                plBox = plr.GetHitBox();
                hbLen = 4;
            }
            else
            {
                plBox = plr.GetCurrentColBox();
                hbLen = 6;
            }

        float dHitMinSq = 1000;
        float dHitMaxSq = 0;
        float dPrMinSq = 1000;
        float dPrMaxSq = 0;
        SPoint projVec = new SPoint();
        float projMin = STAGE_LIMIT * STAGE_LIMIT;
        float projMax = -STAGE_LIMIT * STAGE_LIMIT;
        float hitMin = STAGE_LIMIT * STAGE_LIMIT;
        float hitMax = -STAGE_LIMIT * STAGE_LIMIT;
        for (int i = 0; i < tBox.GetJlength(iInd); i++)
        {
            projVec.x = tBox.GetSPoint(iInd, i).x - origin.x;
            projVec.y = tBox.GetSPoint(iInd, i).y - origin.y;
            distSq = projVec.x * projVec.x + projVec.y * projVec.y;
            if (distSq < EPS * EPS)
                rAng = dir; //Do NOT take atan2(0, 0)
            else
                rAng = dir - Mathf.Atan2(projVec.y, projVec.x);
            projVal = Mathf.Sin(rAng) * distSq;
            if (projVal < projMin){
                projMin = projVal;
                dPrMinSq = distSq;
            }if (projVal > projMax){
                projMax = projVal;
                dPrMaxSq = distSq;
            }
        }
        for (int i = 0; i < hbLen; i++)
        {
            projVec.x = plBox[i].x - origin.x;
            projVec.y = plBox[i].y - origin.y;
            distSq = projVec.x * projVec.x + projVec.y * projVec.y;
            if (distSq < EPS * EPS)
                rAng = dir; //Do NOT take atan2(0, 0)
            else
                rAng = dir - Mathf.Atan2(projVec.y, projVec.x);
            projVal = Mathf.Sin(rAng) * distSq;
            if (projVal < hitMin){
                hitMin = projVal;
                dHitMinSq = distSq;
            } if (projVal > hitMax) {
                hitMax = projVal;
                dHitMaxSq = distSq;
            }
        }
        if (dPrMinSq != 0)
            projMin = projMin / Mathf.Sqrt(dPrMinSq);
        if (dPrMaxSq != 0)
            projMax = projMax / Mathf.Sqrt(dPrMaxSq);
        if (dHitMinSq != 0)
            hitMin = hitMin / Mathf.Sqrt(dHitMinSq);
        if (dHitMaxSq != 0)
            hitMax = hitMax / Mathf.Sqrt(dHitMaxSq);
        if ((hitMax <= projMin) || (projMax <= hitMin))
            isHit = false;
        if ((Mathf.Abs(projMax - hitMin) < EPS) || (Mathf.Abs(hitMax - projMin) < EPS))
            isHit = false;
        //determine exit vector here
        float moveAng = Mathf.Atan2(moveVec.y, moveVec.x);
        float angDiff = Mathf.Abs(moveAng - (dir - Mathf.PI / 2));
        if (angDiff > Mathf.PI)
            angDiff = Mathf.Abs(angDiff - Mathf.PI * 2);
        moveDist = 0;
        if (isHit)
        {
            if (angDiff < Mathf.PI / 2) //moveVector in direction of exit vector
                moveDist = -Mathf.Abs(hitMax - projMin);
            else
                moveDist = Mathf.Abs(projMax - hitMin);
        }
        moveVec.x = moveDist * Mathf.Cos(dir - Mathf.PI / 2);
        moveVec.y = moveDist * Mathf.Sin(dir - Mathf.PI / 2);

        return moveVec;
    }
예제 #2
0
    protected bool ColDetect(Ninja plr)
    {
        if (gameWon) {

        if(Input.anyKey){
                Application.LoadLevel ("menu");
                foreach (GameObject o in Object.FindObjectsOfType<GameObject>()) {
                    Destroy(o);}
                Application.LoadLevel ("menu");
            }
        return false;
        }

        bool hitflag=false;
        int polyIndex = -1;//to keep record of which polygon caused the collision
        int hitIndex = -1;//to keep record of which side of the polygon caused collision
        SPoint[] plBox, plLast;
        bool retFlag=false;//holds the return value
        //this loads plBox[] and plLast[] with the player's hitboc this
        //and last frame respectively
        int hbLen=4;
        SPoint posDiff = new SPoint(plr.GetPos().x-plr.GetLastPos().x, plr.GetPos().y-plr.GetLastPos().y);
        if(posDiff.SqDistFromOrigin()!=0){
            plBox = plr.GetCurrentColBox();
            plLast=plr.GetCurrentColBox();
            hbLen = 6;
            for(int i=0;i<hbLen;i++){
                plLast[i].x-=posDiff.x;
                plLast[i].y-=posDiff.y;
            }
        }else{
            plBox = plr.GetHitBox();
            plLast=plr.GetHitBox();
            hbLen=4;
        }
        if((plr.GetPos().x>9)&&(plr.GetPos().x-posDiff.x<9))
            hbLen= hbLen;

        SPoint hld;
        float[] plAng = new float[hbLen];
        for(int i=0;i<hbLen-1;i++){
            plAng[i]= new SPoint(plBox[i].x-plBox[i+1].x,plBox[i].y-plBox[i+1].y).GetDir();
        }
        plAng[hbLen-1] = new SPoint(plBox[hbLen-1].x-plBox[0].x,plBox[hbLen-1].y-plBox[0].y).GetDir();
        // FillCollisionBox(plBox, plr->GetPos(), plr->stats.size.y, plr->stats.size.x);
        // FillCollisionBox(plLast, plr->stats.motion.lastPos, plr->stats.size.y, plr->stats.size.x);
        //set up angles here for easy acces along with the hitboxes above.

        for(int i = 0; i < tBox.iLength; i++){
            hitflag = true;//assume true, then prove false.
            for(int j = 0; j < tBox.GetJlength(i); j++)
            if(!plr.CheckAxis(tBox.GetSPoint(i, j), tBox.GetAng(i, j), plBox,tBox.pBounds[i], hbLen, tBox.jLength[i])){ //no axis intersection
                hitflag = false;
                j=tBox.GetJlength(i);//exit loop early
            }
            if(hitflag)//possible collision; check against other polygon axise
            for(int j = 0; j < hbLen; j++){
                if(!plr.CheckAxis(plBox[j], plAng[j], plBox, tBox.pBounds[i], hbLen, tBox.jLength[i])){ //no axis intersection
                    hitflag = false;
                    j=hbLen;//exit loop early
                }
            }
            if(hitflag){//all checks are done, collision is sure
                polyIndex = i;//keep record of the last polygon caused the flag
                i=tBox.iLength;//Collision detected, end loop early
            }

        }

        SPoint prV=new SPoint();
        SPoint pCtr;

                //extra added to detect and destroy any projectiles on-screen
        int cv;
        bool pHitFlag = true;

        float flAng = 1.55f;
        if(polyIndex!=-1){
            //hitflag = true;//force to true to return
            retFlag=true;
            //see which side has collided
            for(int i = 0; i < tBox.GetJlength(polyIndex); i++){
                if(!plr.CheckAxis(tBox.GetSPoint(polyIndex, i), tBox.GetAng(polyIndex, i), plLast, tBox.pBounds[polyIndex], hbLen, tBox.jLength[polyIndex])){
                    hitIndex = i;
                    i=tBox.GetJlength(polyIndex);//end loop prematurely
                }
            }
            bool pAxisFlag=false;
            if(hitIndex == -1){
                for(int i  = 0; i < hbLen; i++){//check player angs to find the axis
                    if(!plr.CheckAxis(plLast[i], plAng[i], plLast, tBox.pBounds[polyIndex], hbLen, tBox.jLength[polyIndex]) ){
                        hitIndex = i;
                        pAxisFlag = true;
                    }
                }//do collision detection again for this particular index on the polygon
            }//to get the exit vector

            SPoint axP = new SPoint();
            if(hitIndex>=0){

                if (!pAxisFlag){//using poly axis
                    axP = ExitDist(polyIndex, tBox.GetSPoint(polyIndex, hitIndex), tBox.GetAng(polyIndex, hitIndex), plr, 0);
                    flAng=tBox.GetAng(polyIndex, hitIndex);
                                       }
                else{//using player axis
                    axP = ExitDist(polyIndex, plBox[hitIndex], plAng[hitIndex], plr, 0);

                    flAng=plAng[hitIndex];
                }

                if ((axP.x == 0) && (axP.y == 0))
                {
                polyIndex = polyIndex;// V-jank fix, add a check to get this answer in the first place
                    axP = ExitDist(polyIndex, tBox.GetSPoint(polyIndex, hitIndex+2), tBox.GetAng(polyIndex, hitIndex+2), plr, 0);
                }
            }else
                retFlag=false;
            if (polyIndex == 2)
                polyIndex = 2;
            if (polyIndex == 1)
                polyIndex = 1;
            plr.stats.motion.pos.x+=axP.x;
            plr.stats.motion.pos.y+=axP.y;
            //for walking
            float axAng = Mathf.Atan2(axP.y, axP.x);
            float wallAng = Mathf.Atan2(plr.GetVel().y, plr.GetVel().x);
            float wallDist = Mathf.Sqrt(Mathf.Pow(plr.GetVel().x, 2) + Mathf.Pow(plr.GetVel().y, 2) );
            wallAng -= axAng;

            //separate cases for wall collision
            //depend on whether player is tumbling

            //non-reounding

                if((axAng>0)&&(axAng < Mathf.PI))
                    plr.Land(flAng);
                plr.stats.motion.vel.x -= Mathf.Cos(wallAng)*wallDist*Mathf.Cos(axAng);
                plr.stats.motion.vel.y -= Mathf.Cos(wallAng)*wallDist*Mathf.Sin(axAng);
            if (( Mathf.Abs(  Mathf.Abs(axAng) - Mathf.PI )< 0.1f) && (plr.fHelper.airborne))
                plr.WallHang(axAng);
            else if  ((Mathf.Abs(axAng) < 0.1f) && (plr.fHelper.airborne))
                    plr.WallHang(axAng);

        }

        if ((!plr.fHelper.airborne)&&(!retFlag)&&(!plr.tPortFlag))
            if(!GroundTrack(plr))//ground tracking done here
                plr.Fall();

        if((plr.GetPos().x > uBound.x)||(plr.GetPos().y > uBound.y)||(plr.GetPos().x < lBound.x)||(plr.GetPos().y < lBound.y)){
            if((plr.stats.stocks>0)||(!matchModeOn)){
            //SetPlStart(plr);
            plr.stats.stocks--;
            plr.stats.motion.vel = new SPoint(0,0);
            plr.stats.damage=0;}
        }
        if (retFlag)
            ColDetect (plr);
        return retFlag;
    }
예제 #3
0
    public SPoint ExitDistN(int iInd, SPoint origin, float dir, Ninja plr, int ifGrab)
    {
        // helper function for the Separating Axis Theorem that takes an axis defined by origin and dir
        //re-conditioned to handle the parameters of the attack box
        bool isHit = true;
        float projMin, projMax, hitMin, hitMax, distSq, projVal, cVal;
        float dHitMinSq = 1000;
        float dHitMaxSq = 0;
        float dPrMinSq = 1000;
        float dPrMaxSq = 0;
        SPoint projVec, nVec, rVec, cVec;
        projVec = new SPoint();
        SPoint moveVec = new SPoint();
        projMin = STAGE_LIMIT;
        projMax = -STAGE_LIMIT;
        hitMin = STAGE_LIMIT;
        hitMax = -STAGE_LIMIT;
        moveVec.x = plr.GetPos().x - plr.GetLastPos().x;
        moveVec.y = plr.GetPos().y - plr.GetLastPos().y;
        SPoint[] plBox;
        int hbLen = 4;
        if (ifGrab < 0)
        {//implies groundCheck
            plBox = plr.GetHitBox();
            hbLen = 4;
        }
        else
        {
            plBox = plr.GetCurrentColBox();
            hbLen = 6;
        }

        for (int i = 0; i < tBox.GetJlength(iInd); i++)
        {
            projVec.x = tBox.GetSPoint(iInd, i).x - origin.x;
            projVec.y = tBox.GetSPoint(iInd, i).y - origin.y;

            distSq = projVec.x * projVec.x + projVec.y * projVec.y;
            nVec = projVec.GetNormal();

            cVec = new SPoint(Mathf.Cos(dir + Mathf.PI / 2), Mathf.Sin(dir + Mathf.PI / 2));

            cVal = -cVec.Dot(nVec);
            //projVal = sin(rAng)*abs(sin(rAng))*distSq;
            projVal = cVal * Mathf.Abs(cVal) * distSq;

            if (projVal < projMin){
                projMin = projVal;
                dPrMinSq = distSq;
            }
            if (projVal > projMax) {
                projMax = projVal;
                dPrMaxSq = distSq;
            }
        }
        if (dPrMinSq != 0)
            projMin = projMin / Mathf.Sqrt(dPrMinSq);
        if (dPrMaxSq != 0)
            projMax = projMax / Mathf.Sqrt(dPrMaxSq);
        if (dHitMinSq != 0)
            hitMin = hitMin / Mathf.Sqrt(dHitMinSq);
        if (dHitMaxSq != 0)
            hitMax = hitMax / Mathf.Sqrt(dHitMaxSq);
        for (int i = 0; i < hbLen; i++)
        {
            projVec.x = plBox[i].x - origin.x;
            projVec.y = plBox[i].y - origin.y;
            distSq = projVec.x * projVec.x + projVec.y * projVec.y;
            cVec = new SPoint(Mathf.Cos(dir + Mathf.PI / 2), Mathf.Sin(dir + Mathf.PI / 2));
            nVec = projVec.GetNormal();
            cVal = -cVec.Dot(nVec);
            //projVal = sin(rAng)*abs(sin(rAng))*distSq;
            projVal = cVal * Mathf.Abs(cVal) * distSq;
            if (projVal < hitMin){
                hitMin = projVal;
                dHitMinSq = distSq;
            }if (projVal > hitMax){
                hitMax = projVal;
                dHitMaxSq = distSq;
            }
        }
        if ((hitMax <= projMin) || (projMax <= hitMin))
            isHit = false;
        if ((Mathf.Abs(projMax - hitMin) < EPS) || (Mathf.Abs(hitMax - projMin) < EPS))
            isHit = false;

        //determine exit vector here
        float moveAng = Mathf.Atan2(moveVec.y, moveVec.x);
        float angDiff = Mathf.Abs(moveAng - (dir - Mathf.PI/2)) ;
        if(angDiff > Mathf.PI)
            angDiff = Mathf.Abs(angDiff - Mathf.PI*2);
        float moveDist=0;
        if(isHit){
            if(angDiff < Mathf.PI/2) //moveVector in direction of exit vector
                moveDist = -Mathf.Abs(hitMax - projMin)/2;
            else
                moveDist = Mathf.Abs(projMax - hitMin)/2;
        }
        moveVec.x = moveDist*Mathf.Cos(dir - Mathf.PI/2);
        moveVec.y = moveDist*Mathf.Sin(dir - Mathf.PI/2);
        if(!isHit){
            moveVec.x = 0;
            moveVec.y = 0;
        }

        return moveVec;
    }