Beispiel #1
0
        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);
        }
Beispiel #2
0
        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;
            }
        }
Beispiel #3
0
        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;
        }
Beispiel #4
0
        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"));
        }
Beispiel #5
0
        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;
        }
Beispiel #6
0
        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;
        }
Beispiel #7
0
        //player 0 is on bottom, player 1 on top
        void ClampPaddlePosition(Paddle[] paddles, int player)
        {
            float radius = Constants.paddleRadius;
            float epsilon = 0.0001f;

            if (player == 0)
            {
                if (paddles[player].position.Y - radius * Constants.centerLineOverlap > 0)
                {
                    paddles[player].position.Y = radius * Constants.centerLineOverlap + epsilon;
                    if (paddles[player].velocity.Y > 0)
                        paddles[player].velocity.Y = 0;

                }
            }
            if (player == 1)
            {
                if (paddles[player].position.Y + radius * Constants.centerLineOverlap < 0)
                {
                    paddles[player].position.Y = -radius * Constants.centerLineOverlap - epsilon;
                    if (paddles[player].velocity.Y < 0)
                        paddles[player].velocity.Y = 0;
                }
            }
            if (paddles[player].position.X + radius > Constants.tableWidth * 0.5f)
            {
                paddles[player].position.X = Constants.tableWidth * 0.5f - radius + epsilon;
                if (paddles[player].velocity.X > 0)
                    paddles[player].velocity.X = 0;
            }
            if (paddles[player].position.X - radius < -Constants.tableWidth * 0.5f)
            {
                paddles[player].position.X = -Constants.tableWidth * 0.5f + radius - epsilon;
                if (paddles[player].velocity.X < 0)
                    paddles[player].velocity.X = 0;
            }
            if (paddles[player].position.Y + radius > Constants.tableHeight * 0.5f)
            {
                paddles[player].position.Y = Constants.tableHeight * 0.5f - radius + epsilon;
                if (paddles[player].velocity.Y > 0)
                    paddles[player].velocity.Y = 0;
            }
            if (paddles[player].position.Y - radius < -Constants.tableHeight * 0.5f)
            {
                paddles[player].position.Y = -Constants.tableHeight * 0.5f + radius - epsilon;
                if (paddles[player].velocity.Y < 0)
                    paddles[player].velocity.Y = 0;
            }
        }
Beispiel #8
0
        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;
        }
Beispiel #9
0
        public LANGameOpponentPlayer()
        {
            port = 5555; //TODO: Move to constants or networkign or something...

            receivingClient = new UdpClient();
            receivingClient.Client.Bind(new IPEndPoint(IPAddress.Any, port));

            receivingThread = new Thread(Receiver);

            receivingThread.IsBackground = true;

            receivingThread.Start();

            paddle = new Paddle();
        }
Beispiel #10
0
 public virtual void Update(Paddle playerPaddle, Paddle opponentPadde, Puck puck, float deltaTime)
 {
 }
Beispiel #11
0
 public override void Update(Paddle playerPaddle, Paddle opponentPadde, Puck puck, float deltaTime)
 {
     playerPaddle.velocity = (clientToView(mouseX(), mouseY()) - playerPaddle.position) / deltaTime;
 }
Beispiel #12
0
 public override void Update(Paddle playerPaddle, Paddle opponentPadde, Puck puck, float deltaTime)
 {
     playerPaddle.position = paddle.position;
     playerPaddle.velocity = paddle.velocity;
 }