6

編集:私はクリーンで新しいプロジェクトを作成しましたが、それでも機能させることができません。それをダウンロードしてください。見るべき小さなコードがあり、おそらく専門家やリモートで経験する人なら誰でも、私が間違っていることを簡単に確認できます。その整数を送信しようとしているだけです。

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

やあ

私はiPhoneゲームにGameCenterマルチプレイヤーを実装しようとしていますが、AppleDocsやサードパーティからのデータの送受信に関するサンプルを理解するのに苦労しています。

誰かがここで公式アップルドキュメントのコードサンプルを説明してもらえますか: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/はどこPacketから来たのですか?そして、データを送受信したいときに、次のように呼び出すと仮定します。

[self sendPosition];

また

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

試合、データ、playerIDとして何を入力しますか?

たとえば、「score」という名前のintがありますが、何かを使用するために必要な特別なキーはありませんか?

4

1 に答える 1

18

この例では、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オブジェクトは単なるバイトバケットであるため、NSDataオブジェクトにカプセル化したいものは何でも送信できます。例のようにint、struct、またはNSObjects(NSCodingを実装している場合)などのプリミティブ型を送信できます。この方法でNSObjectを送受信する方法の詳細については、NSKeyedArchiver、NSCoding、およびNSDataを参照してください。これは、 Archvingに関するAppleのリファレンスドキュメントです。

受信に関しては、メソッドを呼び出さず、キットによって呼び出されます。これは、「デリゲートメソッド」(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

追加: askerが投稿したコードを使用して、いくつかの変更を加え、このベアボーンのユースケースで「機能する」バージョンを作成しました。 GameCenterを介して1つの整数を送信するためのテストアプリの動作バージョン私は、コードの品質、またはコードの適合性については何も主張しません。私はその99.9%を書きませんでした-そこに現れるものを支持するものとして、ここに私の投稿を受け取らないでください。

学んだ教訓の1つ(私は知らなかったので、他の人に役立つことを願ってここに置いています)は、シミュレーターでマッチメイキングサービスを使用できないということです。つまり、このシナリオをテストするには、開発用にプロビジョニングされた2台のiOSデバイスが必要であり、重要なプログラムの場合は、2台の開発マシンで両方のデバイスを同時にデバッグする必要があります。これを理解している間、この問題は私に最も多くの時間を費やしました。

于 2011-01-01T17:09:53.990 に答える