コード例 #1
0
ファイル: Arena.cs プロジェクト: yjd6808/CSharpNetworking
        // Sends information about the current game state to the players
        // resendTimeout is how long to wait until sending another GameStatePacket
        private void _sendGameState(PlayerInfo player, TimeSpan resendTimeout)
        {
            if (DateTime.Now >= (player.LastPacketSentTime.Add(resendTimeout)))
            {
                // Set the data
                GameStatePacket gsp = new GameStatePacket();
                gsp.LeftY        = LeftPlayer.Paddle.Position.Y;
                gsp.RightY       = RightPlayer.Paddle.Position.Y;
                gsp.BallPosition = _ball.Position;
                gsp.LeftScore    = LeftPlayer.Paddle.Score;
                gsp.RightScore   = RightPlayer.Paddle.Score;

                _sendTo(player, gsp);
            }
        }
コード例 #2
0
        protected override void Update(GameTime gameTime)
        {
            // Check for close
            KeyboardState kbs = Keyboard.GetState();

            if (kbs.IsKeyDown(Keys.Escape))
            {
                // Player wants to quit, send a ByePacket (if we're connected)
                if ((_state == ClientState.EstablishingConnection) ||
                    (_state == ClientState.WaitingForGameStart) ||
                    (_state == ClientState.InGame))
                {
                    // Will trigger the network thread to send the Bye Packet
                    _sendBye.Value = true;
                }

                // Will stop the network thread
                _running.Value = false;
                _state         = ClientState.GameOver;
                Exit();
            }

            // Check for time out with the server
            if (_timedOut())
            {
                _state = ClientState.GameOver;
            }

            // Get message
            NetworkMessage message;
            bool           haveMsg = _incomingMessages.TryDequeue(out message);

            // Check for Bye From server
            if (haveMsg && (message.Packet.Type == PacketType.Bye))
            {
                // Shutdown the network thread (not needed anymore)
                _running.Value = false;
                _state         = ClientState.GameOver;
            }

            switch (_state)
            {
            case ClientState.EstablishingConnection:
                _sendRequestJoin(TimeSpan.FromSeconds(1));
                if (haveMsg)
                {
                    _handleConnectionSetupResponse(message.Packet);
                }
                break;

            case ClientState.WaitingForGameStart:
                // Send a heartbeat
                _sendHeartbeat(TimeSpan.FromSeconds(0.2));

                if (haveMsg)
                {
                    switch (message.Packet.Type)
                    {
                    case PacketType.AcceptJoin:
                        // It's possible that they didn't receive our ACK in the previous state
                        _sendAcceptJoinAck();
                        break;

                    case PacketType.HeartbeatAck:
                        // Record ACK times
                        _lastPacketReceivedTime = message.ReceiveTime;
                        if (message.Packet.Timestamp > _lastPacketReceivedTimestamp)
                        {
                            _lastPacketReceivedTimestamp = message.Packet.Timestamp;
                        }
                        break;

                    case PacketType.GameStart:
                        // Start the game and ACK it
                        _sendGameStartAck();
                        _state = ClientState.InGame;
                        break;
                    }
                }
                break;

            case ClientState.InGame:
                // Send a heartbeat
                _sendHeartbeat(TimeSpan.FromSeconds(0.2));

                // update our paddle
                _previousY = _ourPaddle.Position.Y;
                _ourPaddle.ClientSideUpdate(gameTime);
                _sendPaddlePosition(_sendPaddlePositionTimeout);

                if (haveMsg)
                {
                    switch (message.Packet.Type)
                    {
                    case PacketType.GameStart:
                        // It's possible the server didn't receive our ACK in the previous state
                        _sendGameStartAck();
                        break;

                    case PacketType.HeartbeatAck:
                        // Record ACK times
                        _lastPacketReceivedTime = message.ReceiveTime;
                        if (message.Packet.Timestamp > _lastPacketReceivedTimestamp)
                        {
                            _lastPacketReceivedTimestamp = message.Packet.Timestamp;
                        }
                        break;

                    case PacketType.GameState:
                        // Update the gamestate, make sure its the latest
                        if (message.Packet.Timestamp > _lastPacketReceivedTimestamp)
                        {
                            _lastPacketReceivedTimestamp = message.Packet.Timestamp;

                            GameStatePacket gsp = new GameStatePacket(message.Packet.GetBytes());
                            _left.Score    = gsp.LeftScore;
                            _right.Score   = gsp.RightScore;
                            _ball.Position = gsp.BallPosition;

                            // Update what's not our paddle
                            if (_ourPaddle.Side == PaddleSide.Left)
                            {
                                _right.Position.Y = gsp.RightY;
                            }
                            else
                            {
                                _left.Position.Y = gsp.LeftY;
                            }
                        }

                        break;

                    case PacketType.PlaySoundEffect:
                                #if CAN_PLAY_SOUNDS
                        // Play a sound
                        PlaySoundEffectPacket psep = new PlaySoundEffectPacket(message.Packet.GetBytes());
                        if (psep.SFXName == "ball-hit")
                        {
                            _ballHitSFX.Play();
                        }
                        else if (psep.SFXName == "score")
                        {
                            _scoreSFX.Play();
                        }
                                #endif
                        break;
                    }
                }

                break;

            case ClientState.GameOver:
                // Purgatory is here
                break;
            }

            base.Update(gameTime);
        }