• <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>

            天行健 君子當(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 閱讀(290) 評(píng)論(0)  編輯 收藏 引用


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


            公告

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關(guān)鏈接

            搜索

            最新評(píng)論

            狠狠综合久久综合中文88| 国产一区二区三精品久久久无广告| 久久久这里有精品| 久久天天躁狠狠躁夜夜躁2O2O| 国产精品久久久久久影院| 久久久亚洲精品蜜桃臀| 久久只有这里有精品4| avtt天堂网久久精品| 欧美与黑人午夜性猛交久久久| 午夜精品久久久久久中宇| 99久久综合国产精品二区| 国产69精品久久久久9999APGF| 久久综合狠狠综合久久激情 | 久久精品国产半推半就| 久久久久亚洲av毛片大| AV无码久久久久不卡网站下载| 欧洲国产伦久久久久久久| 91久久精品电影| 精品久久久久久| 久久精品国产亚洲av影院| 人妻无码精品久久亚瑟影视 | 成人午夜精品久久久久久久小说| 久久天天躁夜夜躁狠狠躁2022| 99久久精品国产一区二区蜜芽| 久久精品人人做人人爽电影蜜月| 要久久爱在线免费观看| 久久97久久97精品免视看秋霞 | 久久久久久综合一区中文字幕| 精品多毛少妇人妻AV免费久久| 国产精品内射久久久久欢欢| 色综合久久中文综合网| 久久精品国产半推半就| 色偷偷888欧美精品久久久| 国产欧美一区二区久久| 国产91色综合久久免费| 国产精品久久久久影视不卡| 久久精品国产亚洲av影院| 国产精品视频久久久| 久久久久国产一级毛片高清版| 94久久国产乱子伦精品免费| 99精品久久久久久久婷婷|