public void Step(GameFrame gameFrame, float deltaTime) { Contact contact; float time; int numIterations = 0; // to prevent infinite loops when squeezed int maxIterations = 10; ApplyTurbulence(gameFrame, deltaTime); ClampVelocity(gameFrame); while (FindFirstContact(gameFrame.Paddles, gameFrame.Puck, deltaTime, out contact, out time) && numIterations < maxIterations) { deltaTime -= time * 0.999f; Integrate(gameFrame, time * 0.999f); //TODO: should ensure GapEpsilon seperation, this is arbitrary ResolveContact(gameFrame.Puck, contact); numIterations++; } // integrate the rest of the frame Integrate(gameFrame, deltaTime); ClampPaddlePosition(gameFrame.Paddles, 0); ClampPaddlePosition(gameFrame.Paddles, 1); PositionCorrection(gameFrame.Puck, gameFrame.Paddles); // apply drag gameFrame.Puck.velocity *= Constants.puckDrag; }
void Integrate(GameFrame gameFrame, float deltaTime) { foreach (Body body in gameFrame.Bodies) { body.position += body.velocity * deltaTime; } }
void ClampVelocity(GameFrame gameFrame) { if (gameFrame.Puck.velocity.GetLength() > Constants.maxPuckSpeed) { gameFrame.Puck.velocity = Constants.maxPuckSpeed * gameFrame.Puck.velocity / gameFrame.Puck.velocity.GetLength(); } }
void ApplyTurbulence(GameFrame gameFrame, float deltaTime) { //TODO: temp, make good Random rand = new Random(); int i = rand.Next(0, 100); float a = 3.14f * 2 * (float)i / 100.0f; Vector2 turbulence = new Vector2(MathFunctions.Cos(a), MathFunctions.Sin(a)) * deltaTime * 2; gameFrame.Puck.velocity += turbulence; }
public void Update(GameFrame gameFrame, float deltaTime) { Body playerPaddle = gameFrame.Paddles[1]; Body opponentPaddle = gameFrame.Paddles[0]; Body puck = gameFrame.Puck; thinkTimer += deltaTime; if (thinkTimer > 0.4) { thinkTimer = 0.0f; if (puck.position.Y < 0) // puck is on player side, move towards defensive position(close to goal). { state = AIState.Defense; } // else if (puck.velocity.Y < 0) // aiState = AIState.Defense; // else if ((puck.position - paddles[1].position).Y + Constants.puckRadius + Constants.paddleRadius > 0) // aiState = AIState.Defense; else { state = AIState.Attack; } } Vector2 trajectory; if (state == AIState.Defense) { target = new Vector2(0, 0.4f * Constants.tableHeight); target.X += puck.position.X; } else { target = puck.position + new Vector2(0, Constants.puckRadius * 0.6f); // try to hit near the top but a little inside } trajectory = target - playerPaddle.position; trajectory.Normalize(); playerPaddle.velocity = trajectory * speed; // don't overshoot target if (speed * deltaTime > (target - playerPaddle.position).GetLength() - Constants.puckRadius - Constants.paddleRadius && state == AIState.Defense) { //TODO: this is wrong, the impulse should not necessarily be small when we are really close... playerPaddle.velocity = trajectory * ((target - playerPaddle.position).GetLength() - Constants.puckRadius - Constants.paddleRadius) / deltaTime; } }
public int CheckForScore(GameFrame gameFrame) { Body puck = gameFrame.Puck; if (puck.position.Y - Constants.puckRadius > Constants.tableHeight * 0.5f) // let the puck get inside the goal before showing the score. { return(0); } else if (puck.position.Y + Constants.puckRadius < -Constants.tableHeight * 0.5f) // let the puck get inside the goal before showing the score. { return(1); } return(-1); }
public PlayingState(StateManager stateManager, ISoundEngine soundEngine, Renderer renderer, ResourceManager resourceManager) : base(stateManager) { physics = new Physics(); contacts = new List <Physics.Contact>(); physics.Collision += (sender, contact) => { if (contact.collider == Collider.Paddle) { soundEngine.Play2D(ResourceManager.MediaPath + "puckHitPaddle.wav"); contacts.Add(contact); } if (contact.collider == Collider.Table) { soundEngine.Play2D(ResourceManager.MediaPath + "puckHitWall.wav"); contacts.Add(contact); } }; tableGraphicsObject = new Visual( GeometryFactory.CreateBox( new Box2(-Constants.tableWidth * 0.5f, Constants.tableHeight * 0.5f, Constants.tableWidth * 0.5f, -Constants.tableHeight * 0.5f)), new TextureEffect("table.png")); puckGraphicsObject = new Visual( GeometryFactory.CreateCircle(Constants.puckRadius, new Color4(1, 0, 0, 1)), new VertexColorEffect()); paddleGraphicsObjects = new Visual[2]; paddleGraphicsObjects[0] = new Visual( GeometryFactory.CreateCircle(Constants.paddleRadius, new Color4(1, 1, 1, 1)), new VertexColorEffect()); paddleGraphicsObjects[1] = new Visual( GeometryFactory.CreateCircle(Constants.paddleRadius, new Color4(1, 1, 1, 1)), new VertexColorEffect()); gameFrame = new GameFrame(); ai = new AIPlayer(); }