具有多人连接的实时多人游戏真的很慢
Realtime Multiplayer game with MultipeerConnectivity really slow
我正在 Swift 中使用 MultipeerConnectivityFramework 开发多人游戏。我的问题是,这不是很顺利,而且延迟相对较高。
我的意思是延迟很高,连接的 phone 上的更改不会立即发生,但延迟会使游戏卡住。
所以从简单开始:每当玩家触摸屏幕时,一个节点应该在两个屏幕上移动。所以我当然需要在用户每次触摸屏幕时发送一条消息。所以在我的 touchesBegan
方法中我调用了发送方法:
func sendMessage(dict:NSDictionary){
let messageDict = dict
let messageData = NSJSONSerialization.dataWithJSONObject(messageDict, options: NSJSONWritingOptions.PrettyPrinted, error: nil)
appDelegate.mpcHandler.session.sendData(messageData, toPeers: appDelegate.mpcHandler.session.connectedPeers, withMode: MCSessionSendDataMode.Reliable, error: nil)
}
像那样:
sendMessage(["moved":MoveDirection.Left.rawValue])
然后,我在另一台设备上接收它,运行更新节点位置的函数:
func handleReceivedDataWithNotification(notification:NSNotification){
let userInfo = notification.userInfo! as Dictionary
let receivedData:NSData = userInfo["data"] as NSData
let message = NSJSONSerialization.JSONObjectWithData(receivedData, options: NSJSONReadingOptions.AllowFragments, error: nil) as NSDictionary
if let mess: AnyObject = message.objectForKey("lostState"){
gameOver = true
createGameOverLabel(mess as String)
}else if let mess: AnyObject = message.objectForKey("higher"){
println(mess)
let coNumber = mess as Int
println(yourNumber)
if(coNumber > yourNumber){
leftAndRight = true
}else{
leftAndRight = false
}
}else if let mess:AnyObject = message.objectForKey("moved"){
var moved = mess as Int
var move = moveHeight/3
switch moved{
case MoveDirection.Left.rawValue:
moveNode.position.x -= move
case MoveDirection.Right.rawValue:
moveNode.position.x += move
case MoveDirection.Down.rawValue:
moveNode.position.y -= move
case MoveDirection.Up.rawValue:
moveNode.position.y += move
default:
break
}
}
}
所以我的问题是:我做错了什么吗?我已经在真实的 iPhone 6 和真实的 iPhone 5 上对其进行了测试。除了 GameCenter 或其他方式之外,还有其他替代方法可以使 sending/receiving 运行得更快吗?
我怀疑您的问题是您试图从后台线程而不是主线程更新 UI。结果显然是 UI 反映接收到的数据之前的长时间延迟。
收到数据后,didReceiveData:fromPeer 在后台线程上调用,如果您 post 来自该方法的通知,则不会在 UI 线程上。
尝试使用 dispatch_async
dispatch_async(dispatch_get_main_queue(), {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "handleReceivedDataWithNotification:", name: "MPC_DidReceiveDataNotification", object: nil)
})
我正在 Swift 中使用 MultipeerConnectivityFramework 开发多人游戏。我的问题是,这不是很顺利,而且延迟相对较高。
我的意思是延迟很高,连接的 phone 上的更改不会立即发生,但延迟会使游戏卡住。
所以从简单开始:每当玩家触摸屏幕时,一个节点应该在两个屏幕上移动。所以我当然需要在用户每次触摸屏幕时发送一条消息。所以在我的 touchesBegan
方法中我调用了发送方法:
func sendMessage(dict:NSDictionary){
let messageDict = dict
let messageData = NSJSONSerialization.dataWithJSONObject(messageDict, options: NSJSONWritingOptions.PrettyPrinted, error: nil)
appDelegate.mpcHandler.session.sendData(messageData, toPeers: appDelegate.mpcHandler.session.connectedPeers, withMode: MCSessionSendDataMode.Reliable, error: nil)
}
像那样:
sendMessage(["moved":MoveDirection.Left.rawValue])
然后,我在另一台设备上接收它,运行更新节点位置的函数:
func handleReceivedDataWithNotification(notification:NSNotification){
let userInfo = notification.userInfo! as Dictionary
let receivedData:NSData = userInfo["data"] as NSData
let message = NSJSONSerialization.JSONObjectWithData(receivedData, options: NSJSONReadingOptions.AllowFragments, error: nil) as NSDictionary
if let mess: AnyObject = message.objectForKey("lostState"){
gameOver = true
createGameOverLabel(mess as String)
}else if let mess: AnyObject = message.objectForKey("higher"){
println(mess)
let coNumber = mess as Int
println(yourNumber)
if(coNumber > yourNumber){
leftAndRight = true
}else{
leftAndRight = false
}
}else if let mess:AnyObject = message.objectForKey("moved"){
var moved = mess as Int
var move = moveHeight/3
switch moved{
case MoveDirection.Left.rawValue:
moveNode.position.x -= move
case MoveDirection.Right.rawValue:
moveNode.position.x += move
case MoveDirection.Down.rawValue:
moveNode.position.y -= move
case MoveDirection.Up.rawValue:
moveNode.position.y += move
default:
break
}
}
}
所以我的问题是:我做错了什么吗?我已经在真实的 iPhone 6 和真实的 iPhone 5 上对其进行了测试。除了 GameCenter 或其他方式之外,还有其他替代方法可以使 sending/receiving 运行得更快吗?
我怀疑您的问题是您试图从后台线程而不是主线程更新 UI。结果显然是 UI 反映接收到的数据之前的长时间延迟。
收到数据后,didReceiveData:fromPeer 在后台线程上调用,如果您 post 来自该方法的通知,则不会在 UI 线程上。
尝试使用 dispatch_async
dispatch_async(dispatch_get_main_queue(), {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "handleReceivedDataWithNotification:", name: "MPC_DidReceiveDataNotification", object: nil)
})