网络——从Lobby移动到实际游戏

问题

创建了会话后,你想给所有玩家时间用来聚集、聊天、让他们可以示意已经准备好可以进行游戏了。

解决方案

XNA在会话状态和玩家的IsReady属性中带有基本的lobby功能。

会话开始于Lobby状态。只有主机可以调用NetworkSession. StartGame方法,这个方法将会话移动到Playing状态。主机可以基于所有玩家的IsReady状态做出决定。

工作原理

当会话创建后,会话的SessionState属性会拥有Lobby值。 当在这个状态时,你需要让所有在这个会话中的玩家可以示意他们已经做好了准备,这可以通过将他们的IsReady设为true做到。这个值可以被会话中的所有玩家读取:

case GameState.InSession:

...{

    switch (networkSession.SessionState)

...    {

        case NetworkSessionState.Lobby:

        ...{

            if (keybState != lastKeybState) 

...            {

                if (keybState.IsKeyDown(Keys.R))

                {

                    LocalNetworkGamer localGamer = networkSession.LocalGamers[0]; 

                    localGamer.IsReady = !localGamer.IsReady;

                }

            }

        }

        break;

        case NetworkSessionState.Playing:

...        {

        }

        break;

    }



    networkSession.Update(); 

}

主机需要检测是否所有玩家都将IsReady设为了true。最简单的方法是检查NetworkSess ion.IsEveryoneReady的值,如果所有人都准备好了,主机会调用NetworkSession.StartGame方法,这个方法将状态从Lobby移动到Playing:

case NetworkSessionState.Lobby:

...{

    if (keybState != lastKeybState)

...    {

        if (keybState.IsKeyDown(Keys.R))

...        {

            LocalNetworkGamer localGamer = networkSession.LocalGamers[0]; 

            localGamer.IsReady = !localGamer.IsReady;

        }

    }

    if (networkSession.IsHost)

    ...{

        if (networkSession.AllGamers.Count > 1) 

        ...{

            if (networkSession.IsEveryoneReady) 

            ...{

                networkSession.StartGame();

                log.Add("All players ready -- start the game!");

            }

        }

    }

}

break;

当状态改变至Playing时,会话会引发GameStarted事件,这个事件所有玩家都会进行监听。这样可以让他们绘制游戏屏幕并开始发送和接收游戏数据。

当主机决定结束游戏时,需要调用NetworkSession.EndGame方法,这个方法将所有玩家的IsReady重置为false并返回Lobby状态。

case NetworkSessionState.Playing:

...{

    if (networkSession.IsHost)

...    {

        if (keybState != lastKeybState) 

...        {

            if (keybState.IsKeyDown(Keys.E)) 

                ...{

                    networkSession.EndGame();

            }

        }

        }

}

break;

这会引发会话的GameEnded事件,所有玩家都可以监听这个事件,这样他们就可以,例如,绘制lobby图像。

代码

InSession状态包含大多数基本代码让多个玩家表示他们的IsReady,让主机从Lobby状态移动到Playing状态或返回:

case GameState.InSession:

...{

    switch (networkSession.SessionState)

    ...{

        case NetworkSessionState.Lobby:

        ...{

            if (keybState != lastKeybState)

...            {

                if (keybState.IsKeyDown(Keys.R))

...                {

                    LocalNetworkGamer localGamer = networkSession.LocalGamers[0]; localGamer.IsReady = !localGamer.IsReady;

                }

            }

            if (networkSession.IsHost)

...            {

                if (networkSession.AllGamers.Count > 1) 

                ...{

                    if (networkSession.IsEveryoneReady) 

                    ...{

                        networkSession.StartGame();

                        log.Add("All players ready -- start the game!");

                    } 

                }

            }

        }

        break;

        case NetworkSessionState.Playing:

...        {

            if (networkSession.IsHost)

...            {

                if (keybState != lastKeybState)

...                {

                    if (keybState.IsKeyDown(Keys.E))

...                    {

                        networkSession.EndGame();

                    }

                }

            }

        }

        break; 

    }

    networkSession.Update();

}

break;

你可能感兴趣的:(游戏)