• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            天行健 君子當(dāng)自強(qiáng)而不息

            Getting Online with Multiplayer Gaming(17)

             

            Message Handling

            The client application uses the same message structures as the server, but the client
            has no need for queuing messages. As Figure 19.16 demonstrates, incoming messages
            are immediately parsed by the client.

            Now that you’ve seen the receive function that handles incoming message, it’s time
            to examine each message handling function.

             

            cApp::create_player

            As clients join the game, the server informs other connected clients of those new
            arrivals. The purpose of the following create_player function is to find room in the
            sPlayer structure and store the player data:

            void cApp::create_player(const sMsg* msg)
            {
                sCreatePlayerMsg* create_msg = (sCreatePlayerMsg*) msg;

                
            // do not add local player to list
                if(create_msg->header.player_id == m_players[0].player_id)
                    
            return;

                
            long player_index = -1;

                
            for(long i = 1; i < MAX_PLAYERS; i++)
                {
                    
            if(m_players[i].connected)
                    {
                        
            // makre sure player not already in list
                        if(m_players[i].player_id == create_msg->header.player_id)
                            
            return;
                    }
                    
            else
                        player_index = i;
                }

                
            if(player_index == -1)  // no open slots
                    return;

                EnterCriticalSection(&m_update_cs);

                
            // add player data
                m_players[player_index].connected  = true;
                m_players[player_index].player_id  = create_msg->header.player_id;
                m_players[player_index].x_pos      = create_msg->x_pos;
                m_players[player_index].y_pos      = create_msg->y_pos;
                m_players[player_index].z_pos      = create_msg->z_pos;
                m_players[player_index].direction  = create_msg->direction;
                m_players[player_index].speed      = 0.0f;
                m_players[player_index].last_state = STATE_IDLE;

                m_num_players++;

                LeaveCriticalSection(&m_update_cs);
            }

             

            cApp::destroy_player

            The server notifies clients when a player is leaving a session. The clients, in turn,
            signal the player as being disconnected and skips updating the player during the
            update cycle. The following code determines which client is disconnected and
            takes the appropriate steps:

            void cApp::destroy_player(const sMsg* msg)
            {
                sDestroyPlayerMsg* destroy_msg = (sDestroyPlayerMsg*) msg;

                
            // do not remove local player from list
                if(destroy_msg->header.player_id == m_players[0].player_id)
                    
            return;

                
            long player_index = get_player_index(destroy_msg->header.player_id);
                
            if(player_index == -1)
                    
            return;

                EnterCriticalSection(&m_update_cs);

                m_players[player_index].connected = 
            false;
                m_num_players--;

                LeaveCriticalSection(&m_update_cs);
            }
             

            cApp::change_player_state

            The client processes changes of state in players by pulling out the message data and
            putting it in the player’s structure. If a player isn’t found in the list of players, the
            client requests that player’s information via a MSG_GET_PLAYER_INFO message and exits the
            change_player_state function without further ado.

            This is the only situation in which a player’s coordinates can be directly modified
            by a state change—clients are not allowed to make direct changes to their coordinates
            (to avoid cheating), so it’s up to the server to tell players just where they are
            in the world during the updates:

            void cApp::change_player_state(const sMsg* msg)
            {
                sStateChangeMsg* change_msg = (sStateChangeMsg*) msg;

                
            long player_index = get_player_index(change_msg->header.player_id);

                
            if(player_index == -1)  // unknown player - request information
                {
                    sRequestPlayerInfoMsg request_msg;

                    request_msg.header.type       = MSG_GET_PLAYER_INFO;
                    request_msg.header.size       = 
            sizeof(sRequestPlayerInfoMsg);
                    request_msg.header.player_id  = m_players[0].player_id;
                    request_msg.request_player_id = change_msg->header.player_id;

                    send_network_msg(&request_msg, DPNSEND_NOLOOPBACK);
                    
            return;
                }

                EnterCriticalSection(&m_update_cs);

                
            // store new player state information
                m_players[player_index].last_state = change_msg->state;
                m_players[player_index].x_pos      = change_msg->x_pos;
                m_players[player_index].y_pos      = change_msg->y_pos;
                m_players[player_index].z_pos      = change_msg->z_pos;
                m_players[player_index].direction  = change_msg->direction;
                m_players[player_index].speed      = change_msg->speed;
                m_players[player_index].latency    = change_msg->latency;

                
            // bounds latency to 1 second
                if(m_players[player_index].latency > 1000)
                    m_players[player_index].latency = 1000;

                
            // adjust time based on latency
                m_players[player_index].last_update_time = timeGetTime() - m_players[player_index].latency;

                LeaveCriticalSection(&m_update_cs);
            }

            //////////////////////////////////////////////////////////////////////////////////////////////

            bool cApp::send_network_msg(void* msg, long send_flags)
            {
                sMsgHeader* header = (sMsgHeader*) msg;

                
            if(header->size == 0)
                    
            return false;

                
            return m_client.send_data(msg, header->size, send_flags);
            }

            Just like the server, the client has a send_network_msg to send the game-related
            network messages to the server.

            NOTE
            The client also depends on the latency time to modify
            the timing calculations.The server sends this latency
            time to the client, but to make things safe, the client
            application is allowed to cut the latency down to one
            second if the server states that it is higher.


            posted on 2007-12-19 16:44 lovedday 閱讀(241) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            公告

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關(guān)鏈接

            搜索

            最新評(píng)論

            亚洲精品美女久久久久99小说| 亚洲欧美一区二区三区久久| 久久99国产精品一区二区| 精品久久久久久中文字幕| 人人狠狠综合久久亚洲高清| 性欧美丰满熟妇XXXX性久久久| 伊人久久综合热线大杳蕉下载| 久久精品人妻中文系列| 久久久精品免费国产四虎| 久久亚洲sm情趣捆绑调教| 精品久久久久久国产潘金莲| 国产精品久久久久久久久软件 | 国产欧美久久久精品| 亚洲精品美女久久久久99小说| 久久青青草原国产精品免费| 久久亚洲AV成人无码| 国内精品久久久久久麻豆| av无码久久久久不卡免费网站 | AAA级久久久精品无码片| 久久这里只有精品首页| 精品久久久久久国产免费了| 久久99热只有频精品8| A级毛片无码久久精品免费| 韩国三级中文字幕hd久久精品| 久久99久久99小草精品免视看| 少妇久久久久久被弄高潮| 波多野结衣久久一区二区| 久久久亚洲精品蜜桃臀| 久久国产精品视频| 久久国产成人午夜aⅴ影院 | 久久亚洲精品无码AV红樱桃| 久久婷婷色香五月综合激情| 国产精品久久久香蕉| 伊人久久精品影院| 日韩欧美亚洲综合久久 | 亚洲va久久久噜噜噜久久狠狠| 偷偷做久久久久网站| 国内精品久久久久久久久电影网 | 狠狠色丁香久久综合五月| 热re99久久精品国产99热| 精品久久久久久久中文字幕|