diff --git a/GoldWars/GoldWars/Assets.xcassets/roundInfo_texture.imageset/Contents.json b/GoldWars/GoldWars/Assets.xcassets/roundInfo_texture.imageset/Contents.json new file mode 100644 index 0000000..2044f76 --- /dev/null +++ b/GoldWars/GoldWars/Assets.xcassets/roundInfo_texture.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "roundInfo_texture.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "roundInfo_texture-1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "roundInfo_texture-2.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/GoldWars/GoldWars/Assets.xcassets/roundInfo_texture.imageset/roundInfo_texture-1.png b/GoldWars/GoldWars/Assets.xcassets/roundInfo_texture.imageset/roundInfo_texture-1.png new file mode 100644 index 0000000..2668882 Binary files /dev/null and b/GoldWars/GoldWars/Assets.xcassets/roundInfo_texture.imageset/roundInfo_texture-1.png differ diff --git a/GoldWars/GoldWars/Assets.xcassets/roundInfo_texture.imageset/roundInfo_texture-2.png b/GoldWars/GoldWars/Assets.xcassets/roundInfo_texture.imageset/roundInfo_texture-2.png new file mode 100644 index 0000000..2668882 Binary files /dev/null and b/GoldWars/GoldWars/Assets.xcassets/roundInfo_texture.imageset/roundInfo_texture-2.png differ diff --git a/GoldWars/GoldWars/Assets.xcassets/roundInfo_texture.imageset/roundInfo_texture.png b/GoldWars/GoldWars/Assets.xcassets/roundInfo_texture.imageset/roundInfo_texture.png new file mode 100644 index 0000000..2668882 Binary files /dev/null and b/GoldWars/GoldWars/Assets.xcassets/roundInfo_texture.imageset/roundInfo_texture.png differ diff --git a/GoldWars/GoldWars/Entities/EntityManager.swift b/GoldWars/GoldWars/Entities/EntityManager.swift index ebeec1b..2b2580d 100644 --- a/GoldWars/GoldWars/Entities/EntityManager.swift +++ b/GoldWars/GoldWars/Entities/EntityManager.swift @@ -53,6 +53,10 @@ class EntityManager { scene.addChild(hudEntitiy.spySkill) scene.addChild(hudEntitiy.roundTimerLabel) scene.addChild(hudEntitiy.finishButton) + scene.addChild(hudEntitiy.backgroundRoundCounter) + scene.addChild(hudEntitiy.currentRoundLabel) + scene.addChild(hudEntitiy.roundsLabel) + scene.addChild(hudEntitiy.roundLabel) } if let spriteNode = entity.component(ofType: DefaultBaseComponent.self) { diff --git a/GoldWars/GoldWars/Entities/HUD.swift b/GoldWars/GoldWars/Entities/HUD.swift index 324e742..04b0c60 100644 --- a/GoldWars/GoldWars/Entities/HUD.swift +++ b/GoldWars/GoldWars/Entities/HUD.swift @@ -27,6 +27,11 @@ class HUD: GKEntity { var roundTimerLabel: SKLabelNode let roundTimer: RoundTimer + var backgroundRoundCounter: SKSpriteNode + var currentRoundLabel: SKLabelNode + var roundsLabel: SKLabelNode + var roundLabel: SKLabelNode + var finishButton: ButtonNode init(size: CGSize) { @@ -84,13 +89,19 @@ class HUD: GKEntity { text: "Done", isEnabled: true, position: CGPoint( - x: EntityManager.gameEMInstance.scene.size.width * 0.1, - y: EntityManager.gameEMInstance.scene.size.height * 0.1), + x: EntityManager.gameEMInstance.scene.size.width * 0.15, + y: EntityManager.gameEMInstance.scene.size.height * 0.06), onButtonPress: { } ) finishButton.size = CGSize(width: 80, height: 40) finishButton.zPosition = 2 + + backgroundRoundCounter = SKSpriteNode(texture: SKTexture(imageNamed: "roundInfo_texture")) + currentRoundLabel = SKLabelNode(fontNamed: "Courier-Bold") + roundsLabel = SKLabelNode(fontNamed: "Courier-Bold") + roundLabel = SKLabelNode(fontNamed: "Courier-Bold") super.init() + initRoundInfo(size: size) finishButton.onButtonPress = { [unowned self] in self.finishRound() @@ -134,4 +145,39 @@ class HUD: GKEntity { self.roundTimer.timeLeft = 1; self.roundTimer.roundEnded = "Waiting for other player..." } + + func initRoundInfo(size: CGSize) -> () { + backgroundRoundCounter.zPosition = 2 + backgroundRoundCounter.position = CGPoint(x: Double(size.width) * 0.06, y: Double(size.height) * 0.08) + + currentRoundLabel.text = "\(RoundCalculatorService.sharedInstance.currentRound)" + currentRoundLabel.fontSize = 50 + currentRoundLabel.fontColor = SKColor.black + currentRoundLabel.verticalAlignmentMode = .center + currentRoundLabel.position = CGPoint(x: backgroundRoundCounter.position.x, y: backgroundRoundCounter.position.y - 5) + currentRoundLabel.zPosition = backgroundRoundCounter.zPosition + 1 + + roundsLabel.zPosition = backgroundRoundCounter.zPosition + 1 + roundsLabel.text = "of \(RoundCalculatorService.sharedInstance.MAX_ROUNDS)" + roundsLabel.fontColor = SKColor.black + roundsLabel.verticalAlignmentMode = .center + roundsLabel.fontSize = 12 + roundsLabel.position = CGPoint(x: currentRoundLabel.position.x, y: currentRoundLabel.position.y - 25) + + roundLabel.zPosition = backgroundRoundCounter.zPosition + 1 + roundLabel.text = "Round" + roundLabel.fontColor = SKColor.black + roundLabel.verticalAlignmentMode = .center + roundLabel.fontSize = 12 + roundLabel.position = CGPoint(x: currentRoundLabel.position.x, y: currentRoundLabel.position.y + 25) + } + + func setCurrentRound(round: Int) -> Void { + currentRoundLabel.text = "\(round)" + let newRoundAction = SKAction.sequence([ + SKAction.scale(by: 2, duration: 1), + SKAction.scale(by: 0.5, duration: 1), + ]) + currentRoundLabel.run(newRoundAction) + } } diff --git a/GoldWars/GoldWars/GameCenterManager.swift b/GoldWars/GoldWars/GameCenterManager.swift index 64bfd7a..d10654b 100644 --- a/GoldWars/GoldWars/GameCenterManager.swift +++ b/GoldWars/GoldWars/GameCenterManager.swift @@ -22,6 +22,8 @@ struct State: Codable { // 1 RemotePlayerInit fertig // 2 Peer hat Map erhalten // 3 Host hat Spiel gestartet + // 4 Peer hat verloren + // 5 Peer hat gewonnen let state: Int } @@ -92,7 +94,7 @@ final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate, GKG achievement.percentComplete += increasePercentComplete achievement.showsCompletionBanner = true GKAchievement.report([achievement]) { (error) in - print(error?.localizedDescription ?? "") + print(error?.localizedDescription ?? "") } } }) @@ -101,7 +103,7 @@ final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate, GKG newAchievement.showsCompletionBanner = true newAchievement.percentComplete = increasePercentComplete GKAchievement.report([newAchievement]) { (error) in - print(error?.localizedDescription ?? "") + print(error?.localizedDescription ?? "") } } } @@ -140,7 +142,7 @@ final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate, GKG initAndSendMap() }else { os_log("Host hat Player initialisiert", log: LOG, type: .info) - } + } case 2: os_log("State 2 erhalten", log: LOG, type: .info) sendStateToPeers(state: State(state: 3)) @@ -150,6 +152,12 @@ final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate, GKG os_log("State 3 erhalten", log: LOG, type: .info) initIsFinish = true os_log("Spiel startet", log: LOG, type: .info) + case 4: + os_log("State 4 erhalten, Peer hat verloren", log: LOG, type: .info) + // TODO: Trigger Loser Scene + case 5: + os_log("State 5 erhalten, Peer hat gewonnen", log: LOG, type: .info) + // TODO: Trigger Winner Scene default: break } @@ -159,6 +167,8 @@ final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate, GKG } if let snapshotModel = try? jsonDecoder.decode(SnapshotModel.self, from: data) { DataService.sharedInstance.snapshotModel = snapshotModel + RoundCalculatorService.sharedInstance.currentRound += 1 + entityManager.getHUD()?.setCurrentRound(round: RoundCalculatorService.sharedInstance.currentRound) entityManager.updateSnapshotModel(snapshotModel: snapshotModel) entityManager.getHUD()?.startWithDuration() } diff --git a/GoldWars/GoldWars/RoundCalculatorService.swift b/GoldWars/GoldWars/RoundCalculatorService.swift index fc57f96..95f0c72 100644 --- a/GoldWars/GoldWars/RoundCalculatorService.swift +++ b/GoldWars/GoldWars/RoundCalculatorService.swift @@ -10,20 +10,19 @@ import GameKit import os class RoundCalculatorService { + var entityManager = EntityManager.gameEMInstance static let sharedInstance = RoundCalculatorService() static let LOG = OSLog.init(subsystem: "Round Calculator", category: "RoundCalculatorService") - let ATK_BOOST_MULTIPLICATOR = 1.1 - let DEF_BOOST_MULTIPLICATOR = 1.1 - var allPlayerMoves: [String: [PlayerMove]] = [:] // TODO: Better data structure var boosts: [String: (Bool, Bool)] = [:] // First bool is atk boost, second is def boost - var entityManager = EntityManager.gameEMInstance - + let ATK_BOOST_MULTIPLICATOR = 1.1 + let DEF_BOOST_MULTIPLICATOR = 1.1 + let MAX_ROUNDS = 20 + var currentRound = 1 var isCalculating = false - var numberOfAttacks = 0 var numberOfOwnUnitMoves = 0 @@ -148,6 +147,23 @@ class RoundCalculatorService { DataService.sharedInstance.localRoundData.localPlayerMoves.removeAll() DataService.sharedInstance.localRoundData.hasAttackBoost = false DataService.sharedInstance.localRoundData.hasDefenceBoost = false + + if isGameOver() { + let winner: String? + if MAX_ROUNDS == currentRound { + os_log("Game is over by rounds", log: RoundCalculatorService.LOG, type: .info) + winner = determineWinner(by: "rounds") + } else { + os_log("Game is over by capture", log: RoundCalculatorService.LOG, type: .info) + winner = determineWinner(by: "capture") + } + winner == GameCenterManager.sharedInstance.hostingPlayer?.displayName ? GameCenterManager.sharedInstance.sendStateToPeers(state: State(state: 4)) : GameCenterManager.sharedInstance.sendStateToPeers(state: State(state: 5)) + //TODO: Trigger Winner/Loser-Scene for Server + return + } + currentRound += 1 + entityManager.getHUD()?.setCurrentRound(round: currentRound) + MultiplayerNetwork.sharedInstance.sendSnapshotModelToPlayers() DataService.sharedInstance.snapshotModel = currentSnapshotModel entityManager.updateSnapshotModel(snapshotModel: currentSnapshotModel!) @@ -168,7 +184,7 @@ class RoundCalculatorService { DataService.sharedInstance.remotePlayerMoves[GameCenterManager.sharedInstance.peerPlayer!.displayName]?.hasAttackBoost ?? false, DataService.sharedInstance.remotePlayerMoves[GameCenterManager.sharedInstance.peerPlayer!.displayName]?.hasDefenceBoost ?? false ) - + allPlayerMoves[GKLocalPlayer.local.displayName] = DataService.sharedInstance.localRoundData.localPlayerMoves var baseSpecificMoves: [Int: [String: [PlayerMove]]] = [:] @@ -206,4 +222,33 @@ class RoundCalculatorService { self.numberOfAttacks += 1 } } + + func isGameOver() -> Bool { + let remoteplayerBasesCount = entityManager.getBasesByPlayer(for: GameCenterManager.sharedInstance.peerPlayer!).count + let localplayerBasesCount = entityManager.getBasesByPlayer(for: GameCenterManager.sharedInstance.hostingPlayer!).count + let onePlayerLoseAllBases = remoteplayerBasesCount == 0 || localplayerBasesCount == 0 + let reachMaxRounds = MAX_ROUNDS == currentRound + return onePlayerLoseAllBases || reachMaxRounds + } + + func determineWinner(by criteria: String) -> String { + var winner: String? + switch criteria { + case "rounds": + let peerPlayerBasesCount = entityManager.getBasesByPlayer(for: GameCenterManager.sharedInstance.peerPlayer!).count + let hostingPlayerBasesCount = entityManager.getBasesByPlayer(for: GameCenterManager.sharedInstance.hostingPlayer!).count + if peerPlayerBasesCount == hostingPlayerBasesCount { + let hostingPlayerUnitCount = entityManager.getUnitSum(by: GameCenterManager.sharedInstance.hostingPlayer!) + let peerPlayerUnitCount = entityManager.getUnitSum(by: GameCenterManager.sharedInstance.peerPlayer!) + winner = hostingPlayerUnitCount > peerPlayerUnitCount ? GameCenterManager.sharedInstance.hostingPlayer?.displayName : GameCenterManager.sharedInstance.peerPlayer?.displayName + } else { + winner = hostingPlayerBasesCount > peerPlayerBasesCount ? GameCenterManager.sharedInstance.hostingPlayer?.displayName : GameCenterManager.sharedInstance.peerPlayer?.displayName + } + case "capture": + winner = entityManager.getBasesByPlayer(for: GameCenterManager.sharedInstance.hostingPlayer!).count == 0 ? GameCenterManager.sharedInstance.peerPlayer?.displayName : GameCenterManager.sharedInstance.hostingPlayer?.displayName + default: + break + } + return winner! + } } diff --git a/GoldWars/GoldWars/SettingsScene.swift b/GoldWars/GoldWars/SettingsScene.swift index 306e579..2e0760d 100644 --- a/GoldWars/GoldWars/SettingsScene.swift +++ b/GoldWars/GoldWars/SettingsScene.swift @@ -13,7 +13,6 @@ class SettingsScene: SKScene { var entityManager = EntityManager.settingsEMInstance override func sceneDidLoad() { - entityManager.setScene(scene: self) let positionX = self.size.width * 0.1 let positionY = self.size.height * 0.05