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

天行健 君子當自強而不息

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 閱讀(246) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


公告

導航

統計

常用鏈接

隨筆分類(178)

3D游戲編程相關鏈接

搜索

最新評論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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久久久久久久女警| 美女成人午夜| 亚洲成人在线视频网站| 99精品视频一区二区三区| 精品福利电影| 亚洲一品av免费观看| 亚洲精品中文字幕女同| 久久亚洲一区二区| 欧美在线免费观看视频| 国产精品99免费看 | 一区二区精品在线| 亚洲免费观看高清在线观看| 美女主播一区| 久久精品国产一区二区三区免费看 | 欧美一区国产在线| 亚洲免费小视频| 欧美日韩中文字幕| 亚洲免费观看高清在线观看| 亚洲人体影院| 欧美黄色影院| 欧美黄色免费| 亚洲人精品午夜| 女同一区二区| 亚洲经典三级| 日韩网站在线看片你懂的| 欧美mv日韩mv国产网站| 欧美大片免费久久精品三p | 伊人伊人伊人久久| 欧美极品在线播放| 乱人伦精品视频在线观看| 国产欧美va欧美不卡在线| 一本色道久久加勒比88综合| 在线亚洲精品福利网址导航| 欧美人妖在线观看| 日韩视频亚洲视频| 亚洲在线视频一区| 国产精品日本精品| 欧美在线电影| 麻豆国产精品va在线观看不卡 | 亚洲三级视频在线观看| 欧美大片在线观看| 亚洲免费成人av电影| 一区二区三区四区五区在线| 欧美三级网址| 午夜激情综合网| 久久网站免费| 亚洲人午夜精品免费| 欧美激情区在线播放| 另类春色校园亚洲| 欧美福利专区| 最新成人av网站| 欧美日韩福利在线观看| 一区二区三区免费网站| 欧美一区午夜视频在线观看| 国产一级精品aaaaa看| 久久在线视频在线| 亚洲另类黄色| 欧美一区日本一区韩国一区| 国内一区二区在线视频观看| 久久久成人精品| 99国产精品久久久久久久成人热| 欧美一级久久久| 亚洲电影观看| 国产精品人人做人人爽| 久热国产精品| 亚洲在线第一页| 亚洲高清视频的网址| 亚洲一二三区在线观看| 午夜欧美理论片| 亚洲一区二区三区四区五区午夜| 国产精品欧美日韩一区二区| 久久精品亚洲乱码伦伦中文| 亚洲欧洲精品一区| 久久久精品国产免费观看同学| 亚洲国产美女精品久久久久∴| 欧美性理论片在线观看片免费| 久久免费黄色| 亚洲一区日韩| 亚洲三级国产| 美女主播视频一区| 午夜视频久久久| 这里只有精品视频| 国外视频精品毛片| 国产精品高清在线观看| 欧美寡妇偷汉性猛交| 欧美自拍丝袜亚洲| 亚洲一区二区精品在线| 亚洲欧洲偷拍精品| 欧美国产第一页| 免费成年人欧美视频| 性欧美1819性猛交| 亚洲午夜激情网页| 99在线热播精品免费| 欧美精品www| 久久久免费av| 亚洲在线免费观看| 日韩一级黄色片| 亚洲国产高清一区二区三区| 老司机精品福利视频| 欧美在线影院在线视频| 亚洲欧美一区二区精品久久久| 99在线观看免费视频精品观看| 91久久国产综合久久91精品网站| 国产主播一区二区三区四区| 国产欧美1区2区3区| 国产精品久久久久久五月尺| 欧美日韩一级黄| 欧美日韩伦理在线免费| 欧美激情视频给我| 欧美精品尤物在线| 欧美日韩高清区| 欧美日产一区二区三区在线观看| 欧美成年人在线观看| 欧美成人免费小视频| 欧美成人69av| 欧美日韩成人在线| 欧美视频在线观看一区二区| 久久精品一区中文字幕| 亚洲婷婷国产精品电影人久久| 日韩系列在线| 99精品福利视频| 一区二区欧美在线| 亚洲综合欧美日韩| 欧美一区网站| 免费视频久久| 欧美极品在线播放| 欧美四级在线观看| 国产精品一级在线| 激情视频一区二区| 亚洲精品久久久久中文字幕欢迎你| 亚洲精品日韩激情在线电影| 99re在线精品| 欧美亚洲免费在线| 久色成人在线| 亚洲片区在线| 亚洲欧美第一页| 久久久久久亚洲精品杨幂换脸 | 欧美日韩亚洲免费| 国产精品v日韩精品| 国产日本欧美在线观看| 亚洲激情校园春色| 亚洲一区二区在线免费观看视频 | 欧美亚洲三区| 免费在线成人av| 日韩午夜激情| 久久精品国产精品| 欧美激情麻豆| 国产亚洲成精品久久| 99天天综合性| 久久一区二区三区四区| 亚洲激情在线视频| 小黄鸭视频精品导航| 欧美大学生性色视频| 国产乱人伦精品一区二区| 亚洲高清三级视频| 久久成人亚洲| 亚洲人在线视频| 久久国产精品久久久久久久久久| 欧美精品久久久久久久久久| 国产女主播在线一区二区| 亚洲毛片在线观看.| 欧美在线日韩精品| 亚洲毛片av在线| 久久日韩精品| 国产香蕉97碰碰久久人人| 亚洲剧情一区二区| 久久中文精品| 亚洲一区在线播放| 欧美日韩视频在线观看一区二区三区| 国内精品视频在线播放| 亚洲欧美日韩精品在线| 最新中文字幕亚洲| 欧美jizzhd精品欧美巨大免费| 国产亚洲成av人片在线观看桃| 亚洲午夜一二三区视频| 亚洲第一区在线| 久久天堂成人| 国模叶桐国产精品一区| 午夜精品久久久久久久久久久久久| 亚洲国产精品一区二区www| 欧美主播一区二区三区| 国产区欧美区日韩区| 亚洲在线一区二区三区| 国内外成人在线视频| 亚洲综合成人在线| 99国内精品| 欧美日韩国产一区二区三区| 91久久久久久久久久久久久| 久久综合精品一区| 久久久亚洲国产天美传媒修理工| 国产免费观看久久黄| 香蕉av福利精品导航| 在线一区欧美| 国产精品国产三级国产普通话99 | 亚洲激情欧美| 噜噜爱69成人精品| 久久久久国内| 影视先锋久久| 欧美高清在线一区| 欧美—级高清免费播放|