2011-01-01 110 views
6

EDIT: Tôi đã thực hiện một dự án mới, sạch sẽ, nhưng vẫn không thể làm cho nó hoạt động. Xin vui lòng tải xuống, có một chút mã để xem xét và có lẽ dễ dàng cho một chuyên gia hoặc bất cứ ai từ xa kinh nghiệm để xem những gì tôi đang làm sai. Chỉ cố gắng gửi số nguyên đó.Trung tâm trò chơi - Gửi và nhận dữ liệu

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

Hi

Tôi cố gắng để thực hiện Game Center nhiều người trong game iphone của tôi và gặp khó khăn trong việc hiểu các mẫu tôi có trong tay trong Apple Documents và từ các bên thứ ba liên quan đến việc gửi và nhận dữ liệu.

Ai đó có thể xin giải thích các mẫu mã trong các tài liệu chính thức của Apple tại đây xin vui lòng: http://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/GameKit_Guide/MatchesandVoice/MatchesandVoice.html#//apple_ref/doc/uid/TP40008304-CH10-SW4

Hoặc giúp tôi tìm ra mẫu này code tôi đã được cung cấp với. Của nó một lớp được xây dựng sẵn, thực hiện để xử lý tất cả các nhiệm vụ trung tâm trò chơi và một mẫu từ nó để gửi và nhận dữ liệu sẽ được này:

- (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 
    } 
} 

Và nhận:

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

câu hỏi lớn của tôi về mã này tạo tài liệu chính thức là:

Nơi nào PositionPacket/Packet có nguồn gốc từ đâu? Và giả sử khi bạn muốn gửi/nhận dữ liệu bạn gọi cho họ như vậy:

[self sendPosition]; 

hoặc

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

nào để nhập gì như trận đấu, dữ liệu và playerid?

Ví dụ: Tôi có một 'điểm số' có tên int nhưng không có một khóa đặc biệt nào tôi cần để sử dụng một cái gì đó?

Trả lời

18

Trong ví dụ này, PositionPacket chỉ là một cấu trúc. Dòng sau đây đặt cấu trúc đó vào một NSData mà chỉ là một đối tượng "byte byte".

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

Vì vậy, nếu bạn chỉ muốn gửi một số int, bạn có thể có một phương pháp sendScore trông như thế này:

- (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 
    } 
} 

Thông thường, bạn sẽ muốn có một struct để có một số thông tin bổ sung cho phép người nhận biết loại dữ liệu đó là gì. Trong ví dụ này, mà có thể đã được mục đích của dòng này:

msg.messageKind = PositionMessage; 

Nói chung, bạn có thể gửi bất cứ điều gì bạn muốn gói gọn trong một đối tượng NSData, vì nó chỉ là một cái xô byte. Bạn có thể gửi các kiểu nguyên thủy như ints, hoặc structs như trong ví dụ, hoặc thậm chí NSObjects (miễn là chúng thực hiện NSCoding). Bạn nên đọc trên NSKeyedArchiver, NSCoding và NSData để biết thêm thông tin về cách gửi và nhận NSObject theo cách này. Đây là tài liệu tham khảo của Apple trên Archving.

Đối với việc nhận, bạn không gọi phương thức, nó được gọi là BẬT cho bạn bằng Kit.Đó là những gì được gọi là một "phương pháp đại biểu" (trong ca cao Cocoa) hoặc một "phương pháp gọi lại." Bạn có thể nghĩ nó giống như "cuộc gọi điện thoại" mà ứng dụng của bạn có thể nhận không đồng bộ. Bằng cách triển khai phương thức có chữ ký:

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

... bạn đang nói "Tôi có thể nhận được loại cuộc gọi điện thoại này". Vì vậy, khi GameKit nhận dữ liệu thay mặt bạn từ người chơi khác, nó sẽ thấy rằng bạn muốn nhận các cuộc gọi lại thuộc loại đó và sau đó sẽ gọi phương thức đó - sau đó bạn cập nhật trạng thái ứng dụng nội bộ của mình dựa trên nội dung được nhận.

Tiếp tục với ví dụ này, nếu bạn đã gửi "gì, nhưng một số nguyên" đơn giản thông điệp mô tả ở trên, bạn có thể thực hiện phương pháp như thế này:

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

Đó là, tất nhiên, giả định rằng bạn có một phương thức gọi là updateScore: forPlayer: có thể cập nhật một bảng điểm.

Bạn có thể tìm thấy một cuộc thảo luận tổng quát hơn/giải thích về cách đại biểu và phương pháp đại biểu làm việc tại mục này blog: http://mohrt.blogspot.com/2010/01/cocoa-and-delegates.html

thêm: Sử dụng mã hỏi được đăng, tôi thực hiện một vài thay đổi và sản xuất một phiên bản đó "hoạt động" cho xương trần này sử dụng trường hợp. Working Version of Test App To Send One Integer Through GameCenter Tôi không tuyên bố về chất lượng của mã, hoặc sự phù hợp của nó đối với, tốt, bất cứ điều gì cả. Tôi không viết 99,9% của nó - xin vui lòng không đưa tôi đăng nó ở đây như là một sự chứng thực của bất cứ điều gì xuất hiện trong đó.

Một bài học kinh nghiệm (mà tôi không biết, vì vậy tôi đặt ở đây với hy vọng rằng nó sẽ giúp người khác) là bạn không thể sử dụng dịch vụ Matchmaking với trình mô phỏng. Điều này có nghĩa là bạn cần hai thiết bị iOS được cấp phát triển để thử nghiệm kịch bản này, và có thể, đối với các chương trình không tầm thường, hai máy phát triển để gỡ lỗi cả hai thiết bị cùng một lúc. Vấn đề này khiến tôi tốn nhiều thời gian nhất trong khi tìm ra điều này.

+0

Điều này thật tuyệt vời, cảm ơn rất nhiều! Làm cho ý nghĩa hơn nhiều, mặc dù như đối với 'trận đấu' này chỉ là một GKMatch mới tôi có thể tuyên bố hoặc nó cần phải được từ một địa điểm cụ thể? –

+0

Trong trường hợp của phương pháp này, trận đấu được chuyển cho bạn. Tôi nghi ngờ rằng trong trường hợp đơn giản (tức là chỉ có một trò chơi diễn ra tại một thời điểm) mà bạn không cần phải lo lắng về nó/làm bất cứ điều gì với nó trong các phương pháp này. Nếu bạn đang tìm kiếm thêm thông tin về các trận đấu nói chung, họ đến từ dịch vụ Matchmaking. Chi tiết tại đây: http://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/GameKit_Guide/MatchesandVoice/MatchesandVoice.html#//apple_ref/doc/uid/TP40008304-CH10-SW9 – ipmcc

+0

Tôi hiểu rằng nhận được phương thức dữ liệu cho chúng ta GKMatch 'match' nhưng' match' đến từ đâu trong phương thức sendScore? –

Các vấn đề liên quan