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; }
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; }