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

天行健 君子當自強而不息

Getting Online with Multiplayer Gaming(9)

 

Storing Player Information

Players in the game are only allowed to move around and swing their weapons (hitting
other players). The server will want to track every player’s current state (walking,
standing still, swinging their weapons, or being hurt), the coordinates in the world,
the direction they are facing, and the speed they are walking (if they are walking).

This player data is stored inside a structure called sPlayer. Because all connected
players in the game need their own set of unique data, an array of sPlayer structures
are allocated to store the information. Both the number of player structures
to allocate and the number of players to allow to join the game session are stored
in the macro MAX_PLAYERS, which is currently set to 8.

The sPlayer structure is as follows (with supporting state definition 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

typedef 
struct sPlayer
{
    
bool    connected;

    
char    name[256];
    DPNID   player_id;

    
long    last_state;      
    
long    last_update_time;
    
long    latency;

    
float   x_pos, y_pos, z_pos;
    
float   direction;
    
float   speed;

    
///////////////////////////////////////////////////////////////
    
    sPlayer()
    {
        ZeroMemory(
thissizeof(*this));
    }
} *sPlayerPtr;

There’s not much to the sPlayer structure; you have a flag if the player is connected,
the name of the player, the player’s DirectPlay identification number, the
player’s current state (as defined by the state macros), time of last state change,
network latency value, the player’s coordinates, direction, and walking speed.

The variables in sPlayer are self-explanatory, except for latency. Remember that
latency is the delay resulting from network transmission. By storing the time it takes
for a message to go from the server to the client (and vice versa), time-based calculations
become more synchronized between the server and client.

Speaking of time-based calculations, that's the purpose of the last_update_time variable. Whenever
the server updates all players, it needs to know the time that has elapsed between
updates. Every time a player state is changed (from the client), the last_update_time variable is set
to the current time (minus the latency time).

Time is also used to control actions. If a player swings a weapon, the server refuses
to accept further state changes from the client until the swing weapon state is
cleared. How does the state clear? After a set amount of time, that’s how! After one
second passes, the update player cycle clears the player’s state back to idle, allowing
the client to begin sending new state-change messages.

On the subject of sending messages, take a look at how the server deals with the
incoming network messages.

 

Handling Messages

You’ve already seen DirectPlay messages in action, but now you focus on the game
action messages (state changes). Because DirectPlay has only three functions of
interest when handling incoming network messages (create_player, destroy_player, and
receive), the server will need to convert the incoming networking message to messages
more suited to game-play.

The server receives messages from clients via the DirectPlay network’s receive function.
Those messages are stored in the pReceiveData buffer contained within the
DPNMSG_RECEIVE structure passed to the receive function. That buffer is cast into a
more usable game message, which is stuffed into the game message queue.

The server game code doesn’t deal directly with network messages. Those are handled
by a small subset of functions that take the incoming messages and convert
them into game messages (which are entered into the message queue). The server
game code works with those game messages.

Because there can be many different types of game messages, a generic message
container structure is needed. Each message starts with a header that stores
the type of message, the total size of the message data (in bytes) including the
header, and a DirectPlay player identification number that is usually set to the
player sending the message.

I’ve taken the liberty of separating the header into another structure, making
it possible to reuse the header in every game message:

#define MESSAGES_PER_FRAME 64 // number of messages to process per frame
#define MAX_MESSAGES 1024 // number of message to allocate for message queue

typedef struct sMsgHeader
{
  long type; // type of message (MSG_*)
  long size; // size of data to send
  DPNID player_id; // player performing action
} *sMsgHeaderPtr;

Because there can be many different game messages, you first need a generic message
container capable of holding all the different game messages. This generic
message container is a structure as follows:

typedef struct sMsg // the message queue message structure
{
  sMsgHeader header;
  char data[512];
} *sMsgPtr;

Pretty basic, isn’t it? The sMsg structure needs to contain only the message header
and an array of chars used to store the specific message data. To use a specific message,
you can cast the sMsg structure into another structure to access the data.

For example, here is a structure that represents a state-change message:

typedef struct sStateChangeMsg
{
  sMsgHeader header;

  long state; // State message (STATE_*)
  float x_pos, y_pos, z_pos;
  float direction;
  float speed;
  long latency;
} *sStateChangeMsgPtr;

 

To cast the sMsg structure that contains a state-change message into a usable
sStateChangeMsg structure, you can use this code bit:

sMsg Msg; // Assuming message contains data
sStateChangeMsg *scm = (sStateChangeMsg*) Msg;

// Access state-change message data
scm->state = STATE_IDLE;
scm->direction = 1.57f;

In addition to the state-change message, the following message structures are used
in the network game:

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;

Each message also has a related macro that both the server and client use. Those
message macros are the values store in the sMsgHeader::type variable. Those message
type macros are as follows:

#define MSG_CREATE_PLAYER    1
#define MSG_SEND_PLAYER_INFO 2
#define MSG_DESTROY_PLAYER   3
#define MSG_STATE_CHANGE     4

You see each message in action in the sections “Processing Game Messages” and
“Working with Game Clients,” later in this chapter, but for now, check out how the
server maintains these game-related messages.

posted on 2007-12-18 19:52 lovedday 閱讀(271) 評論(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>
            99视频精品全国免费| 亚洲激情视频| 欧美一区激情视频在线观看| 午夜亚洲性色视频| 激情婷婷亚洲| 亚洲国产日韩综合一区| 欧美日韩大片| 欧美一区二区三区电影在线观看| 午夜国产精品视频免费体验区| 韩日精品在线| 日韩午夜黄色| 9久re热视频在线精品| 国产精品一区二区女厕厕| 久久全国免费视频| 欧美区视频在线观看| 欧美一区二区三区免费在线看| 久久精品人人做人人综合| 亚洲精品视频一区二区三区| 亚洲午夜免费福利视频| 亚洲第一福利视频| 中文国产成人精品久久一| 一区在线观看视频| 日韩视频二区| 亚洲国产精品成人一区二区 | 亚洲一区二区高清视频| 欧美一区在线看| 亚洲视频一起| 嫩草成人www欧美| 欧美一区二区三区视频在线观看| 狂野欧美一区| 久久疯狂做爰流白浆xx| 欧美日韩在线播放三区四区| 乱码第一页成人| 国产精品最新自拍| 亚洲美女啪啪| 亚洲人成网站777色婷婷| 午夜精品一区二区在线观看| 亚洲午夜激情网页| 免费观看成人鲁鲁鲁鲁鲁视频| 性高湖久久久久久久久| 欧美日韩性生活视频| 欧美激情一区在线观看| 国内免费精品永久在线视频| 亚洲无毛电影| 中文av一区二区| 欧美激情亚洲国产| 欧美电影电视剧在线观看| 国产欧美亚洲一区| 亚洲自拍偷拍一区| 亚洲一区精品在线| 欧美日韩免费网站| 91久久久一线二线三线品牌| 91久久久亚洲精品| 狂野欧美性猛交xxxx巴西| 麻豆精品传媒视频| 国产一区二区av| 欧美在线播放一区二区| 久久国产精品黑丝| 国产喷白浆一区二区三区| 亚洲午夜一级| 欧美一级一区| 国产日韩欧美一区二区三区四区 | 另类专区欧美制服同性| 韩国v欧美v日本v亚洲v| 久久国产精品毛片| 久久亚洲图片| 在线看不卡av| 欧美精品激情在线观看| 亚洲九九爱视频| 亚洲午夜免费福利视频| 国产精品xvideos88| 在线亚洲观看| 久久久久99| 亚洲成人中文| 欧美日本三区| 亚洲午夜视频在线| 久久久国产一区二区三区| 亚洲午夜精品在线| 久久国产欧美精品| ●精品国产综合乱码久久久久| 奶水喷射视频一区| 99精品视频免费全部在线| 午夜电影亚洲| 在线欧美一区| 欧美日韩免费一区二区三区视频| 亚洲一级在线| 欧美a级片网站| 中文精品视频| 国精品一区二区| 欧美成人69av| 亚洲自拍偷拍色片视频| 男女激情视频一区| 亚洲一区二区欧美| 狠狠色丁香婷综合久久| 欧美精品在线观看播放| 欧美一区二区三区婷婷月色| 亚洲国产导航| 久久都是精品| 国产精品99久久久久久白浆小说| 国产欧美一区二区三区国产幕精品| 老**午夜毛片一区二区三区| 亚洲午夜精品| 亚洲黄色一区| 久久一区二区精品| 亚洲欧美高清| 日韩视频在线一区二区三区| 国产一区二区视频在线观看 | 久久精品国产清自在天天线| 99精品视频免费观看| 欧美成年人网站| 久久精品99国产精品| 在线午夜精品| 亚洲激情一区二区| 一区二区三区在线高清| 国产欧美日韩亚洲精品| 欧美人交a欧美精品| 久久精品人人爽| 欧美一区二区日韩| 一区二区三区视频观看| 亚洲欧洲日产国产综合网| 老司机午夜精品| 久久久91精品国产一区二区精品| 亚洲香蕉网站| 亚洲视频免费看| 亚洲最新视频在线| 亚洲黄色视屏| 亚洲国产天堂久久综合网| 国内外成人免费激情在线视频网站 | 亚洲午夜精品网| 日韩午夜在线播放| 亚洲三级免费观看| 亚洲国产毛片完整版| 欧美国产高潮xxxx1819| 免费久久99精品国产| 久久婷婷av| 美女精品在线| 欧美电影在线观看完整版| 久久中文在线| 蜜臀av性久久久久蜜臀aⅴ| 久久在线免费观看视频| 浪潮色综合久久天堂| 久久午夜精品| 欧美成人伊人久久综合网| 免费在线观看日韩欧美| 免费观看30秒视频久久| 欧美成年人在线观看| 亚洲黄色免费| 一本色道久久综合亚洲二区三区| 99re在线精品| 亚洲午夜一区二区| 香蕉成人伊视频在线观看| 亚洲一区国产| 久久久精品免费视频| 美女网站久久| 亚洲人成77777在线观看网| 日韩亚洲精品在线| 午夜视频在线观看一区| 久久久之久亚州精品露出| 男女激情视频一区| 欧美色播在线播放| 国产日韩av一区二区| 亚洲国产精品福利| 一区二区三区欧美日韩| 亚欧美中日韩视频| 免费美女久久99| 亚洲免费观看视频| 久久riav二区三区| 欧美jizz19性欧美| 国产精品伦理| 亚洲黄色免费| 欧美一区二区三区免费观看| 免费观看亚洲视频大全| 亚洲美女区一区| 久久国产精品黑丝| 欧美体内谢she精2性欧美| 国产一区二区三区久久 | 久久久久久久久久久久久久一区 | 久久成年人视频| 欧美日韩精品一区二区在线播放| 国产精品欧美风情| 亚洲人午夜精品免费| 欧美专区在线观看一区| 亚洲国产精品久久久久久女王| 亚洲综合电影一区二区三区| 欧美.www| 国产有码在线一区二区视频| 一区二区电影免费观看| 美国成人直播| 亚洲一区在线播放| 欧美国产精品日韩| 国内揄拍国内精品少妇国语| 亚洲视频在线观看视频| 欧美成在线视频| 欧美专区在线观看| 国产精品亚洲网站| 中日韩在线视频| 亚洲激情在线激情| 久久天天躁夜夜躁狠狠躁2022| 国产欧美日本一区二区三区| 一区二区三区日韩精品|