gpt4 book ai didi

ios - 无法收到游戏中心邀请

转载 作者:行者123 更新时间:2023-12-02 03:59:52 24 4
gpt4 key购买 nike

我正在尝试使用http://www.raywenderlich.com/3325/how-to-make-a-simple-multiplayer-game-with-game-center-tutorial-part-22上的教程,使用cocos2d为IOS开发一个实时多人游戏。

一切正常,包括自动匹配随机玩家,但邀请 friend 不起作用,因为其他设备无法收到邀请。

当我点击“邀请 friend ”按钮,然后使用标准游戏中心界面选择一个 friend 时,它说“等待(永远)”,但没有任何反应。我的 friend 无法收到来自游戏中心的邀请(没有通知)。

我可以通过使用附近的 friend 功能来邀请 friend (当在两台设备上均启用此功能时),但当附近的 friend 被禁用时,不会有邀请通知。

我花了很多时间在 Google 上搜索,发现了类似的情况,但没有解决方案。

一些有关可能答案的早期反馈:

  • 我使用两台设备(一台 iPhone 和一台 iPad),没有模拟器
  • iTunes connect 上的所有设置均正常,包括多人游戏设置
  • 我使用不同的测试帐户验证了两台设备均已连接到沙箱
  • 我已经检查了两台设备上游戏中心的通知设置
  • 我已经检查了所有代理/防火墙问题,并尝试了两台设备的 WiFi 和蜂窝网络
  • 两个设备/帐户均启用游戏邀请
  • 我已经检查了 bundle ID、应用版本 ID 等...
  • 两台设备均为 IOS 6.x,应用目标版本操作系统为 IOS 5.0
  • 我对游戏中心没有任何其他问题(排行榜、随机配对等......都很好)
  • 按照 Apple 文档中所述,在对用户进行身份验证后,我会尽快调用 informHandler 方法。

这是我的游戏中心助手类头文件:

#import <Foundation/Foundation.h>
#import <GameKit/GameKit.h>
@protocol GCHelperDelegate
- (void)matchStarted;
- (void)matchEnded;
- (void)match:(GKMatch *)match didReceiveData:(NSData *)data
fromPlayer:(NSString *)playerID;
- (void)inviteReceived;
@end

@interface GCHelper : NSObject <GKMatchmakerViewControllerDelegate, GKMatchDelegate>{
BOOL gameCenterAvailable;
BOOL userAuthenticated;

UIViewController *presentingViewController;
GKMatch *match;
BOOL matchStarted;
id <GCHelperDelegate> delegate;

NSMutableDictionary *playersDict;

GKInvite *pendingInvite;
NSArray *pendingPlayersToInvite;
NSMutableArray *unsentScores;
}

@property (retain) GKInvite *pendingInvite;
@property (retain) NSArray *pendingPlayersToInvite;

@property (assign, readonly) BOOL gameCenterAvailable;

@property (retain) NSMutableDictionary *playersDict;

@property (retain) UIViewController *presentingViewController;
@property (retain) GKMatch *match;
@property (assign) id <GCHelperDelegate> delegate;

- (void)findMatchWithMinPlayers:(int)minPlayers maxPlayers:(int)maxPlayers
viewController:(UIViewController *)viewController
delegate:(id<GCHelperDelegate>)theDelegate;

- (BOOL) reportAchievementIdentifier: (NSString*) identifier percentComplete: (float) percent;

+ (GCHelper *)sharedInstance;
- (void)authenticateLocalUser;

@end

这是游戏中心辅助类的实现

#import "GCHelper.h"

@implementation GCHelper

@synthesize gameCenterAvailable;

@synthesize presentingViewController;
@synthesize match;
@synthesize delegate;
@synthesize playersDict;
@synthesize pendingInvite;
@synthesize pendingPlayersToInvite;

#pragma mark Initialization

static GCHelper *sharedHelper = nil;
+ (GCHelper *) sharedInstance {
if (!sharedHelper) {
sharedHelper = [[GCHelper alloc] init];
}
return sharedHelper;
}
- (BOOL)isGameCenterAvailable {
// check for presence of GKLocalPlayer API
Class gcClass = (NSClassFromString(@"GKLocalPlayer"));

// check if the device is running iOS 4.1 or later
NSString *reqSysVer = @"4.1";
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
BOOL osVersionSupported = ([currSysVer compare:reqSysVer
options:NSNumericSearch] != NSOrderedAscending);

return (gcClass && osVersionSupported);
}
- (id)init {
if ((self = [super init])) {
gameCenterAvailable = [self isGameCenterAvailable];
if (gameCenterAvailable) {
NSNotificationCenter *nc =
[NSNotificationCenter defaultCenter];
[nc addObserver:self
selector:@selector(authenticationChanged)
name:GKPlayerAuthenticationDidChangeNotificationName
object:nil];
}
}
return self;
}
- (void)authenticationChanged {

if ([GKLocalPlayer localPlayer].isAuthenticated && !userAuthenticated) {
NSLog(@"Authentication changed: player authenticated.");
userAuthenticated = TRUE;

[GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite) {

NSLog(@"Received invite");
self.pendingInvite = acceptedInvite;
self.pendingPlayersToInvite = playersToInvite;
[delegate inviteReceived];

};

} else if (![GKLocalPlayer localPlayer].isAuthenticated && userAuthenticated) {
NSLog(@"Authentication changed: player not authenticated");
userAuthenticated = FALSE;
}

}
- (void)lookupPlayers {

NSLog(@"Looking up %d players...", match.playerIDs.count);
[GKPlayer loadPlayersForIdentifiers:match.playerIDs withCompletionHandler:^(NSArray *players, NSError *error) {

if (error != nil) {
NSLog(@"Error retrieving player info: %@", error.localizedDescription);
matchStarted = NO;
[delegate matchEnded];
} else {

// Populate players dict
self.playersDict = [NSMutableDictionary dictionaryWithCapacity:players.count];
for (GKPlayer *player in players) {
NSLog(@"Found player: %@", player.alias);
[playersDict setObject:player forKey:player.playerID];
}

// Notify delegate match can begin
matchStarted = YES;
[delegate matchStarted];

}
}];

}

#pragma mark User functions

- (void)authenticateLocalUser {

if (!gameCenterAvailable) return;

NSLog(@"Authenticating local user...");
if ([GKLocalPlayer localPlayer].authenticated == NO) {
[[GKLocalPlayer localPlayer] authenticateWithCompletionHandler:nil];
} else {
NSLog(@"Already authenticated!");
}
}

- (void)findMatchWithMinPlayers:(int)minPlayers maxPlayers:(int)maxPlayers viewController:(UIViewController *)viewController delegate:(id<GCHelperDelegate>)theDelegate {

if (!gameCenterAvailable) return;

matchStarted = NO;
self.match = nil;
self.presentingViewController = viewController;
delegate = theDelegate;

if (pendingInvite != nil) {

[presentingViewController dismissModalViewControllerAnimated:NO];
GKMatchmakerViewController *mmvc = [[[GKMatchmakerViewController alloc] initWithInvite:pendingInvite] autorelease];
mmvc.matchmakerDelegate = self;
[presentingViewController presentModalViewController:mmvc animated:YES];

self.pendingInvite = nil;
self.pendingPlayersToInvite = nil;

} else {

[presentingViewController dismissModalViewControllerAnimated:NO];
GKMatchRequest *request = [[[GKMatchRequest alloc] init] autorelease];
request.minPlayers = minPlayers;
request.maxPlayers = maxPlayers;
request.playersToInvite = pendingPlayersToInvite;

GKMatchmakerViewController *mmvc = [[[GKMatchmakerViewController alloc] initWithMatchRequest:request] autorelease];
mmvc.matchmakerDelegate = self;

[presentingViewController presentModalViewController:mmvc animated:YES];

self.pendingInvite = nil;
self.pendingPlayersToInvite = nil;

}

}

#pragma mark GKMatchmakerViewControllerDelegate

// The user has cancelled matchmaking
- (void)matchmakerViewControllerWasCancelled:(GKMatchmakerViewController *)viewController {
[presentingViewController dismissModalViewControllerAnimated:YES];
}

// Matchmaking has failed with an error
- (void)matchmakerViewController:(GKMatchmakerViewController *)viewController didFailWithError:(NSError *)error {
[presentingViewController dismissModalViewControllerAnimated:YES];
NSLog(@"Error finding match: %@", error.localizedDescription);
}

// A peer-to-peer match has been found, the game should start
- (void)matchmakerViewController:(GKMatchmakerViewController *)viewController didFindMatch:(GKMatch *)theMatch {
[presentingViewController dismissModalViewControllerAnimated:YES];
self.match = theMatch;
match.delegate = self;
if (!matchStarted && match.expectedPlayerCount == 0) {
NSLog(@"Ready to start match!");
[self lookupPlayers];
}
}

#pragma mark GKMatchDelegate

// The match received data sent from the player.
- (void)match:(GKMatch *)theMatch didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID {
if (match != theMatch) return;

[delegate match:theMatch didReceiveData:data fromPlayer:playerID];
}

// The player state changed (eg. connected or disconnected)
- (void)match:(GKMatch *)theMatch player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state {
if (match != theMatch) return;

switch (state) {
case GKPlayerStateConnected:
// handle a new player connection.
NSLog(@"Player connected!");

if (!matchStarted && theMatch.expectedPlayerCount == 0) {
NSLog(@"Ready to start match!");
[self lookupPlayers];
}

break;
case GKPlayerStateDisconnected:
// a player just disconnected.
NSLog(@"Player disconnected!");
matchStarted = NO;
[delegate matchEnded];
break;
}
}

// The match was unable to connect with the player due to an error.
- (void)match:(GKMatch *)theMatch connectionWithPlayerFailed:(NSString *)playerID withError:(NSError *)error {

if (match != theMatch) return;

NSLog(@"Failed to connect to player with error: %@", error.localizedDescription);
matchStarted = NO;
[delegate matchEnded];
}

// The match was unable to be established with any players due to an error.
- (void)match:(GKMatch *)theMatch didFailWithError:(NSError *)error {

if (match != theMatch) return;

NSLog(@"Match failed with error: %@", error.localizedDescription);
matchStarted = NO;
[delegate matchEnded];
}

- (void)reportScore:(int64_t)score forCategory:(NSString *)category {
// Only execute if OS supports Game Center & player is logged in
if ([self isGameCenterAvailable] && [GKLocalPlayer localPlayer].authenticated == YES)
{
// Create score object
GKScore *scoreReporter = [[[GKScore alloc] initWithCategory:category] autorelease];

// Set the score value
scoreReporter.value = score;

// Try to send
[scoreReporter reportScoreWithCompletionHandler:^(NSError *error) {
if (error != nil)
{
// Handle reporting error here by adding object to a serializable array, to be sent again later
[unsentScores addObject:scoreReporter];
}
}];
}
}

- (BOOL) reportAchievementIdentifier: (NSString*) identifier percentComplete: (float) percent {

if ([self isGameCenterAvailable] && [GKLocalPlayer localPlayer].authenticated == YES)
{
GKAchievement *achievement = [[[GKAchievement alloc] initWithIdentifier: identifier] autorelease];
if (achievement)
{
achievement.percentComplete = percent;
[achievement reportAchievementWithCompletionHandler:^(NSError *error)
{
if (error != nil)
{
// Retain the achievement object and try again later (not shown).
}
}];
}

return YES;
}

return NO;
}


@end

最后,这就是我从游戏层调用游戏中心的方式(我尝试了两种不同的选项,但没有一个起作用)

选项 1

[[GCHelper sharedInstance] findMatchWithMinPlayers:2 maxPlayers:2 viewController: [[[UIApplication sharedApplication] keyWindow] rootViewController] delegate: self];

选项 2

AppController *app = (AppController*) [[UIApplication sharedApplication] delegate];
UINavigationController *viewController = [app navController];
[[GCHelper sharedInstance] findMatchWithMinPlayers:2 maxPlayers:2 viewController:viewController delegate:self];

任何帮助将不胜感激。提前致谢...

最佳答案

我已经处理多人游戏几个月了,邀请对我来说一直是一个真正的问题......和你一样,我使用 Ray 的教程来开始。今天我意识到 Ray 的代码有一个错误,如果两个客户端都启动了 GKMatchmakerView,则邀请将不起作用。当您第一次收到邀请时,您需要将其驳回,其中包含以下内容:

        [gcdelegate.viewController  dismissViewControllerAnimated:YES
completion:^{
GKMatchmakerViewController *mmvc = [[GKMatchmakerViewController alloc] initWithInvite:pendingInvite];
mmvc.matchmakerDelegate = self;
[gcdelegate.viewController presentModalViewController:mmvc animated:YES];
self.pendingInvite = nil;
self.pendingPlayersToInvite = nil;
boo_invite=true;
}];

关于ios - 无法收到游戏中心邀请,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16247009/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com