我正在尝试使用自定义UI(没有gkmatchmakerViewController)实现实时多人游戏.我正在使用startbrowsingForNearbyPlayersWithReachableHandler:^(Nsstring * playerID,BOOL可达)来查找本地播放器,然后使用gkmatchmaker单例(我已经启动)发起匹配请求.

这是我遇到麻烦的地方.当我发送请求时,完成处理程序几乎立即触发,没有错误,并且它返回的匹配具有预期的玩家计数为零.同时,其他玩家肯定没有回复该请求

相关守则:

- (void) findMatch {
  GKMatchRequest *request = [[GKMatchRequest alloc] init];
  request.minPlayers = NUM_PLAYERS_PER_MATCH; //2
  request.maxPlayers = NUM_PLAYERS_PER_MATCH; //2
  if (nil != self.playersToInvite) {
    // we always successfully get in this if-statement
    request.playersToInvite = self.playersToInvite;
    request.inviteeResponseHandler = ^(Nsstring *playerID,GKInviteeResponse response) {
      [self.delegate updateUIForPlayer: playerID accepted: (response == GKInviteeResponseAccepted)];
  };
}
request.inviteMessage = @"Let's Play!";

[self.matchmaker findMatchForRequest:request withCompletionHandler:^(GKMatch *match,NSError *error) {
  if (error) {
    // Print the error
    NSLog(@"%@",error.localizedDescription);
  } else 
    if (match != nil) {
      self.currentMatch = match;
      self.currentMatch.delegate = self;

      // All players are connected
      if (match.expectedplayerCount == 0) {
        // start match
        [self startMatch];
      }
        [self stopLookingForPlayers];
      }
  }];
}

我从上一个问题(iOS Gamecenter Programmatic Matchmaking)中知道我需要包含这个:

- (void)matchForInvite:(GKInvite *)invite completionHandler:(void (^)(GKMatch *match,NSError *error))completionHandler

在上面的代码,但我不知道应该包括在哪里.我已经尝试过GKMatchRequest inviteeResponseHandler和matchmaker finMatchForRequest:withCompletionHandler都无济于事.发生的行为是匹配器立即返回匹配(甚至在被邀请者被邀请之前),并且即使在被邀请者点击匹配邀请之后也不会调用matchRequest inviteeResponseHandler.

有人可以就此提出建议吗?谢谢.

…吉姆

解决方法

今晚我的比赛正在进行中.为了获得通信通道设置,您需要进行更多的协商.返回给邀请者的初始匹配正在等待被邀请者回复…这是我的过程只有两个玩家.以下是我的通信启动执行的所有步骤.显然,此处不包含真正的错误处理:

首先,验证您的播放器

第二,在认证设置inviteHandler之后.像这样的东西:

[gkmatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite* acceptedInvite,NSArray *playersToInvite)
{
    if(acceptedInvite != nil)
    {
        // Get a match for the invite we obtained...
        [[gkmatchmaker sharedMatchmaker] matchForInvite:acceptedInvite completionHandler:^(GKMatch *match,NSError *error)
        {
            if(match != nil)
            {
                [self disconnectMatch];
                // Record the new match...
                self.MM_gameCenterCurrentMatch = match;
                self.MM_gameCenterCurrentMatch.delegate = self;
             }
            else if(error != nil)
            {
                NSLog(@"ERROR: From matchForInvite: %@",[error description]);
            }
            else 
            {
                NSLog(@"ERROR: Unexpected return from matchForInvite...");
            }
         }];
    }
};

第三,获取朋友playerIds(不是别名)的列表.

第四,设置这样的GKMatchRequest ……我只邀请一位朋友:

// Initialize the match request - Just targeting iOS 6 for Now...
GKMatchRequest* request = [[GKMatchRequest alloc] init];
request.minPlayers = 2;
request.maxPlayers = 2;
request.playersToInvite = [NSArray arrayWithObject:player.playerID];
request.inviteMessage = @"Let's play!";
// This gets called when somebody accepts
request.inviteeResponseHandler = ^(Nsstring *playerID,GKInviteeResponse response)
{
    if (response == GKInviteeResponseAccepted)
    {
        //NSLog(@"DEBUG: Player Accepted: %@",playerID);
        // Tell the infrastructure we are don matching and will start using the match
        [[gkmatchmaker sharedMatchmaker] finishMatchmakingForMatch:self.MM_gameCenterCurrentMatch];
     }
};

五,使用请求调用findMatchForRequest:withCompletionHandler:这样的……

[[gkmatchmaker sharedMatchmaker] findMatchForRequest:request withCompletionHandler:^(GKMatch* match,NSError *error) {
    if (error)
    {
        NSLog(@"ERROR: Error makeMatch: %@",[error description] );
        [self disconnectMatch];
    }
    else if (match != nil)
    {
        // Record the new match and set me up as the delegate...
        self.MM_gameCenterCurrentMatch = match;
        self.MM_gameCenterCurrentMatch.delegate = self;
        // There will be no players until the players accept...
    }
}];

第六,这将请求发送给另一个玩家,如果他们接受来自第二步的“inviteHandler”则被调用.

第七,来自第二步的“inviteHandler”获得了GKInvite的比赛!

第八,来自第四步的“inviteeResponseHandler”被召唤完成比赛!

第九,从GKMatchDelegate创建一个didChangeState来处理匹配的最终化.像这样的东西:

- (void)match:(GKMatch *)match player:(Nsstring *)playerID didChangeState:(GKPlayerConnectionState)state{
switch (state)
{
    case GKPlayerStateConnected:
        // Handle a new player connection.
        break;
    case GKPlayerStatedisconnected:
        // A player just disconnected.
        break;
}
if (!self.matchStarted && match.expectedplayerCount == 0)
{
    self.matchStarted = YES;
    // Handle initial match negotiation.
    if (self.iAmHost && !self.sentinitialResponse)
    {
        self.sentinitialResponse = true;
        // Send a hello log entry
        [self sendMessage: [Nsstring stringWithFormat:@"Message from friend,'Hello,thanks for accepting,you have connected with %@'",self.MM_gameCenterLocalPlayer.alias] toPlayersInMatch: [NSArray arrayWithObject:playerID]];
    }
}}

第十,这是我的sendMessage:

- (void) sendMessage:(Nsstring*)action toPlayersInMatch:(NSArray*) playerIds{   
NSError* err = nil;
if (![self.MM_gameCenterCurrentMatch sendData:[action dataUsingEncoding:NSUTF8StringEncoding] toPlayers:playerIds withDataMode:GKMatchSendDataReliable error:&err])
{
    if (err != nil)
    {
        NSLog(@"ERROR: Could not send action to players (%@): %@ (%d) - '%@'",[playersInMatch componentsJoinedByString:@","],[err localizedDescription],[err code],action);
    }
    else
    {
        NSLog(@"ERROR: Could not send action to players (%@): null error - '%@'",action);
    }
}
else
{
    NSLog(@"DEBUG: Message sent to players (%@) - '%@'",action);
}}

第十一,从GKMatchDelegate创建一个这样的didReceiveData:

- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(Nsstring *)playerID{
Nsstring* actionString = [[[Nsstring alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
// Send the initial response after we got the initial send from the
// invitee...
if (!self.iAmHost &&!self.sentinitialResponse)
{
    self.sentinitialResponse = true;
    // Send a hello log entry
    [self sendMessage: [Nsstring stringWithFormat:@"Message from friend,thanks for inviting,self.MM_gameCenterLocalPlayer.alias] toPlayersInMatch: [NSArray arrayWithObject:playerID]];
}
// Execute the action we were sent...
NSLog(actionString);}

第十二……好了,现在你已经开始运行了沟通渠道……做你想做的事……

iOS游戏中心GameKit程序化邀请配对的更多相关文章

  1. swift – 使用“如果让…”与许多表达式

    Swift1.2更新从Swift1.2开始,如果允许允许展开多个可选项,那么现在可以写下这个,如下例所示:您甚至可以交换条件,如:以前在Swift1.2之前有效没有一个丑陋的力量包装,你可以这样做:实际上仍然很冗长这是因为可选类型的表单类型?实际上是可选的的缩写,这是一个大致如下的枚举:然后,您可以使用模式匹配作为任何其他枚举。

  2. android – Airbnb探索屏幕等工具栏中的自定义视图

    我想在应用程序(工具栏)的顶部栏区域添加多个输入字段,以便我的应用程序进行搜索.我看到Airbnb做到了最好!我在CoordinatorLayout中尝试了使用AppBarLayout的各种场景,但都失败了.是否有可能获得相同或类似的效果?

  3. QuickBlox WebRtc VideoChat Android

    几天我正在研究quickblox.i让对手观点在我的观点下面,如this.它工作正常,但是当我保持像skype这样的视图时:–对手视图在全屏幕上,我的视图位于对手视图的右上角,它只渲染一个最终渲染的视图.我在quickblox网站上看了quickbloxwebrtc示例.我看到了该示例中的代码,但它包含了一些会议对话,其中包含一些复杂的循环视图编码,对我来说,单个一对一的谈话是必需的,任何人都可以

  4. android – 如何在AlertDialog中显示CalendarView?

    我正在尝试在警报对话框中显示CalendarView,但所有显示的都是月/年和星期几.这些是布局文件的内容:这是我用于将布局添加到AlertDialog的代码:任何帮助都会非常感激,因为我完全被难倒了.该应用程序没有给我任何错误继续.解决方法要正确显示日历,需要最小高度.其余代码工作正常.

  5. 无法使用android.support.v7.widget.AppCompatTextView实例化以下类

    最近我在Android工作室的应用程序中将我的sdk从25改为26,我在我的所有xml中都遇到了这个奇怪的错误.目前错误并没有以我能看到的任何方式影响我的应用程序,但是每次我必须编辑或更改xml中的某些内容时都很烦人.这里的错误:无法实例化以下类–android.support.v7.widget.AppCompatTextView我的朋友:编辑:添加了一些我的xml代码解决方法我也收到了这个错误

  6. android软键盘出现时会破坏布局

    解决方法由于输入进入你的EditText,它总是会移动一些东西.考虑使用两种布局,一种用于键盘关闭时,一种用于键盘启动时.使用ViewSwitcher可能会有所帮助.

  7. android – 我可以像这样创建一个nestedScroll布局吗?

    我认为它可以通过nestedScrollingChildnestedScrollingParent来实现.但我无法理解他们.谁可以帮助我!产品经理坚持设计.ScrollView包含LinearLayout,“TabLayout”和ViewPager.ViewPager包含2个包含RecyclerView的片段或仅包含2个RecyclerView.当ScrollView滚动到Bottom时,Recy

  8. android – 在NestedScrollView onBindViewHolder中的RecyclerView调用所有getItemCount大小

    当我将RecyclerView放入nestedScrollView时,然后onBindViewHolder调用所有行,比如说我有一个大小为30的列表,那么即使没有滚动,也会同时为所有30行调用onBindViewHolder我的xml是但如果我删除nestedScrollView它正常工作.解决方法高度问题引起的问题.1)编辑nestedScrollView&RecyclerView如下:2)确保

  9. android – 将ImageView对齐到屏幕的右上角

    我的布局中有一个imageView,它可以作为不可缩放的背景.但我需要将我的图像放在屏幕的右上角.我现在将我的图像放在屏幕的左上角.这是我对imageview的xml:我也尝试将它放在一个linearlayout中,它具有gravity=“top|right”但是不会删除图片周围的空白区域,因为它具有match_parent大小.我还需要保持图片的比例,所以我不能做fill_parent.我希望有人可以帮助我!解决方法也许加你的ImageView?我有类似的问题.

  10. android – ListView展开项目动画仅在第二次点击后有效

    我有一个带有以下视图的CardView:当我打开我的ListViewview_2设置为Visible.GONE所以你无法看到它.现在我使用了thisblog的ExpandAnimation.这里有代码:我在AdapterView中使用它:我现在只有一个问题:当我在列表中展开一个项目时,它第一次立即出现而没有动画,之后关闭和打开动画顺利进行.有人知道为什么第一次打开没有动画但是之后的每次点击都会触发正确的动画吗?

随机推荐

  1. iOS实现拖拽View跟随手指浮动效果

    这篇文章主要为大家详细介绍了iOS实现拖拽View跟随手指浮动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  2. iOS – genstrings:无法连接到输出目录en.lproj

    使用我桌面上的项目文件夹,我启动终端输入:cd然后将我的项目文件夹拖到终端,它给了我路径.然后我将这行代码粘贴到终端中找.-name*.m|xargsgenstrings-oen.lproj我在终端中收到此错误消息:genstrings:无法连接到输出目录en.lproj它多次打印这行,然后说我的项目是一个目录的路径?没有.strings文件.对我做错了什么的想法?

  3. iOS 7 UIButtonBarItem图像没有色调

    如何确保按钮图标采用全局色调?解决方法只是想将其转换为根注释,以便为“回答”复选标记提供更好的上下文,并提供更好的格式.我能想出这个!

  4. ios – 在自定义相机层的AVFoundation中自动对焦和自动曝光

    为AVFoundation定制图层相机创建精确的自动对焦和曝光的最佳方法是什么?

  5. ios – Xcode找不到Alamofire,错误:没有这样的模块’Alamofire’

    我正在尝试按照github(https://github.com/Alamofire/Alamofire#cocoapods)指令将Alamofire包含在我的Swift项目中.我创建了一个新项目,导航到项目目录并运行此命令sudogeminstallcocoapods.然后我面临以下错误:搜索后我设法通过运行此命令安装cocoapodssudogeminstall-n/usr/local/bin

  6. ios – 在没有iPhone6s或更新的情况下测试ARKit

    我在决定下载Xcode9之前.我想玩新的框架–ARKit.我知道要用ARKit运行app我需要一个带有A9芯片或更新版本的设备.不幸的是我有一个较旧的.我的问题是已经下载了新Xcode的人.在我的情况下有可能运行ARKit应用程序吗?那个或其他任何模拟器?任何想法或我将不得不购买新设备?解决方法任何iOS11设备都可以使用ARKit,但是具有高质量AR体验的全球跟踪功能需要使用A9或更高版本处理器的设备.使用iOS11测试版更新您的设备是必要的.

  7. 将iOS应用移植到Android

    我们制作了一个具有2000个目标c类的退出大型iOS应用程序.我想知道有一个最佳实践指南将其移植到Android?此外,由于我们的应用程序大量使用UINavigation和UIView控制器,我想知道在Android上有类似的模型和实现.谢谢到目前为止,guenter解决方法老实说,我认为你正在计划的只是制作难以维护的糟糕代码.我意识到这听起来像很多工作,但从长远来看它会更容易,我只是将应用程序的概念“移植”到android并从头开始编写.

  8. ios – 在Swift中覆盖Objective C类方法

    我是Swift的初学者,我正在尝试在Swift项目中使用JSONModel.我想从JSONModel覆盖方法keyMapper,但我没有找到如何覆盖模型类中的Objective-C类方法.该方法的签名是:我怎样才能做到这一点?解决方法您可以像覆盖实例方法一样执行此操作,但使用class关键字除外:

  9. ios – 在WKWebView中获取链接URL

    我想在WKWebView中获取tapped链接的url.链接采用自定义格式,可触发应用中的某些操作.例如HTTP://我的网站/帮助#深层链接对讲.我这样使用KVO:这在第一次点击链接时效果很好.但是,如果我连续两次点击相同的链接,它将不报告链接点击.是否有解决方法来解决这个问题,以便我可以检测每个点击并获取链接?任何关于这个的指针都会很棒!解决方法像这样更改addobserver在observeValue函数中,您可以获得两个值

  10. ios – 在Swift的UIView中找到UILabel

    我正在尝试在我的UIViewControllers的超级视图中找到我的UILabels.这是我的代码:这是在Objective-C中推荐的方式,但是在Swift中我只得到UIViews和CALayer.我肯定在提供给这个方法的视图中有UILabel.我错过了什么?我的UIViewController中的调用:解决方法使用函数式编程概念可以更轻松地实现这一目标.

返回
顶部