public override bool collide(cCritter pcritter) { if (Position.distanceTo(pcritter.Position) < collideRadius) { pcritter.moveTo(pcritter.OldPosition); return(true); } return(false); }
public override bool collide(cCritter pCritter) { if (contains(pCritter)) //disk of pcritter is wholly inside my disk { pCritter.addHealth(-1); pCritter.moveTo(new cVector3(_movebox.Midx, _movebox.Loy + 1.0f, _movebox.Hiz - 3.0f)); return(true); } else { return(false); } }
public override cVector3 force(cCritter pcritter) { if (_pnode == null) { return(new cVector3(0.0f, 0.0f, 0.0f)); } if (pcritter.distanceTo(_pnode) < _rodlength) { pcritter.moveTo(_pnode.Position + _pnode.directionTo(pcritter) * _rodlength, true); /* The TRUE arg means * to allow the motion cause a change in pcritter's _tangent, _normal, etc. */ return(new cVector3(0.0f, 0.0f, 0.0f)); } return(_pnode.Position - pcritter.Position * _intensity); }
public override bool collide(cCritter pcritter) { if (contains(pcritter)) //disk of pcritter is wholly inside my disk { Framework.snd.play(Sound.Clap); pcritter.addScore(100); pcritter.addHealth(1); pcritter.moveTo(new cVector3(_movebox.Midx, _movebox.Loy + 1.0f, _movebox.Hiz - 3.0f)); return(true); } else { return(false); } }
/* Overload this so as not to change * velocity as I normally want my walls to be stable and not drift after being dragged. */ /// <summary> /// There's a collision if pcritter has crossed the wall or if the radius of pcritter is more than /// the pcritter's distance to the wall. Has code to prevent the pcritter from going through the wall. /// Returns true if a collision was detected and false otherwise. /// </summary> /// <param name="pcritter">The critter to test for a collision with the wall.</param> /// <returns></returns> public override bool collide(cCritter pcritter) { cVector3 oldlocalpos, newlocalpos; float newdistance; int oldoutcode, newoutcode; bool crossedwall; oldlocalpos = globalToLocalPosition(pcritter.OldPosition); oldoutcode = _pskeleton.outcode(oldlocalpos); newlocalpos = globalToLocalPosition(pcritter.Position); newdistance = _pskeleton.distanceToOutcode(newlocalpos, out newoutcode); //Sets the newoutcode as well. crossedwall = crossed(oldoutcode, newoutcode); if (newdistance >= pcritter.Radius && !crossedwall) //No collision { return(false); /*See if there's a collision at all. We * say there's a collision if crossedwall or if the * cCritterWall.distance is less than radius. Remember that * cCritterWall.distance measures the distance to the OUTSIDE * PERIMETER of the box, not the distance to the box's center. */ } /* I collided, so I need to move back further into the last good * zone I was in outside the wall. I want to set newlocalpos so * the rim of its critter is touching the wall. The idea is to back * up in the direction of oldlocalpos. To allow the possibility * of skidding along the wall, we plan to back up from the * the face (or edge or corner) facing oldlocalpos. This works * only if oldlocalpos was a good one, not inside the box. In * principle this should always be true, but some rare weird circumstance * (like a triple collsion) might mess this up, so we check for the * bad case before starting. */ if (oldoutcode == cRealBox3.BOX_INSIDE) //Note that this almost never happens. { cVector3 insidepos = new cVector3(); insidepos.copy(oldlocalpos); oldlocalpos -= pcritter.Tangent * _pskeleton.MaxSize; //Do a brutally large backup to get out of the box for sure. oldoutcode = _pskeleton.outcode(oldlocalpos); //Recalculate outcode at this new position. oldlocalpos = _pskeleton.closestSurfacePoint(oldlocalpos, oldoutcode, insidepos, cRealBox3.BOX_INSIDE, false); //Go to the closest surface point from there. oldoutcode = _pskeleton.outcode(oldlocalpos); //Recalculate outcode one more time to be safe. crossedwall = crossed(oldoutcode, newoutcode); //Recalculate crossedwall } /* I find that with this code, the mouse can drag things through walls, * so I do a kludge to block it by setting crossedwall to TRUE, this * affects the action of cRealBox.closestSurfacePoint, as modified * in build 34_4. */ if (pcritter.Listener is cListenerCursor) { crossedwall = true; //Don't trust the mouse listener. } newlocalpos = _pskeleton.closestSurfacePoint(oldlocalpos, oldoutcode, newlocalpos, newoutcode, crossedwall); /* This call to closestSurfacePoint will move the newlocal pos * from the far new side (or inside, or overlapping) of the box back to * the surface, usually on the old near side, edge, or corner given by * oldoutcode. This prevents going through the wall. * If oldoutcode is a corner position and you are in fact heading * towards a face near the corner, we used to bounce off the corner * even though visually you can see you should bounce off the * face. This had the effect of making a scooter player get hung up on * a corner sometimes. As of build 34_3, I'm moving the * newlocalpos to the newoutocode side in the case where oldlocalpos * is an edge or a corner, and where crossedwall isn't TRUE. I * have to force in a TRUE for the cCursorLIstener case. The USEJIGGLE * code below also helps keep non-player critters from getting stuck * on corners. */ //Now back away from the box. newoutcode = _pskeleton.outcode(newlocalpos); cVector3 avoidbox = _pskeleton.escapeVector(newlocalpos, newoutcode); newlocalpos += avoidbox * pcritter.Radius; newoutcode = _pskeleton.outcode(newlocalpos); pcritter.moveTo(localToGlobalPosition(newlocalpos), true); //TRUE means continuous motion, means adjust tangent etc. //Done with position, now change the velocity cVector3 localvelocity = globalToLocalDirection(pcritter.Velocity); cVector3 oldlocalvelocity = new cVector3(); oldlocalvelocity.copy(localvelocity); _pskeleton.reflect(localvelocity, newoutcode); /* I rewrote the reflect code on Feb 22, 2004 for VErsion 34_3, changing * it so that when you reflect off an edge or corner, you only bounce * the smallest of your three velocity components. Balls stll seem to * get hung up on the corner once is awhile. */ /* Now decide, depending on the pcritter's absorberflag and bounciness, * how much you want to use the new localvelocity vs. the * oldlocalvelocity. We decompose the new localvelocity into the * tangentvelocity parallel to the wall and the normalvelocity * away from the wall. Some pencil and paper drawings convince * me that the tangent is half the sum of the oldlocalvelocity * and the reflected new localvelocity. */ cVector3 tangentvelocity = (localvelocity + oldlocalvelocity) * 0.5f; cVector3 normalvelocity = localvelocity - tangentvelocity; float bouncefactor = 1.0f; if (pcritter.AbsorberFlag) { bouncefactor = 0.0f; } else { bouncefactor = pcritter.Bounciness; } localvelocity = tangentvelocity + normalvelocity * bouncefactor; /* Maybe the rotation should depend on the kind of edge or corner. * Right now let's just use critter's binormal. Don't to it * to the player or viewer as it's confusing. */ if (!(cRealBox3.isFaceOutcode(newoutcode)) && //edge or corner !(pcritter is cCritterViewer) && //not viewer !(pcritter is cCritterArmedPlayer)) //Not player. Note that cPlayer inherits from cCritterArmedPlayer, //so don't use cCritterPlayer as the base class here. { localvelocity.rotate(new cSpin( Framework.randomOb.randomReal( -cCritterWall.CORNERJIGGLETURN, cCritterWall.CORNERJIGGLETURN), //A random turn pcritter.Binormal)); //Around the critter's binormal localvelocity *= cCritterWall.CORNERJIGGLEKICK; //Goose it a little } pcritter.Velocity = localToGlobalDirection(localvelocity); return(true); }
public void Place(cCritter object1, int xcord, int ycord) { object1.moveTo(new cVector3(game.Border.Hix - ((xcord * width) + width / 2), 0, game.Border.Hiz - ((ycord * width) + width / 2))); }