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

天行健 君子當自強而不息

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

公告

導航

統計

常用鏈接

隨筆分類(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>
            亚洲一区二区三区视频播放| 日韩一区二区精品| 欧美日韩二区三区| 美女久久一区| 欧美一区激情| 午夜精品久久久久久久蜜桃app| 精品成人一区二区| 国产日韩欧美一二三区| 国产精品乱子久久久久| 国产精品成av人在线视午夜片 | 国产精品揄拍一区二区| 欧美成人精品1314www| 久久久久国产一区二区三区四区| 亚洲一区视频在线| 亚洲视频观看| 一本色道婷婷久久欧美| 亚洲三级影院| 亚洲精品久久久一区二区三区| 欧美午夜精品一区二区三区| 欧美午夜不卡视频| 国产伦精品一区二区三区四区免费 | 亚洲一区尤物| 亚洲欧美日韩电影| 久久成人综合网| 欧美xart系列在线观看| 欧美日韩视频在线一区二区| 国产精品日韩在线| 国产精品入口尤物| 亚洲成人在线观看视频| 亚洲一区不卡| 欧美激情一区二区三区| 亚洲专区一区| 欧美四级电影网站| 亚洲激情六月丁香| 久久久久亚洲综合| 亚洲免费在线视频| 国产欧美韩日| 亚洲一区二区三区免费在线观看| 久久成人av少妇免费| 国产精品免费福利| 亚洲一区二区三区高清不卡| 亚洲欧洲综合| 欧美成人日韩| 亚洲精品四区| 最近中文字幕日韩精品 | 欧美日本亚洲视频| 伊人蜜桃色噜噜激情综合| 久久国产精品99国产| 午夜精品福利一区二区三区av | 极品少妇一区二区三区精品视频 | 久久色在线观看| 亚洲欧美日韩一区二区| 国产精品视频免费在线观看| 亚洲一区二区在线免费观看| aa日韩免费精品视频一| 欧美日韩美女在线| 亚洲制服少妇| 久久久www免费人成黑人精品| 含羞草久久爱69一区| 欧美国产免费| 国产精品看片你懂得| 欧美一区二视频| 欧美福利视频| 欧美一区亚洲一区| 乱码第一页成人| 亚洲欧美另类在线观看| 久久久久久自在自线| 亚洲午夜精品一区二区| 久久精品人人做人人综合| 最新国产乱人伦偷精品免费网站 | 国产亚洲精品高潮| 亚洲高清不卡在线| 国产精品视频一| 亚洲黄一区二区| 欲色影视综合吧| 亚洲欧美一区二区原创| 亚洲美女少妇无套啪啪呻吟| 欧美中文字幕在线| 久久久最新网址| 国产视频在线观看一区二区三区 | 欧美中在线观看| 欧美日韩国产色站一区二区三区| 久久久爽爽爽美女图片| 欧美高清成人| 欧美三级第一页| 一区二区三区精品久久久| 亚洲三级视频| 先锋影音国产一区| 亚洲国产精品免费| 美日韩精品视频| 欧美国产一区二区三区激情无套| 激情久久中文字幕| 久久久精品动漫| 免费在线观看精品| 亚洲激情欧美| 国产精品久久久一区麻豆最新章节 | 另类春色校园亚洲| 亚洲第一成人在线| 欧美日韩一区二区在线| 亚洲亚洲精品三区日韩精品在线视频| 亚洲尤物在线视频观看| 国产一区二区三区在线观看网站 | 午夜精品短视频| 老司机成人在线视频| 中文久久精品| 亚洲电影免费| 欧美性视频网站| 久久久久久久999精品视频| 亚洲国产人成综合网站| 亚洲影视在线| 欧美在线网址| 日韩视频一区二区三区| 久久久久久午夜| 亚洲免费中文| 一区二区三区 在线观看视| 亚洲国产91精品在线观看| 国产亚洲欧洲| 国产欧美日韩91| 欧美亚日韩国产aⅴ精品中极品| 欧美本精品男人aⅴ天堂| 亚洲一区二区三区四区五区黄| 欧美成人免费网| 猫咪成人在线观看| 久久夜色精品国产欧美乱| 久久精品国产一区二区电影| 亚洲自拍偷拍福利| 欧美三级免费| 午夜精品久久久久久久99黑人| 亚洲看片免费| 99国产一区| 亚洲综合导航| 久久久精品网| 欧美日韩一区在线观看视频| 欧美精品一区在线观看| 欧美日韩精品在线观看| 国产精品久久九九| 国产日韩欧美另类| 在线看成人片| 亚洲免费在线观看| 老司机免费视频一区二区三区 | 欧美午夜视频网站| 国产综合色在线| 宅男精品视频| 亚洲国产成人午夜在线一区| 亚洲激情国产精品| 欧美一区二区三区电影在线观看| 老色批av在线精品| 国产精品日韩专区| 99热这里只有精品8| 久久久中精品2020中文| 日韩视频一区二区在线观看| 亚洲第一偷拍| 欧美影视一区| 国产精品美女久久久久久2018 | 久久精品国产99| 国产精品久久久久久久app| 亚洲国产成人91精品| 欧美在线播放| 亚洲一区二区久久| 欧美三级乱码| 亚洲综合精品四区| 亚洲自拍电影| 国产亚洲一区在线播放| 欧美在线播放视频| 亚洲欧美在线aaa| 国产日韩亚洲欧美| 久久九九精品| 久久夜色精品| 亚洲精品日韩在线观看| 欧美国产日韩一二三区| 免费国产自线拍一欧美视频| 91久久久久| 亚洲香蕉在线观看| 国产日韩欧美在线播放不卡| 久久久久久久久久久成人| 久久久夜精品| 欧美日韩成人在线播放| 韩日在线一区| 欧美成人在线网站| 欧美精品国产一区| 久久国产精品99久久久久久老狼| 香蕉亚洲视频| 亚洲少妇诱惑| 久久综合伊人77777麻豆| 亚洲欧美另类在线| 免费亚洲一区二区| 久久精品av麻豆的观看方式| 免费成人美女女| 欧美在线一级va免费观看| 老色鬼久久亚洲一区二区| 久久精品在线免费观看| 欧美三级韩国三级日本三斤| 国产精品外国| 亚洲一区免费| 亚洲欧美国产va在线影院| 欧美va亚洲va香蕉在线| 久久久久久综合| 国产精品一二三四区| 亚洲愉拍自拍另类高清精品| 亚洲欧洲精品一区|