Merge branch '26-mm-anbindung-an-gamecenter' into 'development'
Resolve "[MM] Anbindung an GameCenter" Closes #26 See merge request marcel.schwarz/software-projekt-2!40
This commit is contained in:
commit
350682cf82
@ -42,6 +42,7 @@
|
|||||||
AB1D759D245DD18100671525 /* TwoPlayerDefaultTestMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB1D759B245DD18100671525 /* TwoPlayerDefaultTestMap.swift */; };
|
AB1D759D245DD18100671525 /* TwoPlayerDefaultTestMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB1D759B245DD18100671525 /* TwoPlayerDefaultTestMap.swift */; };
|
||||||
AB1D75A0245DEC0500671525 /* MapFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB1D759F245DEC0500671525 /* MapFactory.swift */; };
|
AB1D75A0245DEC0500671525 /* MapFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB1D759F245DEC0500671525 /* MapFactory.swift */; };
|
||||||
ABA03DA0244BD54F00A66916 /* Base.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABA03D9F244BD54F00A66916 /* Base.swift */; };
|
ABA03DA0244BD54F00A66916 /* Base.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABA03D9F244BD54F00A66916 /* Base.swift */; };
|
||||||
|
AE151589245F18EF001D363E /* MatchmakingHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE151588245F18EF001D363E /* MatchmakingHelper.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
@ -95,6 +96,7 @@
|
|||||||
AB1D759B245DD18100671525 /* TwoPlayerDefaultTestMap.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TwoPlayerDefaultTestMap.swift; sourceTree = "<group>"; };
|
AB1D759B245DD18100671525 /* TwoPlayerDefaultTestMap.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TwoPlayerDefaultTestMap.swift; sourceTree = "<group>"; };
|
||||||
AB1D759F245DEC0500671525 /* MapFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapFactory.swift; sourceTree = "<group>"; };
|
AB1D759F245DEC0500671525 /* MapFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapFactory.swift; sourceTree = "<group>"; };
|
||||||
ABA03D9F244BD54F00A66916 /* Base.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Base.swift; sourceTree = "<group>"; };
|
ABA03D9F244BD54F00A66916 /* Base.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Base.swift; sourceTree = "<group>"; };
|
||||||
|
AE151588245F18EF001D363E /* MatchmakingHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatchmakingHelper.swift; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
@ -150,6 +152,7 @@
|
|||||||
110360DA244B101A008610AF /* GameViewController.swift */,
|
110360DA244B101A008610AF /* GameViewController.swift */,
|
||||||
110360DF244B101B008610AF /* Assets.xcassets */,
|
110360DF244B101B008610AF /* Assets.xcassets */,
|
||||||
110360E4244B101B008610AF /* Info.plist */,
|
110360E4244B101B008610AF /* Info.plist */,
|
||||||
|
AE151588245F18EF001D363E /* MatchmakingHelper.swift */,
|
||||||
3EBD242B245D8044003CECE7 /* GameCenterHelper.swift */,
|
3EBD242B245D8044003CECE7 /* GameCenterHelper.swift */,
|
||||||
);
|
);
|
||||||
path = GoldWars;
|
path = GoldWars;
|
||||||
@ -366,6 +369,7 @@
|
|||||||
9E78ACBA245CBDAF00526FF7 /* HUD.swift in Sources */,
|
9E78ACBA245CBDAF00526FF7 /* HUD.swift in Sources */,
|
||||||
11738A3B24508F68004426F1 /* Unit.swift in Sources */,
|
11738A3B24508F68004426F1 /* Unit.swift in Sources */,
|
||||||
9E174C86245DD91500209FF0 /* ButtonComponent.swift in Sources */,
|
9E174C86245DD91500209FF0 /* ButtonComponent.swift in Sources */,
|
||||||
|
AE151589245F18EF001D363E /* MatchmakingHelper.swift in Sources */,
|
||||||
11036113244B3E30008610AF /* MenuScene.swift in Sources */,
|
11036113244B3E30008610AF /* MenuScene.swift in Sources */,
|
||||||
9EA3ABE9245C6DAA006BC61D /* DefaultBaseComponent.swift in Sources */,
|
9EA3ABE9245C6DAA006BC61D /* DefaultBaseComponent.swift in Sources */,
|
||||||
9E174C8A245E1A0A00209FF0 /* Background.swift in Sources */,
|
9E174C8A245E1A0A00209FF0 /* Background.swift in Sources */,
|
||||||
@ -541,8 +545,8 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CODE_SIGN_ENTITLEMENTS = GoldWars/GoldWars.entitlements;
|
CODE_SIGN_ENTITLEMENTS = GoldWars/GoldWars.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Manual;
|
||||||
CURRENT_PROJECT_VERSION = 2;
|
CURRENT_PROJECT_VERSION = 2;
|
||||||
DEVELOPMENT_TEAM = DDKFQG46BQ;
|
DEVELOPMENT_TEAM = DDKFQG46BQ;
|
||||||
INFOPLIST_FILE = GoldWars/Info.plist;
|
INFOPLIST_FILE = GoldWars/Info.plist;
|
||||||
@ -553,7 +557,7 @@
|
|||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = de.hft.stuttgart.ip2.goldwars;
|
PRODUCT_BUNDLE_IDENTIFIER = de.hft.stuttgart.ip2.goldwars;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "Developer Profile";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = 2;
|
TARGETED_DEVICE_FAMILY = 2;
|
||||||
};
|
};
|
||||||
@ -564,8 +568,8 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CODE_SIGN_ENTITLEMENTS = GoldWars/GoldWars.entitlements;
|
CODE_SIGN_ENTITLEMENTS = GoldWars/GoldWars.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Manual;
|
||||||
CURRENT_PROJECT_VERSION = 2;
|
CURRENT_PROJECT_VERSION = 2;
|
||||||
DEVELOPMENT_TEAM = DDKFQG46BQ;
|
DEVELOPMENT_TEAM = DDKFQG46BQ;
|
||||||
INFOPLIST_FILE = GoldWars/Info.plist;
|
INFOPLIST_FILE = GoldWars/Info.plist;
|
||||||
@ -576,7 +580,7 @@
|
|||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = de.hft.stuttgart.ip2.goldwars;
|
PRODUCT_BUNDLE_IDENTIFIER = de.hft.stuttgart.ip2.goldwars;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "Developer Profile";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = 2;
|
TARGETED_DEVICE_FAMILY = 2;
|
||||||
};
|
};
|
||||||
|
@ -24,6 +24,7 @@ class GameViewController: UIViewController {
|
|||||||
view.showsNodeCount = true
|
view.showsNodeCount = true
|
||||||
|
|
||||||
GameCenterHelper.helper.viewController = self
|
GameCenterHelper.helper.viewController = self
|
||||||
|
MatchmakingHelper.sharedInstance.viewController = self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
178
GoldWars/GoldWars/MatchmakingHelper.swift
Normal file
178
GoldWars/GoldWars/MatchmakingHelper.swift
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
//
|
||||||
|
// MatchmakingHelper.swift
|
||||||
|
// GoldWars
|
||||||
|
//
|
||||||
|
// Created by Chauntalle Schüle, Ömer Özel, Eray Kör on 03.05.20.
|
||||||
|
// Copyright © 2020 SP2. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import GameKit
|
||||||
|
|
||||||
|
protocol GameKitHelperDelegate {
|
||||||
|
func matchStarted()
|
||||||
|
func matchEnded()
|
||||||
|
func matchReceivedData(match: GKMatch, data: NSData,
|
||||||
|
fromPlayer player: String)
|
||||||
|
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Diese Klasse wird für das Matchmaking über das Gamecenter gebraucht
|
||||||
|
@param: delegate: erhält alle Multiplayerevents
|
||||||
|
@param: mpMatch: repräsentiert das Netzwerk, alle Mitspieler besitzen ein gemeinsames Spiel
|
||||||
|
@param: viewController: ist nicht der ViewController des Gamecenters, sondern des Spiels
|
||||||
|
@param: mpMatchStarted: gibt an, ob ein Match schon gestartet wurde
|
||||||
|
@param: isServer: gibt an, ob der local player, als der Server fungiert
|
||||||
|
@param: spieler1: ist immer der Spieler, der der Server ist
|
||||||
|
@param: spieler2: ist immer der Spieler, der der Client ist
|
||||||
|
@param: sharedInstance: ist eine geteilte Instanz für alle Spieler
|
||||||
|
*/
|
||||||
|
class MatchmakingHelper: NSObject, GKMatchmakerViewControllerDelegate, GKMatchDelegate {
|
||||||
|
|
||||||
|
var delegate: GameKitHelperDelegate?
|
||||||
|
var mpMatch: GKMatch?
|
||||||
|
var viewController: UIViewController?
|
||||||
|
var mpMatchStarted: Bool
|
||||||
|
var isServer: Bool
|
||||||
|
var spieler1: GKPlayer?
|
||||||
|
var nameSpieler1 = ""
|
||||||
|
var menusc: MenuScene?
|
||||||
|
let localPlayer: GKLocalPlayer = GKLocalPlayer.local
|
||||||
|
|
||||||
|
static let sharedInstance = MatchmakingHelper()
|
||||||
|
|
||||||
|
|
||||||
|
static var isAuthenticated: Bool{
|
||||||
|
return GKLocalPlayer.local.isAuthenticated
|
||||||
|
}
|
||||||
|
|
||||||
|
override init() {
|
||||||
|
mpMatchStarted = false
|
||||||
|
isServer = false
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Diese Methode wechselt von der MenuScene zum GameCenter ViewController. Die Spieler werden hier gesucht und gematcht. Mit minplayers/maxplayers kann bestimmt werden, wie viele Spieler insgesamt zusammen miteinander spielen.
|
||||||
|
*/
|
||||||
|
func presentMatchmaker(scene: MenuScene) {
|
||||||
|
menusc = scene
|
||||||
|
guard GKLocalPlayer.local.isAuthenticated else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let request = GKMatchRequest()
|
||||||
|
|
||||||
|
request.minPlayers = 2
|
||||||
|
request.maxPlayers = 2
|
||||||
|
request.inviteMessage = "Willst du GoldWars spielen?"
|
||||||
|
|
||||||
|
let matchmakerVC = GKMatchmakerViewController.init(matchRequest: request)
|
||||||
|
matchmakerVC!.matchmakerDelegate = self
|
||||||
|
viewController?.present(matchmakerVC!, animated: true, completion: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Der User hat die Verbindung mit "Abbrechen" unterbrochen. GameCenter MatchMaking wird beendet.
|
||||||
|
*/
|
||||||
|
func matchmakerViewControllerWasCancelled(_ viewController: GKMatchmakerViewController) {
|
||||||
|
viewController.dismiss(animated: true, completion: nil)
|
||||||
|
delegate?.matchEnded()
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Wenn GameCenter kein match erstellen kann, wird der viewcontroller dismissed.
|
||||||
|
*/
|
||||||
|
func matchmakerViewController(_ viewController: GKMatchmakerViewController, didFailWithError error: Error) {
|
||||||
|
viewController.dismiss(animated: true, completion: nil)
|
||||||
|
print("Error finding match", error.localizedDescription)
|
||||||
|
delegate?.matchEnded()
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Gamecenter hat erfolgreich ein Match gefunden, das Spiel kann gestartet werden.
|
||||||
|
expectedPlayerCount: Die verbleibende Anzahl von Spielern, die sich noch nicht mit dem Spiel verbunden haben
|
||||||
|
z.B 0 gibt an, dass keine weiteren Spieler benötigt werden um das Match zu starten
|
||||||
|
*/
|
||||||
|
func matchmakerViewController(_ viewController: GKMatchmakerViewController, didFind match: GKMatch) {
|
||||||
|
viewController.dismiss(animated: true, completion: nil)
|
||||||
|
mpMatch = match
|
||||||
|
match.delegate = self
|
||||||
|
if !mpMatchStarted && match.expectedPlayerCount == 0 {
|
||||||
|
startMatch()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Vom match erhaltene Spielerdaten
|
||||||
|
*/
|
||||||
|
private func match(match: GKMatch!, didReceiveData data: NSData!,fromPlayer playerID: String!) {
|
||||||
|
if mpMatch != match { return }
|
||||||
|
delegate?.matchReceivedData(match: match, data: data, fromPlayer: playerID)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Verbindung/Matchmaking ist fehlgeschlagen
|
||||||
|
*/
|
||||||
|
private func match(match: GKMatch!, didFailWithError error: NSError!) {
|
||||||
|
if mpMatch != match {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mpMatchStarted = false
|
||||||
|
delegate?.matchEnded()
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Wird beim ändern des States/Zustands des Spielers aufgerufen udn gibt dessen Zustand zurück.
|
||||||
|
*/
|
||||||
|
func match(_ match: GKMatch, player: GKPlayer, didChange state: GKPlayerConnectionState) {
|
||||||
|
if mpMatch != match {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case GKPlayerConnectionState.connected:
|
||||||
|
if (!mpMatchStarted && match.expectedPlayerCount == 0) {
|
||||||
|
startMatch()
|
||||||
|
}
|
||||||
|
case GKPlayerConnectionState.disconnected:
|
||||||
|
mpMatchStarted = false
|
||||||
|
delegate?.matchEnded()
|
||||||
|
default:
|
||||||
|
delegate?.matchEnded()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Ein Spieler wird als Host für das Match gewählt. Dieser ist Spieler 1. Im Anschluss wird die GameScene geladen.
|
||||||
|
*/
|
||||||
|
func startMatch() {
|
||||||
|
|
||||||
|
mpMatch!.chooseBestHostingPlayer(completionHandler: {
|
||||||
|
(player) in
|
||||||
|
|
||||||
|
self.mpMatchStarted = true
|
||||||
|
|
||||||
|
if player == GKLocalPlayer.local {
|
||||||
|
self.isServer = true
|
||||||
|
self.spieler1 = player
|
||||||
|
self.nameSpieler1 = self.spieler1!.displayName
|
||||||
|
|
||||||
|
} else {
|
||||||
|
self.isServer = false
|
||||||
|
}
|
||||||
|
|
||||||
|
self.delegate?.matchStarted()
|
||||||
|
self.menusc!.loadScene(scene: GameScene(size: self.menusc!.size))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Trennt die Verbindung vom Match
|
||||||
|
*/
|
||||||
|
func disconnect() {
|
||||||
|
if mpMatch != nil {
|
||||||
|
mpMatch?.disconnect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -21,7 +21,7 @@ class MenuScene: SKScene {
|
|||||||
text: "Start Game",
|
text: "Start Game",
|
||||||
position: CGPoint(x: midX, y: midY),
|
position: CGPoint(x: midX, y: midY),
|
||||||
onButtonPress: {
|
onButtonPress: {
|
||||||
self.loadScene(scene: GameScene(size: self.size))
|
MatchmakingHelper.sharedInstance.presentMatchmaker(scene: self)
|
||||||
}))
|
}))
|
||||||
entityManager.add(Button(name: "settingsButton",
|
entityManager.add(Button(name: "settingsButton",
|
||||||
iconName: "",
|
iconName: "",
|
||||||
|
Loading…
Reference in New Issue
Block a user