Пример #1
0
    public virtual void AttackDetect(Ninja plr)
    {
        bool multiHitFlag = false;
        string hitText;
        //std::stringstream log;
        bool hitflag = true;
        int atkLen;
        int spI=0;
        int spJ=0;
        int hbLen=4;
        SPoint[] plBox;
        SPoint[][] spBox;
        float[] plAng ={0, Mathf.PI/2, Mathf.PI, -Mathf.PI/2};
        int il = 0;

            il = attackBox.trackList[fHelper.atkType].iLength;//num of tracks
        AttkTrack aBox = new AttkTrack();

        int polyHit=-1;
        plBox = plr.GetHitBox();//loads victim hitbox into plBox
        //each side is made from the vertices [i] and [+1]
        int numPoly = 0; //number of polygons in a track;
        int pInd = 0;//polygon index
        SPoint[] pHdr = new SPoint[8];

        il = 1;
        if(!atkTmr.IsReady()){//only continue if an attack is out

            //attack checks

            for(int t=0;t<il;t++){//iterate through all sub tr

                //if(plr.CharName().CompareTo("PsySword")==0)
                //	int ds=2;//checkpt
                if((fHelper.seqInd!=0)&&((fHelper.seqInd-1)!=t)){
                    hitflag=false;//do nothing, for now
                }else {
                    aBox= new AttkTrack();
                    aBox.noHit=false;
                        if(attackBox.trackList[fHelper.atkType].trackType==AttkBox.FLASH){
                            if(fHelper.frame>lastFlash){

                                for(AttkVtx av = attackBox.trackList[fHelper.atkType].aVtx[0][0]; av!=null;av=av.next){
                                    if((av.frame==lastFlash)&&(av.next!=null)){
                                        lastFlash=av.next.frame;
                                        attackBox.flashAtkRdy=true;
                                        attackBox.ResetHits (fHelper.atkType);
                                        while(av.next!=null)
                                            av=av.next;
                                        //av=null;//force exit
                                    }
                                }
                            }
                        }
                    attackBox.FetchFrame(fHelper.atkType, atkTmr.GetLen(), fHelper.frame, t, new SPoint(GetPos().x, GetPos().y), fHelper.IsFacingRight(), aBox);//fetches frame into aBox

                        //aBox has its polygons separated into different tracks for efficiency
                    //make a new SPoint array, spBox, to use checkAxis.

                    hitflag=true;
                    if(aBox.noHit==false){

                        //if(plr.CharName().CompareTo("PsySword")==0)
                        //	int d2s=2;//checkpt
                        spBox=new SPoint[aBox.iLength][];
                        for(int i=0;i<aBox.iLength;i++)
                            spBox[i]=new SPoint[aBox.jLength[i]];
                        aBox.FetchSPArr(spBox);
                            if(ClashCheck(plr, spBox, aBox.atkAng)){
                            SPoint p1Vel = new SPoint(GetPos().x - plr.GetPos().x, GetPos().y - plr.GetPos().y).GetNormal();
                            float cRat = 0.2f;
                            stats.motion.vel.x = p1Vel.x*cRat;
                            stats.motion.vel.y = p1Vel.y*cRat;
                            plr.stats.motion.vel.x = -p1Vel.x*cRat;
                            plr.stats.motion.vel.y = -p1Vel.y*cRat;
                            fHelper.airborne = true;
                            plr.fHelper.airborne = true;
                            return;
                            }

                        numPoly=aBox.iLength;
                            bool hitCheck = false;
                        for(pInd=0;pInd<numPoly;pInd++){//iterate per poly
                                hitflag=true;
                            atkLen =  aBox.GetJlength(pInd);
                            for(int j = 0; j < atkLen; j++)
                                if(!CheckAxis(aBox.aVtx[pInd][j].pos, aBox.atkAng[pInd][j], plBox, spBox[pInd], hbLen, aBox.GetJlength(pInd)) ) //no axis intersection
                                    hitflag = false;

                            if(hitflag)//test on the axis of the player hit box to confirm
                                for(int j = 0; j < 4; j++)
                                    if(!CheckAxis(plBox[j], plAng[j], plBox, spBox[pInd], hbLen, aBox.GetJlength(pInd))) //no axis intersection
                                        hitflag = false;
                            if(hitflag)
                                    hitCheck=true;

                        }
                            hitflag=hitCheck;
                        //log.str(std::string());
                        /*	for(int i=0;i<aBox.iLength;i++){//tidy up
                            if(!aBox.noHit)
                                delete [] spBox[i];
                        }
                        if(aBox.iLength==0){
                            int ee = 2;
                            //log.str(std::string());
                        }
                        else if(!aBox.noHit){//make sure it was hit
                            if(aBox.iLength>1)
                                delete [] spBox;
                            else
                                delete spBox;
                            spBox=NULL;
                        }*/
                    }else
                        hitflag=false;//abandon
                    if(hitflag){
                        AttkData retOb  = new AttkData(aBox.GetJlength(t));//initilize for holding vals
                        Attack(plr, t, aBox, retOb);
                        if(!retOb.noHit){

                            plr.GetHit(retOb);
                            multiHitFlag=true;
                            t=il;//force exit; one track hit
                        }

                    }

                }
            }
        }
        //seems the ideal place to determine pushback
        //if the difference in z is less than their average width
        if((Mathf.Abs(plr.GetPos().x-GetPos().x) < (plr.stats.size.x+stats.size.x)/2  )
           &&(Mathf.Abs(plr.GetPos().y-GetPos().y) < (plr.stats.size.y+stats.size.y)/2)
           &&(!fHelper.airborne)&&(!plr.fHelper.airborne))
        if(plr.GetPos().x-GetPos().x>0){
            stats.motion.move.x-=0.1f;
            plr.stats.motion.move.x+=0.1f;}
        else{
            stats.motion.move.x+=0.1f;
            plr.stats.motion.move.x-=0.1f;}
    }
Пример #2
0
    protected virtual void Attack(Ninja plr,int tr, AttkTrack aBox, AttkData data)
    {
        //pHit is a bool array of flags that tell whether a sub-poly held collision
        //aBox is a modified track taken from current frame
        //plr is the player hit
        //check pnum else we cut Serenuity's sword
        if((plr.stats.id.num<100)&&(attackBox.trackList[fHelper.atkType].hit[tr][plr.stats.id.num])){//if this attack was recorded already
            data.noHit=true; //flag so this does not trigger impact
            return;//don't hit again
        }
        attackBox.trackList[fHelper.atkType].hit[tr][plr.stats.id.num]=true;

        bool isInBox=false;
        bool vNextInBox=false;
        AttkVtx iVt;
        bool[] cornerFlag = new bool[4];
        SPoint[] hb = plr.GetHitBox();// double[4]
        for(int i=0;i<4;i++){
            cornerFlag[i]=true;
            hb[i].x = hb[i].x-GetPos().x;//translate to origin
            hb[i].y = hb[i].y-GetPos().y;
        }
        bool emptyFlag = true;
        bool fullFlag =true;//assume true, disprove by counterexample
        SPoint vPos = new SPoint ();
        SPoint opp = new SPoint();
        int vNext,vLast,jl, il;
        float nX, nY, lY=0, lX=0, vX, vY, ppX, ppY, ph2, pw2, diDist,vDir, vDmg, vMag, vWgt = 0;
        //add poitional value (for wgt=0) into data
        opp.x=plr.GetPos().x-GetPos().x;//used to store the centerpoint
        if(fHelper.IsFacingRight())      //for input into data
            opp.x-=(aBox.centre.pos.x);
        else
            opp.x+=(aBox.centre.pos.x);
        opp.y=plr.GetPos().y-GetPos().y+aBox.centre.pos.y;
        data.SetAVals(opp);
        il = aBox.iLength;
        //set data.abds as an sPoint holding the vertices for aBox.vtx
        //this is done purely for debug rendering
        //which will later handle 'data'
        data.aBds = new SPoint[il][];
        for(int j=0;j<il;j++){
            data.aBds[j] = new SPoint[aBox.GetJlength(j)];
            for(int i=0;i<aBox.GetJlength(j);i++)
                data.aBds[j][i] = new SPoint(aBox.aVtx[j][i].pos.x-GetPos().x, aBox.aVtx[j][i].pos.y-GetPos().y);
        }

        emptyFlag=true;
        fullFlag=true;
        ph2 = plr.stats.size.y/2;
        pw2 = plr.stats.size.x/2;
        ppX = plr.GetPos().x;
        ppY = plr.GetPos().y+ph2;
        for(int i=0;i<4;i++)//assume true then prove false
            cornerFlag[i]=true;
        for(int p=0; p<aBox.iLength;p++){
            jl = aBox.GetJlength(p);
            for(int v = 0; v < jl;v++){//loop through the second index
                vPos = aBox.aVtx[p][v].pos;//use this vertex to check whether it falls
                if((Mathf.Abs(vPos.x-ppX)<pw2)&&(Mathf.Abs(vPos.y-ppY)<ph2))// within hitbox
                    emptyFlag = false;//can't be empty
                else
                    fullFlag = false;//can't be full
            }
            if(fullFlag){
                for(int v = 0; v < jl;v++){
                    int before = v-1;
                    if(before<0)
                        before=jl-1;
                    diDist = Mathf.Sqrt(Mathf.Pow(aBox.aVtx[p][before].pos.x-aBox.aVtx[p][v].pos.x, 2) + Mathf.Pow(aBox.aVtx[p][before].pos.y-aBox.aVtx[p][v].pos.y, 2));
                    vMag = aBox.aVtx[p][v].mag;
                    vDir = aBox.aVtx[p][v].dir;
                    vDmg = aBox.aVtx[p][v].dmg;
                    vWgt = aBox.aVtx[p][v].wgt;
                    data.addVal(aBox.aVtx[p][v].pos, vMag, vDir, diDist, vDmg, vWgt);
                    for(int i=0;i<4;i++)
                        cornerFlag[i]=false;//none possible to be included
                }
            }
            else if(emptyFlag){
                for(int j = 0;j<jl;j++){
                    diDist=1;
                    vMag = aBox.aVtx[p][j].mag;
                    vDir = aBox.aVtx[p][j].dir;
                    vDmg = aBox.aVtx[p][j].dmg;
                    vWgt = aBox.aVtx[p][j].wgt;
                    vPos = aBox.aVtx[p][j].pos;
                    vPos.x-=GetPos().x;
                    vPos.y-=GetPos().y;
                    data.addVal(vPos, vMag, vDir, diDist, vDmg, vWgt);
                }
            }
            else
            for(int v = 0; v < jl;v++){
                vNext = (v+1)%jl;//circular array
                vPos = aBox.aVtx[p][vNext].pos;
                vNextInBox = ((Mathf.Abs(vPos.x-ppX)<pw2)&&(Mathf.Abs(vPos.y-ppY)<ph2));
                vLast=v-1;
                if(vLast<0)
                    vLast=jl-1;
                vMag = aBox.aVtx[p][v].mag;
                vDir = aBox.aVtx[p][v].dir;
                vDmg = aBox.aVtx[p][v].dmg;
                vWgt = aBox.aVtx[p][v].wgt;
                vPos = aBox.aVtx[p][v].pos;
                vX = aBox.aVtx[p][v].pos.x-GetPos().x;//all values translated to origin
                vY = aBox.aVtx[p][v].pos.y-GetPos().y;
                if(v==0){
                    lX=vX;//mustdefine these ahead of time
                    lY=vY;//so the first dir is properly averaged
                }     //in case the loop below is not entered
                if((Mathf.Abs(vPos.x-ppX)<pw2)&&(Mathf.Abs(vPos.y-ppY)<ph2)){//within the victim's hitbox
                    diDist = Mathf.Sqrt( (lX-vX)*(lX-vX) + (lY-vY)*(lY-vY));
                    data.addVal(new SPoint(vX, vY), vMag, vDir, diDist, vDmg, vWgt);
                    lX=vX;
                    lY=vY;
                    if(!vNextInBox){
                        iVt = InterpVert(aBox.aVtx[p][v], aBox.aVtx[p][vNext], plr);
                        iVt.pos.x-=GetPos().x;//all values translated to origin
                        iVt.pos.y-=GetPos().y;
                        diDist = Mathf.Sqrt(Mathf.Pow(iVt.pos.x-vX, 2)+Mathf.Pow(iVt.pos.y-vY, 2));
                        data.addVal(iVt.pos, iVt.mag, iVt.dir, diDist, iVt.dmg, iVt.wgt);
                        lX=iVt.pos.x;
                        lY=iVt.pos.y;
                    }
                }
                else {
                    if(vNextInBox){
                        iVt = InterpVert(aBox.aVtx[p][vNext], aBox.aVtx[p][v], plr);
                        iVt.pos.x-=GetPos().x;//all values translated to origin
                        iVt.pos.y-=GetPos().y;
                        diDist = Mathf.Sqrt(Mathf.Pow(iVt.pos.x-lX, 2)+Mathf.Pow(iVt.pos.y-lY, 2));
                        data.addVal(iVt.pos, iVt.mag, iVt.dir, diDist, iVt.dmg, iVt.wgt);
                        lX=iVt.pos.x;
                        lY=iVt.pos.y;
                    }
                }
                for(int i = 0; i<4;i++){//check player corner axis
                    vX = aBox.aVtx[p][v].pos.x-GetPos().x-hb[i].x;//all values translated to origin
                    vY = aBox.aVtx[p][v].pos.y-GetPos().y-hb[i].y;
                    nX = aBox.aVtx[p][vNext].pos.x-GetPos().x-hb[i].x;
                    nY = aBox.aVtx[p][vNext].pos.y-GetPos().y-hb[i].y;
                    if((fHelper.IsFacingRight())&&(nX*vY-vX*nY<0))//second part is a shortcut formula
                        cornerFlag[i]=false;
                    else if((!fHelper.IsFacingRight())&&(nX*vY-vX*nY>0))
                        cornerFlag[i]=false;
                }
            }
            //last step; add corners that retained their flag
            if(emptyFlag){//for now ; TODO: add case later
                for(int i=0;i<4;i++)
                if(cornerFlag[i]){
                    iVt = InterpCorner(aBox.aVtx[p], aBox.GetJlength(p), plr.GetPos());
                    iVt.pos.x-=GetPos().x;//all values translated to origin
                    iVt.pos.y-=GetPos().y;
                    diDist = Mathf.Sqrt(Mathf.Pow(iVt.pos.x-lX, 2)+Mathf.Pow(iVt.pos.y-lY, 2));
                    data.addVal(iVt.pos, iVt.mag, iVt.dir, diDist, iVt.dmg,iVt.wgt);
                    lX=iVt.pos.x;
                    lY=iVt.pos.y;
                }
            }
        }

        data.rollIntoAvg();
        if (attackBox.trackList [fHelper.atkType].isVacuum) {
            data.isVacuum=true;
        }

        data.SetConOrigin(aBox.centre.pos);
        data.PlayerHitBoxInput(hb);
    }
Пример #3
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;
    }
Пример #4
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;
    }
Пример #5
0
    public bool GroundTrack(Ninja plr)
    {
        //specialized collision detection function
        //ensures the Ninja keeps flush with the floor
        bool hitflag = true;
        bool indflag = true;
        bool pAxisFlag = false;
        float hitInd = -1;
        int polyIndex = -1;
        SPoint[] plBox = new SPoint[4];
        SPoint[] plLast = new SPoint[4];
        for(int i=0;i<4;i++){
            plBox[i]=new SPoint();
            plLast[i]=new SPoint();
        }
        float[] plAng = {0, Mathf.PI/2, Mathf.PI, -Mathf.PI/2};
        int hbLen=4;

                //modified from colision detect to move the player down

        FillCollisionBox(plBox, new SPoint(plr.GetPos().x, plr.GetPos().y-plr.stats.size.y/2), plr.stats.size.y, plr.stats.size.x);
        FillCollisionBox(plLast, new SPoint(plr.GetPos().x, plr.GetPos().y+plr.stats.size.y/2), plr.stats.size.y, plr.stats.size.x);
        //holds default angles

        for(int i = 0; i < tBox.iLength; i++){
            hitflag = true;
            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;
            if(hitflag)
                for(int j = 0; j < 4; j++)
                    if(!plr.CheckAxis(plBox[j], plAng[j], plBox,tBox.pBounds[i], hbLen, tBox.jLength[i]) ) //no axis intersection
                        hitflag = false;
            if(hitflag)
                polyIndex = i;
        }
        int hitIndex = -1;
        if(polyIndex >= 0){
            hitflag = true;
            float moveDist = 0;
            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;
                }
            }
            if(hitIndex == -1){
                //check player angs to find the axis
                for(int i  = 0; i < 4; i++){
                    if(!plr.CheckAxis(plLast[i], plAng[i], plLast, tBox.pBounds[polyIndex], hbLen, tBox.jLength[polyIndex]) ){
                        hitIndex = i;
                        pAxisFlag = true;
                    }
                }
            }

            bool floorHit = false;
            SPoint floorVec=new SPoint(0,0);
            plr.stats.motion.pos.y-=plr.stats.size.y/2;
            if(!pAxisFlag)
                floorVec = ExitDist(polyIndex, tBox.GetSPoint(polyIndex, hitIndex), tBox.GetAng(polyIndex, hitIndex), plr, -1);
            else
                floorVec = ExitDist(polyIndex, plBox[hitIndex], plAng[hitIndex], plr, -1);
            float wallAng = Mathf.Atan2(floorVec.y, floorVec.x)-Mathf.PI/2;
            float wallDist=Mathf.Sqrt(floorVec.SqDistFromOrigin());
            if((floorVec.x==0)&&(floorVec.y==0))
                plr.stats.motion.pos.y+=plr.stats.size.y/2;
            else if(Mathf.Cos(wallAng)!=0){
                plr.stats.motion.pos.y+=(wallDist)/Mathf.Cos(wallAng);
                floorHit=true;
            }
            else{
                plr.stats.motion.pos.y+=plr.stats.size.y/2;
                floorHit=true;
            }
            if((floorHit)&&(!plr.fHelper.airborne)){
                plr.Land(tBox.GetAng(polyIndex, hitIndex));

                return true;
            }
        }
        return false;
    }
Пример #6
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;
    }