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

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

Getting Online with Multiplayer Gaming(15)

 

Working with Game Clients

The client application (referred to as the client) is the conduit between the gaming
server and the player. The client accepts the user’s input and forwards it to the server.
Between updates from the server, the client updates itself based on what little information
it has—the player’s movement, other players’ movements, NPC actions, and so on.

The client uses graphics, sound, and input-processing to work its magic. However,
if you were to strip away the graphics and sound, you would be left with a rather
bland application. This “dumb” client structure might look unworthy, but believe
me, it will work perfectly for your game project.

To use the Client application, you can follow these steps:

1. Locate and run the Client application. The Connect to Server dialog box
(shown in Following snap) appears.

Besides picking an adapter and entering a player name, you’ll need to know the server’s IP address in order to connect and play the game.

2. In the Connect to Server dialog box, enter the host’s IP address, select an
adapter, and enter your player’s name.

3. Click OK to begin the game and connect to the server.

The client works almost identically to the server in some respects, the first of which
is dealing with players.

 

Handling Player Data

The client, much like the server, uses an sPlayer structure that contains the information
about each connected player in the game. This time, however, information is
needed to track the 3-D object for drawing the player (as well as the weapon) and
the player animation being played. Other than that, you can see many similarities
between the sPlayer structure being used by the client and server. Take a look at
the declaration of the client’s sPlayer structure (along with supporting macros):

#define MAX_PLAYERS           8     // Maximum number of players allowed to be connected at once

#define STATE_IDLE            1 
#define STATE_MOVE            2
#define STATE_SWING           3
#define STATE_HURT            4

#define ANIM_IDLE             1
#define ANIM_WALK             2
#define ANIM_SWING            3
#define ANIM_HURT             4

typedef 
struct sPlayer
{
    
bool    connected;    
    DPNID   player_id;

    
long    last_state;      
    
long    last_update_time;
    
long    latency;

    
float   x_pos, y_pos, z_pos;
    
float   direction;
    
float   speed;

    cObject body;
    cObject weapon;
    
long    last_anim;

    
///////////////////////////////////////////////////////////////
    
    sPlayer()
    {
        connected        = 
false;
        player_id        = 0;
        last_anim        = 0;
        last_update_time = 0;
    }
} *sPlayerPtr;

Again, an array of sPlayer structures is allocated to hold the player information.
Each player is allowed to use a separate Graphics Core object for the character’s
body and weapon mesh. The local player uses the first element in the player data
array (defined as m_players in the application class), although joining players are
stuffed into the first empty slot found.

#define MSG_CREATE_PLAYER     1
#define MSG_GET_PLAYER_INFO   2
#define MSG_DESTROY_PLAYER    3
#define MSG_STATE_CHANGE      4

typedef 
struct sMsgHeader
{
    
long    type;       // type of message (MSG_*)
    long    size;       // size of data to send
    DPNID   player_id;  // player performing action
} *sMsgHeaderPtr;

typedef 
struct sMsg     // The message queue message structure
{
    sMsgHeader  header;
    
char        data[512];
} *sMsgPtr;

typedef 
struct sCreatePlayerMsg
{
    sMsgHeader  header;
    
float       x_pos, y_pos, z_pos;    // Create player coordinates
    float       direction;
} *sCreatePlayerMsgPtr;

typedef 
struct sRequestPlayerInfoMsg
{
    sMsgHeader  header;
    DPNID       request_player_id;      
// which player to request
} *sRequestPlayerInfoMsgPtr;

typedef 
struct sDestroyPlayerMsg
{
    sMsgHeader header;
} *sDestroyPlayerMsgPtr;

typedef 
struct sStateChangeMsg
{
    sMsgHeader  header;
    
    
long        state;                  // State message (STATE_*)
    float       x_pos, y_pos, z_pos;
    
float       direction;
    
float       speed;
    
long        latency;
} *sStateChangeMsgPtr;

/****************************************************************************************************/

class cApp : public cFramework
{
private:
    CRITICAL_SECTION    m_update_cs;    

    cInput              m_input;
    cInputDevice        m_keyboard;
    cInputDevice        m_mouse;

    cMesh               m_terrain_mesh;
    cNodeTreeMesh       m_nodetree_mesh;

    cMesh               m_char_mesh;
    cMesh               m_weapon_mesh;
    cAnimation          m_char_anim;

    cCamera             m_camera;
    
float               m_cam_angle;
    
    cNetworkAdapter     m_adapter;
    cClient             m_client;
    GUID*               m_adapter_guid;

    
char                m_host_ip[16];
    
char                m_player_name[32];

    
long                m_num_players;
    sPlayer*            m_players;    

    ID3DXFont*          m_font;

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

public:
    cApp();

    
virtual bool init();
    
virtual bool frame();
    
virtual void shutdown();
    
    
bool receive(const DPNMSG_RECEIVE* msg);
    
void set_info(GUID* adapter_guid, const char* host_ip, const char* player_name);

    
void set_local_player(DPNID player_id);

private:
    
bool select_adapter();
    
bool init_game();
    
bool join_game();    

    
void update_all_players();
    
void render_scene();

    
bool send_network_msg(void* msg, long send_flags);
    
long get_player_index(DPNID player_id);

    
void create_player(const sMsg* msg);
    
void destroy_player(const sMsg* msg);
    
void change_player_state(const sMsg* msg);
};

BOOL CALLBACK connect_dialog_proc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam);

As the application class for the client is initialized, all character and weapon
meshes are loaded and assigned to each of the player data structures. This is your
first chance to customize your network game; by loading different meshes, you can
have each player appear differently. For example, one character can be a warrior,
another character a wizard, and so on.

A list of animations is also loaded. Those animations represent the various states of
players: a walking animation, standing still (idle), swinging a weapon, and finally a
hurt animation. Those animations are set by the update_all_players function, which you
see in a bit in the section “Updating Local Players.”

One extra tidbit in the sPlayer structure is a DirectPlay identification number.
Clients normally don’t have access to their identification numbers; those are left
for the server to track. However, clients are designed so that their identification
numbers track all players, and in order to start playing, all clients must request
their identification number from the server.

When a game message is received from the server, the client application scans
through the list of connected players. When the player identification number from
the local list of players and from the server is matched, the client knows exactly
which player to update.

The client uses a function called get_player_index to scan the list of players and return
the index number of the matching player (or -1 if no such match is found):

long cApp::get_player_index(DPNID player_id)
{
    
// scan list looking for match
    for(long i = 0; i < MAX_PLAYERS; i++)
    {
        
if(m_players[i].player_id == player_id && m_players[i].connected)
            
return i;
    }

    
return -1;  // no found in list
}

From now on, the client will always use the get_player_index function to determine
which player to update. If a player is not found in the list but is known to exist, the
client must send a MSG_GET_PLAYER_INFO message, which requests the player’s information
from the server. In response, the server will return a create-player message to the
requesting client.

But I’m getting a little ahead of myself, so let’s slow things down a bit. Much like
the server, the client uses the Network Core to handle network communications.
Now, take a look at the client component I’m using for the client application.

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


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


公告

導(dǎo)航

統(tǒng)計(jì)

常用鏈接

隨筆分類(lèi)(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>
            欧美日韩在线视频一区| 亚洲天堂久久| 亚洲伊人第一页| 亚洲国产cao| 欧美一区二区精美| 99视频国产精品免费观看| 久久国产精品电影| 午夜影院日韩| 欧美午夜在线一二页| 欧美成人在线免费视频| 国产一区二区三区久久久| 一本久道久久综合中文字幕| 亚洲精品社区| 久久综合久久综合久久综合| 久久国产精品黑丝| 国产精品亚洲аv天堂网| 99综合电影在线视频| 亚洲免费观看| 欧美激情一区二区三级高清视频| 欧美 日韩 国产一区二区在线视频| 国产精品一区二区三区四区五区 | 99国产精品99久久久久久| 亚洲第一黄网| 久久婷婷麻豆| 久久婷婷麻豆| 国模精品娜娜一二三区| 久久久久91| 牛牛影视久久网| 亚洲第一精品久久忘忧草社区| 欧美一区不卡| 久久阴道视频| 91久久国产综合久久| 女女同性精品视频| 亚洲成色www8888| 亚洲国产精品久久久久| 你懂的视频欧美| 亚洲日本中文字幕| 亚洲午夜久久久久久久久电影院| 欧美日韩国产精品一卡| 中日韩视频在线观看| 亚洲欧美欧美一区二区三区| 国产精品一区二区三区久久久| 亚洲欧美日韩一区二区在线 | 欧美性做爰毛片| 亚洲一区中文字幕在线观看| 久久精品国产亚洲aⅴ| 国产揄拍国内精品对白| 久久综合色综合88| 99精品视频一区| 午夜在线一区二区| 亚洲成人资源| 欧美日韩八区| 性高湖久久久久久久久| 嫩模写真一区二区三区三州| 一本色道88久久加勒比精品| 国产欧美精品一区| 久久只有精品| 亚洲一区二区网站| 奶水喷射视频一区| 亚洲午夜电影网| 樱花yy私人影院亚洲| 欧美精品三级日韩久久| 校园激情久久| 亚洲国产日韩欧美在线动漫| 午夜精品久久久久| 亚洲精品黄网在线观看| 国产精品捆绑调教| 免费视频久久| 欧美亚洲专区| 一本色道久久综合亚洲精品不卡 | 免费不卡中文字幕视频| 亚洲一区在线视频| 在线免费观看视频一区| 欧美亚韩一区| 欧美成人精品影院| 久久国产综合精品| 一本色道久久综合精品竹菊| 免费成人av资源网| 西瓜成人精品人成网站| 亚洲开发第一视频在线播放| 国产毛片精品视频| 欧美日韩国产片| 蜜臀av性久久久久蜜臀aⅴ| 亚洲自拍另类| 亚洲视频免费在线| 亚洲精品亚洲人成人网| 久久综合一区二区| 欧美一区二区网站| 亚洲淫性视频| 夜夜嗨av色一区二区不卡| 永久91嫩草亚洲精品人人| 国产情人综合久久777777| 欧美视频在线一区| 欧美精品免费看| 欧美国产日韩一区二区三区| 老牛影视一区二区三区| 欧美一二三区精品| 亚洲欧美国产精品va在线观看 | 国产伦精品一区二区三区| 欧美日韩国产成人精品| 欧美精品激情blacked18| 久久综合久久综合久久综合| 久久久av毛片精品| 久久成人国产精品| 久久国产加勒比精品无码| 欧美亚洲尤物久久| 欧美一区二视频| 性欧美8khd高清极品| 香蕉成人久久| 欧美中文在线观看国产| 欧美影片第一页| 欧美一级视频| 久久福利一区| 嫩草影视亚洲| 欧美日韩国产一区二区三区| 欧美日韩高清在线播放| 欧美亚男人的天堂| 国产精品欧美一区喷水| 国产日韩欧美精品一区| 国产日韩在线看| 红桃av永久久久| 亚洲人成小说网站色在线| 亚洲伦理久久| 午夜激情综合网| 久久久噜噜噜久久| 欧美刺激午夜性久久久久久久| 欧美激情中文字幕在线| 亚洲激情成人网| 一区二区国产精品| 欧美一区二区三区日韩| 久热精品视频在线观看一区| 欧美激情一区二区三区在线视频| 欧美三级特黄| 国产婷婷一区二区| 亚洲精品久久久久久久久久久久久 | 亚洲国产精品va在线看黑人 | 可以免费看不卡的av网站| 亚洲第一中文字幕| 一本色道综合亚洲| 久久精品国产成人| 欧美激情在线免费观看| 国产美女扒开尿口久久久| 在线看视频不卡| 亚洲综合另类| 亚洲国产精品激情在线观看| 亚洲私人影院在线观看| 久久精品91久久久久久再现| 久久久99免费视频| 欧美在线观看一区二区| 欧美国产亚洲精品久久久8v| 欧美日韩国产首页| 国产精品一区二区久久| 亚洲激情专区| 午夜精品久久久久| 免费在线欧美视频| 亚洲午夜免费福利视频| 久久久精品五月天| 欧美精品日韩www.p站| 国产精品日韩一区二区| 亚洲精品欧美日韩专区| 亚洲欧美另类在线观看| 小黄鸭精品密入口导航| 欧美一区二区三区四区在线| 欧美韩日一区二区| 在线亚洲欧美| 亚洲一区视频在线观看视频| 久久婷婷成人综合色| 国产精品一区2区| 亚洲精品一区二区三区婷婷月| 午夜精品www| 91久久线看在观草草青青| 亚洲免费在线播放| 免费在线亚洲| 国产日韩欧美一区二区| 亚洲综合日韩在线| 欧美国产第二页| 欧美一区二区三区久久精品| 欧美日韩亚洲激情| 亚洲国产精品一区二区三区| 欧美一区二区视频在线观看2020| 亚洲第一天堂无码专区| 久久久国产视频91| 国产精品拍天天在线| 一本久道久久综合狠狠爱| 久久久久久久欧美精品| 亚洲欧美成人综合| 欧美性猛交99久久久久99按摩| 亚洲日本激情| 美女性感视频久久久| 欧美一区1区三区3区公司| 欧美天天影院| 一本久久精品一区二区| 日韩特黄影片| 欧美成人中文字幕在线| 一区视频在线| 欧美a级一区| 久久午夜国产精品| 国产一区二区av| 99视频一区二区| 一本一本久久|