Group Group Group Group Group Group Group Group Group

Game Center for iOS: Building a Turn-Based Game | raywenderlich.com

#1

In this tutorial, you’ll learn about authentication with Game Center and how its turn-based mechanics work. In the end, you’ll have the foundations of how to integrate a multiplayer game with GameCenter.


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/7544-game-center-for-ios-building-a-turn-based-game
#2

Hi, I got stuck where I need to change online button state:
at this line

// MARK: - Notifications

@objc private func authenticationChanged(_ notification: Notification) {
onlineButton.isEnabled = notification.object as? Bool ?? false
}

My console says unexpectedly find nil in optional (something like this)
I am sure I followed everything exactly.

moreover, the build was fine but crashed when run on simulator.

#3

@naturaln0va Can you please help with this when you get a chance? Thank you - much appreciated! :]

1 Like
#4

Hello, I’m sorry this happened. I assume it’s crashing because the notification is fired before setUpScene(in:) is called. This would result in the onlineButton being nil. To fix this you’ll need to change:

@objc private func authenticationChanged(_ notification: Notification) {
  onlineButton.isEnabled = notification.object as? Bool ?? false
}

to

@objc private func authenticationChanged(_ notification: Notification) {
  onlineButton?.isEnabled = notification.object as? Bool ?? false
}

Let me know if that doesn’t work.

#5

Hi, thank you for your solution.

Actually this was my false. When you say:

To use the authentication notification, add the following to the top of the authenticateHandler block:

NotificationCenter.default .post(name: .authenticationChanged, object: GKLocalPlayer.local.isAuthenticated)

I misunderstood and put that code on top, which was outside, the handler. It now works when I moved it in.

Thank you anyway. Your tutorial is very much enjoying for a newbie like myself.

#6

I’m glad you got it working!

#8

Thanks for the tutorial! One question:

I am trying to use some of the ideas here for another 2-player game, which is in many ways similar to chess but much simpler. However, there are also two “factions” and one of the always starts (similar to “white” in chess). I would like to assign players to these factions before the game (or perhaps give them the possibility to choose). What do you think would be a good way of doing this? I guess what is not very clear to me from your tutorial is how you know that a new game has started, rather than it just being your turn

would appreciate any thoughts on this

#9

@naturaln0va Can you please help with this when you get a chance? Thank you - much appreciated! :]

#10

Sorry for the delay in responding. I’m glad you enjoyed the tutorial!

If you’d like to determine when there is a new game you can check to see if the game model has any information. For instance, in the tutorial inside MenuScene.swift the loadAndDisplay(match: GKTurnBasedMatch) attempts to load the game’s data for a match. If there isn’t any data returned from Game Center then a new game is created.

For your question when you create a new game part of your logic can include setting a state in the model where your game scene would recognize it’s in the “select a faction” state and ask the player to choose. You can also just assign a player at this point if you’d rather not have the players choose.

I hope that helps. Let me know if I can elaborate more, or answer anything else!

#11

Hi. I tried to run this on my iPad Air 2 and it crashed with the following error when I pressed the load Game button.
Nine Knights[664:75183] *** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: 'Invalid size specified: {768, -70.9119873046875}'
The game ran fine on my iPhone. I made the following change to prevent the crash in iPad Air 2.

Class: GameScene
replace:
let skySize = CGSize(width: viewWidth, height: viewHeight - groundNode.position.y)
with:
let adjustedHeight = max(0, viewHeight - groundNode.position.y)
let skySize = CGSize(width: viewWidth, height: adjustedHeight)

This fixes the crash, but to make the screen look good on both an iPad and iPhone make additional changes:

in Class: GameScene replace:
messageNode.position = CGPoint( x: sceneMargin, y: runningYOffset - (sceneMargin * 1.25))
with:
let messageNodeHeigth = min(runningYOffset - (sceneMargin * 1.25), viewHeight - safeAreaTopInset - (sceneMargin * 3) - 50)
messageNode.position = CGPoint(x: sceneMargin, y: messageNodeHeigth)

in class MenuScene: replace:
runningYOffset -= sceneMargin + logoNode.size.height
with:
runningYOffset -= sceneMargin + logoNode.size.height + (buttonSize.height / 2)

#12

Thanks for point this issue out! I went ahead and updated the sample project based on this. I also made the board smaller on iPad so the layout wasn’t overlapping.

#13

This tutorial is more than six months old so questions are no longer supported at the moment for it. Thank you!

closed #14