• <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(13)

             

            cApp::remove_player

            Just as players join the game, so do players quit, and that’s the purpose of the
            remove_player function. In the remove_player function, the server will scan the list of
            connected players for a match of a DirectPlay identification number (from the disconnecting
            player) and remove that player from the list. After the scan is complete
            and the appropriate player is removed from the list, all clients are notified of the
            disconnecting player, and the server rebuilds a list of existing players.

            void cApp::remove_player(const sMsg* msg)
            {
                
            // search for player in list
                for(long i = 0; i < MAX_PLAYERS; i++)
                {
                    
            if(m_players[i].player_id == msg->header.player_id && m_players[i].connected)
                    {
                        m_players[i].connected = 
            false;

                        
            // send remove player message to all players

                        sDestroyPlayerMsg destroy_msg;

                        destroy_msg.header.type      = MSG_DESTROY_PLAYER;
                        destroy_msg.header.size      = 
            sizeof(sDestroyPlayerMsg);
                        destroy_msg.header.player_id = msg->header.player_id;

                        send_network_msg(&destroy_msg, DPNSEND_NOLOOPBACK, ALL_CLIENT_PLAYERS);

                        m_connected_player_num--;
                        list_players();

                        
            break;
                    }
                }
            }
             

            cApp::send_player_info

            Unfortunately, in network gaming, game messages sometimes get lost along the
            way. What if one of those lost messages intended to inform the client application
            that a player had joined the game? Furthermore, what if the client started receiving
            messages related to a player that the client didn’t know existed (because of a lost
            message)?

            In cases where the client has no knowledge of a player and is receiving messages
            related to that player, the client will request the appropriate player’s data from the
            server in order to continue. The server, in turn, will send the requested player’s
            information to the client using the send_player_info function:

            bool cApp::send_player_info(const sMsg* msg, DPNID to)
            {
                sRequestPlayerInfoMsg* request_msg = (sRequestPlayerInfoMsg*) msg;

                
            for(long i = 0; i < MAX_PLAYERS; i++)
                {
                    
            // only send if found in list
                    if(m_players[i].player_id == request_msg->request_player_id && m_players[i].connected)
                    {
                        
            // send player infomation to requesting player

                        sCreatePlayerMsg create_msg;

                        create_msg.header.type      = MSG_SEND_PLAYER_INFO;
                        create_msg.header.size      = 
            sizeof(sCreatePlayerMsg);
                        create_msg.header.player_id = request_msg->request_player_id;
                        create_msg.x_pos            = m_players[i].x_pos;
                        create_msg.y_pos            = m_players[i].y_pos;
                        create_msg.z_pos            = m_players[i].z_pos;
                        create_msg.direction        = m_players[i].direction;

                        send_network_msg(&create_msg, DPNSEND_NOLOOPBACK, to);

                        
            break;
                    }
                }

                
            return true;
            }
             

            cApp::player_state_change

            The major message-processing function in the server must be player_state_change,
            which takes incoming actions from the clients and updates the internal player data.

            bool cApp::player_state_change(const sMsg* msg)
            {
                
            // get player index in list
                long player_index = -1;
                
                
            for(long i = 0; i < MAX_PLAYERS; i++)
                {
                    
            if(m_players[i].player_id == msg->header.player_id && m_players[i].connected)
                    {
                        player_index = i;
                        
            break;
                    }
                }

                
            if(player_index == -1)
                    
            return false;

                sPlayer* player = &m_players[player_index];

                
            bool allow_change = true;
                
                
            // refuse to update player if swinging sword or hurt
                if(player->last_state == STATE_SWING || player->last_state == STATE_HURT)
                    allow_change = 
            false;    

                
            // only change state if allowed
                if(! allow_change)
                    
            return false;

                sStateChangeMsg* change_msg = (sStateChangeMsg*) msg;

                
            // update selected player
                player->last_update_time = timeGetTime();
                player->last_state       = change_msg->state;
                player->direction        = change_msg->direction;

                
            // adjust action time based on latency
                player->last_update_time -= player->latency;

                sStateChangeMsg state_msg;

                
            // send player data to all clients
                state_msg.header.type      = MSG_STATE_CHANGE;
                state_msg.header.size      = 
            sizeof(sStateChangeMsg);
                state_msg.header.player_id = change_msg->header.player_id;
                state_msg.state            = player->last_state;
                state_msg.x_pos            = player->x_pos;
                state_msg.y_pos            = player->y_pos;
                state_msg.z_pos            = player->z_pos;
                state_msg.direction        = player->direction;
                state_msg.speed            = player->speed;

                send_network_msg(&state_msg, DPNSEND_NOLOOPBACK, ALL_CLIENT_PLAYERS);

                
            if(change_msg->state != STATE_SWING)
                    
            return true;

                
            // If swinging sword, determing who is hurt, check all players.
                for(long i = 0; i < MAX_PLAYERS; i++)
                {
                    
            // only check against other players that are connected
                    if(i == player_index || !m_players[i].connected)
                        
            continue;

                    
            // get distance to player
                    float x_diff = fabs(player->x_pos - m_players[i].x_pos);
                    
            float z_diff = fabs(player->z_pos - m_players[i].z_pos);
                    
            float dist   = x_diff * x_diff + z_diff * z_diff;

                    
            // continue if distance between players acceptable
                    if(dist >= 10000.0f)
                        
            continue;

                    
            // get angle between players
                    float angle = -atan2(m_players[i].z_pos - player->z_pos, m_players[i].x_pos - player->x_pos) + 1.570796f;

                    angle -= player->direction;     
            // adjust for attacker's direction
                    angle += 0.785f;                // adjust for FOV

                    // bounds angle value
                    if(angle < 0.0f)        angle += 6.28f;
                    
            if(angle >= 6.28f)      angle -= 6.28f;

                    
            // player hit if in front of attacker (90 FOV)
                    if(angle >= 0.0f && angle <= 1.570796f && m_players[i].last_state != STATE_HURT)
                    {
                        m_players[i].last_state = STATE_HURT;
                        m_players[i].last_update_time = timeGetTime();

                        
            // send network message
                        state_msg.header.type      = MSG_STATE_CHANGE;
                        state_msg.header.size      = 
            sizeof(sStateChangeMsg);
                        state_msg.header.player_id = m_players[i].player_id;
                        state_msg.state            = m_players[i].last_state;
                        state_msg.x_pos            = m_players[i].x_pos;
                        state_msg.y_pos            = m_players[i].y_pos;
                        state_msg.z_pos            = m_players[i].z_pos;
                        state_msg.direction        = m_players[i].direction;
                        state_msg.speed            = m_players[i].speed;

                        send_network_msg(&state_msg, DPNSEND_NOLOOPBACK, ALL_CLIENT_PLAYERS);
                    }
                }

                
            return true;
            }

            Up to this point, the server has looked for the player that uses the state-change
            message. If a message is coming from a player who is not connected, the message
            is ignored. From now on, the game’s logic takes over.

            Players are allowed to walk, stand still, or swing their weapons. Players whose states
            are already set as swinging their weapons or being hurt are not allowed to update
            their states (until those states are cleared).

            Now the player’s state is updated (if allowed) and sent out to all other connected
            players. Next, if the player has swung his weapon, all players are scanned to see
            whether the attacker hit them. If so, the states of those hurt are changed to HURT.

            Also, notice that I offset the state’s time variable (sPlayer::last_update_time) by the player’s
            latency value (sPlayer::latency). This adjusts for network transmission delays and
            improves synchronization. If you remove the latency offset, you’ll see a jumping
            effect when players are moving around the level.

            Note that players who are swinging their swords have a chance to hit the players in
            front of them. To check whether another player was hit during an attack, you first
            perform a distance calculation, and if any characters are considered close enough,
            the angles between the players are checked. If the players being attacked are within
            a 90-degree field of view in front of the attackers (as illustrated in Figure 19.14),
            they are considered hit, at which point, those victims’ states are changed to HURT.

            And that’s it for dealing with the game messages and state changes in players.
            Although the player_state_change function is responsible for parsing the queued game
            messages, it’s really up to another function to move players and clear their swinging
            or hurt states, as you see in the following section.

            posted on 2007-12-18 22:39 lovedday 閱讀(239) 評論(0)  編輯 收藏 引用


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


            公告

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            隨筆分類(178)

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

            搜索

            最新評論

            香蕉久久夜色精品国产小说| 久久99精品国产麻豆婷婷| 一本色道久久HEZYO无码| 久久经典免费视频| 久久久噜噜噜www成人网| 国产激情久久久久影院老熟女| 久久久久一本毛久久久| 精品久久久久久中文字幕人妻最新| 狠狠色综合网站久久久久久久| 亚洲精品国产综合久久一线| 中文精品久久久久国产网址 | 久久国产精品国语对白| 午夜精品久久久久久毛片| 99久久精品国产一区二区三区| 狠狠色丁香婷婷久久综合五月| 伊人久久综在合线亚洲2019| 日韩久久久久久中文人妻| 久久免费大片| 亚洲国产精品久久| 久久精品欧美日韩精品| 久久久久久曰本AV免费免费| 精品久久国产一区二区三区香蕉| 精品久久8x国产免费观看| 97精品伊人久久大香线蕉| 女同久久| 久久无码国产| 亚洲国产成人精品女人久久久| 中文精品久久久久国产网址| 久久99精品综合国产首页| 国产精品99久久99久久久| 亚洲AV无码久久精品色欲| 一本一本久久aa综合精品 | 久久国产成人| 久久免费大片| 久久天天躁夜夜躁狠狠躁2022| 久久久这里有精品| 一本一道久久综合狠狠老| 日韩精品久久久久久久电影蜜臀| 人妻精品久久无码区| 国产91色综合久久免费分享| 嫩草影院久久99|