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

天行健 君子當(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>
            欧美一级淫片aaaaaaa视频| 老巨人导航500精品| 亚洲狼人精品一区二区三区| 男人插女人欧美| 亚洲毛片一区二区| 99精品国产福利在线观看免费| 欧美日韩精品系列| 欧美一区二区免费视频| 久久激情综合网| 亚洲欧洲偷拍精品| 一区二区黄色| 国产亚洲一本大道中文在线| 免费精品99久久国产综合精品| 麻豆精品视频| 亚洲素人在线| 午夜在线精品| 亚洲高清电影| 亚洲精品欧美在线| 国产日产精品一区二区三区四区的观看方式 | 免费的成人av| 这里只有精品丝袜| 午夜久久久久久| 亚洲国产成人av在线| 日韩午夜黄色| 国产在线精品一区二区夜色| 欧美成人按摩| 国产精品a久久久久久| 久久综合久久综合久久| 欧美日本韩国| 美女黄色成人网| 欧美性色综合| 亚洲第一福利社区| 国产精品五区| 亚洲人成艺术| 在线日本高清免费不卡| 一区二区三区精品在线| 亚洲成人中文| 亚洲欧美日本伦理| 日韩视频免费| 久久综合99re88久久爱| 午夜激情综合网| 欧美极品一区| 欧美成人国产一区二区| 国产精品国产亚洲精品看不卡15| 欧美成年人视频| 国产自产在线视频一区| 一区二区免费在线播放| 亚洲人成啪啪网站| 久久人人爽人人爽| 久久精品免费看| 国产精品永久免费观看| 日韩亚洲一区在线播放| 亚洲日本成人| 久久久久九九九九| 久久久久一区二区| 国产日韩欧美视频| 亚洲图片欧美一区| 亚洲综合色在线| 欧美理论电影在线观看| 欧美国产精品久久| 亚洲第一福利视频| 久久一综合视频| 久久青青草综合| 极品少妇一区二区| 久久久久国产精品一区| 久久人人爽人人| 影音欧美亚洲| 久久婷婷国产综合国色天香| 久久日韩粉嫩一区二区三区| 国产一区二区三区四区老人| 欧美一区二区三区免费视| 欧美一区国产在线| 国产亚洲欧美一区二区| 新片速递亚洲合集欧美合集| 久久久久99| 怡红院精品视频在线观看极品| 久久一区精品| 亚洲欧洲精品一区二区三区不卡| 日韩一区二区精品| 欧美视频在线一区二区三区| 亚洲网站视频| 久久不射2019中文字幕| 国语自产精品视频在线看抢先版结局 | 欧美a级理论片| 亚洲二区在线视频| 欧美福利一区二区| 一本色道久久88精品综合| 中文在线一区| 国产精品中文在线| 久久精品亚洲一区二区| 免费一级欧美片在线观看| 亚洲第一狼人社区| 欧美精品乱人伦久久久久久| 亚洲精品裸体| 欧美亚洲一区二区三区| 国内精品亚洲| 美女视频黄免费的久久| 亚洲日本理论电影| 性娇小13――14欧美| 国内伊人久久久久久网站视频 | 亚洲国产精品久久久久| 99国产精品| 国产精品热久久久久夜色精品三区 | 99re8这里有精品热视频免费| 欧美色图一区二区三区| 校园春色国产精品| 亚洲国产欧美另类丝袜| 亚洲一区欧美二区| 在线不卡亚洲| 国产精品久久一级| 久久嫩草精品久久久久| 国产精品99久久久久久久女警| 久久影院午夜片一区| 国产精品99久久久久久宅男| 激情五月婷婷综合| 国产精品久久久久久av福利软件| 久久视频一区二区| 亚洲视频一区二区| 亚洲国产你懂的| 久久女同精品一区二区| 亚洲免费视频观看| 日韩亚洲欧美综合| 在线欧美三区| 国产亚洲精品自拍| 国产精品久久久久久久久久三级| 欧美成人一区二区三区片免费| 午夜国产一区| 亚洲一区免费在线观看| 亚洲精品久久久一区二区三区| 久久综合国产精品台湾中文娱乐网| 亚洲中字在线| 日韩午夜三级在线| 91久久嫩草影院一区二区| 黄色免费成人| 国产亚洲欧洲| 国产一区99| 国产欧美日韩亚洲| 国产精品美女久久久久久久| 欧美日韩一视频区二区| 欧美日韩不卡| 欧美人妖在线观看| 欧美激情小视频| 欧美黄免费看| 欧美黄色大片网站| 欧美黄色免费网站| 欧美激情综合五月色丁香小说| 欧美成人a∨高清免费观看| 免费成人在线观看视频| 猛干欧美女孩| 免费毛片一区二区三区久久久| 免费高清在线视频一区·| 久久综合久色欧美综合狠狠 | 欧美一区91| 久久国产福利| 久久亚洲一区二区三区四区| 噜噜噜躁狠狠躁狠狠精品视频| 免费黄网站欧美| 欧美日本精品在线| 国产精品地址| 国产欧美日韩综合一区在线观看| 国产拍揄自揄精品视频麻豆| 国产视频在线一区二区| 在线观看成人小视频| 91久久精品国产91久久| 亚洲婷婷在线| 欧美在线免费观看| 欧美成ee人免费视频| 亚洲欧洲另类国产综合| 亚洲一级黄色片| 性欧美大战久久久久久久免费观看| 久久精品国产一区二区电影 | 欧美国产日本| 国产精品久久久久99| 国产一区二区精品| 亚洲精品你懂的| 亚洲欧美视频在线观看| 麻豆精品在线播放| 亚洲乱码久久| 欧美一二区视频| 欧美激情第二页| 国产欧美一区二区三区久久人妖| 亚洲成人影音| 亚洲欧美综合另类中字| 欧美国产精品v| 亚洲欧美日韩精品久久| 麻豆成人综合网| 国产精品亚洲激情| 亚洲欧洲另类国产综合| 久久av资源网| 91久久久精品| 久久久久88色偷偷免费| 欧美日韩一区二区在线观看视频| 国内久久精品视频| 亚洲一级片在线看| 亚洲高清av在线| 久久国产精品亚洲77777| 欧美色精品天天在线观看视频| 在线观看视频免费一区二区三区| 亚洲综合社区| 亚洲精品一二区|