From 08dfe6a9220c215f8676dbecd285741d3fdbca72 Mon Sep 17 00:00:00 2001 From: Marcel Schwarz Date: Fri, 29 May 2020 16:23:56 +0200 Subject: [PATCH] Pull TwoPlayerMapGenerator in as MapFactory --- GoldWars/GoldWars.xcodeproj/project.pbxproj | 16 +- GoldWars/GoldWars/DataService.swift | 2 +- GoldWars/GoldWars/GameCenterManager.swift | 2 +- GoldWars/GoldWars/Map/MapFactory.swift | 300 ++++++++++++++---- GoldWars/GoldWars/Map/MapUtils.swift | 68 ++++ .../GoldWars/Map/TwoPlayerMapGenerator.swift | 267 ---------------- GoldWars/GoldWars/Scenes/GameScene.swift | 2 +- 7 files changed, 320 insertions(+), 337 deletions(-) create mode 100644 GoldWars/GoldWars/Map/MapUtils.swift delete mode 100644 GoldWars/GoldWars/Map/TwoPlayerMapGenerator.swift diff --git a/GoldWars/GoldWars.xcodeproj/project.pbxproj b/GoldWars/GoldWars.xcodeproj/project.pbxproj index 5261a4e..7371bab 100644 --- a/GoldWars/GoldWars.xcodeproj/project.pbxproj +++ b/GoldWars/GoldWars.xcodeproj/project.pbxproj @@ -44,9 +44,9 @@ 9EEDE02D246FCD770096C735 /* SpinningLogoEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EEDE02C246FCD770096C735 /* SpinningLogoEntity.swift */; }; 9EEDE02F246FCD800096C735 /* SpinningLogoComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EEDE02E246FCD800096C735 /* SpinningLogoComponent.swift */; }; AB0B88F6247AD89200C8DF66 /* SkillComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB0B88F5247AD89200C8DF66 /* SkillComponent.swift */; }; - AB1D75A0245DEC0500671525 /* MapFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB1D759F245DEC0500671525 /* MapFactory.swift */; }; - AB21D7D5246C748A00B09CBA /* TwoPlayerMapGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB21D7D4246C748A00B09CBA /* TwoPlayerMapGenerator.swift */; }; + AB21D7D5246C748A00B09CBA /* MapFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB21D7D4246C748A00B09CBA /* MapFactory.swift */; }; ABA03DA0244BD54F00A66916 /* Base.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABA03D9F244BD54F00A66916 /* Base.swift */; }; + ABC0C3732481509300387B8F /* MapUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABC0C3722481509300387B8F /* MapUtils.swift */; }; C04783EE2468583F004961FB /* intro-music.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = C04783ED2468583F004961FB /* intro-music.mp3 */; }; C04783F024685995004961FB /* SettingsScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = C04783EF24685995004961FB /* SettingsScene.swift */; }; C05BB9C4247D890C00411249 /* SliderComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C05BB9C3247D890C00411249 /* SliderComponent.swift */; }; @@ -110,9 +110,9 @@ 9EEDE02C246FCD770096C735 /* SpinningLogoEntity.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpinningLogoEntity.swift; sourceTree = ""; }; 9EEDE02E246FCD800096C735 /* SpinningLogoComponent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpinningLogoComponent.swift; sourceTree = ""; }; AB0B88F5247AD89200C8DF66 /* SkillComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkillComponent.swift; sourceTree = ""; }; - AB1D759F245DEC0500671525 /* MapFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapFactory.swift; sourceTree = ""; }; - AB21D7D4246C748A00B09CBA /* TwoPlayerMapGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoPlayerMapGenerator.swift; sourceTree = ""; }; + AB21D7D4246C748A00B09CBA /* MapFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapFactory.swift; sourceTree = ""; }; ABA03D9F244BD54F00A66916 /* Base.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Base.swift; sourceTree = ""; }; + ABC0C3722481509300387B8F /* MapUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapUtils.swift; sourceTree = ""; }; C04783ED2468583F004961FB /* intro-music.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = "intro-music.mp3"; sourceTree = ""; }; C04783EF24685995004961FB /* SettingsScene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsScene.swift; sourceTree = ""; }; C05BB9C3247D890C00411249 /* SliderComponent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SliderComponent.swift; sourceTree = ""; }; @@ -283,8 +283,8 @@ isa = PBXGroup; children = ( 3E67853F24728368007B9DE4 /* CElements.swift */, - AB1D759F245DEC0500671525 /* MapFactory.swift */, - AB21D7D4246C748A00B09CBA /* TwoPlayerMapGenerator.swift */, + AB21D7D4246C748A00B09CBA /* MapFactory.swift */, + ABC0C3722481509300387B8F /* MapUtils.swift */, ); path = Map; sourceTree = ""; @@ -411,17 +411,17 @@ 9E174C86245DD91500209FF0 /* ButtonComponent.swift in Sources */, 11036113244B3E30008610AF /* MenuScene.swift in Sources */, C099579C246C5E5C0016AA22 /* DataService.swift in Sources */, - AB21D7D5246C748A00B09CBA /* TwoPlayerMapGenerator.swift in Sources */, + AB21D7D5246C748A00B09CBA /* MapFactory.swift in Sources */, 9EA3ABE9245C6DAA006BC61D /* DefaultBaseComponent.swift in Sources */, 9E174C8A245E1A0A00209FF0 /* Background.swift in Sources */, 8BB6FF402472B8F000162BBD /* SingeClickButtonNode.swift in Sources */, AB0B88F6247AD89200C8DF66 /* SkillComponent.swift in Sources */, C064E9A8246C0EA50022B228 /* LabelNode.swift in Sources */, 3F745DF0246F48FC00CE7375 /* PlayerMoveType.swift in Sources */, - AB1D75A0245DEC0500671525 /* MapFactory.swift in Sources */, 3E67854024728368007B9DE4 /* CElements.swift in Sources */, ABA03DA0244BD54F00A66916 /* Base.swift in Sources */, C064E9AC246C151F0022B228 /* Label.swift in Sources */, + ABC0C3732481509300387B8F /* MapUtils.swift in Sources */, 9E174C82245DD81D00209FF0 /* ButtonNode.swift in Sources */, 9EC7E48B2461FBF700396BCD /* SliderNode.swift in Sources */, 9EEDE02F246FCD800096C735 /* SpinningLogoComponent.swift in Sources */, diff --git a/GoldWars/GoldWars/DataService.swift b/GoldWars/GoldWars/DataService.swift index 5ae7da0..cba4f4d 100644 --- a/GoldWars/GoldWars/DataService.swift +++ b/GoldWars/GoldWars/DataService.swift @@ -67,6 +67,6 @@ class DataService { func setMapModel(model: MapGenerationModel) { self.mapModel = model - MapFactory(scene: entityManager.scene, entityManager: entityManager).loadMap(fromModel: DataService.sharedInstance.mapModel!) + MapFactory(scene: entityManager.scene, entityManager: entityManager).load(fromModel: DataService.sharedInstance.mapModel!) } } diff --git a/GoldWars/GoldWars/GameCenterManager.swift b/GoldWars/GoldWars/GameCenterManager.swift index ba0ce93..7571212 100644 --- a/GoldWars/GoldWars/GameCenterManager.swift +++ b/GoldWars/GoldWars/GameCenterManager.swift @@ -148,7 +148,7 @@ final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate ,GKM func initAndSendMap() -> Void { self.gameScene = GameScene(size: self.menusc!.size) - let mapModel = MapFactory(scene: self.gameScene!, entityManager: entityManager).loadMap() + let mapModel = MapFactory(scene: self.gameScene!, entityManager: entityManager).load() os_log("Map wurde erstellt", log: LOG, type: .info) MultiplayerNetwork.sharedInstance.sendMapModelToPlayers(mapModel: mapModel) os_log("Map wurde an Peer gesendet", log: LOG, type: .info) diff --git a/GoldWars/GoldWars/Map/MapFactory.swift b/GoldWars/GoldWars/Map/MapFactory.swift index 42d2aca..bcddf4d 100644 --- a/GoldWars/GoldWars/Map/MapFactory.swift +++ b/GoldWars/GoldWars/Map/MapFactory.swift @@ -1,80 +1,262 @@ // -// MapFactory.swift +// TwoPlayerMapGenerator.swift // GoldWars // -// Created by Marcel Schwarz on 02.05.20. +// Created by Marcel Schwarz on 13.05.20. // Copyright © 2020 SP2. All rights reserved. // import Foundation import SpriteKit +import GameKit import os - -protocol CenterElementProtocol { - - var bases: [Base] {get set} - var ways: [Way] {get set} - var id: Int { get } - - init(frame: CGRect) - - func getAllBases() -> [Base] - func getInternalWays() -> [Way] - func getTopConnection() -> Base? - func getRightConnection() -> Base? - func getBottomConnection() -> Base? - func getLeftConnection() -> Base? -} - class MapFactory { - let LOG = OSLog.init(subsystem: "MapGenerator", category: "MapFactory") - var twoPlayerMapGenerator: TwoPlayerMapGenerator + let LOG = OSLog.init(subsystem: "MapGenerator", category: "TwoPlayerMapGenerator") - init(scene: SKScene, entityManager: EntityManager) { - self.twoPlayerMapGenerator = TwoPlayerMapGenerator(scene: scene, entityManager: entityManager) + var size: CGSize! + var entityManager: EntityManager! + + static func getNewMapModel() -> MapGenerationModel { + + let noOfCElements = CenterElementProvider.centerElements.count - 1 + + return MapGenerationModel( + numBasesP1: Int.random(in: 1...3), + numBasesP2: Int.random(in: 1...3), + topLeftId: Int.random(in: 0...noOfCElements), + topRightId: Int.random(in: 0...noOfCElements), + bottomLeftId: Int.random(in: 0...noOfCElements), + bottomRightId: Int.random(in: 0...noOfCElements) + ) + } - func loadMap() -> MapGenerationModel { - let mapModel = TwoPlayerMapGenerator.getNewMapModel() - loadMap(fromModel: mapModel) + required init(scene: SKScene, entityManager: EntityManager) { + self.size = scene.size + self.entityManager = entityManager + } + + func load() -> MapGenerationModel { + let mapModel = MapFactory.getNewMapModel() + load(fromModel: mapModel) return mapModel } - func loadMap(fromModel model: MapGenerationModel) { - os_log("Loading two player map", log: LOG, type: .info) - twoPlayerMapGenerator.load(withModel: model) - } -} - -class CenterElementProvider { - static let LOG = OSLog.init(subsystem: "MapGenerator", category: "CenterElementProvider") - - static let centerElements: [CenterElementProtocol.Type] = [ - CElement0.self, - CElement1.self, - CElement2.self, - CElement3.self, - CElement4.self, - CElement5.self, - CElement6.self, - CElement7.self, - CElement8.self, - CElement9.self, - CElement10.self, - CElement11.self, - CElement12.self, - CElement13.self, - CElement14.self, - CElement15.self, - CElement16.self, - CElement17.self - ] - - static func get(inFrame frame: CGRect, withId id: Int) -> CenterElementProtocol { - os_log("Getting new predifined center element from provider", log: LOG, type: .info) + func load(fromModel mapModel: MapGenerationModel) { + os_log("Loading from TwoPlayerMapFactory", log: LOG, type: .info) - return centerElements[id].init(frame: frame) + // Generate bases structure + os_log("Get player one base", log: LOG, type: .info) + let basePlayerOne = Base( + position: CGPoint(x: self.size.width * 0.07, y: self.size.height / 2), + player: (GameCenterManager.sharedInstance.isServer) ? GKLocalPlayer.local : GameCenterManager.sharedInstance.myMatch?.players[0], + team: .team1 + ) + + os_log("Get player one's startbases", log: LOG, type: .info) + var p1StartBases = [String: Base]() + var ways = [Way]() + + if (mapModel.numBasesP1 == 1) { + p1StartBases["mid"] = Base(position: CGPoint(x: self.size.width * 0.2, y: self.size.height * 0.5)) + ways.append(Way(fromBase: basePlayerOne, toBase: p1StartBases["mid"]!)) + } else if (mapModel.numBasesP1 == 2) { + p1StartBases["top"] = Base(position: CGPoint(x: self.size.width * 0.2, y: self.size.height * 0.333)) + p1StartBases["bot"] = Base(position: CGPoint(x: self.size.width * 0.2, y: self.size.height * 0.666)) + ways.append(Way(fromBase: basePlayerOne, toBase: p1StartBases["top"]!)) + ways.append(Way(fromBase: basePlayerOne, toBase: p1StartBases["bot"]!)) + } else { + p1StartBases["top"] = Base(position: CGPoint(x: self.size.width * 0.2, y: self.size.height * 0.25)) + p1StartBases["mid"] = Base(position: CGPoint(x: self.size.width * 0.2, y: self.size.height * 0.5)) + p1StartBases["bot"] = Base(position: CGPoint(x: self.size.width * 0.2, y: self.size.height * 0.75)) + ways.append(Way(fromBase: basePlayerOne, toBase: p1StartBases["top"]!)) + ways.append(Way(fromBase: basePlayerOne, toBase: p1StartBases["mid"]!)) + ways.append(Way(fromBase: basePlayerOne, toBase: p1StartBases["bot"]!)) + } + + os_log("Generate Map center", log: LOG, type: .info) + let gridCellWidth = self.size.width * 0.2 + let gridCellHeight = self.size.height * 0.4 + let cellInsetX = CGFloat(self.size.width * 0.05) + let cellInsetY = CGFloat(self.size.height * 0.07) + + let gridTopLeft = CGRect( + x: self.size.width * 0.3, + y: self.size.height * 0.1, + width: gridCellWidth, + height: gridCellHeight + ).insetBy(dx: cellInsetX, dy: cellInsetY) + + let gridTopRight = CGRect( + x: self.size.width * 0.5, + y: self.size.height * 0.1, + width: gridCellWidth, + height: gridCellHeight + ).insetBy(dx: cellInsetX, dy: cellInsetY) + + let gridBottomLeft = CGRect( + x: self.size.width * 0.3, + y: self.size.height * 0.5, + width: gridCellWidth, + height: gridCellHeight + ).insetBy(dx: cellInsetX, dy: cellInsetY) + + let gridBottomRight = CGRect( + x: self.size.width * 0.5, + y: self.size.height * 0.5, + width: gridCellWidth, + height: gridCellHeight + ).insetBy(dx: cellInsetX, dy: cellInsetY) + + let topLeft = CenterElementProvider.get(inFrame: gridTopLeft, withId: mapModel.topLeftId) + let topRight = CenterElementProvider.get(inFrame: gridTopRight, withId: mapModel.topRightId) + let bottomLeft = CenterElementProvider.get(inFrame: gridBottomLeft, withId: mapModel.bottomLeftId) + let bottomRight = CenterElementProvider.get(inFrame: gridBottomRight, withId: mapModel.bottomRightId) + + ways.append(contentsOf: topLeft.getInternalWays()) + ways.append(contentsOf: topRight.getInternalWays()) + ways.append(contentsOf: bottomLeft.getInternalWays()) + ways.append(contentsOf: bottomRight.getInternalWays()) + + os_log("Get player two base", log: LOG, type: .info) + let basePlayerTwo = Base( + position: CGPoint(x: self.size.width * 0.93, y: self.size.height / 2), + player: (!GameCenterManager.sharedInstance.isServer) ? GKLocalPlayer.local : GameCenterManager.sharedInstance.myMatch?.players[0], + team: .team2 + ) + + os_log("Get player two's startbases", log: LOG, type: .info) + var p2StartBases = [String: Base]() + + if (mapModel.numBasesP2 == 1) { + p2StartBases["mid"] = Base(position: CGPoint(x: self.size.width * 0.8, y: self.size.height * 0.5)) + ways.append(Way(fromBase: basePlayerTwo, toBase: p2StartBases["mid"]!)) + } else if (mapModel.numBasesP2 == 2) { + p2StartBases["top"] = Base(position: CGPoint(x: self.size.width * 0.8, y: self.size.height * 0.333)) + p2StartBases["bot"] = Base(position: CGPoint(x: self.size.width * 0.8, y: self.size.height * 0.666)) + ways.append(Way(fromBase: basePlayerTwo, toBase: p2StartBases["top"]!)) + ways.append(Way(fromBase: basePlayerTwo, toBase: p2StartBases["bot"]!)) + } else { + p2StartBases["top"] = Base(position: CGPoint(x: self.size.width * 0.8, y: self.size.height * 0.25)) + p2StartBases["mid"] = Base(position: CGPoint(x: self.size.width * 0.8, y: self.size.height * 0.5)) + p2StartBases["bot"] = Base(position: CGPoint(x: self.size.width * 0.8, y: self.size.height * 0.75)) + ways.append(Way(fromBase: basePlayerTwo, toBase: p2StartBases["top"]!)) + ways.append(Way(fromBase: basePlayerTwo, toBase: p2StartBases["mid"]!)) + ways.append(Way(fromBase: basePlayerTwo, toBase: p2StartBases["bot"]!)) + } + + // Create adjacency mapping + os_log("Connecting base p1 and start bases", log: LOG, type: .info) + basePlayerOne.adjacencyList.append(contentsOf: p1StartBases.values) + p1StartBases.values.forEach({base in base.adjacencyList.append(basePlayerOne)}) + + if (p1StartBases["top"] != nil && topLeft.getLeftConnection() != nil) { + os_log("Connecting p1 startbase top with topLeft segment", log: LOG, type: .info) + p1StartBases["top"]!.adjacencyList.append(topLeft.getLeftConnection()!) + topLeft.getLeftConnection()!.adjacencyList.append(p1StartBases["top"]!) + ways.append(Way(fromBase: p1StartBases["top"]!, toBase: topLeft.getLeftConnection()!)) + } + + if (p1StartBases["mid"] != nil) { + if (topLeft.getLeftConnection() != nil) { + os_log("Connecting p1 startbase mid with topLeft segment", log: LOG, type: .info) + p1StartBases["mid"]!.adjacencyList.append(topLeft.getLeftConnection()!) + topLeft.getLeftConnection()!.adjacencyList.append(p1StartBases["mid"]!) + ways.append(Way(fromBase: p1StartBases["mid"]!, toBase: topLeft.getLeftConnection()!)) + } + + if (bottomLeft.getLeftConnection() != nil) { + os_log("Connecting p1 startbase mid with bottomLeft segment", log: LOG, type: .info) + p1StartBases["mid"]!.adjacencyList.append(bottomLeft.getLeftConnection()!) + bottomLeft.getLeftConnection()!.adjacencyList.append(p1StartBases["mid"]!) + ways.append(Way(fromBase: p1StartBases["mid"]!, toBase: bottomLeft.getLeftConnection()!)) + } + } + + if (p1StartBases["bot"] != nil && bottomLeft.getLeftConnection() != nil) { + os_log("Connecting p1 startbase bot with bottomLeft segment", log: LOG, type: .info) + p1StartBases["bot"]!.adjacencyList.append(bottomLeft.getLeftConnection()!) + bottomLeft.getLeftConnection()!.adjacencyList.append(p1StartBases["bot"]!) + ways.append(Way(fromBase: p1StartBases["bot"]!, toBase: bottomLeft.getLeftConnection()!)) + } + + if (topLeft.getRightConnection() != nil && topRight.getLeftConnection() != nil) { + os_log("Connecting topLeft with topRight segment horizontally", log: LOG, type: .info) + topLeft.getRightConnection()!.adjacencyList.append(topRight.getLeftConnection()!) + topRight.getLeftConnection()!.adjacencyList.append(topLeft.getRightConnection()!) + ways.append(Way(fromBase: topLeft.getRightConnection()!, toBase: topRight.getLeftConnection()!)) + } + + if (bottomLeft.getRightConnection() != nil && bottomRight.getLeftConnection() != nil) { + os_log("Connecting bottomLeft with bottomRight segment horizontally", log: LOG, type: .info) + bottomLeft.getRightConnection()!.adjacencyList.append(bottomRight.getLeftConnection()!) + bottomRight.getLeftConnection()!.adjacencyList.append(bottomLeft.getRightConnection()!) + ways.append(Way(fromBase: bottomLeft.getRightConnection()!, toBase: bottomRight.getLeftConnection()!)) + } + + if (topLeft.getBottomConnection() != nil && bottomLeft.getTopConnection() != nil) { + os_log("Connecting topLeft with bottomLeft segment vertically", log: LOG, type: .info) + topLeft.getBottomConnection()!.adjacencyList.append(bottomLeft.getTopConnection()!) + bottomLeft.getTopConnection()!.adjacencyList.append(topLeft.getBottomConnection()!) + ways.append(Way(fromBase: topLeft.getBottomConnection()!, toBase: bottomLeft.getTopConnection()!)) + } + + if (topRight.getBottomConnection() != nil && bottomRight.getTopConnection() != nil) { + os_log("Connecting topRight with bottomRight segment vertically", log: LOG, type: .info) + topRight.getBottomConnection()!.adjacencyList.append(bottomRight.getTopConnection()!) + bottomRight.getTopConnection()!.adjacencyList.append(topRight.getBottomConnection()!) + ways.append(Way(fromBase: topRight.getBottomConnection()!, toBase: bottomRight.getTopConnection()!)) + } + + os_log("Connecting base p2 and start bases", log: LOG, type: .info) + basePlayerTwo.adjacencyList.append(contentsOf: p2StartBases.values) + p2StartBases.values.forEach({base in base.adjacencyList.append(basePlayerTwo)}) + + if (p2StartBases["top"] != nil && topRight.getRightConnection() != nil) { + os_log("Connecting p2 startbase top with topRight segment", log: LOG, type: .info) + p2StartBases["top"]!.adjacencyList.append(topRight.getRightConnection()!) + topRight.getRightConnection()!.adjacencyList.append(p2StartBases["top"]!) + ways.append(Way(fromBase: p2StartBases["top"]!, toBase: topRight.getRightConnection()!)) + } + + if (p2StartBases["mid"] != nil) { + if (topRight.getRightConnection() != nil) { + os_log("Connecting p2 startbase mid with topRight segment", log: LOG, type: .info) + p2StartBases["mid"]!.adjacencyList.append(topRight.getRightConnection()!) + topRight.getRightConnection()!.adjacencyList.append(p2StartBases["mid"]!) + ways.append(Way(fromBase: topRight.getRightConnection()!, toBase: p2StartBases["mid"]!)) + } + + if (bottomRight.getRightConnection() != nil) { + os_log("Connecting p2 startbase mid with bottomRight segment", log: LOG, type: .info) + p2StartBases["mid"]!.adjacencyList.append(bottomRight.getRightConnection()!) + bottomRight.getRightConnection()!.adjacencyList.append(p2StartBases["mid"]!) + ways.append(Way(fromBase: p2StartBases["mid"]!, toBase: bottomRight.getRightConnection()!)) + } + } + + if (p2StartBases["bot"] != nil && bottomRight.getRightConnection() != nil) { + os_log("Connecting p2 startbase bot with bottomRight segment", log: LOG, type: .info) + p2StartBases["bot"]!.adjacencyList.append(bottomRight.getRightConnection()!) + bottomRight.getRightConnection()!.adjacencyList.append(p2StartBases["bot"]!) + ways.append(Way(fromBase: p2StartBases["bot"]!, toBase: bottomRight.getRightConnection()!)) + } + + + // Add all bases to the scene + entityManager.add(basePlayerOne) + p1StartBases.forEach({(key, base) in entityManager.add(base)}) + + topLeft.getAllBases().forEach({base in entityManager.add(base)}) + topRight.getAllBases().forEach({base in entityManager.add(base)}) + bottomLeft.getAllBases().forEach({base in entityManager.add(base)}) + bottomRight.getAllBases().forEach({base in entityManager.add(base)}) + + entityManager.add(basePlayerTwo) + p2StartBases.forEach({(key, base) in entityManager.add(base)}) + + ways.forEach({way in entityManager.add(way)}) } } diff --git a/GoldWars/GoldWars/Map/MapUtils.swift b/GoldWars/GoldWars/Map/MapUtils.swift new file mode 100644 index 0000000..0c636fc --- /dev/null +++ b/GoldWars/GoldWars/Map/MapUtils.swift @@ -0,0 +1,68 @@ +// +// MapUtils.swift +// GoldWars +// +// Created by Marcel Schwarz on 29.05.20. +// Copyright © 2020 SP2. All rights reserved. +// + +import GameKit +import os + +protocol CenterElementProtocol { + + var bases: [Base] {get set} + var ways: [Way] {get set} + var id: Int { get } + + init(frame: CGRect) + + func getAllBases() -> [Base] + func getInternalWays() -> [Way] + func getTopConnection() -> Base? + func getRightConnection() -> Base? + func getBottomConnection() -> Base? + func getLeftConnection() -> Base? +} + +struct MapGenerationModel: Codable { + + let numBasesP1: Int + let numBasesP2: Int + let topLeftId: Int + let topRightId: Int + let bottomLeftId: Int + let bottomRightId: Int + +} + +class CenterElementProvider { + static let LOG = OSLog.init(subsystem: "MapGenerator", category: "CenterElementProvider") + + static let centerElements: [CenterElementProtocol.Type] = [ + CElement0.self, + CElement1.self, + CElement2.self, + CElement3.self, + CElement4.self, + CElement5.self, + CElement6.self, + CElement7.self, + CElement8.self, + CElement9.self, + CElement10.self, + CElement11.self, + CElement12.self, + CElement13.self, + CElement14.self, + CElement15.self, + CElement16.self, + CElement17.self + ] + + static func get(inFrame frame: CGRect, withId id: Int) -> CenterElementProtocol { + os_log("Getting new predifined center element from provider", log: LOG, type: .info) + + return centerElements[id].init(frame: frame) + } +} diff --git a/GoldWars/GoldWars/Map/TwoPlayerMapGenerator.swift b/GoldWars/GoldWars/Map/TwoPlayerMapGenerator.swift deleted file mode 100644 index 07731cb..0000000 --- a/GoldWars/GoldWars/Map/TwoPlayerMapGenerator.swift +++ /dev/null @@ -1,267 +0,0 @@ -// -// TwoPlayerMapGenerator.swift -// GoldWars -// -// Created by Marcel Schwarz on 13.05.20. -// Copyright © 2020 SP2. All rights reserved. -// - -import Foundation -import SpriteKit -import GameKit -import os - -struct MapGenerationModel: Codable { - - let numBasesP1: Int - let numBasesP2: Int - let topLeftId: Int - let topRightId: Int - let bottomLeftId: Int - let bottomRightId: Int - -} - -class TwoPlayerMapGenerator { - - let LOG = OSLog.init(subsystem: "MapGenerator", category: "TwoPlayerMapGenerator") - - var size: CGSize! - var entityManager: EntityManager! - - static func getNewMapModel() -> MapGenerationModel { - - let noOfCElements = CenterElementProvider.centerElements.count - 1 - - return MapGenerationModel( - numBasesP1: Int.random(in: 1...3), - numBasesP2: Int.random(in: 1...3), - topLeftId: Int.random(in: 0...noOfCElements), - topRightId: Int.random(in: 0...noOfCElements), - bottomLeftId: Int.random(in: 0...noOfCElements), - bottomRightId: Int.random(in: 0...noOfCElements) - ) - - } - - required init(scene: SKScene, entityManager: EntityManager) { - self.size = scene.size - self.entityManager = entityManager - } - - func load(withModel mapModel: MapGenerationModel) { - os_log("Loading from TwoPlayerMapFactory", log: LOG, type: .info) - - // Generate bases structure - os_log("Get player one base", log: LOG, type: .info) - let basePlayerOne = Base( - position: CGPoint(x: self.size.width * 0.07, y: self.size.height / 2), - player: (GameCenterManager.sharedInstance.isServer) ? GKLocalPlayer.local : GameCenterManager.sharedInstance.myMatch?.players[0], - team: .team1 - ) - - os_log("Get player one's startbases", log: LOG, type: .info) - var p1StartBases = [String: Base]() - var ways = [Way]() - - if (mapModel.numBasesP1 == 1) { - p1StartBases["mid"] = Base(position: CGPoint(x: self.size.width * 0.2, y: self.size.height * 0.5)) - ways.append(Way(fromBase: basePlayerOne, toBase: p1StartBases["mid"]!)) - } else if (mapModel.numBasesP1 == 2) { - p1StartBases["top"] = Base(position: CGPoint(x: self.size.width * 0.2, y: self.size.height * 0.333)) - p1StartBases["bot"] = Base(position: CGPoint(x: self.size.width * 0.2, y: self.size.height * 0.666)) - ways.append(Way(fromBase: basePlayerOne, toBase: p1StartBases["top"]!)) - ways.append(Way(fromBase: basePlayerOne, toBase: p1StartBases["bot"]!)) - } else { - p1StartBases["top"] = Base(position: CGPoint(x: self.size.width * 0.2, y: self.size.height * 0.25)) - p1StartBases["mid"] = Base(position: CGPoint(x: self.size.width * 0.2, y: self.size.height * 0.5)) - p1StartBases["bot"] = Base(position: CGPoint(x: self.size.width * 0.2, y: self.size.height * 0.75)) - ways.append(Way(fromBase: basePlayerOne, toBase: p1StartBases["top"]!)) - ways.append(Way(fromBase: basePlayerOne, toBase: p1StartBases["mid"]!)) - ways.append(Way(fromBase: basePlayerOne, toBase: p1StartBases["bot"]!)) - } - - os_log("Generate Map center", log: LOG, type: .info) - let gridCellWidth = self.size.width * 0.2 - let gridCellHeight = self.size.height * 0.4 - let cellInsetX = CGFloat(self.size.width * 0.05) - let cellInsetY = CGFloat(self.size.height * 0.07) - - let gridTopLeft = CGRect( - x: self.size.width * 0.3, - y: self.size.height * 0.1, - width: gridCellWidth, - height: gridCellHeight - ).insetBy(dx: cellInsetX, dy: cellInsetY) - - let gridTopRight = CGRect( - x: self.size.width * 0.5, - y: self.size.height * 0.1, - width: gridCellWidth, - height: gridCellHeight - ).insetBy(dx: cellInsetX, dy: cellInsetY) - - let gridBottomLeft = CGRect( - x: self.size.width * 0.3, - y: self.size.height * 0.5, - width: gridCellWidth, - height: gridCellHeight - ).insetBy(dx: cellInsetX, dy: cellInsetY) - - let gridBottomRight = CGRect( - x: self.size.width * 0.5, - y: self.size.height * 0.5, - width: gridCellWidth, - height: gridCellHeight - ).insetBy(dx: cellInsetX, dy: cellInsetY) - - let topLeft = CenterElementProvider.get(inFrame: gridTopLeft, withId: mapModel.topLeftId) - let topRight = CenterElementProvider.get(inFrame: gridTopRight, withId: mapModel.topRightId) - let bottomLeft = CenterElementProvider.get(inFrame: gridBottomLeft, withId: mapModel.bottomLeftId) - let bottomRight = CenterElementProvider.get(inFrame: gridBottomRight, withId: mapModel.bottomRightId) - - ways.append(contentsOf: topLeft.getInternalWays()) - ways.append(contentsOf: topRight.getInternalWays()) - ways.append(contentsOf: bottomLeft.getInternalWays()) - ways.append(contentsOf: bottomRight.getInternalWays()) - - os_log("Get player two base", log: LOG, type: .info) - let basePlayerTwo = Base( - position: CGPoint(x: self.size.width * 0.93, y: self.size.height / 2), - player: (!GameCenterManager.sharedInstance.isServer) ? GKLocalPlayer.local : GameCenterManager.sharedInstance.myMatch?.players[0], - team: .team2 - ) - - os_log("Get player two's startbases", log: LOG, type: .info) - var p2StartBases = [String: Base]() - - if (mapModel.numBasesP2 == 1) { - p2StartBases["mid"] = Base(position: CGPoint(x: self.size.width * 0.8, y: self.size.height * 0.5)) - ways.append(Way(fromBase: basePlayerTwo, toBase: p2StartBases["mid"]!)) - } else if (mapModel.numBasesP2 == 2) { - p2StartBases["top"] = Base(position: CGPoint(x: self.size.width * 0.8, y: self.size.height * 0.333)) - p2StartBases["bot"] = Base(position: CGPoint(x: self.size.width * 0.8, y: self.size.height * 0.666)) - ways.append(Way(fromBase: basePlayerTwo, toBase: p2StartBases["top"]!)) - ways.append(Way(fromBase: basePlayerTwo, toBase: p2StartBases["bot"]!)) - } else { - p2StartBases["top"] = Base(position: CGPoint(x: self.size.width * 0.8, y: self.size.height * 0.25)) - p2StartBases["mid"] = Base(position: CGPoint(x: self.size.width * 0.8, y: self.size.height * 0.5)) - p2StartBases["bot"] = Base(position: CGPoint(x: self.size.width * 0.8, y: self.size.height * 0.75)) - ways.append(Way(fromBase: basePlayerTwo, toBase: p2StartBases["top"]!)) - ways.append(Way(fromBase: basePlayerTwo, toBase: p2StartBases["mid"]!)) - ways.append(Way(fromBase: basePlayerTwo, toBase: p2StartBases["bot"]!)) - } - - // Create adjacency mapping - os_log("Connecting base p1 and start bases", log: LOG, type: .info) - basePlayerOne.adjacencyList.append(contentsOf: p1StartBases.values) - p1StartBases.values.forEach({base in base.adjacencyList.append(basePlayerOne)}) - - if (p1StartBases["top"] != nil && topLeft.getLeftConnection() != nil) { - os_log("Connecting p1 startbase top with topLeft segment", log: LOG, type: .info) - p1StartBases["top"]!.adjacencyList.append(topLeft.getLeftConnection()!) - topLeft.getLeftConnection()!.adjacencyList.append(p1StartBases["top"]!) - ways.append(Way(fromBase: p1StartBases["top"]!, toBase: topLeft.getLeftConnection()!)) - } - - if (p1StartBases["mid"] != nil) { - if (topLeft.getLeftConnection() != nil) { - os_log("Connecting p1 startbase mid with topLeft segment", log: LOG, type: .info) - p1StartBases["mid"]!.adjacencyList.append(topLeft.getLeftConnection()!) - topLeft.getLeftConnection()!.adjacencyList.append(p1StartBases["mid"]!) - ways.append(Way(fromBase: p1StartBases["mid"]!, toBase: topLeft.getLeftConnection()!)) - } - - if (bottomLeft.getLeftConnection() != nil) { - os_log("Connecting p1 startbase mid with bottomLeft segment", log: LOG, type: .info) - p1StartBases["mid"]!.adjacencyList.append(bottomLeft.getLeftConnection()!) - bottomLeft.getLeftConnection()!.adjacencyList.append(p1StartBases["mid"]!) - ways.append(Way(fromBase: p1StartBases["mid"]!, toBase: bottomLeft.getLeftConnection()!)) - } - } - - if (p1StartBases["bot"] != nil && bottomLeft.getLeftConnection() != nil) { - os_log("Connecting p1 startbase bot with bottomLeft segment", log: LOG, type: .info) - p1StartBases["bot"]!.adjacencyList.append(bottomLeft.getLeftConnection()!) - bottomLeft.getLeftConnection()!.adjacencyList.append(p1StartBases["bot"]!) - ways.append(Way(fromBase: p1StartBases["bot"]!, toBase: bottomLeft.getLeftConnection()!)) - } - - if (topLeft.getRightConnection() != nil && topRight.getLeftConnection() != nil) { - os_log("Connecting topLeft with topRight segment horizontally", log: LOG, type: .info) - topLeft.getRightConnection()!.adjacencyList.append(topRight.getLeftConnection()!) - topRight.getLeftConnection()!.adjacencyList.append(topLeft.getRightConnection()!) - ways.append(Way(fromBase: topLeft.getRightConnection()!, toBase: topRight.getLeftConnection()!)) - } - - if (bottomLeft.getRightConnection() != nil && bottomRight.getLeftConnection() != nil) { - os_log("Connecting bottomLeft with bottomRight segment horizontally", log: LOG, type: .info) - bottomLeft.getRightConnection()!.adjacencyList.append(bottomRight.getLeftConnection()!) - bottomRight.getLeftConnection()!.adjacencyList.append(bottomLeft.getRightConnection()!) - ways.append(Way(fromBase: bottomLeft.getRightConnection()!, toBase: bottomRight.getLeftConnection()!)) - } - - if (topLeft.getBottomConnection() != nil && bottomLeft.getTopConnection() != nil) { - os_log("Connecting topLeft with bottomLeft segment vertically", log: LOG, type: .info) - topLeft.getBottomConnection()!.adjacencyList.append(bottomLeft.getTopConnection()!) - bottomLeft.getTopConnection()!.adjacencyList.append(topLeft.getBottomConnection()!) - ways.append(Way(fromBase: topLeft.getBottomConnection()!, toBase: bottomLeft.getTopConnection()!)) - } - - if (topRight.getBottomConnection() != nil && bottomRight.getTopConnection() != nil) { - os_log("Connecting topRight with bottomRight segment vertically", log: LOG, type: .info) - topRight.getBottomConnection()!.adjacencyList.append(bottomRight.getTopConnection()!) - bottomRight.getTopConnection()!.adjacencyList.append(topRight.getBottomConnection()!) - ways.append(Way(fromBase: topRight.getBottomConnection()!, toBase: bottomRight.getTopConnection()!)) - } - - os_log("Connecting base p2 and start bases", log: LOG, type: .info) - basePlayerTwo.adjacencyList.append(contentsOf: p2StartBases.values) - p2StartBases.values.forEach({base in base.adjacencyList.append(basePlayerTwo)}) - - if (p2StartBases["top"] != nil && topRight.getRightConnection() != nil) { - os_log("Connecting p2 startbase top with topRight segment", log: LOG, type: .info) - p2StartBases["top"]!.adjacencyList.append(topRight.getRightConnection()!) - topRight.getRightConnection()!.adjacencyList.append(p2StartBases["top"]!) - ways.append(Way(fromBase: p2StartBases["top"]!, toBase: topRight.getRightConnection()!)) - } - - if (p2StartBases["mid"] != nil) { - if (topRight.getRightConnection() != nil) { - os_log("Connecting p2 startbase mid with topRight segment", log: LOG, type: .info) - p2StartBases["mid"]!.adjacencyList.append(topRight.getRightConnection()!) - topRight.getRightConnection()!.adjacencyList.append(p2StartBases["mid"]!) - ways.append(Way(fromBase: topRight.getRightConnection()!, toBase: p2StartBases["mid"]!)) - } - - if (bottomRight.getRightConnection() != nil) { - os_log("Connecting p2 startbase mid with bottomRight segment", log: LOG, type: .info) - p2StartBases["mid"]!.adjacencyList.append(bottomRight.getRightConnection()!) - bottomRight.getRightConnection()!.adjacencyList.append(p2StartBases["mid"]!) - ways.append(Way(fromBase: p2StartBases["mid"]!, toBase: bottomRight.getRightConnection()!)) - } - } - - if (p2StartBases["bot"] != nil && bottomRight.getRightConnection() != nil) { - os_log("Connecting p2 startbase bot with bottomRight segment", log: LOG, type: .info) - p2StartBases["bot"]!.adjacencyList.append(bottomRight.getRightConnection()!) - bottomRight.getRightConnection()!.adjacencyList.append(p2StartBases["bot"]!) - ways.append(Way(fromBase: p2StartBases["bot"]!, toBase: bottomRight.getRightConnection()!)) - } - - - // Add all bases to the scene - entityManager.add(basePlayerOne) - p1StartBases.forEach({(key, base) in entityManager.add(base)}) - - topLeft.getAllBases().forEach({base in entityManager.add(base)}) - topRight.getAllBases().forEach({base in entityManager.add(base)}) - bottomLeft.getAllBases().forEach({base in entityManager.add(base)}) - bottomRight.getAllBases().forEach({base in entityManager.add(base)}) - - entityManager.add(basePlayerTwo) - p2StartBases.forEach({(key, base) in entityManager.add(base)}) - - ways.forEach({way in entityManager.add(way)}) - } -} diff --git a/GoldWars/GoldWars/Scenes/GameScene.swift b/GoldWars/GoldWars/Scenes/GameScene.swift index b38524c..7fa2a3b 100644 --- a/GoldWars/GoldWars/Scenes/GameScene.swift +++ b/GoldWars/GoldWars/Scenes/GameScene.swift @@ -24,7 +24,7 @@ class GameScene: SKScene{ entityManager.add(HUD(size: self.size)) entityManager.add(Background(size: self.size)) if CommandLine.arguments.contains("--no-matchmaking") { - _ = MapFactory(scene: self, entityManager: entityManager).loadMap() + _ = MapFactory(scene: self, entityManager: entityManager).load() return } }