diff --git a/GoldWars/GoldWars.xcodeproj/project.pbxproj b/GoldWars/GoldWars.xcodeproj/project.pbxproj index d28b1c8..072a1dd 100644 --- a/GoldWars/GoldWars.xcodeproj/project.pbxproj +++ b/GoldWars/GoldWars.xcodeproj/project.pbxproj @@ -36,6 +36,8 @@ 9EA3ABEB245C6DFA006BC61D /* BaseNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA3ABEA245C6DFA006BC61D /* BaseNode.swift */; }; 9EA3ABED245C8143006BC61D /* ModalBackgroundComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA3ABEC245C8143006BC61D /* ModalBackgroundComponent.swift */; }; 9EA3ABEF245C834B006BC61D /* ModalContentComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA3ABEE245C834B006BC61D /* ModalContentComponent.swift */; }; + 9EC7E48B2461FBF700396BCD /* SliderNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EC7E48A2461FBF700396BCD /* SliderNode.swift */; }; + 9EC7E48D2461FE2C00396BCD /* SliderComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EC7E48C2461FE2C00396BCD /* SliderComponent.swift */; }; 9EC86B9F245C88A300796EF3 /* Modal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EC86B9E245C88A300796EF3 /* Modal.swift */; }; 9EC86BA6245C8AD000796EF3 /* ModalType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EC86BA5245C8AD000796EF3 /* ModalType.swift */; }; AB1D759C245DD18100671525 /* MapProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB1D759A245DD18100671525 /* MapProtocol.swift */; }; @@ -88,6 +90,8 @@ 9EA3ABEA245C6DFA006BC61D /* BaseNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseNode.swift; sourceTree = ""; }; 9EA3ABEC245C8143006BC61D /* ModalBackgroundComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalBackgroundComponent.swift; sourceTree = ""; }; 9EA3ABEE245C834B006BC61D /* ModalContentComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalContentComponent.swift; sourceTree = ""; }; + 9EC7E48A2461FBF700396BCD /* SliderNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SliderNode.swift; sourceTree = ""; }; + 9EC7E48C2461FE2C00396BCD /* SliderComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SliderComponent.swift; sourceTree = ""; }; 9EC86B9E245C88A300796EF3 /* Modal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Modal.swift; sourceTree = ""; }; 9EC86BA5245C8AD000796EF3 /* ModalType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalType.swift; sourceTree = ""; }; 9ECD3699245C91F7008DEEBD /* GoldWars.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = GoldWars.entitlements; sourceTree = ""; }; @@ -179,6 +183,8 @@ 9E174C85245DD91500209FF0 /* ButtonComponent.swift */, 9E174C87245DF1FF00209FF0 /* BackgroundComponent.swift */, 9E04AFAE245E2B73002D5CFC /* AttackActionComponent.swift */, + 9EC7E48A2461FBF700396BCD /* SliderNode.swift */, + 9EC7E48C2461FE2C00396BCD /* SliderComponent.swift */, ); path = Components; sourceTree = ""; @@ -374,8 +380,10 @@ AB1D759C245DD18100671525 /* MapProtocol.swift in Sources */, AB1D75A0245DEC0500671525 /* MapFactory.swift in Sources */, AB1D759D245DD18100671525 /* TwoPlayerDefaultTestMap.swift in Sources */, + 9EC7E48D2461FE2C00396BCD /* SliderComponent.swift in Sources */, ABA03DA0244BD54F00A66916 /* Base.swift in Sources */, 9E174C82245DD81D00209FF0 /* ButtonNode.swift in Sources */, + 9EC7E48B2461FBF700396BCD /* SliderNode.swift in Sources */, 9E174C84245DD8CE00209FF0 /* Button.swift in Sources */, 110360DB244B101A008610AF /* GameViewController.swift in Sources */, 110360D3244B101A008610AF /* AppDelegate.swift in Sources */, diff --git a/GoldWars/GoldWars/Components/ModalContentComponent.swift b/GoldWars/GoldWars/Components/ModalContentComponent.swift index 0b1a09e..df004a3 100644 --- a/GoldWars/GoldWars/Components/ModalContentComponent.swift +++ b/GoldWars/GoldWars/Components/ModalContentComponent.swift @@ -30,7 +30,7 @@ class ModalContentComponent: GKComponent{ self.body.fontSize = 40 self.footer = SKLabelNode(text: footer) - self.footer.position = CGPoint(x: anchorPoint.x, y: anchorPoint.y - 20) + self.footer.position = CGPoint(x: anchorPoint.x, y: anchorPoint.y - 40) self.footer.fontName = "HelveticaNeue-Bold" self.footer.fontSize = 40 super.init() diff --git a/GoldWars/GoldWars/Components/SliderNode.swift b/GoldWars/GoldWars/Components/SliderNode.swift new file mode 100644 index 0000000..93f42d2 --- /dev/null +++ b/GoldWars/GoldWars/Components/SliderNode.swift @@ -0,0 +1,66 @@ +// +// SliderNode.swift +// GoldWars +// +// Created by Niko Jochim on 05.05.20. +// Copyright © 2020 SP2. All rights reserved. +// + +import SpriteKit + + +class SliderNode :SKNode { + + var sliderLine :SKShapeNode + var sliderKnob :SliderKnob + var width: CGFloat + + var getValue: CGFloat{ + get{ + return ((sliderKnob.position.x.rounded() - sliderKnob.min) / width) + } + } + + init(width: CGFloat, position: CGPoint) { + self.width = width + sliderLine = SKShapeNode(rectOf: CGSize(width: width, height: 8)) + sliderLine.position = position + sliderLine.fillColor = SKColor.white + sliderKnob = SliderKnob(circleOfRadius: 20) + sliderKnob.min = position.x - width / 2 + sliderKnob.max = position.x + width / 2 + sliderKnob.fillColor = SKColor.red + sliderKnob.zPosition = sliderLine.zPosition + 1 + sliderKnob.position = CGPoint(x: sliderLine.position.x, y: sliderLine.position.y + 1) + super.init() + + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} + +class SliderKnob: SKShapeNode { + var min = CGFloat() + var max = CGFloat() + + override func touchesMoved(_ touches: Set, with event: UIEvent?) { + + for touch in touches { + let touchLocation = touch.location(in: self.scene!) + + if self.position.x >= min - 1 && self.position.x <= max + 1{ + self.position.x = touchLocation.x + } + + if(self.position.x <= min){ + self.position.x = min + } + if(self.position.x >= max){ + self.position.x = max + } + } + } +} + diff --git a/GoldWars/GoldWars/Entities/Base.swift b/GoldWars/GoldWars/Entities/Base.swift index 8292bbd..57af8e2 100644 --- a/GoldWars/GoldWars/Entities/Base.swift +++ b/GoldWars/GoldWars/Entities/Base.swift @@ -2,7 +2,7 @@ // Base.swift // GoldWars // -// Created by Marcel Schwarz on 18.04.20. +// Created by Aldin Duraki on 18.04.20. // Copyright © 2020 SP2. All rights reserved. // @@ -13,21 +13,27 @@ class Base: GKEntity { var unitCount: Int var adjacencyList: Array + var changeOwnerShip: Bool init(position: CGPoint, team: Team! = nil) { self.unitCount = 0 self.adjacencyList = [Base]() - + self.changeOwnerShip = false super.init() addComponent(DefaultBaseComponent(texture: SKTexture(imageNamed: "Base"), position: position)) if(team != nil){ addComponent(TeamComponent(team: team!, position: position)) - self.unitCount = 100 + self.unitCount = 500 } } - + 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 9d0758b..f10ef87 100644 --- a/GoldWars/GoldWars/Entities/EntityManager.swift +++ b/GoldWars/GoldWars/Entities/EntityManager.swift @@ -57,6 +57,10 @@ class EntityManager { scene.addChild(node) } } + if let sliderNode = entity.component(ofType: SliderComponent.self)?.sliderNode { + scene.addChild(sliderNode.sliderKnob) + scene.addChild(sliderNode.sliderLine) + } } func remove(_ entity: GKEntity) { @@ -72,9 +76,26 @@ class EntityManager { modal.body.removeFromParent() modal.footer.removeFromParent() } + if let sliderNode = entity.component(ofType: SliderComponent.self)?.sliderNode { + sliderNode.sliderKnob.removeFromParent() + sliderNode.sliderLine.removeFromParent() + } 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)!)) + 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), @@ -91,6 +112,19 @@ class EntityManager { return entities.filter{$0 is Base && ($0 as! Base).component(ofType: TeamComponent.self)?.team == team } as! Set } + func getTeamByBase(base: Base) -> Team? { + for entity in entities { + if entity is Base && entity == base{ + for component in entity.components{ + if component is TeamComponent { + return entity.component(ofType: TeamComponent.self)!.team + } + } + } + } + return nil + } + func getBackground() -> GKEntity? { return entities.filter{$0 is Background}[0] } @@ -102,4 +136,6 @@ class EntityManager { func getButtonByName(buttonName:String) -> Button { return entities.filter{$0 is Button && ($0 as! Button).name == buttonName }[0] as! Button } + + } diff --git a/GoldWars/GoldWars/Entities/Modal.swift b/GoldWars/GoldWars/Entities/Modal.swift index 3ef701c..cdafa53 100644 --- a/GoldWars/GoldWars/Entities/Modal.swift +++ b/GoldWars/GoldWars/Entities/Modal.swift @@ -9,10 +9,12 @@ import GameplayKit 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)) @@ -20,8 +22,13 @@ class Modal: GKEntity{ body: "Diese Basis enthält \(base.unitCount) Einheiten", footer: "", anchorPoint: anchorPoint)) - default: - break + 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)) } } diff --git a/GoldWars/GoldWars/Partikels/Fire.sks b/GoldWars/GoldWars/Partikels/Fire.sks index 839f2ca..f25e78f 100644 Binary files a/GoldWars/GoldWars/Partikels/Fire.sks and b/GoldWars/GoldWars/Partikels/Fire.sks differ diff --git a/GoldWars/GoldWars/Scenes/GameScene.swift b/GoldWars/GoldWars/Scenes/GameScene.swift index 92f7819..435ff51 100644 --- a/GoldWars/GoldWars/Scenes/GameScene.swift +++ b/GoldWars/GoldWars/Scenes/GameScene.swift @@ -34,7 +34,30 @@ class GameScene: SKScene{ let touchLocation = touch.location(in: self) - if !isMoveTouch { + if isMoveTouch{ + 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))) + } + + } + } + } + else { for entity in entityManager.entities { let spriteNode = entity.component(ofType: DefaultBaseComponent.self)?.spriteNode @@ -62,14 +85,6 @@ class GameScene: SKScene{ } } } - else { - isMoveTouch = false - currentDraggedBase!.component(ofType: DefaultBaseComponent.self)?.spriteNode.position = currentDraggedBasePos - currentDraggedBase!.component(ofType: TeamComponent.self)?.fire.position = currentDraggedBasePos - } - } - - override func touchesBegan(_ touches: Set, with event: UIEvent?) { } @@ -79,6 +94,17 @@ class GameScene: SKScene{ } let touchLocation = touch.location(in: self) + for child in children { + if atPoint(touchLocation) == child { + child.touchesMoved(touches, with: event) + } + } + + for e in entityManager.entities{ + if let body = e.component(ofType: ModalContentComponent.self)?.body{ + body.text = "Schicke \( ((e.component(ofType: SliderComponent.self)?.sliderNode.getValue ?? 0) * CGFloat((e as! Modal).unitCount)).rounded(.up)) Einheiten " + } } + let bases = entityManager.getBasesByTeam(for: .team1) for base in bases { @@ -86,7 +112,6 @@ class GameScene: SKScene{ if !isMoveTouch { currentDraggedBasePos = base.component(ofType: DefaultBaseComponent.self)!.spriteNode.position currentDraggedBase = base - } isMoveTouch = true @@ -101,11 +126,6 @@ class GameScene: SKScene{ } } } - - - - - } override func update(_ currentTime: TimeInterval) {