我有一个游戏可以将一个玩家的数据发送给所有玩家。我无法弄清楚如何发送UIBezierPath对象。我将UIBezierPath对象存档到NSData中。
以下是我用来发送和接收数据的数据结构:
struct DataStruct {
var action: Action = Action.Nil
var point: CGPoint = CGPoint(x: 0.0, y: 0.0)
var path: NSData = NSData()
var speed: CGFloat = 0.0
}
在Struct中没有NSData,一切正常。有了它,我能够发送数据,但无法接收和getBytes()。我无法弄清楚如何编码和解码它。这是有道理的,因为DataStruct的sizeof()不是所发送数据的正确大小。但我无法找到这样的例子。非常感谢任何示例或帮助。我在发送和接收数据方面经验有限。
这是我存档和发送它的功能:
func sendData(action: Action, point: CGPoint, path: UIBezierPath, speed: CGFloat, mode: GKMatchSendDataMode) {
// update player position, velocity and angle
let pathData = NSKeyedArchiver.archivedDataWithRootObject(path)
var dataStruct = DataStruct(action: action, point: point, path: pathData, speed: speed)
let data: NSData = NSData(bytes: &dataStruct, length: sizeof(DataStruct))
do {
try GameCenterMatch.sendDataToAllPlayers(data, withDataMode: mode)
print("data sent: \(dataStruct)")
} catch {
print("data sent error")
}
}
以下是我接收它的功能的一部分:
func match(match: GKMatch, didReceiveData data: NSData, fromRemotePlayer player: GKPlayer) {
if GameCenterMatch == match {
var dataStruct = DataStruct()
data.getBytes(&dataStruct, length: sizeof(DataStruct))
print("data received: \(player.displayName), data: \(dataStruct)")
答案 0 :(得分:2)
我还没有这样做,但有一点突出的是当一些内容(路径)只是指向另一个字节数组的指针时,你发送一个字节数组。你会遇到与String相同的问题,因为sizeOf DataStruct是常量,并且不包括引用内容的内容,如NSData,String,object等,只包括它们的指针。
您应归档DataStruct,并在另一端发送和取消归档。
答案 1 :(得分:0)
感谢Michael的建议,我创建了一个编码和解码的类,它的工作原理!希望这将有助于其他人。
class DataClass: NSObject, NSCoding {
var action: ActionType
var point: CGPoint
var path: UIBezierPath
var speed: CGFloat
override init() {
self.action = ActionType.Nil
self.point = CGPoint(x: 0.0, y: 0.0)
self.path = UIBezierPath()
self.speed = 0.0
super.init()
}
init(action: ActionType, point: CGPoint, path: UIBezierPath, speed: CGFloat) {
self.action = action
self.point = point
self.path = path
self.speed = speed
super.init()
}
// MARK: NSCoding
required convenience init?(coder decoder: NSCoder) {
let action = ActionType(rawValue: decoder.decodeIntegerForKey("action")) ?? .Nil
let point = decoder.decodeCGPointForKey("point")
let path = decoder.decodeObjectForKey("path") as! UIBezierPath
let speed = CGFloat(decoder.decodeFloatForKey("speed"))
self.init(
action: action,
point: point,
path: path,
speed: speed
)
}
func encodeWithCoder(coder: NSCoder) {
coder.encodeInteger(action.rawValue, forKey: "action")
coder.encodeCGPoint(self.point, forKey: "point")
coder.encodeObject(self.path, forKey: "path")
coder.encodeFloat(Float(self.speed), forKey: "speed")
}
}