diff --git a/GoldWars/GoldWars.xcodeproj/project.pbxproj b/GoldWars/GoldWars.xcodeproj/project.pbxproj index ebaec53..ba4f9b5 100644 --- a/GoldWars/GoldWars.xcodeproj/project.pbxproj +++ b/GoldWars/GoldWars.xcodeproj/project.pbxproj @@ -46,6 +46,12 @@ AB1D75A0245DEC0500671525 /* MapFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB1D759F245DEC0500671525 /* MapFactory.swift */; }; ABA03DA0244BD54F00A66916 /* Base.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABA03D9F244BD54F00A66916 /* Base.swift */; }; AE151589245F18EF001D363E /* MatchmakingHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE151588245F18EF001D363E /* MatchmakingHelper.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 */; }; + C05FAED62468559D0006AF2E /* SoundManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C05FAED52468559D0006AF2E /* SoundManager.swift */; }; + C064E9A8246C0EA50022B228 /* LabelNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = C064E9A7246C0EA50022B228 /* LabelNode.swift */; }; + C064E9AA246C114C0022B228 /* LabelComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C064E9A9246C114C0022B228 /* LabelComponent.swift */; }; + C064E9AC246C151F0022B228 /* Label.swift in Sources */ = {isa = PBXBuildFile; fileRef = C064E9AB246C151F0022B228 /* Label.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -103,6 +109,12 @@ AB1D759F245DEC0500671525 /* MapFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapFactory.swift; sourceTree = ""; }; ABA03D9F244BD54F00A66916 /* Base.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Base.swift; sourceTree = ""; }; AE151588245F18EF001D363E /* MatchmakingHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatchmakingHelper.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 = ""; }; + C05FAED52468559D0006AF2E /* SoundManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SoundManager.swift; sourceTree = ""; }; + C064E9A7246C0EA50022B228 /* LabelNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelNode.swift; sourceTree = ""; }; + C064E9A9246C114C0022B228 /* LabelComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelComponent.swift; sourceTree = ""; }; + C064E9AB246C151F0022B228 /* Label.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Label.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -146,6 +158,7 @@ 110360D1244B101A008610AF /* GoldWars */ = { isa = PBXGroup; children = ( + C04783ED2468583F004961FB /* intro-music.mp3 */, 9ECD3699245C91F7008DEEBD /* GoldWars.entitlements */, 9E11FF74245CD79100EED3BE /* Partikels */, 116060F5245C5709004E5A36 /* Entities */, @@ -155,11 +168,16 @@ 9EC86BA4245C8A1E00796EF3 /* Scenes */, 9EC86BA3245C89F400796EF3 /* Storyboards */, 110360D2244B101A008610AF /* AppDelegate.swift */, + C05FAED52468559D0006AF2E /* SoundManager.swift */, 110360DA244B101A008610AF /* GameViewController.swift */, 110360DF244B101B008610AF /* Assets.xcassets */, 110360E4244B101B008610AF /* Info.plist */, AE151588245F18EF001D363E /* MatchmakingHelper.swift */, 3EBD242B245D8044003CECE7 /* GameCenterHelper.swift */, + C04783EF24685995004961FB /* SettingsScene.swift */, + C064E9A7246C0EA50022B228 /* LabelNode.swift */, + C064E9A9246C114C0022B228 /* LabelComponent.swift */, + C064E9AB246C151F0022B228 /* Label.swift */, ); path = GoldWars; sourceTree = ""; @@ -347,6 +365,7 @@ 9E11FF79245CD81100EED3BE /* Fire.sks in Resources */, 110360E0244B101B008610AF /* Assets.xcassets in Resources */, 110360E3244B101B008610AF /* LaunchScreen.storyboard in Resources */, + C04783EE2468583F004961FB /* intro-music.mp3 in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -372,7 +391,9 @@ 9EA3ABEB245C6DFA006BC61D /* BaseNode.swift in Sources */, 9E04AFAF245E2B73002D5CFC /* AttackActionComponent.swift in Sources */, 110360D9244B101A008610AF /* GameScene.swift in Sources */, + C04783F024685995004961FB /* SettingsScene.swift in Sources */, 116060F7245C57D2004E5A36 /* EntityManager.swift in Sources */, + C064E9AA246C114C0022B228 /* LabelComponent.swift in Sources */, 3EBD242E245D9332003CECE7 /* Team.swift in Sources */, 9E174C88245DF1FF00209FF0 /* BackgroundComponent.swift in Sources */, 9E78ACBA245CBDAF00526FF7 /* HUD.swift in Sources */, @@ -383,12 +404,14 @@ 9EA3ABE9245C6DAA006BC61D /* DefaultBaseComponent.swift in Sources */, 9E174C8A245E1A0A00209FF0 /* Background.swift in Sources */, 9EA3ABED245C8143006BC61D /* ModalBackgroundComponent.swift in Sources */, + C064E9A8246C0EA50022B228 /* LabelNode.swift in Sources */, 3EBD242C245D8044003CECE7 /* GameCenterHelper.swift in Sources */, AB1D759C245DD18100671525 /* MapProtocol.swift in Sources */, AB1D75A0245DEC0500671525 /* MapFactory.swift in Sources */, AB1D759D245DD18100671525 /* TwoPlayerDefaultTestMap.swift in Sources */, 9EBFD7552462CF5A00E1E219 /* SliderComponent.swift in Sources */, ABA03DA0244BD54F00A66916 /* Base.swift in Sources */, + C064E9AC246C151F0022B228 /* Label.swift in Sources */, 9E174C82245DD81D00209FF0 /* ButtonNode.swift in Sources */, 9EC7E48B2461FBF700396BCD /* SliderNode.swift in Sources */, 9E174C84245DD8CE00209FF0 /* Button.swift in Sources */, @@ -397,6 +420,7 @@ 110360D3244B101A008610AF /* AppDelegate.swift in Sources */, 9EC86B9F245C88A300796EF3 /* Modal.swift in Sources */, 9E78ACC2245CC9EE00526FF7 /* DefBoostSkillComponent.swift in Sources */, + C05FAED62468559D0006AF2E /* SoundManager.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/GoldWars/GoldWars/Components/BackgroundComponent.swift b/GoldWars/GoldWars/Components/BackgroundComponent.swift index 7239741..f74d5dd 100644 --- a/GoldWars/GoldWars/Components/BackgroundComponent.swift +++ b/GoldWars/GoldWars/Components/BackgroundComponent.swift @@ -12,6 +12,7 @@ class BackgroundComponent: GKComponent{ var nodes = [SKSpriteNode]() let size: CGSize + static var isMovingBackgroundEnabled = true init(size: CGSize) { self.size = size @@ -27,10 +28,12 @@ class BackgroundComponent: GKComponent{ } func update(){ - for node in nodes{ - node.position.x -= 2 - if node.position.x < -(size.width) { - node.position.x += (size.width) * 3 + if BackgroundComponent.isMovingBackgroundEnabled { + for node in nodes{ + node.position.x -= 2 + if node.position.x < -(size.width) { + node.position.x += (size.width) * 3 + } } } } diff --git a/GoldWars/GoldWars/Components/TeamComponent.swift b/GoldWars/GoldWars/Components/TeamComponent.swift index a6b27fa..c5efa70 100644 --- a/GoldWars/GoldWars/Components/TeamComponent.swift +++ b/GoldWars/GoldWars/Components/TeamComponent.swift @@ -12,17 +12,16 @@ import GameKit class TeamComponent: GKComponent { let team: Team - let fire: SKEmitterNode - let player: GKPlayer - - init(team: Team, position: CGPoint, player: GKPlayer) { - fire = SKEmitterNode(fileNamed: "Fire")! - fire.zPosition = -1 - fire.position = position - fire.name = "fire" - fire.particleColorSequence = nil - fire.particleColorBlendFactor = 1.0 - + let fire: SKEmitterNode + + init(team: Team, position: CGPoint) { + fire = SKEmitterNode(fileNamed: "Fire")! + fire.zPosition = -1 + fire.position = position + fire.name = "fire" + fire.particleColorSequence = nil + fire.particleColorBlendFactor = 1.0 + switch team { case .team1: fire.particleColor = SKColor.red case .team2: fire.particleColor = SKColor.purple diff --git a/GoldWars/GoldWars/Entities/Base.swift b/GoldWars/GoldWars/Entities/Base.swift index cf63a46..1e43e87 100644 --- a/GoldWars/GoldWars/Entities/Base.swift +++ b/GoldWars/GoldWars/Entities/Base.swift @@ -8,20 +8,17 @@ import SpriteKit import GameplayKit -import GameKit class Base: GKEntity { var unitCount: Int var adjacencyList: Array - var changeOwnership: Bool - var ownershipPlayer: GKPlayer? + var changeOwnerShip: Bool - init(position: CGPoint, player: GKPlayer! = nil, team: Team! = nil) { + init(position: CGPoint, team: Team! = nil) { self.unitCount = 0 self.adjacencyList = [Base]() - self.changeOwnership = false - self.ownershipPlayer = player + self.changeOwnerShip = false super.init() addComponent(DefaultBaseComponent(texture: SKTexture(imageNamed: "Base"), position: position)) @@ -31,13 +28,12 @@ class Base: GKEntity { } } - func attackBase(base: Base, units:Int) -> [GKEntity]{ - base.changeOwnership = true - base.ownershipPlayer = self.ownershipPlayer - self.unitCount -= units - base.unitCount += units - return [self, base] - } + func attackBase(base: Base, units:Int) -> [GKEntity]{ + base.changeOwnerShip = true + self.unitCount -= units + base.unitCount += units + return [self, base] + } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") diff --git a/GoldWars/GoldWars/Entities/EntityManager.swift b/GoldWars/GoldWars/Entities/EntityManager.swift index 3499c82..5d798b2 100644 --- a/GoldWars/GoldWars/Entities/EntityManager.swift +++ b/GoldWars/GoldWars/Entities/EntityManager.swift @@ -31,7 +31,6 @@ class EntityManager { } if let spriteNode = entity.component(ofType: ModalBackgroundComponent.self)?.spriteNode { scene.addChild(spriteNode) - isModal = true } if let modal = entity.component(ofType: ModalContentComponent.self) { scene.addChild(modal.header) @@ -55,6 +54,7 @@ class EntityManager { } if let buttonNode = entity.component(ofType: ButtonComponent.self)?.buttonNode { scene.addChild(buttonNode) + isModal = true } if let nodes = entity.component(ofType: BackgroundComponent.self)?.nodes { for node in nodes { @@ -65,6 +65,9 @@ class EntityManager { scene.addChild(sliderNode.sliderKnob) scene.addChild(sliderNode.sliderLine) } + if let labelNode = entity.component(ofType: LabelComponent.self)?.labelNode { + scene.addChild(labelNode) + } } func remove(_ entity: GKEntity) { @@ -73,7 +76,6 @@ class EntityManager { } if let spriteNode = entity.component(ofType: ModalBackgroundComponent.self)?.spriteNode { spriteNode.removeFromParent() - isModal = false } if let modal = entity.component(ofType: ModalContentComponent.self) { modal.header.removeFromParent() @@ -84,35 +86,30 @@ class EntityManager { sliderNode.sliderKnob.removeFromParent() sliderNode.sliderLine.removeFromParent() } + if let modalButton = entity.component(ofType: ButtonComponent.self) { + modalButton.buttonNode.removeFromParent() + isModal = false + } entities.remove(entity) } - - func update(_ entities: [GKEntity]){ - for entity in entities { - self.entities.update(with: entity) - let base = (entity as! Base) - - if base.changeOwnership { - base.addComponent( - TeamComponent( - team: (entities[0] as! Base).component(ofType: TeamComponent.self)!.team, - position: (base.component(ofType: DefaultBaseComponent.self)?.spriteNode.position)!, - player: (entities[0] as! Base).component(ofType: TeamComponent.self)!.player)) - base.changeOwnership = false - scene.addChild(base.component(ofType: TeamComponent.self)!.fire) - } - } - - } - - func getBaseByPlayer(for player: GKPlayer) -> Set { - return entities.filter{$0 is Base && ($0 as! Base).component(ofType: TeamComponent.self)?.player == player } as! Set - } - - func getBaseByTeam(for team: Team) -> GKEntity? { - for entity in entities { - if let teamComponent = entity.component(ofType: TeamComponent.self), - let _ = entity.component(ofType: DefaultBaseComponent.self) { + + func update(_ entities: [GKEntity]){ + for entity in entities { + self.entities.update(with: entity) + let base = (entity as! Base) + + if base.changeOwnerShip { + base.addComponent(TeamComponent(team: (entities[0] as! Base).component(ofType: TeamComponent.self)!.team, position: (base.component(ofType: DefaultBaseComponent.self)?.spriteNode.position)!)) + base.changeOwnerShip = false + scene.addChild(base.component(ofType: TeamComponent.self)!.fire) + } + } + + } + func getBaseByTeam(for team: Team) -> GKEntity? { + for entity in entities { + if let teamComponent = entity.component(ofType: TeamComponent.self), + let _ = entity.component(ofType: DefaultBaseComponent.self) { if teamComponent.team == team { return entity } diff --git a/GoldWars/GoldWars/Entities/Modal.swift b/GoldWars/GoldWars/Entities/Modal.swift index cdafa53..954f795 100644 --- a/GoldWars/GoldWars/Entities/Modal.swift +++ b/GoldWars/GoldWars/Entities/Modal.swift @@ -12,28 +12,43 @@ class Modal: GKEntity{ var unitCount:Int - init(modaltype: ModalType, base: Base, anchorPoint: CGPoint) { - unitCount = base.unitCount - super.init() - switch modaltype{ - case .BaseDetails: - addComponent(ModalBackgroundComponent(anchorPoint: anchorPoint)) - addComponent(ModalContentComponent(header: "Basis Information", - body: "Diese Basis enthält \(base.unitCount) Einheiten", - footer: "", - anchorPoint: anchorPoint)) - case .BaseAttack: - addComponent(ModalBackgroundComponent(anchorPoint: anchorPoint)) - addComponent(SliderComponent(width: 300, position: CGPoint(x: anchorPoint.x , y: anchorPoint.y - 80))) - addComponent(ModalContentComponent(header: "Angriff", - body: "Schicke \(unitCount / 2) Einheiten", - footer: "", - anchorPoint: anchorPoint)) - } - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - + var unitCount:Int + + init(modaltype: ModalType, base: Base, anchorPoint: CGPoint, entityManager: EntityManager, gameScene: SKScene) { + unitCount = base.unitCount + super.init() + switch modaltype{ + case .BaseDetails: + addComponent(ModalBackgroundComponent(anchorPoint: anchorPoint)) + addComponent(ModalContentComponent(header: "Basis Information", body: "Diese Basis enthält \(base.unitCount) Einheiten", footer: "", anchorPoint: anchorPoint)) + addComponent(ButtonComponent(iconName: "", text: "Zurück", position: CGPoint(x: anchorPoint.x , y: anchorPoint.y - 120), isEnabled: true, onButtonPress: { + self.removeModalEntities(entityManager: entityManager, gameScene: gameScene) + })) + case .BaseAttack: + addComponent(ModalBackgroundComponent(anchorPoint: anchorPoint)) + addComponent(SliderComponent(width: 300, position: CGPoint(x: anchorPoint.x , y: anchorPoint.y - 50))) + addComponent(ModalContentComponent(header: "Angriff", body: "Schicke \(unitCount / 2) Einheiten", + footer: "", anchorPoint: anchorPoint)) + addComponent(ButtonComponent(iconName: "", text: "Senden", position: CGPoint(x: anchorPoint.x , y: anchorPoint.y - 120), isEnabled: true, onButtonPress: { + self.removeModalEntities(entityManager: entityManager, gameScene: gameScene) + })) + } + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + func removeModalEntities(entityManager: EntityManager, gameScene: SKScene){ + for entity in entityManager.entities { + if entityManager.isModal && entity.isMember(of: Modal.self) { + entityManager.remove(entity) + } + for child in gameScene.children { + if(child.name != "fire"){ + child.alpha = 1 + } + } + } + } } diff --git a/GoldWars/GoldWars/Label.swift b/GoldWars/GoldWars/Label.swift new file mode 100644 index 0000000..2cac987 --- /dev/null +++ b/GoldWars/GoldWars/Label.swift @@ -0,0 +1,21 @@ +// +// Label.swift +// GoldWars +// +// Created by Tim Herbst on 13.05.20. +// Copyright © 2020 SP2. All rights reserved. +// + +import GameplayKit + +class Label: GKEntity { + + init(fontnamed: String, name: String, text: String, fontSize: CGFloat, fontColor: UIColor, position: CGPoint, horizontalAlignmentMode: SKLabelHorizontalAlignmentMode, vertikalAligmentMode: SKLabelVerticalAlignmentMode, isAnimationEnabled: Bool, isAnimationInfinite: Bool) { + super.init() + self.addComponent(LabelComponent(fontnamed: fontnamed, name: name, text: text, fontSize: fontSize, fontColor: fontColor, position: position, horizontalAlignmentMode: horizontalAlignmentMode, vertikalAligmentMode: vertikalAligmentMode, isAnimationEnabled: isAnimationEnabled, isAnimationInfinite: isAnimationInfinite)) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} diff --git a/GoldWars/GoldWars/LabelComponent.swift b/GoldWars/GoldWars/LabelComponent.swift new file mode 100644 index 0000000..aa57816 --- /dev/null +++ b/GoldWars/GoldWars/LabelComponent.swift @@ -0,0 +1,32 @@ +// +// LabelComponent.swift +// GoldWars +// +// Created by Tim Herbst on 13.05.20. +// Copyright © 2020 SP2. All rights reserved. +// + +import GameplayKit + +class LabelComponent: GKComponent { + var labelNode: LabelNode + + init(fontnamed: String?, name: String, text: String, fontSize: CGFloat, fontColor: UIColor, position: CGPoint, horizontalAlignmentMode: SKLabelHorizontalAlignmentMode, vertikalAligmentMode: SKLabelVerticalAlignmentMode, isAnimationEnabled: Bool, isAnimationInfinite: Bool) { + labelNode = LabelNode(fontNamed: fontnamed) + labelNode.name = name + labelNode.text = text + labelNode.fontSize = fontSize + labelNode.fontColor = fontColor + labelNode.horizontalAlignmentMode = horizontalAlignmentMode + labelNode.verticalAlignmentMode = vertikalAligmentMode + labelNode.position = position + if isAnimationEnabled { + labelNode.sequentiallyBouncingZoom(delay: 0.3, infinite: isAnimationInfinite) + } + super.init() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} diff --git a/GoldWars/GoldWars/LabelNode.swift b/GoldWars/GoldWars/LabelNode.swift new file mode 100644 index 0000000..669a0b5 --- /dev/null +++ b/GoldWars/GoldWars/LabelNode.swift @@ -0,0 +1,152 @@ +// +// LabelNode.swift +// GoldWars +// +// Created by Tim Herbst on 13.05.20. +// Copyright © 2020 SP2. All rights reserved. +// + +import SpriteKit + +class LabelNode: SKNode { + let colt = SKLabelNode() + var labels = [SKLabelNode]() + var text = "" { + didSet { + refreshLabels() + } + } + var fontName = "HelveticaNeue-UltraLight" { + didSet { + _ = labels.compactMap({ $0.fontName = fontName }) + refreshLabels() + } + } + var fontSize = CGFloat(30.0) { + didSet { + _ = labels.compactMap({ $0.fontSize = fontSize }) + refreshLabels() + } + } + var fontColor = UIColor.init(white: 1.0, alpha: 1.0) { + didSet { + _ = labels.compactMap({ $0.fontColor = fontColor }) + refreshLabels() + } + } + var horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.init(rawValue: 0) { // left + didSet { + _ = labels.compactMap({ $0.horizontalAlignmentMode = horizontalAlignmentMode! }) + refreshLabels() + } + } + var verticalAlignmentMode = SKLabelVerticalAlignmentMode.init(rawValue: 0) { // center + didSet { + _ = labels.compactMap({ $0.verticalAlignmentMode = verticalAlignmentMode! }) + refreshLabels() + } + } + var lineSpacingFactor: CGFloat = -1.3 { + didSet { + refreshLabels() + } + } + override init() { + super.init() + } + convenience init(text: String) { + self.init() + self.text = text + } + convenience init(fontNamed fontName: String?) { + self.init(text: "") + if let f = fontName { + self.fontName = f + } + } + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + func refreshLabels() { + _ = labels.compactMap({ $0.removeFromParent() }) + labels.removeAll() + if text.count > 0 { + var newX: CGFloat = 0.0 + var gapX: CGFloat = 0.0 + let ghostSpace = SKLabelNode(text: ".") + ghostSpace.fontName = fontName + ghostSpace.fontSize = fontSize + let ghostSpaceWidth = ghostSpace.frame.size.width + var fullNodeWidth:CGFloat = 0.0 + for char in text { + if String(char) != " " { + let charLabelNode = SKLabelNode(text: String(char)) + charLabelNode.fontName = fontName + charLabelNode.fontSize = fontSize + fullNodeWidth += charLabelNode.frame.size.width + lineSpacingFactor + } else { + fullNodeWidth += ghostSpaceWidth + lineSpacingFactor + } + } + switch horizontalAlignmentMode { + case .left? : gapX = 0.0 + case .center? : gapX = fullNodeWidth/2 + case .right? : gapX = fullNodeWidth + default: break + } + var index: Int = 0 + for char in text { + if String(char) != " " { + let charLabelNode = SKLabelNode(text: String(char)) + charLabelNode.fontName = fontName + charLabelNode.fontSize = fontSize + charLabelNode.fontColor = fontColor + charLabelNode.horizontalAlignmentMode = .left + charLabelNode.verticalAlignmentMode = verticalAlignmentMode! + charLabelNode.position.x = newX - gapX + charLabelNode.alpha = 1 + self.addChild(charLabelNode) + labels.append(charLabelNode) + newX += charLabelNode.frame.size.width + lineSpacingFactor + } else { + ghostSpace.horizontalAlignmentMode = .left + ghostSpace.verticalAlignmentMode = verticalAlignmentMode! + ghostSpace.position.x = newX - gapX + labels.append(ghostSpace) + newX += ghostSpaceWidth + lineSpacingFactor + } + index += 1 + } + } + } + + func sequentiallyBouncingZoom(delay:TimeInterval, infinite:Bool = false) { + if labels.count > 0 && self.action(forKey: "sequentiallyBouncingZoom") == nil { + let main = SKAction.run { [weak self] in + guard let strongSelf = self else { return } + for i in 0.. SKAction { + return SKAction.sequence([SKAction.wait(forDuration: delay), action]) + } + class func afterDelay(_ delay: TimeInterval, runBlock block: @escaping () -> Void) -> SKAction { + return SKAction.afterDelay(delay, performAction: SKAction.run(block)) + } +} diff --git a/GoldWars/GoldWars/Map/TwoPlayerDefaultTestMap.swift b/GoldWars/GoldWars/Map/TwoPlayerDefaultTestMap.swift index c8b3c50..412be97 100644 --- a/GoldWars/GoldWars/Map/TwoPlayerDefaultTestMap.swift +++ b/GoldWars/GoldWars/Map/TwoPlayerDefaultTestMap.swift @@ -8,7 +8,6 @@ import Foundation import SpriteKit -import GameKit class TwoPlayerDefaultTestMap: MapProtocol { @@ -26,7 +25,6 @@ class TwoPlayerDefaultTestMap: MapProtocol { // Create Bases let basePlayerOne = Base( position: CGPoint(x: self.size.width * 0.1, y: self.size.height / 2), - player: (MatchmakingHelper.sharedInstance.isServer) ? GKLocalPlayer.local : MatchmakingHelper.sharedInstance.mpMatch?.players[0], team: .team1 ) diff --git a/GoldWars/GoldWars/Scenes/GameScene.swift b/GoldWars/GoldWars/Scenes/GameScene.swift index c18a938..8df4c6d 100644 --- a/GoldWars/GoldWars/Scenes/GameScene.swift +++ b/GoldWars/GoldWars/Scenes/GameScene.swift @@ -39,38 +39,29 @@ class GameScene: SKScene{ isMoveTouch = false currentDraggedBase!.component(ofType: DefaultBaseComponent.self)?.spriteNode.position = currentDraggedBasePos currentDraggedBase!.component(ofType: TeamComponent.self)?.fire.position = currentDraggedBasePos - - for base in currentDraggedBase!.adjacencyList { - if atPoint(touchLocation) == base.component(ofType: DefaultBaseComponent.self)?.spriteNode { - // TODO: change interaction based on collision instead of touchlocation - - if !(entityManager.getTeamByBase(base: currentDraggedBase!) == entityManager.getTeamByBase(base: base)){ - entityManager.add(Modal(modaltype: .BaseAttack, - base: currentDraggedBase!, - anchorPoint: CGPoint(x: self.size.width / 2 , y: self.size.height / 2))) - entityManager.update((currentDraggedBase?.attackBase(base: base, units: 100))!) - }else { - entityManager.add(Modal(modaltype: .BaseAttack, - base: currentDraggedBase!, - anchorPoint: CGPoint(x: self.size.width / 2 , y: self.size.height / 2))) - } - - } - } - } + + for base in currentDraggedBase!.adjacencyList { + if atPoint(touchLocation) == base.component(ofType: DefaultBaseComponent.self)?.spriteNode { + // TODO: change interaction based on collision instead of touchlocation + + if !(entityManager.getTeamByBase(base: currentDraggedBase!) == entityManager.getTeamByBase(base: base)){ + entityManager.add(Modal(modaltype: .BaseAttack, + base: currentDraggedBase!, + anchorPoint: CGPoint(x: self.size.width / 2 , y: self.size.height / 2), entityManager: entityManager, gameScene: self)) + entityManager.update((currentDraggedBase?.attackBase(base: base, units: 100))!) + }else { + entityManager.add(Modal(modaltype: .BaseAttack, + base: currentDraggedBase!, + anchorPoint: CGPoint(x: self.size.width / 2 , y: self.size.height / 2), entityManager: entityManager, gameScene: self)) + } + + } + } + } else { for entity in entityManager.entities { let spriteNode = entity.component(ofType: DefaultBaseComponent.self)?.spriteNode - - if entityManager.isModal && entity.isMember(of: Modal.self) { - entityManager.remove(entity) - for child in self.children { - if(child.name != "fire"){ - child.alpha = 1 - } - } - } - + if atPoint(touchLocation) == spriteNode && !entityManager.isModal { spriteNode?.touchesBegan(touches, with: event) if !entityManager.isModal { @@ -81,7 +72,7 @@ class GameScene: SKScene{ } entityManager.add(Modal(modaltype: .BaseDetails, base: entity as! Base, - anchorPoint: CGPoint(x: self.size.width / 2 , y: self.size.height / 2))) + anchorPoint: CGPoint(x: self.size.width / 2 , y: self.size.height / 2), entityManager: entityManager, gameScene: self)) } } } diff --git a/GoldWars/GoldWars/Scenes/MenuScene.swift b/GoldWars/GoldWars/Scenes/MenuScene.swift index edf6bb9..bca03d2 100644 --- a/GoldWars/GoldWars/Scenes/MenuScene.swift +++ b/GoldWars/GoldWars/Scenes/MenuScene.swift @@ -23,6 +23,7 @@ class MenuScene: SKScene { onButtonPress: { if CommandLine.arguments.contains("--no-matchmaking") { self.loadScene(scene: GameScene(size: self.size)) + SoundManager.sharedInstance.stopMenuMusic() } else { MatchmakingHelper.sharedInstance.presentMatchmaker(scene: self) } @@ -32,9 +33,13 @@ class MenuScene: SKScene { text: "Settings", position: CGPoint(x: midX, y: midY - 80 ), onButtonPress: { - //TODO: create Settings Scene - })) + self.loadScene(scene: SettingsScene(size: self.size)) + })) entityManager.add(Background(size: self.size)) + + if SoundManager.sharedInstance.isMusicPlaying == false && SoundManager.sharedInstance.isMusicEnabled == true { + SoundManager.sharedInstance.startMenuMusic() + } } func loadScene(scene: SKScene) { diff --git a/GoldWars/GoldWars/SettingsScene.swift b/GoldWars/GoldWars/SettingsScene.swift new file mode 100644 index 0000000..8eb22f5 --- /dev/null +++ b/GoldWars/GoldWars/SettingsScene.swift @@ -0,0 +1,94 @@ +// +// SettingsScene.swift +// GoldWars +// +// Created by Tim Herbst on 10.05.20. +// Copyright © 2020 SP2. All rights reserved. +// + +import SpriteKit + +class SettingsScene: SKScene { + var entityManager: EntityManager! + + override func sceneDidLoad() { + entityManager = EntityManager(scene: self) + let positionX = self.size.width * 0.1 + let positionY = self.size.height * 0.05 + + entityManager.add(Button(name: "backToMenuScene", + iconName: "", + text: "Back", + position: CGPoint(x: positionX, y: positionY), + onButtonPress: { + self.loadScene(scene: MenuScene(size: self.size)) + })) + entityManager.add(Button(name: "StopMenuMusic", + iconName: "", + text: "ON/OFF", + position: CGPoint(x: self.size.width * 0.6, y: self.size.height / 2), + onButtonPress: { + if SoundManager.sharedInstance.isMusicPlaying { + SoundManager.sharedInstance.stopMenuMusic() + SoundManager.sharedInstance.isMusicEnabled = false + } else { + SoundManager.sharedInstance.isMusicEnabled = true + SoundManager.sharedInstance.startMenuMusic() + } + })) + entityManager.add(Button(name: "StopMovingBackground", + iconName: "", + text: "MOVE/STOP", + position: CGPoint(x: self.size.width * 0.6, y: self.size.height / 2 - 100), + onButtonPress: { + if BackgroundComponent.isMovingBackgroundEnabled { + BackgroundComponent.isMovingBackgroundEnabled = false + } else { + BackgroundComponent.isMovingBackgroundEnabled = true + } + })) + entityManager.add(Label(fontnamed: "Courier-Bold", + name: "SettingsLabel", + text: "Settings", + fontSize: 200.0, + fontColor: .black, + position: CGPoint(x: self.size.width * 0.5, y: self.size.height * 0.7), + horizontalAlignmentMode: .center, + vertikalAligmentMode: .baseline, + isAnimationEnabled: true, + isAnimationInfinite: true) + ) + entityManager.add(Label(fontnamed: "Courier-Bold", + name: "LabelMusic", + text: "Music", fontSize: 50.0, + fontColor: .black, + position: CGPoint(x: self.size.width * 0.5, y: self.size.height / 2 - 15), + horizontalAlignmentMode: .right, + vertikalAligmentMode: .baseline, + isAnimationEnabled: true, + isAnimationInfinite: false) + ) + entityManager.add(Label(fontnamed: "Courier-Bold", + name: "LabelBackground", + text: "Background", + fontSize: 50.0, + fontColor: .black, + position: CGPoint(x: self.size.width * 0.5, y: self.size.height / 2 - 115), + horizontalAlignmentMode: .right, + vertikalAligmentMode: .baseline, + isAnimationEnabled: true, + isAnimationInfinite: false) + ) + entityManager.add(Background(size: self.size)) + } + + func loadScene(scene: SKScene) { + let transition = SKTransition.flipVertical(withDuration: 0.5) + self.view?.presentScene(scene, transition: transition) + } + + override func update(_ currentTime: TimeInterval) { + entityManager.getBackground()!.update(deltaTime: currentTime) + } + +} diff --git a/GoldWars/GoldWars/SoundManager.swift b/GoldWars/GoldWars/SoundManager.swift new file mode 100644 index 0000000..4f8f34d --- /dev/null +++ b/GoldWars/GoldWars/SoundManager.swift @@ -0,0 +1,47 @@ +// +// SoundManager.swift +// GoldWars +// +// Created by Tim Herbst on 10.05.20. +// Copyright © 2020 SP2. All rights reserved. +// + +import SpriteKit +import AVFoundation + +class SoundManager { + public static var sharedInstance = SoundManager() + + var audioPlayer = AVAudioPlayer() + var backgroundMainMenuAudio: URL? + var isMusicPlaying = false + var isMusicEnabled = true + + func startMenuMusic() { + self.isMusicPlaying = true + backgroundMainMenuAudio = Bundle.main.url(forResource: "intro-music", withExtension: "mp3") + do { + audioPlayer = try AVAudioPlayer(contentsOf: backgroundMainMenuAudio!) + } catch { + print("Datei nicht gefunden!") + } + audioPlayer.numberOfLoops = -1 + audioPlayer.prepareToPlay() + if self.isMusicEnabled == true { + audioPlayer.play() + } + } + + func stopMenuMusic() { + audioPlayer.pause() + self.isMusicPlaying = false + } + + func setVolume(_ volume: Float) { + audioPlayer.volume = volume + } + + func getVolume() -> Float { + return audioPlayer.volume + } +} diff --git a/GoldWars/GoldWars/intro-music.mp3 b/GoldWars/GoldWars/intro-music.mp3 new file mode 100644 index 0000000..6aaa001 Binary files /dev/null and b/GoldWars/GoldWars/intro-music.mp3 differ