游戏中心以编程方式查找匹配项

发布于 2024-09-26 05:47:00 字数 1445 浏览 4 评论 0原文

我只是不明白这是如何运作的。我想做的是让两个玩家玩游戏,如果第三个玩家加入,它可以立即加入游戏,如果第四个也是最后一个玩家加入,它也可以立即加入游戏。他们还可以出于任何原因随时离开游戏,如果发生这种情况,应该有一个空间可供其他人或同一个人重新连接。就是这个想法。

现在我得到的是以下内容。出于显而易见的原因,我验证了本地玩家的身份。然后我像这样搜索匹配:

if (matchRequest) [matchRequest release];
matchRequest            = [[GKMatchRequest alloc] init];
matchRequest.minPlayers = 2;
matchRequest.maxPlayers = 4;

[[GKMatchmaker sharedMatchmaker] findMatchForRequest:matchRequest withCompletionHandler:^(GKMatch *match, NSError *error) {
    if (error) {
        // An error occured
    } else {
        if (matchCurrent) [matchCurrent release];
        matchCurrent          = [match retain];
        matchCurrent.delegate = self;
    }
}];

如果我在三个不同的设备上执行此部分,其中两个将找到对方,第三个仍在寻找。所以我想在请求的查找匹配找到最小数量的玩家后,它将被执行一次。所以我需要的是一种使用我保留的 matchCurrent 来添加更多玩家的方法。幸运的是,这种方法存在,但是它如何运作呢?在这种情况下你什么时候调用它?我决定将其放在一个按钮下,以便在找到匹配项时可以手动执行它。

我发现,当我在第一个设备上按下它时,第三个设备最终可以找到第一个和第二个设备所在的匹配项。事实上,第二个和第三个设备包含所涉及的每个设备的playerID。这是一件好事。但有两个问题。

  1. 哪个设备应该实际调用 addPlayersToMatch 方法?如何将其限制为执行该方法的一台设备?另外,什么时候应该调用它?
  2. 为什么在调用该方法的设备上,playerID 没有更新?

    [[GKMatchmaker sharedMatchmaker] addPlayersToMatch:matchCurrent matchRequest:matchRequest finishHandler:^(NSError *error) {
        //matchCurrent.playerIDs 没有更新?!
    }]; 
    

    实际上它们已经更新了。当我看到第二台和第三台设备上出现playerIDs时,我手动更新第一台设备上的matchCurrent.playerIDs,突然它确实识别了玩家。然而,当在设备一上发现新玩家时,甚至不会调用玩家的“didChangeState”。

I just can't figure out how this works. What I am trying to do is let two players play a game if a third player joins it can instantly join the game, if the fourth and last player joins it can also instantly join the game. They can also leave the game at anytime for whatever reason, if that happens there should be a space open for another person or for the same person to reconnect. That's the idea.

Now what I got is the following. I authenticate the local player for obvious reasons. Then I search for a match like so:

if (matchRequest) [matchRequest release];
matchRequest            = [[GKMatchRequest alloc] init];
matchRequest.minPlayers = 2;
matchRequest.maxPlayers = 4;

[[GKMatchmaker sharedMatchmaker] findMatchForRequest:matchRequest withCompletionHandler:^(GKMatch *match, NSError *error) {
    if (error) {
        // An error occured
    } else {
        if (matchCurrent) [matchCurrent release];
        matchCurrent          = [match retain];
        matchCurrent.delegate = self;
    }
}];

If I execute this part on three different devices, two of them will find each other and the third is still looking. So I figured after the find match for request has found the minimum amount of players it will be executed once. So what I needed was a method that used the matchCurrent that I retained to add more players. Luckely that method existed, but how would that work? When do you call it in this case? I decided to put it under a button so I could manually execute it when a match has been found.

What I discovered is that when I pressed it on the first device, finally the third device could find the match the first and second device were in. In fact the second and third device contained the playerIDs of every device involved. Which is a good thing. But there are two problems.

  1. Which device should actually call the addPlayersToMatch method? And how can you restrict it to one device executing that method? Plus when should you call it?
  2. Why, on the device calling that method, isn't the playerIDs updated?

    [[GKMatchmaker sharedMatchmaker] addPlayersToMatch:matchCurrent matchRequest:matchRequest completionHandler:^(NSError *error) {
        //matchCurrent.playerIDs is not updated?!
    }]; 
    

    Actually they are updated. When I see the playerIDs appear on the second and third device I manually update the matchCurrent.playerIDs on device one and suddenly it does recognize the player. However even the 'didChangeState' for player is not called when the new player is discovered on device one.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

放飞的风筝 2024-10-03 05:47:00

您使用 Apple iOS Game Center GKMatchmaker 类。我假设您使用的是点对点连接,而不是托管连接。

GKMatch 类为您提供了playerIDs 数组。

@property(nonatomic, readonly) NSArray *playerIDs

这是一个有序列表,因此您可以使用它来选择第一个调用 addPlayersToMatch 的玩家。

下面链接是一些文档。

http://developer.apple.com/ Library/ios/#documentation/GameKit/Reference/GKMatchmaker_Ref/Reference/Reference.html

http://developer.apple.com/library/ios/#documentation/GameKit/Reference/GKMatch_Ref/Reference/Reference.html

http://开发者。 apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/GameKit_Guide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008304

Your using the Apple iOS Game Center GKMatchmaker class. I'm assuming you are using a peer to peer connection, not hosted.

The GKMatch class gives the playerIDs array to you.

@property(nonatomic, readonly) NSArray *playerIDs

This is an ordered list, so you might be able to use it to select the first player call addPlayersToMatch.

Linked below is some documentation.

http://developer.apple.com/library/ios/#documentation/GameKit/Reference/GKMatchmaker_Ref/Reference/Reference.html

http://developer.apple.com/library/ios/#documentation/GameKit/Reference/GKMatch_Ref/Reference/Reference.html

http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/GameKit_Guide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008304

迷路的信 2024-10-03 05:47:00

哪个设备应该实际调用
addPlayersToMatch 方法?又如何能
您将其限制在一台设备上
执行该方法?

您可以通过让设备“抽吸管”来解决这个问题。每个设备都会生成一个随机数,然后将其发送给其他设备。编号最大的设备是领导者,它是必须调用 addPlayersToMatch 的设备。如果两个设备选择了相同的号码,则丢弃这些号码并重新开始。

Which device should actually call the
addPlayersToMatch method? And how can
you restrict it to one device
executing that method?

You could solve this problem by having the devices "draw straws". Each device generates a random number, then sends it to the others. The device with the largest number is the leader, and it is the one that must call addPlayersToMatch. If two devices pick the same number, throw out the numbers and start over.

笨死的猪 2024-10-03 05:47:00

我建议您定期(也许每秒一次或两次)轮询其他玩家的状态,以便您可以检测是否有人加入或因任何原因离开。除非您使用的 iPhone 架构已经提供了处理该事件的函数。

听起来您可能想为您正在使用的多人游戏框架找到更多文档和/或示例代码。

I would suggest that you periodically (maybe once per second or two) poll for the status of other players, so you can detect if anyone has joined, or left for any reason. Unless the iphone architecture you are using already provides an function that handles that event.

It sounds like you may want to find some more documentation and/or sample code for the multi-player framework you are using.

夜雨飘雪 2024-10-03 05:47:00

我通过 Prime31 的 GameCenterMultiplayerBinding 使用 Unity 执行此操作。我不完全确定它如何映射到 GameKit(文档很少并且没有提供这些细节),但名称非常有启发性。

为了能够将 2 到 4 名玩家匹配到一场比赛中,我正在做:

findMatchProgrammaticallyWithFilters(
                        minPlayers: 2,
                        maxPlayers: 4,
                        playerGroup: GetCurrentPlayerGroup(),
                        playerAttributes: 0);

我假设这映射到 findMatchForRequest:withCompletionHandler

成功后,我调用:

finishMatchmakingForMatch();

这肯定映射到 完成MatchmakingForMatch。我发现,如果我没有先调用 finishMatchmakingForMatch,调用 findMatchForRequest 或 addPlayersToMatch 将会失败,并显示“请求的操作已被用户取消或禁用”。

addPlayersToCurrentMatchWithUpdatedMatchRequest(
                        minPlayers: 2,
                        maxPlayers: 4,
                        playerGroup: GetCurrentPlayerGroup(),
                        playerAttributes: 0,
                        playersToInvite: null);

addPlayersToMatch:matchRequest:completionHandler

之后< /em> 成功后,我调用:

finishMatchmakingForMatch();

如果我有空间容纳更多玩家,我会循环并再次调用 addPlayersToMatch

我希望如此,因为完成后我需要调用 finishMatchmakingForMatch
匹配,触发 findMatchProgrammatically 将继续寻找,直到它
找到了 maxPlayers,但没有。第一场比赛后就放弃了。所以我们需要
调用addPlayersToMatch

I'm doing this with Unity via Prime31's GameCenterMultiplayerBinding. I'm not entirely sure how it maps to GameKit (the docs are sparse and don't give those details), but the names are very suggestive.

To be able to match 2 to 4 players into a match, I'm doing:

findMatchProgrammaticallyWithFilters(
                        minPlayers: 2,
                        maxPlayers: 4,
                        playerGroup: GetCurrentPlayerGroup(),
                        playerAttributes: 0);

I assume this maps to findMatchForRequest:withCompletionHandler.

After that succeeds, I call:

finishMatchmakingForMatch();

Which surely maps to finishMatchmakingForMatch. I found that calling findMatchForRequest or addPlayersToMatch would fail with "The requested operation has been canceled or disabled by the user" if I didn't call finishMatchmakingForMatch first.

addPlayersToCurrentMatchWithUpdatedMatchRequest(
                        minPlayers: 2,
                        maxPlayers: 4,
                        playerGroup: GetCurrentPlayerGroup(),
                        playerAttributes: 0,
                        playersToInvite: null);

addPlayersToMatch:matchRequest:completionHandler

After that succeeds, I call:

finishMatchmakingForMatch();

If I have space for more players, I loop and call addPlayersToMatch again.

I'd expect that since I need to call finishMatchmakingForMatch when I'm done
matchmaking, firing findMatchProgrammatically would keep looking until it
found maxPlayers, but it doesn't. It gives up after the first match. So we need
to call addPlayersToMatch.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文