//Write the state that each AI agent is currently in to the left of the screen private void DrawAIState(Graphics displayDevice) { Physics.Vector2D drawLocation = new Physics.Vector2D(10, 10); foreach (AI.AIEngine AIbrain in mAImanager.aiControllers) { //setup the string to be written string currentState = "NULL"; switch (AIbrain.currentState) { case AI.STATES.WAITING: currentState = "waiting"; break; case AI.STATES.WALKING: currentState = "walking"; break; case AI.STATES.JUMPING: currentState = "jumping"; break; case AI.STATES.FALLING: currentState = "falling"; break; } //write the string mRenderer.Draw(currentState, drawLocation, displayDevice); //update the position to draw to drawLocation.Y += 20; } }
//Draw a red eight pointed star of lines around the provided position public void DrawAISpawn(Physics.Vector2D position, Graphics g) { //offset is the distance between the centre and the outer edges of the star float offset = 20.0f; float halfOffset = offset / 2.0f; Color starColour = Color.Red; //create the 8 points of the pentagram Physics.Vector2D point1, point2, point3, point4, point5, point6, point7, point8; point1 = position + new Physics.Vector2D(-halfOffset, -offset); point2 = position + new Physics.Vector2D(halfOffset, -offset); point3 = position + new Physics.Vector2D(-offset, -halfOffset); point4 = position + new Physics.Vector2D(offset, -halfOffset); point5 = position + new Physics.Vector2D(-offset, halfOffset); point6 = position + new Physics.Vector2D(offset, halfOffset); point7 = position + new Physics.Vector2D(-halfOffset, offset); point8 = position + new Physics.Vector2D(halfOffset, offset); //draw lines between the 8 points DrawLine(point1, point6, g, starColour); DrawLine(point6, point5, g, starColour); DrawLine(point5, point2, g, starColour); DrawLine(point2, point8, g, starColour); DrawLine(point8, point3, g, starColour); DrawLine(point3, point4, g, starColour); DrawLine(point4, point7, g, starColour); DrawLine(point7, point1, g, starColour); }
//return the node from the lowest level that is closest to the specified location public Node GetNearestNode(Physics.Vector2D point) { //If this node is at the lowest depth then return it if (internalNodes == null || internalNodes.Count == 0) { return(this); } Node nearestNode = internalNodes[0].GetNearestNode(point); Node tempNode; //get the nearest point from each child node and return the one which is closest to the specified point foreach (Node n in internalNodes) { tempNode = n.GetNearestNode(point); float currentDistance = (GetNodePosition(nearestNode) - point).Length(); float newDistance = (GetNodePosition(tempNode) - point).Length(); if (currentDistance > newDistance) { nearestNode = tempNode; } } return(nearestNode); }
//Draw a given point as a circle with radius 3, with colour Azure public void Draw(Physics.Vector2D point, Graphics g) { Physics.RigidBody temp = new Physics.RigidBody(); temp.SetPosition(point); temp.Shape = new Physics.Circle(3); temp.Shape.mColor = Color.Azure; Draw(temp, g); }
//Draw a line between two points with a specified colour public void DrawLine(Physics.Vector2D p1, Physics.Vector2D p2, Graphics g, Color chosenColour) { mPen.Color = chosenColour; mPen.EndCap = System.Drawing.Drawing2D.LineCap.NoAnchor; g.DrawLine(mPen, new Point((int)p1.X + (int)cameraLocation.X, (int)p1.Y + (int)cameraLocation.Y), new Point((int)p2.X + (int)cameraLocation.X, (int)p2.Y + (int)cameraLocation.Y)); }
//Draw an arrow between two points with the default colour of LightSteelBlue public void DrawArrow(Physics.Vector2D p1, Physics.Vector2D p2, Graphics g) { mPen.Color = Color.LightSteelBlue; mPen.EndCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor; g.DrawLine(mPen, new Point((int)p1.X + (int)cameraLocation.X, (int)p1.Y + (int)cameraLocation.Y), new Point((int)p2.X + (int)cameraLocation.X, (int)p2.Y + (int)cameraLocation.Y)); }
public float GetHeuristic(Physics.Vector2D destination) { //Apply a simple euclidean distance heuristic //Intended to give nodes a higher cost the further they are from the final goal //If a different destination node is used as an argument then this heuristic may work better or worse WorldGraph mainGraph = WorldGraph.GetWorldGraph(); Physics.Vector2D currentPosition = mainGraph.topLevelNode.GetNodePosition(index); return((currentPosition - destination).Length() * 10); }
//move left/right towards the destination node. //if hard deceleration would result in overshooting the destination, decelerate. //This is to stop the AI from going too fast and driving off the edge of a platform private void stepWalking(float dt) { if (destinationNode == null) { return; } Physics.Vector2D displacement = mainGraph.topLevelNode.GetNodePosition(destinationNode) - AIPlayer.playerBody.Position; //Get the direction of the displacement (-1 = dest is to the left) float sign = displacement.X / Math.Abs(displacement.X); //Get the displacement if the AI were to hard brake float naturalDisplacement = Physics.SuvatEquations.SFromUVA(AIPlayer.playerBody.LinearVelocity.X, 0.0f, AIPlayer.GetHorizontalAcceleration()) * -1; float currentDirectionOfMotion = 1; //force natural displacement to be positive if (AIPlayer.playerBody.LinearVelocity.X != 0) { currentDirectionOfMotion = AIPlayer.playerBody.LinearVelocity.X / Math.Abs(AIPlayer.playerBody.LinearVelocity.X); } naturalDisplacement *= currentDirectionOfMotion; //If the displacement with deceleration results in overshooting, slow down if (displacement.X * sign < naturalDisplacement * sign) { //decelerate if (sign > 0) { actionPlan.Add(new act_dur((int)ACTIONS.MOVE_LEFT, 0.0f)); } else { actionPlan.Add(new act_dur((int)ACTIONS.MOVE_RIGHT, 0.0f)); } } else { //if travelling the wrong way, or travelling below walkingSpeed, accelerate towards the destination if (currentDirectionOfMotion != sign || Math.Abs(AIPlayer.playerBody.LinearVelocity.X) < walkingSpeed) { if (sign < 0) { actionPlan.Add(new act_dur((int)ACTIONS.MOVE_LEFT, 0.0f)); } else { actionPlan.Add(new act_dur((int)ACTIONS.MOVE_RIGHT, 0.0f)); } } else { actionPlan.Add(new act_dur((int)ACTIONS.DO_NOTHING, 0.0f)); } } }
//convert a coordinate into it's corresponding node public Node GetNodeAtPoint(Physics.Vector2D point) { Node temp = topLevelNode.GetNearestNode(point); //if the node is not close enough to the specified point then return null if ((topLevelNode.GetNodePosition(temp) - point).Length() > 25) { return(null); } return(temp); }
public UI() { //initialise everything message = "Climb the tower!"; livesLeft = 12; timeRunning = 0.0f; messageColour = Color.Black; messageLocation = new Physics.Vector2D(GlobalConstants.WINDOW_WIDTH / 2.0f, 20); timerLocation = new Physics.Vector2D(GlobalConstants.WINDOW_WIDTH - 160, 50); livesLocation = new Physics.Vector2D(GlobalConstants.WINDOW_WIDTH - 160, 100); }
public SimpleRenderer() { mBrush = new SolidBrush(Color.Black); mPen = new Pen(Color.Black, 4); mPen.Alignment = System.Drawing.Drawing2D.PenAlignment.Center; //Note: requires the Arial font to be installed for the game to run mFont = new Font("Arial", 16); //Camera location defaults to 0,0 cameraLocation = new Physics.Vector2D(); }
//spawn an AI at a given coordinate public void AddAIAt(Physics.Vector2D spawnLocation) { if (aiControllers.Count < MAX_AI_COUNT) { Physics.Player newAIPlayer = new Physics.Player(); newAIPlayer.playerBody.type = Physics.RBTypes.ENEMY; newAIPlayer.playerBody.SetPosition(spawnLocation); physEng.addRigidBody(newAIPlayer.playerBody); aiControllers.Add(new AI.AIEngine(newAIPlayer)); aiGraphManager.AddAIagent(); } }
//create a net moving away from the player along the vector from the player to the mouse public void FireNet(Physics.Vector2D worldSpaceMouse) { if (currentState == GAMESTATE.RUNNING) { //get the direction of motion Physics.Vector2D direction = (worldSpaceMouse - thePlayer.playerBody.Position).Normalised(); //get the distance from the centre of the player the centre of the net will be spawned float spawnDistFromPlayer = 20.0f; //create the net thePhysicsEngine.addNet(new Physics.DynamicNet((direction * spawnDistFromPlayer) + thePlayer.playerBody.Position, direction * thePlayer.gunForce)); } }
//use logic similar to stepWalking, move towards the destination X //the intent is to approximate the velocity needed to fall in a straight line to the destination //this is done by determining if the AI is going faster or slower than the intended line //then the AI is accelerated or decelerated towards this line private void stepFalling(float dt) { //note that destination node is determined based on straight line distance //this function would be improved if it's destination was chosen from the list of destinations it is capable of falling to if (destinationNode == null) { return; } Physics.Vector2D displacement = mainGraph.topLevelNode.GetNodePosition(destinationNode) - AIPlayer.playerBody.Position; //Get the direction of the displacement (-1 = dest is to the left) float sign = displacement.X / Math.Abs(displacement.X); float fallDuration = Physics.SuvatEquations.TfromSUA(displacement.Y, AIPlayer.playerBody.LinearVelocity.Y, physEng.gravity.Y).Item1; float currentDisplacement = Physics.SuvatEquations.SfromUAT(AIPlayer.playerBody.LinearVelocity.X, 0.0f, fallDuration) * -1; float currentDirectionOfMotion = 1; if (AIPlayer.playerBody.LinearVelocity.X != 0) { currentDirectionOfMotion = AIPlayer.playerBody.LinearVelocity.X / Math.Abs(AIPlayer.playerBody.LinearVelocity.X); } currentDisplacement *= currentDirectionOfMotion; //If the displacement with acceleration results in undershooting, then accelerate if (displacement.X * sign > currentDisplacement * sign) { if (sign < 0) { actionPlan.Add(new act_dur((int)ACTIONS.MOVE_LEFT, 0.0f)); } if (sign > 0) { actionPlan.Add(new act_dur((int)ACTIONS.MOVE_RIGHT, 0.0f)); } } //else decelerate else { if (sign > 0) { actionPlan.Add(new act_dur((int)ACTIONS.MOVE_LEFT, 0.0f)); } if (sign < 0) { actionPlan.Add(new act_dur((int)ACTIONS.MOVE_RIGHT, 0.0f)); } } }
public Node(Physics.Vector2D aPosition, NodeIndex nodeIndex, NODE_TYPE nodeType) { type = nodeType; index = new NodeIndex(nodeIndex); connections = new List <Connection>(); internalNodes = new List <Node>(); lastDestinations = new List <NodeIndex>(); lastOrigins = new List <NodeIndex>(); lastPaths = new List <List <NodeIndex> >(); position = aPosition; }
//check all dynamic objects for collisions against dynamic and static objects, then resolve them public void updateCollisions() { //Check collisions of all dynamic objects for (int i = dynamicPhysicsObjects.Count - 1; i >= 0; i--) { Physics.RigidBody a = dynamicPhysicsObjects[i]; //against other dynamic objects for (int j = dynamicPhysicsObjects.Count - 1; j >= 0; j--) { if (i != j) { Physics.RigidBody b = dynamicPhysicsObjects[j]; if (a.Shape.IsCollided(b.Shape, a.Position, b.Position)) { Physics.Vector2D normal = a.Shape.GetCollisionNormal(b.Shape, a.Position, b.Position); Physics.CollisionPairData pair = new Physics.CollisionPairData(); pair.BodyA = a; pair.BodyB = b; pair.ContactNormal = normal; mCollisionResponder.AddCollisionPair(pair); } } } //and against all static objects for (int j = staticPhysicsObjects.Count - 1; j >= 0; j--) { Physics.RigidBody b = staticPhysicsObjects[j]; if (a.Shape.IsCollided(b.Shape, a.Position, b.Position)) { Physics.Vector2D normal = a.Shape.GetCollisionNormal(b.Shape, a.Position, b.Position); Physics.CollisionPairData pair = new Physics.CollisionPairData(); pair.BodyA = a; pair.BodyB = b; pair.ContactNormal = normal; mCollisionResponder.AddCollisionPair(pair); } } mCollisionResponder.ResolveAllPairs(playerCharacter); } }
//Use the current set of inputs to apply various forces to the player public void step(float dt) { Physics.Vector2D appliedForce = new Vector2D(); //apply forces to the left and right if (controls[(int)CONTROLS.RIGHT]) { appliedForce.X += motionForce; } if (controls[(int)CONTROLS.LEFT]) { appliedForce.X -= motionForce; } //apply a jump if the player is on the ground if (OnGround() && controls[(int)CONTROLS.UP]) { //create the jump vector Physics.Vector2D temp = playerBody.collisionNormal; temp.X *= -jumpInitialVelocity; temp.Y = jumpInitialVelocity; //apply the jump to the velocity playerBody.LinearVelocity += temp; controls[(int)CONTROLS.UP] = false; } else if (controls[(int)CONTROLS.DOWN]) { //speed up the player's fall appliedForce.Y += gravityAssistForce; } //update the player's force to include these input forces playerBody.SetForce(playerBody.Force + appliedForce); //update all cooldowns if (gunReload > 0.01f) { gunReload -= dt; } if (collisionCooldown > 0.0f) { collisionCooldown -= dt; } }
//The following four methods determine AI activity during each state //When waiting, move towards the current node. //If a jump is possible from the node but the AI is slightly off and cannot jump, moving towards the node should move the AI to a position from which the jump is possible private void stepWaiting(float dt) { if (currentNode == null) { return; } Physics.Vector2D displacement = mainGraph.topLevelNode.GetNodePosition(currentNode) - AIPlayer.playerBody.Position; if (displacement.X < 0) { actionPlan.Add(new act_dur((int)ACTIONS.MOVE_LEFT, 0.0f)); } else { actionPlan.Add(new act_dur((int)ACTIONS.MOVE_RIGHT, 0.0f)); } }
public DebugDisplay(Physics.Player thePlayer, AI.AIManager aManager, SimpleRenderer aRender) { //get references to the useful game classes playerCharacter = thePlayer; mAImanager = aManager; physEng = Physics.PhysicsEngine.GetPhysicsEngine(); AIgraph = AI.WorldGraph.GetWorldGraph(); mRenderer = aRender; //initialise the bools showCurrentPlayerJump = false; showNodes = false; showPath = false; showJumpRange = false; showFallRange = false; showJumpBoxCollisions = false; showFallBoxCollisions = false; showCollisionNormals = false; showLocalNodes = -1; jumpDestination = null; }
//given a rigidbody, create its node and its child nodes, then return its node public static Node CreateNodesFromRB(Physics.RigidBody theRB, NodeIndex parentIndex, int localIndex) { //create the node for the rigidbody Node rigidBody = new Node(theRB.Position, new NodeIndex(parentIndex, localIndex), NODE_TYPE.RIGIDBODY); //this temporary position is used to place the child nodes Physics.Vector2D nodePosition = new Physics.Vector2D(); nodePosition.Y = theRB.Shape.ComputeAABB().MIN.Y - (Physics.Player.playerRadius + 1); //Create the leftmost fall node nodePosition.X = theRB.Shape.ComputeAABB().MIN.X - (Physics.Player.playerRadius + 1); rigidBody.AddNode(new Node(new Physics.Vector2D(nodePosition), new NodeIndex(rigidBody.index, rigidBody.internalNodes.Count), NODE_TYPE.FALL)); //Move the node position so it is not above a sheer drop nodePosition.X = theRB.Shape.ComputeAABB().MIN.X + (Physics.Player.playerRadius / 2); //Create the regular nodes an even distance apart float surfaceWidth = theRB.Shape.ComputeAABB().MAX.X - theRB.Shape.ComputeAABB().MIN.X; int numberOfNodes = (int)(surfaceWidth / (Physics.Player.playerRadius * 2) + 0.5); float step = (surfaceWidth - Physics.Player.playerRadius) / numberOfNodes; for (int i = 0; i <= numberOfNodes; ++i) { rigidBody.AddNode(new Node(new Physics.Vector2D(nodePosition), new NodeIndex(rigidBody.index, rigidBody.internalNodes.Count), NODE_TYPE.FLOOR)); nodePosition.X += step; } //Create the rightmost fall node nodePosition.X = theRB.Shape.ComputeAABB().MAX.X + (Physics.Player.playerRadius + 1); rigidBody.AddNode(new Node(new Physics.Vector2D(nodePosition), new NodeIndex(rigidBody.index, rigidBody.internalNodes.Count), NODE_TYPE.FALL)); return(rigidBody); }
//find the path to the goal from a given position //the AI index is used to cache each AI's path for quick lookup public void GeneratePathToCurrentGoal(int aiAgentIndex, Physics.Vector2D start) { if (paths == null || paths.Count <= aiAgentIndex) { return; } Node startNode = topLevelNode.GetNearestNode(start); Node endNode = topLevelNode.GetNearestNode(goalCoords); if (startNode == null || endNode == null) { return; } List <NodeIndex> temp = topLevelNode.GetPath(aiAgentIndex, startNode.index, endNode.index, topLevelNode); //update the ai's path to the path retreived from the nodes paths[aiAgentIndex].Clear(); if (temp != null) { paths[aiAgentIndex] = new List <NodeIndex>(temp); } }
//check to see if the player could jump or fall between the provided nodes private static CONNECTION_TYPE GetConnectionBetween(NODE_TYPE sourceNodeType, NODE_TYPE destNodeType, Physics.Vector2D sourceNodePosition, Physics.Vector2D destinationNodePosition) { //a fall node should never be the destination of a jump or a fall, just the sourcepoint for a fall if (destNodeType == NODE_TYPE.FALL) { return(CONNECTION_TYPE.NONE); } Physics.Player examplePlayer = new Physics.Player(); Physics.PhysicsEngine physEng = Physics.PhysicsEngine.GetPhysicsEngine(); //if a fall connection is possible, return it if ((sourceNodeType == NODE_TYPE.FALL || sourceNodeType == NODE_TYPE.WALL) && physEng.CanPlayerFallFromTo(examplePlayer, sourceNodePosition, destinationNodePosition)) { return(CONNECTION_TYPE.FALL); } //if a jump connection is possible, return it if ((sourceNodeType == NODE_TYPE.FLOOR || sourceNodeType == NODE_TYPE.WALL) && physEng.CanPlayerJumpFromTo(examplePlayer, sourceNodePosition, destinationNodePosition)) { return(CONNECTION_TYPE.JUMP); } return(CONNECTION_TYPE.NONE); }
//draw the provided text with the default colour of black public void Draw(string textToDisplay, Physics.Vector2D position, Graphics g) { Draw(textToDisplay, position, g, Color.Black); }
public void Draw(string textToDisplay, Physics.Vector2D position, Graphics g, Color chosenColour) { mBrush.Color = chosenColour; g.DrawString(textToDisplay, mFont, mBrush, position.X, position.Y); }
public void AddSpawnLocation(Physics.Vector2D newLocation) { AISpawnLocations.Add(newLocation); }
//Draw a line with the default colour LightSteelBlue public void DrawLine(Physics.Vector2D p1, Physics.Vector2D p2, Graphics g) { DrawLine(p1, p2, g, Color.LightSteelBlue); }
public void SetJumpDestination(Physics.Vector2D newDest) { jumpDestination = newDest; }
//the same as the above method but for falling //this method is effectively just copy/pasted from Player.FallCollidesWithRB() with modifications to display the results private void DrawFallCullingPoints(Graphics displayDevice) { Physics.RigidBody temp = new Physics.RigidBody(); temp.Shape = new Physics.Circle(3); temp.Shape.mColor = Color.OrangeRed; //store the start and endpoints of the fall Physics.Vector2D source = playerCharacter.playerBody.Position; Physics.Vector2D destination = jumpDestination; if (destination == null) { destination = new Physics.Vector2D(0, 0); } Physics.Vector2D displacement = destination - source; Tuple <float, float> timeToFall = Physics.SuvatEquations.TfromSUA(displacement.Y, 0.0f, 98); if (timeToFall == null) { return; } if (float.IsNaN(timeToFall.Item1) && float.IsNaN(timeToFall.Item2)) { return; } //calculate the acceleration needed to fall to the destination float acceleration = Physics.SuvatEquations.AfromSUT(displacement.X, 0.0f, Math.Max(timeToFall.Item1, timeToFall.Item2)); //calculate the four points where the path defined by acceleration could potentially collide with the rigidbody Tuple <float, float> timeToReach; float leftmostX; float leftmostY; float righttmostX; float righttmostY; float topY; float topX; float bottomY; float bottomX; //draw the points where the fall arc could collide with each rigidbody foreach (Physics.RigidBody RB in physEng.staticPhysicsObjects) { //obtain the X positions of the sides of the rigidbody leftmostX = (RB.Position.X + RB.Shape.ComputeAABB().MIN.X) - source.X; righttmostX = (RB.Position.X + RB.Shape.ComputeAABB().MAX.X) - source.X; //obtain the Y positions of the top and bottom of the rigidbody topY = (RB.Position.Y + RB.Shape.ComputeAABB().MIN.Y) - source.Y; bottomY = (RB.Position.Y + RB.Shape.ComputeAABB().MAX.Y) - source.Y; //calculate the time to reach the left side of the rigidbody timeToReach = Physics.SuvatEquations.TfromSUA(leftmostX, 0.0f, acceleration); //calculate the first Y position, draw the first point, calculate the second, draw the second point leftmostY = Physics.SuvatEquations.SfromUAT(0.0f, 98, timeToReach.Item1); if (!float.IsNaN(leftmostY)) { mRenderer.Draw(temp, displayDevice); temp.SetPosition(new Physics.Vector2D(leftmostX, leftmostY) + source); } leftmostY = Physics.SuvatEquations.SfromUAT(0.0f, 98, timeToReach.Item2); if (!float.IsNaN(leftmostY)) { mRenderer.Draw(temp, displayDevice); temp.SetPosition(new Physics.Vector2D(leftmostX, leftmostY) + source); } //calculate the time to reach the right side of the rigidbody timeToReach = Physics.SuvatEquations.TfromSUA(righttmostX, 0.0f, acceleration); //calculate the first Y position, draw the first point, calculate the second, draw the second point righttmostY = Physics.SuvatEquations.SfromUAT(0.0f, 98, timeToReach.Item1); if (!float.IsNaN(righttmostY)) { mRenderer.Draw(temp, displayDevice); temp.SetPosition(new Physics.Vector2D(righttmostX, righttmostY) + source); } righttmostY = Physics.SuvatEquations.SfromUAT(0.0f, 98, timeToReach.Item2); if (!float.IsNaN(righttmostY)) { mRenderer.Draw(temp, displayDevice); temp.SetPosition(new Physics.Vector2D(righttmostX, righttmostY) + source); } //calculate the time to reach the top of the rigidbody timeToReach = Physics.SuvatEquations.TfromSUA(topY, 0.0f, 98); //calculate the first X position, draw the first point, calculate the second, draw the second point topX = Physics.SuvatEquations.SfromUAT(0.0f, acceleration, timeToReach.Item1); if (!float.IsNaN(topX)) { mRenderer.Draw(temp, displayDevice); temp.SetPosition(new Physics.Vector2D(topX, topY) + source); } topX = Physics.SuvatEquations.SfromUAT(0.0f, acceleration, timeToReach.Item2); if (!float.IsNaN(topX)) { mRenderer.Draw(temp, displayDevice); temp.SetPosition(new Physics.Vector2D(topX, topY) + source); } //calculate the time to reach the bottom of the rigidbody timeToReach = Physics.SuvatEquations.TfromSUA(bottomY, 0.0f, 98); //calculate the first X position, draw the first point, calculate the second, draw the second point bottomX = Physics.SuvatEquations.SfromUAT(0.0f, acceleration, timeToReach.Item1); if (!float.IsNaN(bottomX)) { mRenderer.Draw(temp, displayDevice); temp.SetPosition(new Physics.Vector2D(bottomX, bottomY) + source); } bottomX = Physics.SuvatEquations.SfromUAT(0.0f, acceleration, timeToReach.Item2); if (!float.IsNaN(bottomX)) { mRenderer.Draw(temp, displayDevice); temp.SetPosition(new Physics.Vector2D(bottomX, bottomY) + source); } } }
//draw the jump arc of a specified player to a specified destination //if specified destination is null then draw the jump assuming the player jumped with no acceleration or deceleration //This function is useful for debugging the "Player.GetJumpFromSourceToDest()", "Player.GetJumpYFromX()", and "Player.GetJumpXFromY()" methods private void DrawJumpArc(Graphics displayDevice, Physics.Player thePlayer, Physics.Vector2D goal) { //a temporary variable used in draw calls Physics.RigidBody temp = new Physics.RigidBody(); //stores how long the player accelerates after hitting jump float accelerationTime = 0.0f; //if a goal was specified // calculate the amount of time the player would need to accelerate after jumping in order to reach the goal // draw the goal point if (goal != null) { accelerationTime = thePlayer.GetJumpFromSourceToDest(thePlayer.playerBody.Position, goal, physEng.gravity); //draw the goal temp.Shape = new Physics.Circle(6); temp.Shape.mColor = Color.Purple; temp.SetPosition(goal); mRenderer.Draw(temp, displayDevice); } //set the object to be drawn to a circle of radius 3 temp.Shape = new Physics.Circle(3); //Temporary variable used to store the coordinates returned from the GetJumpYFromX() and GetJumpXFromY() methods Tuple <Physics.Vector2D, Physics.Vector2D> resultingPoints; //loop through the 1200 X coordinates around the player, calculating the Y position of the jump at that point //Draw a circle at each combined X,Y coordinate in Green temp.Shape.mColor = Color.Green; for (int i = -600; i < 600; i += 1) { //Get the two possible X,Y coords of the jump given a specific X coord resultingPoints = thePlayer.GetJumpYFromX(thePlayer.playerBody.Position, accelerationTime, 15.0f, physEng.gravity, thePlayer.playerBody.Position.X - i); //draw any valid returned coordinates if (resultingPoints.Item1 != null) { temp.SetPosition(resultingPoints.Item1); mRenderer.Draw(temp, displayDevice); } if (resultingPoints.Item2 != null) { temp.SetPosition(resultingPoints.Item2); mRenderer.Draw(temp, displayDevice); } } //loop through the 1200 Y coordinates around the player, calculating the X position of the jump at that point //Draw a circle at each combined X,Y coordinate in red temp.Shape.mColor = Color.OrangeRed; for (int i = -600; i < 600; i += 10) { //Get the two possible X,Y coords of the jump given a specific Y coord resultingPoints = thePlayer.GetJumpXFromY(thePlayer.playerBody.Position, accelerationTime, 15.0f, physEng.gravity, thePlayer.playerBody.Position.Y - i); //draw any valid returned coordinates if (resultingPoints.Item1 != null) { temp.SetPosition(resultingPoints.Item1); mRenderer.Draw(temp, displayDevice); } if (resultingPoints.Item2 != null) { temp.SetPosition(resultingPoints.Item2); mRenderer.Draw(temp, displayDevice); } } }
public NodeOnRails(Node coreNode, Physics.Vector2D point1, Physics.Vector2D point2) : base(coreNode) { railPoint1 = point1; railPoint2 = point2; }