【问题标题】:Projectiles firing from wrong players从错误的玩家发射的弹丸
【发布时间】:2012-06-03 01:32:16
【问题描述】:

我正在为我的朋友们开发一款小游戏。到目前为止,我已经建立了正确的网络,两个玩家都可以飞来飞去,而且一切都是同步的。

现在我添加了像这样生成的射弹(激光):

if (_mou.LeftButton == ButtonState.Pressed 
         && oldState.LeftButton 
         != ButtonState.Released)               
         {
             if (timeSinceShot > timePerShot)
            {
                timeSinceShot = 0;
                bulletRotation = rotation; //Rotation of the players ship
                laser.addLaser(myID, bulletRotation, localPosition);
            }
         }

这很好用,它会从我的船上发射激光,但还没有显示出来。

现在当我开火时,我称之为:

om.Write(bulletRotation); //Sends the rotation to the server

当服务器收到它时,它会将它发送回所有玩家,包括射击的玩家。

这是我在客户端接收数据并将其写入激光器列表的方式:

if (who != myID)
{
   try
   {
      float laserR = msg.ReadFloat();
      laser.addLaser(who, laserR, player.players[i].position);
   }
   catch { }
}

现在,当我在 2 个客户端上对其进行测试并开火时,我可以看到自己在第二个客户端上开火,这很好。然而,它不仅会在第二个客户端上触发,还会在我客户端的第二个播放器上触发。

编辑:谁是 RemoteUniqueIdentifier,myID 是客户端 RemoteUniqueIdentifier

这是我的问题的图片。 http://i.stack.imgur.com/CYJyW.png (由于我没有 10 个代表,因此无法上传。)

编辑 2:

这是服务器将数据发送给所有玩家的方式:

foreach (NetConnection player in server.Connections)
                    {
                        // ... send information about every other player (actually including self)
                        foreach (NetConnection otherPlayer in server.Connections)
                        {
                            // send position update about 'otherPlayer' to 'player'
                            NetOutgoingMessage om = server.CreateMessage();

                            // write who this position is for
                            om.Write(player.RemoteUniqueIdentifier);
                            om.Write(otherPlayer.RemoteUniqueIdentifier);

                            if (otherPlayer.Tag == null)
                                otherPlayer.Tag = new float[4];

                            float[] pos = otherPlayer.Tag as float[];

                            om.Write(pos[0]); // velocity X
                            om.Write(pos[1]); // velocity X
                            om.Write(pos[2]); // rotation

                            if (!noLasers)
                            {
                                om.Write(pos[3]); // bullet rotation
                            }

                            // send message
                            server.SendMessage(om, player, NetDeliveryMethod.Unreliable);
                        }
                    }

【问题讨论】:

  • i 中的players[i] 是什么???
  • for (int i = 0; i
  • 好的,当你调试并设置断点放在IF后面时,它执行了多少次?
  • 取决于在线玩家的数量,所以2个玩家会导致它运行两次。
  • 好的,所以如果if (who != myID)后面的代码被执行两次,这就是你有两个激光的原因。顺便说一句,我喜欢你的游戏:)

标签: c# networking xna


【解决方案1】:

如果RemoteUniqueIdentifier 是某个类的对象,而您试图天真地通过网络传递它,您将永远无法测试本地版本和从服务器获取的版本是否相等。

“另一边”的重构对象将始终具有无法与原始对象进行比较的引用。

在这种情况下,您可以选择从RemoteUniqueIdentifier 切换到某些不可变类型,例如intGuid,即使string 也可以使用。

【讨论】:

  • RemoteUniqueIdentifier 在服务器端和客户端是一样的。
  • 请告诉我它是什么?那是某种类吗?
  • 我正在使用 Lidgren 网络库。 RemoteUniqueIdentifier 是一个随机生成的密钥,只要您连接到服务器,它就会重新生成。
  • NetIncomingMessage 消息; msg.SenderConnection.RemoteUniqueIdentifier
  • 我下载了完整的库,发现 RemoteUniqueIdentifier 是 long 类型。反正你调试的时候,if后面的代码输入两次吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多