游戏中心 - 发送和接收数据

发布于 2024-10-10 02:35:46 字数 1867 浏览 0 评论 0原文

编辑: 我已经创建了一个干净的新项目,但仍然无法运行。请下载它,有一些代码可供查看,对于专业人士或任何远程体验者来说可能很容易看出我做错了什么。只是想发送该整数。

http://www.2shared.com/file/fPOCLlg5/gkTest.html

您好,

我正在尝试在我的 iphone 游戏中实现 Game Center 多人游戏,但无法理解我手头上的 Apple 文档和来自第三方的有关发送和接收数据的示例。

有人可以解释一下苹果官方文档中的代码示例吗: http://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/GameKit_Guide/MatchesandVoice/MatchesandVoice.html#//apple_ref/doc/uid/TP40008304-CH10-SW4

或帮助我弄清楚了我提供的这个示例代码。它是一个预构建的类,用于处理所有游戏中心任务,并且用于发送和接收数据的示例如下:

- (void) sendPosition
{
    NSError *error;
    PositionPacket msg;
    msg.messageKind = PositionMessage;
    msg.x = currentPosition.x;
    msg.y = currentPosition.y;
    NSData *packet = [NSData dataWithBytes:&msg length:sizeof(PositionPacket)];
    [match sendDataToAllPlayers: packet withDataMode: GKMatchSendDataUnreliable error:&error];
    if (error != nil)
    {
        // handle the error
    }
}

接收:

- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID
{
    Packet *p = (Packet*)[data bytes];
    if (p.messageKind == PositionMessage)
        // handle a position message.
}

我关于官方文档中的这段代码的大问题是:

PositionPacket 在哪里code>/数据包从何而来? 假设当您想要发送/接收数据时,您可以像这样调用它们:

[self sendPosition];

或者

[self match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID];

我应该输入什么作为比赛、数据和玩家ID?

例如,我有一个名为“score”的 int,但是没有一个我需要使用的特殊键吗?

EDIT:
I have made a clean, new project, but still can't get it working. Please download it, there is a little code to look at and probably easy for a professional or anyone remotely experience to see whats I am doing wrong. Just trying to send that integer.

http://www.2shared.com/file/fPOCLlg5/gkTest.html

Hi

I am trying to implement Game Center multiplayer in my iphone game and having trouble understanding the samples I have at hand in the Apple Docs and from third parties concerning sending and receiving data.

Could someone please explain the code samples in the Official Apple docs here please:
http://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/GameKit_Guide/MatchesandVoice/MatchesandVoice.html#//apple_ref/doc/uid/TP40008304-CH10-SW4

Or help me figure out this sample code I was supplied with. Its a prebuilt class, made to handle all the game center tasks and a sample from it for sending and receiving data would be this:

- (void) sendPosition
{
    NSError *error;
    PositionPacket msg;
    msg.messageKind = PositionMessage;
    msg.x = currentPosition.x;
    msg.y = currentPosition.y;
    NSData *packet = [NSData dataWithBytes:&msg length:sizeof(PositionPacket)];
    [match sendDataToAllPlayers: packet withDataMode: GKMatchSendDataUnreliable error:&error];
    if (error != nil)
    {
        // handle the error
    }
}

And receiving:

- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID
{
    Packet *p = (Packet*)[data bytes];
    if (p.messageKind == PositionMessage)
        // handle a position message.
}

My big question about this code form the official docs is:

Where does PositionPacket/Packet come from?
And assuming when you want to send/receive data you call them like so:

[self sendPosition];

or

[self match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID];

What do I enter as the match, data and playerID?

E.g. I have an int named 'score' but is there not a special key I need to use something?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

2024-10-17 02:35:46

在此示例中,PositionPacket 只是一个结构体。然后,下面的行将该结构放入 NSData 中,它只是一个“字节桶”对象。

NSData *packet = [NSData dataWithBytes: &msg length: sizeof(PositionPacket)];

因此,如果您只想发送 int 分数,则可以使用如下所示的 sendScore 方法:

- (void) sendScore
{
    NSError *error;
    int myScore = self.score;
    NSData *packet = [NSData dataWithBytes:&myScore length:sizeof(myScore)];
    [match sendDataToAllPlayers: packet withDataMode: GKMatchSendDataUnreliable error: &error];
    if (error != nil)
    {
        // handle the error
    }
}

通常,您需要一个结构体,以便有一些附加信息可以让接收者知道它是什么类型的数据。在这个例子中,这就是这一行的目的:

msg.messageKind = PositionMessage;

一般来说,你可以发送任何你想要封装在 NSData 对象中的东西,因为它只是一个字节桶。您可以发送原始类型,例如整数,或示例中的结构,甚至 NSObject(只要它们实现 NSCoding)。您应该阅读 NSKeyedArchiver、NSCoding 和 NSData 以获取有关以这种方式发送和接收 NSObject 的更多信息。以下是 Apple 关于 Archving 的参考文档。

至于接收,您不调用该方法,而是由套件调用您的方法。这就是所谓的“委托方法”(用 Cocoa 的说法)或“回调方法”。您可以将其视为您的应用程序可以异步接收的“电话”。通过实现带有签名的方法:

- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID;

...您是在说“我可以接听这种电话。”因此,当 GameKit 代表您从另一个玩家接收数据时,它会发现您想要接收此类回调,然后调用该方法 - 然后由您根据接收到的内容更新内部应用程序状态。

继续这个例子,如果你发送了上面描述的简单的“除了一个整数”消息,你可以像这样实现这个方法:

- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID
{
    int* receivedScorePtr = (int*)[data bytes];
    int receivedScore = *receivedScorePtr;
    [self updateScore: received forPlayer: playerID];
}

当然,假设你有一个名为 updateScore:forPlayer: 的方法,它会更新一张分数表。

您可以在此博客条目中找到有关委托和委托方法如何工作的更一般性讨论/说明:http://mohrt.blogspot.com/2010/01/cocoa-and-delegates.html

添加:使用提问者发布的代码,我做了一些修改并制作了一个适用于这个简单用例的版本。 通过 GameCenter 发送一个整数的测试应用程序的工作版本 我对代码的质量,或者说它对任何事情的适用性。其中 99.9% 都不是我写的 - 请不要将我在这里发布的内容视为对其中出现的任何内容的认可。

学到的一个教训(我不知道,所以我放在这里希望对其他人有帮助)是您不能在模拟器中使用配对服务。这意味着您需要两台开发配置的 iOS 设备来测试此场景,并且对于重要的程序,可能需要两台开发计算机来同时调试这两个设备。这个问题花费了我最多的时间来解决这个问题。

In this example, the PositionPacket is just a struct. The following line then puts that struct into an NSData which is just a "byte bucket" object.

NSData *packet = [NSData dataWithBytes: &msg length: sizeof(PositionPacket)];

So if you just wanted to send an int score, you could have a sendScore method that looked like this:

- (void) sendScore
{
    NSError *error;
    int myScore = self.score;
    NSData *packet = [NSData dataWithBytes:&myScore length:sizeof(myScore)];
    [match sendDataToAllPlayers: packet withDataMode: GKMatchSendDataUnreliable error: &error];
    if (error != nil)
    {
        // handle the error
    }
}

Typically, you'll want a struct so that there's some additional information that lets the receivers know what kind of data it is. In the example, that would have been the purpose of this line:

msg.messageKind = PositionMessage;

In general, you can send anything you want encapsulated in an NSData object, since it's just a byte bucket. You can send primitive types like ints, or structs as in the example, or even NSObjects (as long as they implement NSCoding). You should read up on NSKeyedArchiver, NSCoding, and NSData for more information on sending and receiving NSObjects in this way. Here is Apple's reference document on Archving.

As for receiving, YOU don't call the method, it gets called ON you by the Kit. It's what's called a "delegate method" (in Cocoa parlance) or a "callback method." You can think of it like a "phone call" that your app can receive asynchronously. By implementing a method with the signature:

- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID;

...you are saying "I can receive this kind of phone call." So when the GameKit receives data on your behalf from another player, it will see that you want to receive callbacks of that kind and will then call that method -- then it's up to you to update your internal application state based on what is received.

To continue with this example, if you had sent the simple "nothing but an integer" message described above, you might implement that method like this:

- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID
{
    int* receivedScorePtr = (int*)[data bytes];
    int receivedScore = *receivedScorePtr;
    [self updateScore: received forPlayer: playerID];
}

That is, of course, assuming that you have a method called updateScore:forPlayer: that would update a table of scores.

You can find a more general discussion/explanation of how delegates and delegate methods work at this blog entry: http://mohrt.blogspot.com/2010/01/cocoa-and-delegates.html

ADDED: Using code the asker posted, I made a few modifications and produced a version that "works" for this bare bones use case. Working Version of Test App To Send One Integer Through GameCenter I make no claims about the quality of the code, or its suitability for, well, anything at all. I didn't write 99.9% of it - please don't take my posting of it here as an endorsement of anything that appears in it.

One lesson learned (that I didn't know, so I'm putting here in hopes that it helps others) is that you can't use the Matchmaking service with the simulator. This means that you need two development-provisioned iOS devices in order to test this scenario, and likely, for non-trivial programs, two development machines to debug both devices simultaneously. This problem cost me the most time while figuring this out.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文