Game Center - Отправка и получение данных - PullRequest
6 голосов
/ 01 января 2011

EDIT: Я сделал чистый новый проект, но все еще не могу заставить его работать. Пожалуйста, загрузите его, здесь есть небольшой код, который, вероятно, будет легко найти профессионалу или кому-либо еще, чтобы понять, что я делаю неправильно. Просто пытаюсь отправить это целое число.

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

Привет

Я пытаюсь внедрить многопользовательский режим Game Center в свою игру для iphone, и у меня возникают проблемы с пониманием примеров, которые у меня есть в Apple Docs и от третьих лиц, касающихся отправки и получения данных.

Может кто-нибудь объяснить, пожалуйста, примеры кода в Официальных документах 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 / Packet? И, если вы хотите отправить / получить данные, вы называете их так:

[self sendPosition];

или

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

Что мне ввести в качестве совпадения, данных и идентификатора игрока?

например. У меня есть int с именем 'score', но нет ли специального ключа, который мне нужен для использования?

1 Ответ

18 голосов
/ 01 января 2011

В этом примере 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, так как это просто байт. Вы можете отправлять примитивные типы, такие как int, или структуры, как в примере, или даже NSObjects (при условии, что они реализуют NSCoding). Вы должны прочитать о NSKeyedArchiver, NSCoding и NSData для получения дополнительной информации об отправке и получении объектов NSO таким образом. Вот справочный документ Apple по Архивация .

Что касается получения, ВЫ не вызываете метод, он вызывается НА вас с помощью набора. Это то, что называется «метод делегата» (на языке какао) или «метод обратного вызова». Вы можете думать об этом как о «телефонном звонке», который ваше приложение может принимать асинхронно. Путем реализации метода с подписью:

- (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% из них - пожалуйста, не принимайте мои публикации здесь как одобрение всего, что появляется в нем.

Один извлеченный урок (которого я не знал, поэтому я надеюсь, что это поможет другим) заключается в том, что вы не можете использовать службу Matchmaking с симулятором. Это означает, что для тестирования этого сценария вам понадобятся два устройства iOS для разработки и, скорее всего, для нетривиальных программ - две машины для разработки для отладки обоих устройств одновременно. Эта проблема стоила мне больше всего времени при выяснении этого.

...