public override void Update(Paddle playerPaddle, Paddle opponentPadde, Puck puck, float deltaTime) { playerPaddle.velocity = (clientToView(mouseX(), mouseY()) - playerPaddle.position) / deltaTime; // string toSend = userName + ":\n" + tbSend.Text; var data = Encoding.ASCII.GetBytes(playerPaddle.position.X.ToString() + ' ' + playerPaddle.position.Y + ' ' + playerPaddle.velocity.X.ToString() + ' ' + playerPaddle.velocity.Y.ToString()); client.Send(data, data.Length); }
public NewGame(ref GameApplication Application) { this.Application = Application; this.Game = this; this.CPU = new CPU(ref this.Application, ref this.Game); this.GameState = GameState.Running; this.Player = new Player(ref this.Application, ref this.Game); this.Puck = new Puck(ref this.Application, ref this.Game); this.Scoreboard = new Scoreboard(ref this.Application); this.StopWatch = new Stopwatch(); this.Table = new Table(ref this.Application, ref this.Game); }
public override void Update(Paddle playerPaddle, Paddle opponentPaddle, Puck puck, float deltaTime) { 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 be small when we are really close... playerPaddle.velocity = trajectory * ((target - playerPaddle.position).GetLength() - Constants.puckRadius - Constants.paddleRadius) / deltaTime; } }
public bool PaddlePositionCorrection(int player, Puck puck, Paddle[] paddles) { Vector2 diff = puck.position - paddles[player].position; float sumRadii = Constants.paddleRadius + Constants.puckRadius; if (diff.GetLengthSquared() < sumRadii * sumRadii) { // since the paddle is treated as almost infinite mass, the impules equations just becomes the reflection equation with some restitution. Vector2 normal; float length = diff.GetLength(); if (length > 0.001f) { normal = diff / length; } else { normal = new Vector2(0, 0); } Vector2 relativeVelocity = puck.velocity - paddles[player].velocity; float j = -(1.0f + Constants.paddleRestitution) * Vector2.Dot(relativeVelocity, normal); puck.position += normal * (sumRadii - length); // position correction, move out of overlap, TODO: add an epsilon? if (j > 0) // never move towards the collison object { puck.velocity += normal * j; } if (puck.velocity.GetLength() > Constants.maxPuckSpeed) { puck.velocity = Constants.maxPuckSpeed * puck.velocity / puck.velocity.GetLength(); } return true; } return false; }
public AppWindow() : base(640/2, 1136/2) { viewWidth = 4.5f; viewHeight = 9.0f; puck = new Puck(); puck.position = new Vector2(0.0f, 0.0f); puck.velocity = new Vector2(0, 0); paddles = new Paddle[2]; paddles[0] = new Paddle(); paddles[1] = new Paddle(); paddles[0].position = new Vector2(0.0f, -0.7f); paddles[1].position = new Vector2(0.0f, 0.7f); renderer = new Renderer(); renderer.MediaPath = mediaPath; renderer.Viewport(Width, Height); renderer.OrthoCentered(viewWidth, viewHeight); startMenu = new StartMenu(renderer, this); gameOverMenu = new GameOverMenu(renderer, this); opponentPlayer = new LANGameOpponentPlayer(); physics = new Physics(); soundEngine = new ISoundEngine(); networking = new Networking(); //networking.InitializeReceiver(); //networking.InitializeSender(); // networking.StartGameSearch(); //networking.UpdateReceiver = ReceiveUpdate; localPlayer = new LANGameLocalPlayer(() => MouseX, () => MouseY, ClientToView, IPAddress.Parse("192.168.1.108")); }
/// <summary> /// Allows the game to perform any initialization it needs to before starting to run. /// This is where it can query for any required services and load any non-graphic /// related content. Calling base.Initialize will enumerate through any components /// and initialize them as well. /// </summary> protected override void Initialize() { // TODO: Add your initialization logic here var menu = new MainMenu(this); this.Components.Add(menu); var pitch = new Pitch(this); this.Components.Add(pitch); GameMode = AirHockey.GameMode.Menu; PlayerTouchBinder binder = new PlayerTouchBinder(); _player1 = new Player(this, PlayerNumber.Player1, binder); _player2 = new Player(this, PlayerNumber.Player2, binder); _puck = new Puck(this); var collideables = new Collection<ICollidable>(); collideables.Add(_player1); collideables.Add(_player2); collideables.Add(_puck); _collisionManager = new CollisionManager(this, collideables); this.Components.Add(_player1); this.Components.Add(_player2); this.Components.Add(_puck); _player1ScorePosition = new Vector2(GraphicsDevice.Viewport.Width / 2 - 10, 0); _player2ScorePosition = new Vector2(GraphicsDevice.Viewport.Width / 2 + 10, 0); _messageP1Position = new Vector2(GraphicsDevice.Viewport.Width / 2 - 100, GraphicsDevice.Viewport.Height / 2); _messageP2Position = new Vector2(GraphicsDevice.Viewport.Width / 2 + 100, GraphicsDevice.Viewport.Height / 2); InitialiseToNewGameState(); base.Initialize(); }
public int PositionCorrection(Puck puck, Paddle[] paddles) { float epsilon = 0.0001f; bool collision; // if there is a collision from both the paddle and the table, the puck is being squeezed between the two. // the contact get set to the table collision, it's better to have some puck/paddle overlap than to have the puck go off the screen and break the game. //TODO: should I collision correct the puck and prevent all overlap?? if(PaddlePositionCorrection(0, puck, paddles)) { collision = true; } if (PaddlePositionCorrection(1, puck, paddles)) { collision = true; } if (puck.position.X + Constants.puckRadius > Constants.tableWidth * 0.5f) { puck.position.X = Constants.tableWidth * 0.5f - Constants.puckRadius + epsilon; puck.velocity.X = -puck.velocity.X * Constants.tableRestitution; collision = true; } if (puck.position.X - Constants.puckRadius < -Constants.tableWidth * 0.5f) { puck.position.X = -Constants.tableWidth * 0.5f + Constants.puckRadius - epsilon; puck.velocity.X = -puck.velocity.X * Constants.tableRestitution; collision = true; } if (puck.position.Y + Constants.puckRadius > Constants.tableHeight * 0.5f) { if (puck.position.X > Constants.goalWidth * 0.5f - Constants.puckRadius|| puck.position.X < -Constants.goalWidth * 0.5f + Constants.puckRadius) { puck.position.Y = Constants.tableHeight * 0.5f - Constants.puckRadius + epsilon; puck.velocity.Y = -puck.velocity.Y * Constants.tableRestitution; collision = true; } else if (puck.position.Y - Constants.puckRadius > Constants.tableHeight * 0.5f) // let the puck get inside the goal before showing the score. { return 0; } } if (puck.position.Y - Constants.puckRadius < -Constants.tableHeight * 0.5f) { if (puck.position.X > Constants.goalWidth * 0.5f - Constants.puckRadius || puck.position.X < -Constants.goalWidth * 0.5f + Constants.puckRadius) { puck.position.Y = -Constants.tableHeight * 0.5f + Constants.puckRadius - epsilon; puck.velocity.Y = -puck.velocity.Y * Constants.tableRestitution; collision = true; } 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; }
bool FindFirstContact(Paddle[] paddles, Puck puck, float deltaTime, out Contact contact, out int paddle) { contact = new Contact(); contact.time = float.PositiveInfinity; contact.collisionType = PhysicsResult.NoCollision; float contactTime; Vector2 normal; paddle = -1; if(SweepCircles(puck.position, Constants.puckRadius, puck.velocity, paddles[0].position, Constants.paddleRadius, paddles[0].velocity, deltaTime, out contactTime, out normal)) { contact.normal = normal; contact.time = contactTime; contact.restitution = Constants.paddleRestitution; contact.relativeVelocity = puck.velocity - paddles[0].velocity; contact.collisionType = PhysicsResult.PuckPaddleCollision; paddle = 0; } if (SweepCircles(puck.position, Constants.puckRadius, puck.velocity, paddles[1].position, Constants.paddleRadius, paddles[1].velocity, deltaTime, out contactTime, out normal)) { if (contactTime < contact.time) { contact.normal = normal; contact.time = contactTime; contact.restitution = Constants.paddleRestitution; contact.relativeVelocity = puck.velocity - paddles[1].velocity; contact.collisionType = PhysicsResult.PuckPaddleCollision; paddle = 1; } } if(SweepCircleEdge(puck.position.X, Constants.puckRadius, puck.velocity.X, -Constants.tableWidth * 0.5f, deltaTime, out contactTime)) { if(contactTime < contact.time) { contact.normal = new Vector2(1, 0); contact.time = contactTime; contact.restitution = Constants.tableRestitution; contact.relativeVelocity = puck.velocity; contact.collisionType = PhysicsResult.PuckTableCollision; } } if (SweepCircleEdge(puck.position.X, Constants.puckRadius, puck.velocity.X, Constants.tableWidth * 0.5f, deltaTime, out contactTime)) { if (contactTime < contact.time) { contact.normal = new Vector2(-1, 0); contact.time = contactTime; contact.restitution = Constants.tableRestitution; contact.relativeVelocity = puck.velocity; contact.collisionType = PhysicsResult.PuckTableCollision; } } // see if the the puck is going to hit a goal, if so don't sweep float t = (-Constants.tableHeight * 0.5f + Constants.puckRadius - puck.position.Y) / puck.velocity.Y; float x = puck.position.X + puck.velocity.X * t; if (x > Constants.goalWidth * 0.5f - Constants.puckRadius || x < -Constants.goalWidth * 0.5f + Constants.puckRadius) { if (SweepCircleEdge(puck.position.Y, Constants.puckRadius, puck.velocity.Y, -Constants.tableHeight * 0.5f, deltaTime, out contactTime)) { if (contactTime < contact.time) { contact.normal = new Vector2(0, 1); contact.time = contactTime; contact.restitution = Constants.tableRestitution; contact.relativeVelocity = puck.velocity; contact.collisionType = PhysicsResult.PuckTableCollision; } } } t = (Constants.tableHeight * 0.5f - Constants.puckRadius - puck.position.Y) / puck.velocity.Y; x = puck.position.X + puck.velocity.X * t; if (x > Constants.goalWidth * 0.5f - Constants.puckRadius || x < -Constants.goalWidth * 0.5f + Constants.puckRadius) { if (SweepCircleEdge(puck.position.Y, Constants.puckRadius, puck.velocity.Y, Constants.tableHeight * 0.5f, deltaTime, out contactTime)) { if (contactTime < contact.time) { contact.normal = new Vector2(0, -1); contact.time = contactTime; contact.restitution = Constants.tableRestitution; contact.relativeVelocity = puck.velocity; contact.collisionType = PhysicsResult.PuckTableCollision; } } } if (contact.time <= deltaTime) return true; return false; }
public PhysicsResult Update(Puck puck, Paddle[] paddles, float deltaTime) { PhysicsResult result = PhysicsResult.NoCollision; ClampPaddlePosition(paddles, 0); ClampPaddlePosition(paddles, 1); const float epsilon = 0.9990f; // don't actually touch Contact contact; int numIterations = 0; // to prevent infinite loops when squeezed int paddle; if (puck.velocity.GetLength() > Constants.maxPuckSpeed) { puck.velocity = Constants.maxPuckSpeed * puck.velocity / puck.velocity.GetLength(); } while(FindFirstContact(paddles, puck, deltaTime, out contact, out paddle) && numIterations < 10) { // since the paddle is treated as almost infinite mass, the impules equations just becomes the reflection equation with some restitution. result = contact.collisionType; deltaTime -= contact.time; puck.position += puck.velocity * (contact.time * epsilon); paddles[0].position += paddles[0].velocity * (contact.time * epsilon); paddles[1].position += paddles[1].velocity * (contact.time * epsilon); if(paddle != -1) // TODO: keep this? prevents all overlap except is cases where the puck is squeezed between 2 objects. paddles[paddle].velocity = new Vector2(0, 0); float j = -(1.0f + contact.restitution) * Vector2.Dot(contact.relativeVelocity, contact.normal); if (j > 0) // never move towards the collison object, should never happen but just in case. { puck.velocity += contact.normal * j; } if (puck.velocity.GetLength() > Constants.maxPuckSpeed) { puck.velocity = Constants.maxPuckSpeed * puck.velocity / puck.velocity.GetLength(); } numIterations++; } puck.position += puck.velocity * deltaTime; int p = PositionCorrection(puck, paddles); if (p == 0) return PhysicsResult.BottomPlayerScores; if (p == 1) return PhysicsResult.TopPlayerScores; paddles[0].position += paddles[0].velocity * deltaTime; paddles[1].position += paddles[1].velocity * deltaTime; return result; }
public virtual void Update(Paddle playerPaddle, Paddle opponentPadde, Puck puck, float deltaTime) { }
public override void Update(Paddle playerPaddle, Paddle opponentPadde, Puck puck, float deltaTime) { playerPaddle.velocity = (clientToView(mouseX(), mouseY()) - playerPaddle.position) / deltaTime; }
public override void Update(Paddle playerPaddle, Paddle opponentPadde, Puck puck, float deltaTime) { playerPaddle.position = paddle.position; playerPaddle.velocity = paddle.velocity; }