• <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)自強而不息

            Getting Online with Multiplayer Gaming(10)

             

            DirectPlay Messages to Game Messages

            As I’ve mentioned before, the server needs to convert the DirectPlay network messages
            into the game-related messages you’ve just read about. You accomplish this by
            processing incoming player connection, disconnection, and receive data messages from
            DirectPlay and converting those messages into game messages.

            To accomplish this conversion of messages, you derive a class from cNetworkServer
            and override the create_player, destroy_player, and receive functions:

            class cServer : public cNetworkServer
            {
            protected:
                
            virtual bool create_player(const DPNMSG_CREATE_PLAYER* msg);
                
            virtual bool destroy_player(const DPNMSG_DESTROY_PLAYER* msg);
                
            virtual bool receive(const DPNMSG_RECEIVE* msg);
            };

            Because I’m using the System Core to handle application processing, a problem
            quickly arises when dealing with the network. The network component and application
            component are two separate entities, which means that neither component is
            allowed to modify the other's private data.

            As Figure 19.11 illustrates, the network component needs a way to siphon incoming
            messages into the application, which by chance is handled by creating three public
            functions that match the network class’s functions.

            To use the three message functions in the application component, you construct a
            derived cFramework class that contains the three public functions as follows:

            class cApp : public cFramework
            {
            private:
                HWND                m_controls[3];
                
                CRITICAL_SECTION    m_msg_cs;
                cMesh               m_level_mesh;

                GUID*               m_adapter_guid;
                cNetworkAdapter     m_adapter;
                cServer             m_server;

                
            long                m_connected_player_num; 
                sPlayer*            m_players;

                sMsg*               m_msgs;
                
            long                m_msg_head;
                
            long                m_msg_tail;

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

            public:
                
            void set_adapter_guid(GUID* adapter_guid)
                {
                    m_adapter_guid = adapter_guid;
                }

            public:
                cApp();
                
                
            virtual bool init();
                
            virtual bool frame();
                
            virtual void shutdown();

                
            void create_player(const DPNMSG_CREATE_PLAYER* msg);
                
            void destroy_player(const DPNMSG_DESTROY_PLAYER* msg);
                
            void receive(const DPNMSG_RECEIVE* msg);

            private:
                
            bool select_adapter();
                
            void setup_app_window();
                
            bool init_game();
                
            bool host_game();    

                
            void list_players();

                
            void process_queue_msg();
                
            void update_players();
                
            void update_network();
                
            void update_latency();

                
            bool send_player_info(const sMsg* msg, DPNID to);
                
            bool queue_msg(const void* msg);
                
            bool add_player(const sMsg* msg);
                
            void remove_player(const sMsg* msg);
                
            bool player_state_change(const sMsg* msg);

                
            bool send_network_msg(void* msg, long send_flags, int to);

                
            bool check_intersect(cMesh* mesh,
                                     
            float x_start, float y_start, float z_start,
                                     
            float x_end,   float y_end,   float z_end);
            };

            To start sending DirectPlay messages to the application class, you code the overridden
            cServer functions to call upon the matching application functions. In order for the
            server to know which application class instance to send messages to, you need to
            declare a global variable that points to the current application class instance in use:

            cApp* g_app;
            cNetworkAdapter* g_adapter;

            Inside the derived application class’s constructor, you then point the global
            g_app variable to the application class instance:

            cApp::cApp()
            {    
                m_adapter_guid = NULL;
                m_msgs         = NULL;
                m_msg_head     = 0;
                m_msg_tail     = 0;

                m_connected_player_num = 0;
                m_players = NULL;

                g_app     = 
            this;
                g_adapter = &m_adapter;

                InitializeCriticalSection(&m_msg_cs);
            }

            Now, you can code the network server component to send incoming messages to
            the application object defined by the global g_app pointer:


            bool cServer::create_player(const DPNMSG_CREATE_PLAYER* msg)
            {
                g_app->create_player(msg);

                
            return true;
            }

            bool cServer::destroy_player(const DPNMSG_DESTROY_PLAYER* msg)
            {
                g_app->destroy_player(msg);

                
            return true;
            }

            bool cServer::receive(const DPNMSG_RECEIVE* msg)
            {
                g_app->receive(msg);

                
            return true;
            }

            The server component is now complete and is forwarding network messages to the
            application class. To convert those network messages to game-related messages,
            the application class must contain the following public functions:


            void cApp::create_player(const DPNMSG_CREATE_PLAYER* msg)
            {
                sCreatePlayerMsg create_msg;

                create_msg.header.type      = MSG_CREATE_PLAYER;
                create_msg.header.size      = 
            sizeof(sCreatePlayerMsg);
                create_msg.header.player_id = msg->dpnidPlayer;

                queue_msg(&create_msg);
            }

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

            void cApp::destroy_player(const DPNMSG_DESTROY_PLAYER* msg)
            {
                sDestroyPlayerMsg destroy_msg;

                destroy_msg.header.type      = MSG_DESTROY_PLAYER;
                destroy_msg.header.size      = 
            sizeof(sDestroyPlayerMsg);
                destroy_msg.header.player_id = msg->dpnidPlayer;

                queue_msg(&destroy_msg);
            }

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

            void cApp::receive(const DPNMSG_RECEIVE* msg)
            {
                sMsgHeader* header = (sMsgHeader*) msg->pReceiveData;

                
            // make sure it is a valid message type and queue it
                switch(header->type)
                {
                
            case MSG_SEND_PLAYER_INFO:
                
            case MSG_STATE_CHANGE:
                    queue_msg(msg->pReceiveData);
                    
            break;
                }
            }

            You can see that in each of the three functions, I’m constructing a game-related
            message using the data from the DirectPlay messages provided. When a player tries
            to connect to the server, a create-player message is created that stores the connecting
            player’s DirectPlayer identification number (along with the message type and size).
            That create-player message is then queued.

            As for players disconnecting from the game, a disconnect-player message is constructed
            and queued. Last, whenever data (other than a system message) is
            received from a client, the cApp::receive function checks it to see whether it’s a valid
            message type, and if so, the message is queued.

            I keep mentioning the message queue and how the previously shown function adds
            messages to the queue. Next, you find out what the queue is and how it works.

            posted on 2007-12-18 20:35 lovedday 閱讀(235) 評論(0)  編輯 收藏 引用


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


            公告

            導(dǎo)航

            統(tǒng)計

            常用鏈接

            隨筆分類(178)

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

            搜索

            最新評論

            国产精品久久久久久久久鸭| 国产亚洲精午夜久久久久久| 久久精品久久久久观看99水蜜桃| 欧美伊人久久大香线蕉综合 | 日韩十八禁一区二区久久| 天天影视色香欲综合久久| 久久精品国产亚洲AV久| 99久久99久久精品国产| 久久人与动人物a级毛片| 国产精品久久久天天影视| 久久亚洲精品国产精品婷婷| 久久99国产精品久久99| 亚洲а∨天堂久久精品| 国产精品成人99久久久久 | 国产成人久久精品二区三区| 久久婷婷人人澡人人爽人人爱 | 午夜不卡久久精品无码免费| 国产L精品国产亚洲区久久| 亚洲中文精品久久久久久不卡| 国产精品免费久久久久电影网| 青青草原精品99久久精品66| 青青久久精品国产免费看| 国产午夜精品久久久久九九电影| 久久精品aⅴ无码中文字字幕重口 久久精品a亚洲国产v高清不卡 | 国产精品久久久99| 72种姿势欧美久久久久大黄蕉| 亚洲а∨天堂久久精品9966| 久久精品人妻一区二区三区| 色成年激情久久综合| 国产精品久久久久无码av| 久久99精品久久久久久动态图| 狼狼综合久久久久综合网| 久久人人爽爽爽人久久久| A级毛片无码久久精品免费| 亚洲国产精品综合久久网络 | 亚洲国产成人久久综合一| 久久综合九色综合网站| 亚洲va久久久噜噜噜久久男同| 久久久老熟女一区二区三区| 久久午夜伦鲁片免费无码| 国产精品久久久亚洲|