青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

天行健 君子當(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 閱讀(241) 評(píng)論(0)  編輯 收藏 引用


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


公告

導(dǎo)航

統(tǒng)計(jì)

常用鏈接

隨筆分類(178)

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

搜索

最新評(píng)論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            久久深夜福利免费观看| 99精品视频一区二区三区| 蜜桃伊人久久| 男女激情久久| 欧美不卡视频一区发布| 欧美二区在线| 国产精品sm| 国产视频综合在线| 红桃视频一区| 亚洲理论电影网| 亚洲综合国产激情另类一区| 午夜精品999| 蜜臀99久久精品久久久久久软件 | 亚洲欧美日本国产有色| 午夜精品久久久久久久白皮肤| 久久成人精品电影| 欧美国内亚洲| 国产三级欧美三级| 亚洲精选一区| 久久久噜噜噜久久中文字幕色伊伊| 狼狼综合久久久久综合网| 亚洲精品影视在线观看| 欧美在线视频导航| 欧美日韩亚洲一区三区| 激情婷婷欧美| 性欧美大战久久久久久久免费观看 | 欧美成人精品在线观看| 日韩性生活视频| 玖玖精品视频| 国产一区二区久久久| 日韩午夜激情电影| 久久亚洲精品一区| 亚洲午夜精品在线| 欧美老女人xx| 亚洲国产婷婷香蕉久久久久久| 性欧美办公室18xxxxhd| 亚洲人体影院| 久久久久久穴| 国产一区二区日韩精品| 久久精品视频免费播放| 另类亚洲自拍| 国产真实精品久久二三区| 中日韩高清电影网| 亚洲电影自拍| 久久中文字幕导航| 国内精品伊人久久久久av影院| 亚洲神马久久| 亚洲精品欧美精品| 欧美精品色一区二区三区| 亚洲高清在线观看| 美女日韩在线中文字幕| 久久国产欧美日韩精品| 国产欧美精品一区aⅴ影院| 亚洲一区欧美二区| 在线中文字幕日韩| 国产精品久久久999| 亚洲午夜视频| 宅男精品导航| 国产精品青草综合久久久久99| 亚洲视频香蕉人妖| 亚洲精品自在久久| 欧美日韩无遮挡| 亚洲一区成人| 亚洲一区综合| 国产亚洲aⅴaaaaaa毛片| 欧美一区亚洲二区| 欧美一区二区三区视频免费| 国产视频精品xxxx| 免费的成人av| 欧美极品一区| 亚洲天堂偷拍| 欧美亚洲系列| 亚洲黄色片网站| 亚洲激情成人在线| 欧美视频二区| 久久久精品五月天| 久久一区二区三区四区五区| 亚洲国产精品国自产拍av秋霞 | 一本大道久久a久久精二百| 国产精品国产三级国产专区53| 校园激情久久| 久久综合色88| 亚洲深夜福利| 久久精品99国产精品日本| 亚洲国产精品va| 正在播放亚洲一区| 亚洲高清在线观看一区| 一区二区三区日韩欧美| 国内免费精品永久在线视频| 亚洲国产一区在线观看| 国产酒店精品激情| 亚洲第一中文字幕| 国产欧美在线视频| 91久久国产自产拍夜夜嗨| 国产精品一二三视频| 欧美国产综合视频| 国产精品尤物| 亚洲国产一区二区在线| 国产美女精品一区二区三区| 欧美多人爱爱视频网站| 国产精品第2页| a91a精品视频在线观看| 亚洲一区不卡| 亚洲大黄网站| 亚洲女同在线| 一区二区三区四区五区精品视频| 羞羞漫画18久久大片| 亚洲精品视频在线播放| 欧美一级大片在线免费观看| 日韩一级视频免费观看在线| 性感少妇一区| 亚洲综合三区| 欧美日本不卡视频| 欧美激情四色 | 欧美连裤袜在线视频| 久久久综合精品| 国产精品激情av在线播放| 亚洲第一色在线| 国内一区二区三区| 亚洲女女女同性video| 9人人澡人人爽人人精品| 久久夜色精品国产欧美乱极品| 欧美一区在线视频| 国产精品色在线| 亚洲午夜一级| 亚洲欧美国产日韩中文字幕| 欧美精品v日韩精品v国产精品| 裸体丰满少妇做受久久99精品| 国产伦精品一区二区三区视频黑人 | 亚洲高清资源综合久久精品| 午夜精品999| 欧美一级黄色录像| 国产精品夜夜夜| 亚洲欧美成人网| 久久精品国产久精国产一老狼| 国产精品久久久久影院亚瑟| 夜夜夜久久久| 欧美一区二区私人影院日本| 国产精品制服诱惑| 欧美亚洲视频| 美女91精品| 亚洲第一在线综合在线| 久久综合激情| 亚洲三级性片| 香蕉久久国产| 狠狠色丁香婷婷综合| 免费永久网站黄欧美| 亚洲精品九九| 性欧美xxxx大乳国产app| 国产亚洲人成a一在线v站| 久久精品青青大伊人av| 亚洲福利视频三区| 亚洲一区二区三区精品在线| 国产精品视频yy9299一区| 久久国产精品99精品国产| 欧美国产精品| 亚洲一级高清| 一区二区亚洲欧洲国产日韩| 美女网站在线免费欧美精品| 亚洲麻豆av| 久久精品成人欧美大片古装| 一区二区视频免费完整版观看| 欧美日韩黄色一区二区| 欧美一区不卡| 激情视频一区二区| 欧美乱大交xxxxx| 亚洲男人第一网站| 欧美高清hd18日本| 性xx色xx综合久久久xx| 在线精品国产成人综合| 欧美日韩一区二区三区四区在线观看 | 亚洲国产经典视频| 欧美日韩在线免费| 性色av一区二区三区红粉影视| 女女同性精品视频| 亚洲欧美视频| 亚洲精品一区二区在线观看| 国产精品无人区| 欧美不卡在线| 久久精品国产亚洲精品| 9久草视频在线视频精品| 麻豆精品视频| 欧美呦呦网站| 亚洲影音一区| 99国内精品久久久久久久软件| 国产日韩精品视频一区二区三区| 欧美成年人视频网站| 欧美在线短视频| 中日韩男男gay无套| 欧美激情在线免费观看| 久久久高清一区二区三区| 亚洲图片激情小说| 亚洲美女啪啪| 亚洲激情网站| 亚洲国产女人aaa毛片在线| 国产一区二区三区高清 | 开元免费观看欧美电视剧网站| 亚洲性视频h| 日韩视频免费| 91久久在线观看|