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

天行健 君子當自強而不息

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


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


公告

導航

統(tǒng)計

常用鏈接

隨筆分類(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>
            国产精品v欧美精品∨日韩| 亚洲欧美日韩一区二区| 亚洲亚洲精品在线观看 | 欧美黑人国产人伦爽爽爽| 欧美日韩在线视频一区| 欧美国产先锋| 黄色成人片子| 羞羞视频在线观看欧美| 亚洲一区二区日本| 欧美激情精品久久久久| 老司机免费视频久久| 国产精品自拍网站| 亚洲一区二区视频在线观看| 日韩网站在线观看| 欧美成年人网站| 欧美成人伊人久久综合网| 国产一区二区视频在线观看| 亚洲欧美日韩国产一区二区三区| 亚洲一区二区不卡免费| 欧美日韩国产色视频| 亚洲黄页视频免费观看| 一区二区在线观看视频| 久久精品99国产精品| 久久尤物视频| 亚洲福利视频二区| 麻豆精品网站| 亚洲精品久久久蜜桃| 亚洲国产一区二区a毛片| 米奇777超碰欧美日韩亚洲| 欧美成人黑人xx视频免费观看| 伊人狠狠色j香婷婷综合| 久久久久久久欧美精品| 久久嫩草精品久久久精品一| 黄色影院成人| 乱码第一页成人| 91久久综合| 亚洲一区成人| 国产日韩精品一区二区三区在线| 欧美一级淫片播放口| 久久在线视频在线| 亚洲人成精品久久久久| 欧美日韩另类字幕中文| 亚洲一区3d动漫同人无遮挡| 欧美在线免费观看| 国产曰批免费观看久久久| 久久久久久久999| 亚洲人成毛片在线播放| 香港久久久电影| 国内偷自视频区视频综合| 久久久中精品2020中文| 亚洲麻豆视频| 久久久www成人免费精品| 亚洲人成在线播放| 国产精品久久久久久久久久免费看 | 欧美大片在线看免费观看| 亚洲精品少妇30p| 欧美一区日韩一区| 亚洲高清视频在线| 国产精品sm| 久久久一区二区| 亚洲天堂成人| 欧美高清一区二区| 亚洲主播在线播放| 伊人久久噜噜噜躁狠狠躁| 欧美日韩一区二区免费在线观看| 香蕉尹人综合在线观看| 亚洲国产综合在线| 久久久在线视频| 亚洲天堂免费观看| 在线看片欧美| 国产精品综合网站| 欧美国产日韩a欧美在线观看| 亚洲一区成人| 亚洲欧洲一区二区在线播放| 欧美在线观看网站| 9久re热视频在线精品| 韩日精品中文字幕| 国产精品成人一区二区网站软件 | 亚洲深夜av| 亚洲丶国产丶欧美一区二区三区| 国产精品成av人在线视午夜片| 久久精品一区二区国产| 亚洲一区3d动漫同人无遮挡| 亚洲国产精品123| 久久久久久久久蜜桃| 亚洲在线一区二区三区| 亚洲青涩在线| 一区二区亚洲欧洲国产日韩| 国产伦精品一区二区三| 国产精品豆花视频| 欧美日韩精品在线视频| 欧美大片在线观看| 男人天堂欧美日韩| 久久婷婷综合激情| 久久久久久夜精品精品免费| 亚洲综合久久久久| 亚洲专区一二三| 在线亚洲精品福利网址导航| 日韩视频亚洲视频| 日韩一级视频免费观看在线| 亚洲黄一区二区| 亚洲国产专区校园欧美| 亚洲国产经典视频| 91久久久亚洲精品| 亚洲精品1234| 亚洲人成在线播放| 亚洲精品免费看| 亚洲日本aⅴ片在线观看香蕉| 亚洲人成高清| 日韩亚洲成人av在线| 亚洲精品美女在线观看播放| 亚洲人成免费| 亚洲美女精品久久| 一级日韩一区在线观看| 亚洲桃花岛网站| 99精品国产一区二区青青牛奶| 99精品国产高清一区二区| 在线视频精品一区| 亚洲欧美伊人| 久久精品亚洲| 欧美成人一区二区| 欧美另类视频在线| 国产精品国产三级国产aⅴ入口| 国产精品入口日韩视频大尺度| 国产精品久久久久影院色老大| 国产精品视屏| 好吊色欧美一区二区三区视频| 亚洲高清色综合| 一本大道久久a久久精二百| 亚洲一区二区三区在线观看视频| 欧美永久精品| 欧美国产1区2区| 日韩午夜免费| 久久国产精品一区二区三区四区 | 雨宫琴音一区二区在线| 亚洲欧洲日本专区| 亚洲一区二区日本| 久久欧美肥婆一二区| 亚洲欧洲日韩在线| 亚洲一区二区在线播放| 久久久99免费视频| 欧美日韩国产在线播放| 国产欧美一区二区精品忘忧草| 亚洲国产毛片完整版| 亚洲社区在线观看| 久热精品在线| 夜夜爽99久久国产综合精品女不卡| 欧美一级在线播放| 欧美日韩成人综合天天影院| 国产视频精品网| 日韩亚洲精品电影| 久久婷婷麻豆| 一区二区三区高清不卡| 久久久精彩视频| 国产精品免费小视频| 亚洲激情一区二区三区| 欧美在线二区| 亚洲日本精品国产第一区| 欧美夜福利tv在线| 欧美日韩影院| 亚洲精品乱码久久久久久蜜桃91| 午夜激情综合网| 亚洲日本黄色| 噜噜噜噜噜久久久久久91 | 一区二区在线看| 欧美亚洲视频一区二区| 亚洲日本成人网| 美腿丝袜亚洲色图| 激情久久中文字幕| 久久9热精品视频| 亚洲午夜羞羞片| 欧美日韩另类丝袜其他| 亚洲人线精品午夜| 欧美电影在线观看完整版| 久久久7777| 国内精品久久久久影院优| 性欧美激情精品| 亚洲视频视频在线| 欧美日韩一区二区三区在线视频| 亚洲国产视频直播| 蘑菇福利视频一区播放| 久久精品国产久精国产爱| 国产区精品视频| 欧美在线91| 午夜精品亚洲| 国产日韩精品一区| 久久岛国电影| 欧美尤物一区| 精品电影在线观看| 久久一区二区三区超碰国产精品| 午夜精品久久久久久久男人的天堂| 欧美性一区二区| 一区二区三区精品视频在线观看| 亚洲人成在线观看一区二区| 欧美国产综合一区二区| 日韩视频在线永久播放| 亚洲精品一区二区三区99| 欧美激情第8页| 亚洲视频观看| 亚洲一区在线观看视频|