通常我能够自己解决问题,但我必须再次寻求帮助。如果事情不连贯,我会事先道歉,因为看起来我有点发烧。
我目前在XNA中制作非常简单的游戏。这是一个2D头顶射击游戏。唯一的动作是玩家射击子弹。问题是,我想让它成为多人游戏(玩家在同一个网络中)。
我考虑过以下方法:
其中一名玩家托管服务器
服务器创建新的世界(由玩家和子弹组成)并在新的线程中更新它:
while (true)
{
lock (world) world.update();
Thread.Sleep(worldUpdatePeriod);
}
服务器为每个必须处理的玩家创建新线程
玩家连接到服务器
他们应定期从服务器接收信息:
class Asset
{
string type;
Vector2 position;
}
他们应该能够从键盘和鼠标发送输入以进行移动和拍摄。
现在,到了这一点。播放器能够向服务器发送三种类型的消息:
“键盘”
string header = "CAN READ";
lock (streamWriter) { streamWriter.WriteLine(header); }
服务器,在每个客户端的单独线程中等待消息
streamReader = new StreamReader(networkStream);
streamWriter = new StreamWriter(networkStream);
streamWriter.AutoFlush = true;
while (true)
{
if (networkStream.DataAvailable)
{
string header;
lock (streamReader)
{
header = Convert.ToString(streamReader.ReadLine());
Console.WriteLine($"Header received: {header}");
handleHeader(header);
}
}
}
现在,如果标题是“CAN READ”
服务器
case "CAN READ":
if (streamWriter.BaseStream.CanRead)
{
lock (streamWriter)
{
streamWriter.WriteLine(server.world.assets.Count);
foreach (var asset in server.world.assets)
{
streamWriter.WriteLine(asset.type);
streamWriter.WriteLine(asset.position.X);
streamWriter.WriteLine(asset.position.Y);
}
}
}
break;
客户端
int assetCount = Convert.ToInt32(streamReader.ReadLine());
List<Asset> receivedAssets = new List<Asset>();
lock (streamReader)
{
for (int i = 0; i < assetCount; i++)
{
string type = Convert.ToString(streamReader.ReadLine());
int x = Convert.ToInt32(streamReader.ReadLine());
int y = Convert.ToInt32(streamReader.ReadLine());
receivedAssets.Add(new Asset(type, new Vector2(x, y)));
}
return receivedAssets;
}
当然,Client类和handleClient类具有单独的streamReaders nad streamWriters。
你明白了。我试图将来自Server的每个WriteLine()与来自Client的ReadLine()进行匹配,依此类推。它工作正常!直到我向混合物添加用户输入。
一旦我发送键盘输入(如上所示匹配),它似乎工作,偶尔会有System.FormatException,这意味着某些ReadLine()读错了WriteLine()。我能够抓住并重试。
一旦我发送鼠标输入,一切都会变成地狱。不匹配的异常变得更加频繁到“游戏”无法播放的程度。所以我想知道我的方法是否有问题。我为问题的长度道歉,我试图简明扼要,但也觉得需要提供背景。谢谢,如果你把它做到最后,我很乐意回答任何进一步的问题,因为我试图在过去几天解决它。
答案 0 :(得分:1)
我已经阅读了Andrew为我提供的链接,并且我已经能够使其工作。怎么样?使用TCP客户端(设置连接,从客户端读取输入)和UDP客户端(将资产广播到每个客户端)。只是张贴以防万一有人在将来遇到这样的问题,我非常怀疑。
干杯!