diff --git a/GoldWars/.idea/.gitignore b/GoldWars/.idea/.gitignore
new file mode 100644
index 0000000..73f69e0
--- /dev/null
+++ b/GoldWars/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
+# Editor-based HTTP Client requests
+/httpRequests/
diff --git a/GoldWars/.idea/GoldWars.iml b/GoldWars/.idea/GoldWars.iml
new file mode 100644
index 0000000..74121dc
--- /dev/null
+++ b/GoldWars/.idea/GoldWars.iml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/GoldWars/.idea/misc.xml b/GoldWars/.idea/misc.xml
new file mode 100644
index 0000000..28a804d
--- /dev/null
+++ b/GoldWars/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/GoldWars/.idea/modules.xml b/GoldWars/.idea/modules.xml
new file mode 100644
index 0000000..3bd1ffb
--- /dev/null
+++ b/GoldWars/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/GoldWars/.idea/runConfigurations/GoldWars.xml b/GoldWars/.idea/runConfigurations/GoldWars.xml
new file mode 100644
index 0000000..447b8da
--- /dev/null
+++ b/GoldWars/.idea/runConfigurations/GoldWars.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/GoldWars/.idea/vcs.xml b/GoldWars/.idea/vcs.xml
new file mode 100644
index 0000000..6c0b863
--- /dev/null
+++ b/GoldWars/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/GoldWars/.idea/xcode.xml b/GoldWars/.idea/xcode.xml
new file mode 100644
index 0000000..62ab3fc
--- /dev/null
+++ b/GoldWars/.idea/xcode.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/GoldWars/GoldWars.xcodeproj/project.pbxproj b/GoldWars/GoldWars.xcodeproj/project.pbxproj
index 2255b11..1017e12 100644
--- a/GoldWars/GoldWars.xcodeproj/project.pbxproj
+++ b/GoldWars/GoldWars.xcodeproj/project.pbxproj
@@ -21,6 +21,8 @@
3EBD242C245D8044003CECE7 /* GameCenterHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EBD242B245D8044003CECE7 /* GameCenterHelper.swift */; };
3EBD242E245D9332003CECE7 /* Team.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EBD242D245D9332003CECE7 /* Team.swift */; };
8BB6FF402472B8F000162BBD /* SkillButtonNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8BB6FF3F2472B8F000162BBD /* SkillButtonNode.swift */; };
+ 3F745DF0246F48FC00CE7375 /* PlayerMoveType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F745DEF246F48FC00CE7375 /* PlayerMoveType.swift */; };
+ 3FE19DB5246C7A22004827AB /* RoundCalculatorService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FE19DB4246C7A22004827AB /* RoundCalculatorService.swift */; };
9E04AFAF245E2B73002D5CFC /* AttackActionComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E04AFAE245E2B73002D5CFC /* AttackActionComponent.swift */; };
9E11FF79245CD81100EED3BE /* Fire.sks in Resources */ = {isa = PBXBuildFile; fileRef = 9E11FF77245CD81100EED3BE /* Fire.sks */; };
9E174C82245DD81D00209FF0 /* ButtonNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E174C81245DD81D00209FF0 /* ButtonNode.swift */; };
@@ -39,6 +41,7 @@
9EA3ABED245C8143006BC61D /* ModalBackgroundComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA3ABEC245C8143006BC61D /* ModalBackgroundComponent.swift */; };
9EA3ABEF245C834B006BC61D /* ModalContentComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA3ABEE245C834B006BC61D /* ModalContentComponent.swift */; };
9EBFD7552462CF5A00E1E219 /* SliderComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EBFD7542462CF5A00E1E219 /* SliderComponent.swift */; };
+ 9EC239E1246878A900952F74 /* MultiplayerNetwork.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EC239E0246878A900952F74 /* MultiplayerNetwork.swift */; };
9EC7E48B2461FBF700396BCD /* SliderNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EC7E48A2461FBF700396BCD /* SliderNode.swift */; };
9EC86B9F245C88A300796EF3 /* Modal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EC86B9E245C88A300796EF3 /* Modal.swift */; };
9EC86BA6245C8AD000796EF3 /* ModalType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EC86BA5245C8AD000796EF3 /* ModalType.swift */; };
@@ -49,12 +52,15 @@
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 */; };
+ AEBF3AFF246EB146004F7CD5 /* CancelBtnNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEBF3AFE246EB146004F7CD5 /* CancelBtnNode.swift */; };
+ AEBF3B01246EB187004F7CD5 /* CancelBtnComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEBF3B00246EB187004F7CD5 /* CancelBtnComponent.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 */; };
+ C099579C246C5E5C0016AA22 /* DataService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C099579B246C5E5C0016AA22 /* DataService.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -86,6 +92,8 @@
3EBD242B245D8044003CECE7 /* GameCenterHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameCenterHelper.swift; sourceTree = ""; };
3EBD242D245D9332003CECE7 /* Team.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Team.swift; sourceTree = ""; };
8BB6FF3F2472B8F000162BBD /* SkillButtonNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkillButtonNode.swift; sourceTree = ""; };
+ 3F745DEF246F48FC00CE7375 /* PlayerMoveType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerMoveType.swift; sourceTree = ""; };
+ 3FE19DB4246C7A22004827AB /* RoundCalculatorService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoundCalculatorService.swift; sourceTree = ""; };
9E04AFAE245E2B73002D5CFC /* AttackActionComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttackActionComponent.swift; sourceTree = ""; };
9E11FF77245CD81100EED3BE /* Fire.sks */ = {isa = PBXFileReference; lastKnownFileType = file.sks; path = Fire.sks; sourceTree = ""; };
9E174C81245DD81D00209FF0 /* ButtonNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ButtonNode.swift; sourceTree = ""; };
@@ -99,11 +107,12 @@
9E78ACBD245CC9C000526FF7 /* AtkBoostSkillComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtkBoostSkillComponent.swift; sourceTree = ""; };
9E78ACC1245CC9EE00526FF7 /* DefBoostSkillComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefBoostSkillComponent.swift; sourceTree = ""; };
9E78ACC3245CCA3600526FF7 /* SpySkillComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpySkillComponent.swift; sourceTree = ""; };
- 9EA3ABE8245C6DAA006BC61D /* DefaultBaseComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultBaseComponent.swift; sourceTree = ""; };
+ 9EA3ABE8245C6DAA006BC61D /* DefaultBaseComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultBaseComponent.swift; sourceTree = ""; wrapsLines = 1; };
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 = ""; };
9EBFD7542462CF5A00E1E219 /* SliderComponent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SliderComponent.swift; sourceTree = ""; };
+ 9EC239E0246878A900952F74 /* MultiplayerNetwork.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiplayerNetwork.swift; sourceTree = ""; };
9EC7E48A2461FBF700396BCD /* SliderNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SliderNode.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 = ""; };
@@ -115,12 +124,15 @@
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 = ""; };
+ AEBF3AFE246EB146004F7CD5 /* CancelBtnNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CancelBtnNode.swift; sourceTree = ""; };
+ AEBF3B00246EB187004F7CD5 /* CancelBtnComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CancelBtnComponent.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 = ""; };
+ C099579B246C5E5C0016AA22 /* DataService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataService.swift; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -177,9 +189,14 @@
C05FAED52468559D0006AF2E /* SoundManager.swift */,
110360DA244B101A008610AF /* GameViewController.swift */,
110360DF244B101B008610AF /* Assets.xcassets */,
+ 9EC239E0246878A900952F74 /* MultiplayerNetwork.swift */,
+ C099579B246C5E5C0016AA22 /* DataService.swift */,
110360E4244B101B008610AF /* Info.plist */,
AE151588245F18EF001D363E /* MatchmakingHelper.swift */,
+ 3FE19DB4246C7A22004827AB /* RoundCalculatorService.swift */,
3EBD242B245D8044003CECE7 /* GameCenterHelper.swift */,
+ AEBF3B00246EB187004F7CD5 /* CancelBtnComponent.swift */,
+ AEBF3AFE246EB146004F7CD5 /* CancelBtnNode.swift */,
C04783EF24685995004961FB /* SettingsScene.swift */,
C064E9A7246C0EA50022B228 /* LabelNode.swift */,
C064E9A9246C114C0022B228 /* LabelComponent.swift */,
@@ -257,6 +274,7 @@
11738A3A24508F68004426F1 /* UnitType.swift */,
9EC86BA5245C8AD000796EF3 /* ModalType.swift */,
3EBD242D245D9332003CECE7 /* Team.swift */,
+ 3F745DEF246F48FC00CE7375 /* PlayerMoveType.swift */,
);
path = Enums;
sourceTree = "";
@@ -394,7 +412,9 @@
files = (
9E78ACB8245CB75B00526FF7 /* TeamComponent.swift in Sources */,
9EA3ABEF245C834B006BC61D /* ModalContentComponent.swift in Sources */,
+ 3FE19DB5246C7A22004827AB /* RoundCalculatorService.swift in Sources */,
9EC86BA6245C8AD000796EF3 /* ModalType.swift in Sources */,
+ 9EC239E1246878A900952F74 /* MultiplayerNetwork.swift in Sources */,
9E78ACBE245CC9C000526FF7 /* AtkBoostSkillComponent.swift in Sources */,
9E78ACC4245CCA3600526FF7 /* SpySkillComponent.swift in Sources */,
9EA3ABEB245C6DFA006BC61D /* BaseNode.swift in Sources */,
@@ -411,13 +431,16 @@
9E174C86245DD91500209FF0 /* ButtonComponent.swift in Sources */,
AE151589245F18EF001D363E /* MatchmakingHelper.swift in Sources */,
11036113244B3E30008610AF /* MenuScene.swift in Sources */,
+ C099579C246C5E5C0016AA22 /* DataService.swift in Sources */,
9EA3ABE9245C6DAA006BC61D /* DefaultBaseComponent.swift in Sources */,
9E174C8A245E1A0A00209FF0 /* Background.swift in Sources */,
8BB6FF402472B8F000162BBD /* SkillButtonNode.swift in Sources */,
9EA3ABED245C8143006BC61D /* ModalBackgroundComponent.swift in Sources */,
C064E9A8246C0EA50022B228 /* LabelNode.swift in Sources */,
3EBD242C245D8044003CECE7 /* GameCenterHelper.swift in Sources */,
+ 3F745DF0246F48FC00CE7375 /* PlayerMoveType.swift in Sources */,
AB1D759C245DD18100671525 /* MapProtocol.swift in Sources */,
+ AEBF3B01246EB187004F7CD5 /* CancelBtnComponent.swift in Sources */,
AB1D75A0245DEC0500671525 /* MapFactory.swift in Sources */,
AB1D759D245DD18100671525 /* TwoPlayerDefaultTestMap.swift in Sources */,
9EBFD7552462CF5A00E1E219 /* SliderComponent.swift in Sources */,
@@ -427,6 +450,7 @@
9EC7E48B2461FBF700396BCD /* SliderNode.swift in Sources */,
9EEDE02F246FCD800096C735 /* SpinningLogoComponent.swift in Sources */,
9E174C84245DD8CE00209FF0 /* Button.swift in Sources */,
+ AEBF3AFF246EB146004F7CD5 /* CancelBtnNode.swift in Sources */,
110360DB244B101A008610AF /* GameViewController.swift in Sources */,
2086465C2461B66200817C23 /* TimerComponent.swift in Sources */,
110360D3244B101A008610AF /* AppDelegate.swift in Sources */,
@@ -593,8 +617,8 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = GoldWars/GoldWars.entitlements;
- CODE_SIGN_IDENTITY = "iPhone Developer";
- CODE_SIGN_STYLE = Manual;
+ CODE_SIGN_IDENTITY = "Apple Development";
+ CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 3;
DEVELOPMENT_TEAM = DDKFQG46BQ;
INFOPLIST_FILE = GoldWars/Info.plist;
@@ -605,7 +629,7 @@
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = de.hft.stuttgart.ip2.goldwars;
PRODUCT_NAME = "$(TARGET_NAME)";
- PROVISIONING_PROFILE_SPECIFIER = "Developer Profile";
+ PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 2;
};
@@ -616,8 +640,8 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = GoldWars/GoldWars.entitlements;
- CODE_SIGN_IDENTITY = "iPhone Developer";
- CODE_SIGN_STYLE = Manual;
+ CODE_SIGN_IDENTITY = "Apple Development";
+ CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 3;
DEVELOPMENT_TEAM = DDKFQG46BQ;
INFOPLIST_FILE = GoldWars/Info.plist;
diff --git a/GoldWars/GoldWars/CancelBtnComponent.swift b/GoldWars/GoldWars/CancelBtnComponent.swift
new file mode 100644
index 0000000..7d15f68
--- /dev/null
+++ b/GoldWars/GoldWars/CancelBtnComponent.swift
@@ -0,0 +1,27 @@
+//
+// CancelBtnComponent.swift
+// GoldWars
+//
+// Created by Chauntalle Schüle on 15.05.20.
+// Copyright © 2020 SP2. All rights reserved.
+//
+import GameplayKit
+import SpriteKit
+
+class CancelBtnComponent: GKComponent {
+
+ var cancelBtnNode: CancelBtnNode
+
+ init(iconName: String, text: String, position: CGPoint, isEnabled:Bool, onButtonPress: @escaping () -> ()) {
+ cancelBtnNode = CancelBtnNode(iconName: iconName,
+ text: text,
+ isEnabled: isEnabled,
+ position: position,
+ onButtonPress: onButtonPress)
+ super.init()
+ }
+
+ required init?(coder aDecoder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+}
diff --git a/GoldWars/GoldWars/CancelBtnNode.swift b/GoldWars/GoldWars/CancelBtnNode.swift
new file mode 100644
index 0000000..770baa5
--- /dev/null
+++ b/GoldWars/GoldWars/CancelBtnNode.swift
@@ -0,0 +1,57 @@
+//
+// CancelBtnNode.swift
+// GoldWars
+//
+// Created by Chauntalle Schüle on 15.05.20.
+// Copyright © 2020 SP2. All rights reserved.
+//
+
+import SpriteKit
+
+class CancelBtnNode: SKSpriteNode {
+
+ var isEnabled: Bool{
+ didSet{
+ if isEnabled {
+ self.alpha = 1
+ self.childNode(withName: "label")?.alpha = 1
+ } else {
+ self.alpha = 0.3
+ self.childNode(withName: "label")?.alpha = 0.3
+ }
+ }
+ }
+
+ let onButtonPress: () -> ()
+
+ init(iconName: String, text: String, isEnabled: Bool, position: CGPoint, onButtonPress: @escaping () -> ()) {
+ self.onButtonPress = onButtonPress
+ self.isEnabled = isEnabled
+ let texture = SKTexture(imageNamed: "yellow_cross")
+ super.init(texture: texture, color: SKColor.white, size: texture.size())
+ self.size = CGSize(width: 30, height: 30)
+ self.position = position
+ isUserInteractionEnabled = true
+ }
+
+ override func touchesBegan(_ touches: Set, with event: UIEvent?) {
+ if isEnabled {
+ let action = SKAction.sequence(
+ [
+ SKAction.scale(by: (3/4), duration: 0.3),
+ SKAction.scale(by: (4/3), duration: 0.3),
+ ]
+ )
+
+ self.childNode(withName: "label")?.run(action)
+ self.run(action)
+ onButtonPress()
+ }
+ }
+
+
+ required init?(coder aDecoder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+}
diff --git a/GoldWars/GoldWars/Components/TeamComponent.swift b/GoldWars/GoldWars/Components/TeamComponent.swift
index 2369f7b..db67deb 100644
--- a/GoldWars/GoldWars/Components/TeamComponent.swift
+++ b/GoldWars/GoldWars/Components/TeamComponent.swift
@@ -11,9 +11,9 @@ import GameplayKit
import GameKit
class TeamComponent: GKComponent {
- let team: Team
+ var team: Team
+ var player: GKPlayer
let fire: SKEmitterNode
- let player: GKPlayer
init(team: Team, player: GKPlayer, position: CGPoint) {
fire = SKEmitterNode(fileNamed: "Fire")!
diff --git a/GoldWars/GoldWars/Components/TimerComponent.swift b/GoldWars/GoldWars/Components/TimerComponent.swift
index 816ca04..52c51b6 100644
--- a/GoldWars/GoldWars/Components/TimerComponent.swift
+++ b/GoldWars/GoldWars/Components/TimerComponent.swift
@@ -9,12 +9,12 @@
import GameplayKit
class TimerComponent: GKComponent {
-
+
let labelNode :SKLabelNode
var endTime :Date!
var duration :Double
-
- init(text: String, anchorPoint: CGPoint, duration: TimeInterval) {
+
+ init(text: String, anchorPoint: CGPoint, duration: TimeInterval) {
self.labelNode = SKLabelNode(text: text)
self.labelNode.fontColor = UIColor.black
self.labelNode.fontSize = CGFloat(45)
@@ -26,6 +26,7 @@ class TimerComponent: GKComponent {
func startWithDuration(duration: TimeInterval){
endTime = Date().addingTimeInterval(duration)
+ RoundCalculatorService.sharedInstance.isCalculating = false
}
func timeLeft() -> Int {
@@ -45,12 +46,20 @@ class TimerComponent: GKComponent {
if(isFinished()){
self.labelNode.text = "Synching"
+ if !MultiplayerNetwork.sharedInstance.isSending {
+ MultiplayerNetwork.sharedInstance.sendPlayerMoves(playerMoves: DataService.sharedInstance.localPlayerMoves)
+ }
+ if !RoundCalculatorService.sharedInstance.isCalculating
+ && DataService.sharedInstance.didReceiveAllData()
+ && MatchmakingHelper.sharedInstance.isServer {
+ RoundCalculatorService.sharedInstance.calculateRound()
+ }
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
-
+
}
diff --git a/GoldWars/GoldWars/DataService.swift b/GoldWars/GoldWars/DataService.swift
new file mode 100644
index 0000000..e06dff6
--- /dev/null
+++ b/GoldWars/GoldWars/DataService.swift
@@ -0,0 +1,72 @@
+//
+// PlayerMovesService.swift
+// GoldWars
+//
+// Created by Tim Herbst on 13.05.20.
+// Copyright © 2020 SP2. All rights reserved.
+//
+
+struct PlayerMove: Codable{
+ let fromBase: Int
+ let toBase: Int
+ var unitCount: Int
+}
+
+struct Host: Codable {
+ let playerName: String
+}
+
+class SnapshotModel: Codable {
+ var baseEntites: [BaseEntityModel]
+
+ init(baseEntites: [BaseEntityModel]) {
+ self.baseEntites = baseEntites
+ }
+}
+
+class BaseEntityModel: Codable {
+ let baseId: Int
+ var unitCount: Int
+ var ownership: String?
+
+ init(baseId: Int, unitCount: Int, ownership: String?) {
+ self.baseId = baseId
+ self.unitCount = unitCount
+ self.ownership = ownership
+ }
+}
+
+class DataService {
+ static let sharedInstance = DataService()
+ var localPlayerMoves: [PlayerMove] = []
+ var remotePlayerMoves: [String: [PlayerMove]] = [:]
+ var snapshotModel: SnapshotModel?
+ var gameHost: Host?
+
+ func addMove(playerMove: PlayerMove) {
+ var equalMove = localPlayerMoves.filter { (ele) -> Bool in
+ ele.fromBase == playerMove.fromBase && ele.toBase == playerMove.toBase
+ }
+ if equalMove.count == 1 {
+ equalMove[0].unitCount = Int(equalMove[0].unitCount) + Int(playerMove.unitCount)
+ } else {
+ self.localPlayerMoves.append(playerMove)
+ }
+ }
+
+ func addRemotePlayerMoves(playerName: String, playerMoves: [PlayerMove]) {
+ self.remotePlayerMoves[playerName] = playerMoves
+ }
+
+ func didReceiveAllData() -> Bool {
+ return remotePlayerMoves.count == MatchmakingHelper.sharedInstance.mpMatch?.players.count
+ }
+
+ func setGameHost(host: Host) {
+ self.gameHost = host
+ }
+
+ func setSnapshotModel(snapshotModel: SnapshotModel) {
+ self.snapshotModel = snapshotModel
+ }
+}
diff --git a/GoldWars/GoldWars/Entities/Base.swift b/GoldWars/GoldWars/Entities/Base.swift
index d9b865a..322d328 100644
--- a/GoldWars/GoldWars/Entities/Base.swift
+++ b/GoldWars/GoldWars/Entities/Base.swift
@@ -10,13 +10,14 @@ import SpriteKit
import GameplayKit
import GameKit
-class Base: GKEntity {
-
+class Base: GKEntity{
+ static var BASE_ID_COUNT: Int = 0
var unitCount: Int
var unitType: UnitType
var adjacencyList: Array
var changeOwnership: Bool
var ownershipPlayer: GKPlayer?
+ var baseID: Int
init(position: CGPoint, player: GKPlayer! = nil, team: Team! = nil) {
self.unitCount = 0
@@ -24,6 +25,8 @@ class Base: GKEntity {
self.adjacencyList = [Base]()
self.changeOwnership = false
self.ownershipPlayer = player
+ self.baseID = Base.BASE_ID_COUNT
+ Base.BASE_ID_COUNT += 1
super.init()
addComponent(DefaultBaseComponent(texture: SKTexture(imageNamed: "Base"), position: position))
@@ -33,11 +36,14 @@ class Base: GKEntity {
}
}
- func attackBase(base: Base, units:Int) -> [GKEntity]{
+ func doPlayerMoveTypeToBase(base: Base, playerMoveType: PlayerMoveType, units: Int) -> [GKEntity]{
base.changeOwnership = true
base.ownershipPlayer = self.ownershipPlayer
self.unitCount -= units
base.unitCount += units
+ DataService.sharedInstance.addMove(playerMove: PlayerMove(fromBase: self.baseID,
+ toBase: base.baseID,
+ unitCount: units * playerMoveType.rawValue))
return [self, base]
}
diff --git a/GoldWars/GoldWars/Entities/EntityManager.swift b/GoldWars/GoldWars/Entities/EntityManager.swift
index 66e9964..7260b2d 100644
--- a/GoldWars/GoldWars/Entities/EntityManager.swift
+++ b/GoldWars/GoldWars/Entities/EntityManager.swift
@@ -74,6 +74,10 @@ class EntityManager {
if let labelNode = entity.component(ofType: LabelComponent.self)?.labelNode {
scene.addChild(labelNode)
}
+ if let cancelBtnNode = entity.component(ofType: CancelBtnComponent.self)?.cancelBtnNode {
+ scene.addChild(cancelBtnNode)
+ isModal = true
+ }
if let node = entity.component(ofType: SpinningLogoComponent.self)?.node {
scene.addChild(node)
}
@@ -99,6 +103,10 @@ class EntityManager {
modalButton.buttonNode.removeFromParent()
isModal = false
}
+ if let cancelBtnNode = entity.component(ofType: CancelBtnComponent.self)?.cancelBtnNode {
+ cancelBtnNode.removeFromParent()
+ isModal = false
+ }
entities.remove(entity)
}
@@ -108,17 +116,55 @@ class EntityManager {
let base = (entity as! Base)
if base.changeOwnership {
+ //FIX-ME: Find a way to update the Component without deleting it upfront
+ //TODO: outsource component handling to a generic function
+ //base.removeComponent(ofType: TeamComponent.self)
base.addComponent(TeamComponent(
team: (entities[0] as! Base).component(ofType: TeamComponent.self)!.team,
player: (entities[0] as! Base).component(ofType: TeamComponent.self)!.player,
position: (base.component(ofType: DefaultBaseComponent.self)?.spriteNode.position)!
)
)
+ if let fire = entity.component(ofType: TeamComponent.self)?.fire{
+ scene.addChild(fire)
+ }
base.changeOwnership = false
- scene.addChild(base.component(ofType: TeamComponent.self)!.fire)
}
}
-
+ }
+
+ func updateSnapshotModel(snapshotModel: SnapshotModel) {
+ let bases = entities.filter{$0 is Base}
+ for entity in bases{
+ let base = entity as! Base
+ let snapBase = self.getSnapshotBaseById(baseId: base.baseID, snapshotModel: snapshotModel)
+ var getOwnerBySnapBase: GKPlayer? = nil
+ base.unitCount = snapBase.unitCount
+
+ if snapBase.ownership != nil {
+ getOwnerBySnapBase = MatchmakingHelper.sharedInstance.getGKPlayerByUsername(displayName: snapBase.ownership!)
+ }
+ if getOwnerBySnapBase != nil {
+ base.changeOwnership = true
+ base.ownershipPlayer = getOwnerBySnapBase
+ //FIX-ME: Find a way to update the Component without deleting it upfront
+ //TODO: outsource component handling to a generic function
+ //entity.removeComponent(ofType: TeamComponent.self)
+ entity.addComponent(TeamComponent(
+ team: getTeamByPlayer(playerName: snapBase.ownership!),
+ player: getOwnerBySnapBase!,
+ position: (entity.component(ofType: DefaultBaseComponent.self)?.spriteNode.position)!
+ )
+ )
+ if let fire = entity.component(ofType: TeamComponent.self)?.fire{
+ scene.addChild(fire)
+ }
+ }
+ }
+ }
+
+ func getSnapshotBaseById(baseId: Int, snapshotModel: SnapshotModel) -> BaseEntityModel{
+ return snapshotModel.baseEntites.filter { $0.baseId == baseId }[0]
}
func getBaseByPlayer(for player: GKPlayer) -> GKEntity? {
@@ -166,6 +212,19 @@ class EntityManager {
return nil
}
+ func getTeamByPlayer(playerName: String) -> Team {
+ return entities.filter { $0 is Base && ($0 as! Base).component(ofType: TeamComponent.self)?.player.displayName == playerName }[0].component(ofType: TeamComponent.self)!.team
+ }
+
+ func getBasebyID(id: Int) -> Base?{
+ for entity in entities {
+ if entity is Base && (entity as! Base).baseID == id {
+ return (entity as! Base)
+ }
+ }
+ return nil
+ }
+
func getBackground() -> GKEntity? {
return entities.filter{$0 is Background}[0]
}
@@ -181,4 +240,18 @@ class EntityManager {
func getHUD() -> GKEntity? {
return entities.filter{$0 is HUD}[0]
}
+
+
+
+ func getSnapshotModel() -> SnapshotModel {
+ let bases = entities.filter{$0 is Base}
+ var snapBase: [BaseEntityModel] = []
+
+ for entity in bases {
+ let base = entity as! Base
+ snapBase.append(BaseEntityModel(baseId: base.baseID, unitCount: base.unitCount, ownership: base.ownershipPlayer?.displayName))
+ }
+
+ return SnapshotModel(baseEntites: snapBase)
+ }
}
diff --git a/GoldWars/GoldWars/Entities/Modal.swift b/GoldWars/GoldWars/Entities/Modal.swift
index 516efb0..c01999e 100644
--- a/GoldWars/GoldWars/Entities/Modal.swift
+++ b/GoldWars/GoldWars/Entities/Modal.swift
@@ -12,7 +12,7 @@ class Modal: GKEntity{
var unitCount:Int
- init(modaltype: ModalType, base: Base, anchorPoint: CGPoint, entityManager: EntityManager, gameScene: SKScene) {
+ init(modaltype: ModalType, base: Base, anchorPoint: CGPoint, gameScene: GameScene, currentDraggedBase: Base?, touchLocation: CGPoint, collisionBase: Base?) {
unitCount = base.unitCount
super.init()
switch modaltype{
@@ -20,7 +20,7 @@ class Modal: GKEntity{
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)
+ self.removeModalEntities(gameScene: gameScene)
}))
case .BaseAttack:
addComponent(ModalBackgroundComponent(anchorPoint: anchorPoint))
@@ -28,7 +28,11 @@ class Modal: GKEntity{
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)
+ self.sendUnits(currentDraggedBase: currentDraggedBase, touchLocation: touchLocation, gameScene: gameScene, collisionBase: collisionBase)
+ self.removeModalEntities(gameScene: gameScene)
+ }))
+ addComponent(CancelBtnComponent(iconName: "", text: "", position: CGPoint(x: anchorPoint.x + 160, y: anchorPoint.y + 140), isEnabled: true, onButtonPress: {
+ self.removeModalEntities(gameScene: gameScene)
}))
}
}
@@ -37,10 +41,10 @@ class Modal: GKEntity{
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)
+ func removeModalEntities(gameScene: SKScene){
+ for entity in EntityManager.sharedInstance.entities {
+ if EntityManager.sharedInstance.isModal && entity.isMember(of: Modal.self) {
+ EntityManager.sharedInstance.remove(entity)
}
for child in gameScene.children {
if(child.name != "fire"){
@@ -49,4 +53,12 @@ class Modal: GKEntity{
}
}
}
+
+ func sendUnits(currentDraggedBase: Base?, touchLocation: CGPoint, gameScene: GameScene, collisionBase: Base?){
+ for base in currentDraggedBase!.adjacencyList {
+ if base == collisionBase {
+ EntityManager.sharedInstance.update((currentDraggedBase?.doPlayerMoveTypeToBase(base: base, playerMoveType: PlayerMoveType.AtkMove, units: Int(GameScene.sendUnits)))!)
+ }
+ }
+ }
}
diff --git a/GoldWars/GoldWars/Enums/PlayerMoveType.swift b/GoldWars/GoldWars/Enums/PlayerMoveType.swift
new file mode 100644
index 0000000..2f1bdd6
--- /dev/null
+++ b/GoldWars/GoldWars/Enums/PlayerMoveType.swift
@@ -0,0 +1,13 @@
+//
+// PlayerMoveType.swift
+// GoldWars
+//
+// Created by Aldin Duraki on 16.05.20.
+// Copyright © 2020 SP2. All rights reserved.
+//
+
+enum PlayerMoveType: Int, Codable{
+ case AtkMove = 1
+ case TxnMove = -1
+}
+
diff --git a/GoldWars/GoldWars/MatchmakingHelper.swift b/GoldWars/GoldWars/MatchmakingHelper.swift
index a99bb31..a695d39 100644
--- a/GoldWars/GoldWars/MatchmakingHelper.swift
+++ b/GoldWars/GoldWars/MatchmakingHelper.swift
@@ -33,6 +33,8 @@ class MatchmakingHelper: NSObject, GKMatchmakerViewControllerDelegate, GKMatchDe
var viewController: UIViewController?
var mpMatchStarted: Bool
var isServer: Bool
+ var spieler1: GKPlayer?
+ var nameSpieler1 = ""
var menusc: MenuScene?
let localPlayer: GKLocalPlayer = GKLocalPlayer.local
@@ -100,12 +102,27 @@ class MatchmakingHelper: NSObject, GKMatchmakerViewControllerDelegate, GKMatchDe
}
/*
- Vom match erhaltene Spielerdaten
- */
- private func match(match: GKMatch!, didReceiveData data: NSData!,fromPlayer playerID: String!) {
+ Vom match erhaltene Spielerdaten
+ */
+ func match(_ match: GKMatch, didReceive data: Data, fromRemotePlayer player: GKPlayer) {
if mpMatch != match { return }
- delegate?.matchReceivedData(match: match, data: data, fromPlayer: playerID)
+
+ let jsonDecoder = JSONDecoder()
+ if let playerMoves = try? jsonDecoder.decode([PlayerMove].self, from: data) {
+ DataService.sharedInstance.addRemotePlayerMoves(playerName: player.displayName, playerMoves: playerMoves)
+ }
+
+ if let message = try? jsonDecoder.decode(Host.self, from: data) {
+ DataService.sharedInstance.gameHost = message
+ }
+
+ if let snapshotModel = try? jsonDecoder.decode(SnapshotModel.self, from: data) {
+ DataService.sharedInstance.snapshotModel = snapshotModel
+ EntityManager.sharedInstance.updateSnapshotModel(snapshotModel: snapshotModel)
+ }
+
+ MultiplayerNetwork.sharedInstance.isSending = false
}
/*
@@ -152,15 +169,33 @@ class MatchmakingHelper: NSObject, GKMatchmakerViewControllerDelegate, GKMatchDe
if player == GKLocalPlayer.local {
self.isServer = true
+ self.spieler1 = player
+ self.nameSpieler1 = self.spieler1!.displayName
+ DataService.sharedInstance.setGameHost(host: Host(playerName: player!.displayName))
} else {
self.isServer = false
}
self.delegate?.matchStarted()
self.menusc!.loadScene(scene: GameScene(size: self.menusc!.size))
+ MultiplayerNetwork.sharedInstance.sendHostIdentifier()
})
}
+ func getGKPlayerByUsername(displayName: String) -> GKPlayer? {
+ let nilGK : GKPlayer? = nil
+
+ if GKLocalPlayer.local.displayName == displayName {
+ return GKLocalPlayer.local
+ }
+
+ for player in mpMatch!.players {
+ if player.displayName == displayName {
+ return player
+ }
+ }
+ return nilGK
+ }
/*
Trennt die Verbindung vom Match
diff --git a/GoldWars/GoldWars/MultiplayerNetwork.swift b/GoldWars/GoldWars/MultiplayerNetwork.swift
new file mode 100644
index 0000000..7ffbc37
--- /dev/null
+++ b/GoldWars/GoldWars/MultiplayerNetwork.swift
@@ -0,0 +1,64 @@
+//
+// MultiplayerNetwork.swift
+// GoldWars
+//
+// Created by Niko Jochim on 10.05.20.
+// Copyright © 2020 SP2. All rights reserved.
+//
+
+import GameplayKit
+import Foundation
+import GameKit
+
+class MultiplayerNetwork{
+ static let sharedInstance = MultiplayerNetwork()
+
+ var isSending = false
+
+ func sendData(data: Data) {
+ let mmHelper = MatchmakingHelper.sharedInstance
+ if let multiplayerMatch = mmHelper.mpMatch {
+ do {
+ try multiplayerMatch.sendData(toAllPlayers: data, with: .reliable)
+ } catch {
+ //TODO: Add logging
+ }
+ }
+ }
+
+ func sendDataToHost(data: Data) {
+ let mmHelper = MatchmakingHelper.sharedInstance
+ let hostGKPlayer = MatchmakingHelper.sharedInstance.mpMatch?.players.filter{ $0.displayName == DataService.sharedInstance.gameHost!.playerName}[0]
+
+ if let multiplayerMatch = mmHelper.mpMatch{
+ do {
+ try multiplayerMatch.send(data, to: [hostGKPlayer!], dataMode: .reliable)
+ } catch {
+ //TODO: Add logging
+ }
+ }
+ }
+
+ func sendPlayerMoves(playerMoves: [PlayerMove]) {
+ if MatchmakingHelper.sharedInstance.isServer == false {
+ self.isSending = true
+ let encoder = JSONEncoder()
+ let encoded = (try? encoder.encode(playerMoves))!
+ sendDataToHost(data: encoded)
+ }
+ DataService.sharedInstance.localPlayerMoves.removeAll()
+ }
+
+ func sendHostIdentifier() {
+ let encoder = JSONEncoder()
+ let encoded = (try? encoder.encode(DataService.sharedInstance.gameHost))!
+ sendData(data: encoded)
+ }
+
+ func sendSnapshotModelToPlayers() {
+ let encoder = JSONEncoder()
+ let encoded = (try? encoder.encode(DataService.sharedInstance.snapshotModel))!
+ sendData(data: encoded)
+ }
+
+}
diff --git a/GoldWars/GoldWars/PlayerMovesService.swift b/GoldWars/GoldWars/PlayerMovesService.swift
new file mode 100644
index 0000000..3c0f41d
--- /dev/null
+++ b/GoldWars/GoldWars/PlayerMovesService.swift
@@ -0,0 +1,32 @@
+//
+// PlayerMovesService.swift
+// GoldWars
+//
+// Created by Tim Herbst on 13.05.20.
+// Copyright © 2020 SP2. All rights reserved.
+//
+
+struct PlayerMove : Codable{
+ let fromBase: Int
+ let toBase: Int
+ let unitCount: Int
+}
+
+struct Host: Codable {
+ let playerName: String
+}
+
+class DataService {
+ static let sharedInstance = DataService()
+ var playerMoves: [PlayerMove] = []
+ var gameHost: Host?
+
+
+ func addMove(playerMove: PlayerMove) {
+ self.playerMoves.append(playerMove)
+ }
+
+ func setGameHost(host: Host) {
+ self.gameHost = host
+ }
+}
diff --git a/GoldWars/GoldWars/RoundCalculatorService.swift b/GoldWars/GoldWars/RoundCalculatorService.swift
new file mode 100644
index 0000000..3704ec8
--- /dev/null
+++ b/GoldWars/GoldWars/RoundCalculatorService.swift
@@ -0,0 +1,124 @@
+//
+// RoundCalculatorService.swift
+// GoldWars
+//
+// Created by Aldin Duraki on 13.05.20.
+// Copyright © 2020 SP2. All rights reserved.
+//
+
+import GameKit
+import os
+
+class RoundCalculatorService {
+ static let sharedInstance = RoundCalculatorService()
+ static let LOG = OSLog.init(subsystem: "Round Calculator", category: "RoundCalculatorService")
+
+ var allPlayerMoves: [String: [PlayerMove]] = [:]
+ var baseSpecificMoves: [Int: [String: [PlayerMove]]] = [:]
+
+ var isCalculating = false
+
+ func calculateRound() {
+ os_log("Started calculating Round", log: RoundCalculatorService.LOG, type: .info)
+ isCalculating = true
+ let currentSnapshotModel = DataService.sharedInstance.snapshotModel
+
+ for playerMove in DataService.sharedInstance.remotePlayerMoves {
+ addPlayerMove(playerName: playerMove.key, playerMoves: playerMove.value)
+ }
+ addPlayerMove(playerName: GKLocalPlayer.local.displayName, playerMoves: DataService.sharedInstance.localPlayerMoves)
+
+ for playerMove in allPlayerMoves {
+ for move in playerMove.value {
+ mapPlayerMoveToAttackedBase(playerName: playerMove.key, playerMove: move)
+ }
+ }
+
+ // TODO: Refactor to a less complex way
+ for (key, value) in baseSpecificMoves {
+ let baseId = key
+ var playerMovesByBase = value
+ let targetBase = currentSnapshotModel?.baseEntites.filter { $0.baseId == baseId }[0]
+ let possiblyOwnershipMoves = playerMovesByBase.filter { $0.key == targetBase?.ownership}
+
+ for (playerName, playerMoves) in possiblyOwnershipMoves {
+ for playerMove in playerMoves {
+ for base in currentSnapshotModel!.baseEntites {
+ if base.baseId == playerMove.fromBase {
+ base.unitCount -= playerMove.unitCount
+ }
+ if base.baseId == playerMove.toBase {
+ base.unitCount += playerMove.unitCount
+ }
+ }
+ }
+ playerMovesByBase.removeValue(forKey: playerName)
+ }
+
+ for (_, playerMoves) in playerMovesByBase {
+ for playerMove in playerMoves {
+ for base in currentSnapshotModel!.baseEntites {
+ if base.baseId == playerMove.fromBase {
+ base.unitCount -= playerMove.unitCount
+ }
+ }
+ }
+ }
+
+ var combinePotentionalForces: [String: PlayerMove] = [:]
+
+ for playerMoves in playerMovesByBase {
+ combinePotentionalForces[playerMoves.key] = PlayerMove(fromBase: playerMoves.value[0].fromBase, toBase: playerMoves.value[0].toBase, unitCount: 0)
+ for move in playerMoves.value {
+ combinePotentionalForces[playerMoves.key]!.unitCount += move.unitCount
+ }
+ }
+ if(combinePotentionalForces.count > 0) {
+ let sortedPotentionalCombinedForces = combinePotentionalForces.sorted { $0.1.unitCount > $1.1.unitCount }
+
+ var playerMoveWithMaxUnits = sortedPotentionalCombinedForces[0]
+ if playerMovesByBase.count >= 2 {
+ let playerMoveWithSecMaxUnits = sortedPotentionalCombinedForces[1]
+ playerMoveWithMaxUnits.value.unitCount -= playerMoveWithSecMaxUnits.value.unitCount
+ }
+
+ for base in currentSnapshotModel!.baseEntites {
+ if base.baseId == playerMoveWithMaxUnits.value.toBase {
+ base.unitCount += playerMoveWithMaxUnits.value.unitCount
+ if playerMoveWithMaxUnits.value.unitCount == 0 {
+ base.ownership = nil
+ } else {
+ base.ownership = playerMoveWithMaxUnits.key
+ }
+ }
+ }
+ }
+ baseSpecificMoves.removeValue(forKey: baseId)
+ }
+ allPlayerMoves.removeAll()
+ MultiplayerNetwork.sharedInstance.sendSnapshotModelToPlayers()
+ EntityManager.sharedInstance.updateSnapshotModel(snapshotModel: currentSnapshotModel!)
+ os_log("Finished calculating Round", log: RoundCalculatorService.LOG, type: .info)
+ }
+
+ func addPlayerMove(playerName: String, playerMoves: [PlayerMove]) {
+ self.allPlayerMoves[playerName] = playerMoves
+ }
+
+ func mapPlayerMoveToAttackedBase(playerName: String, playerMove: PlayerMove) {
+ if self.baseSpecificMoves.keys.contains(playerMove.toBase) {
+ if (self.baseSpecificMoves[playerMove.toBase]?.keys.contains(playerName))!{
+ self.baseSpecificMoves[playerMove.toBase]?[playerName]?.append(playerMove)
+ } else {
+ self.baseSpecificMoves[playerMove.toBase]?.merge([playerName: [playerMove]]){(current, _) in current}
+ }
+ } else {
+ self.baseSpecificMoves[playerMove.toBase] = [playerName: [playerMove]]
+ }
+ }
+
+ func resolvePlayerMove(playerMove: PlayerMove, unitCount: Int, ownership: String?, resolveType: String) {
+ //TODO: outsource playermoves
+ }
+
+}
diff --git a/GoldWars/GoldWars/Scenes/GameScene.swift b/GoldWars/GoldWars/Scenes/GameScene.swift
index 85d512e..7b91850 100644
--- a/GoldWars/GoldWars/Scenes/GameScene.swift
+++ b/GoldWars/GoldWars/Scenes/GameScene.swift
@@ -15,6 +15,8 @@ class GameScene: SKScene{
var isMoveTouch = false
var currentDraggedBasePos = CGPoint()
var currentDraggedBase : Base?
+ static var sendUnits: CGFloat = 0
+ var collisionBase: Base?
override func sceneDidLoad() {
EntityManager.sharedInstance.setScene(scene: self)
@@ -25,6 +27,7 @@ class GameScene: SKScene{
func initMap() {
MapFactory(scene: self, entityManager: EntityManager.sharedInstance).loadMap(playerCount: 2)
+ DataService.sharedInstance.setSnapshotModel(snapshotModel: EntityManager.sharedInstance.getSnapshotModel())
}
override func touchesEnded(_ touches: Set, with event: UIEvent?) {
@@ -39,44 +42,13 @@ class GameScene: SKScene{
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.sharedInstance.getTeamByBase(base: currentDraggedBase!) == EntityManager.sharedInstance.getTeamByBase(base: base)){
- EntityManager.sharedInstance.add(Modal(modaltype: .BaseAttack,
- base: currentDraggedBase!,
- anchorPoint: CGPoint(x: self.size.width / 2 , y: self.size.height / 2),
- entityManager: EntityManager.sharedInstance, gameScene: self))
- EntityManager.sharedInstance.update((currentDraggedBase?.attackBase(base: base, units: 100))!)
- }else {
- EntityManager.sharedInstance.add(Modal(modaltype: .BaseAttack,
- base: currentDraggedBase!,
- anchorPoint: CGPoint(x: self.size.width / 2 , y: self.size.height / 2),
- entityManager: EntityManager.sharedInstance, gameScene: self))
- }
-
- }
- }
+ addAttackDetails(touchLocation: touchLocation)
}
else {
for entity in EntityManager.sharedInstance.entities {
let spriteNode = entity.component(ofType: DefaultBaseComponent.self)?.spriteNode
- if atPoint(touchLocation) == spriteNode && !EntityManager.sharedInstance.isModal {
- spriteNode?.touchesBegan(touches, with: event)
- if !EntityManager.sharedInstance.isModal {
- for child in self.children {
- if(child.name != "fire"){
- child.alpha = 0.3
- }
- }
- EntityManager.sharedInstance.add(Modal(modaltype: .BaseDetails,
- base: entity as! Base,
- anchorPoint: CGPoint(x: self.size.width / 2 , y: self.size.height / 2),
- entityManager: EntityManager.sharedInstance, gameScene: self))
- }
- }
+ addBaseDetails(touchLocation: touchLocation, spriteNode: spriteNode, touches: touches, event: event, entity: entity)
}
}
@@ -93,37 +65,82 @@ class GameScene: SKScene{
child.touchesMoved(touches, with: event)
}
}
-
- for e in EntityManager.sharedInstance.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 "
- } }
+ checkSlider()
let bases = EntityManager.sharedInstance.getBasesByPlayer(for: GKLocalPlayer.local)
- for base in bases {
- if atPoint(touchLocation) == base.component(ofType: DefaultBaseComponent.self)?.spriteNode{
- if !isMoveTouch {
- currentDraggedBasePos = base.component(ofType: DefaultBaseComponent.self)!.spriteNode.position
- currentDraggedBase = base
- }
- isMoveTouch = true
-
- base.component(ofType: DefaultBaseComponent.self)?.spriteNode.position = touchLocation
- base.component(ofType: TeamComponent.self)?.fire.position = touchLocation
- for adjacencyBase in base.adjacencyList {
- let node = adjacencyBase.component(ofType: DefaultBaseComponent.self)?.spriteNode
- node?.run(SKAction.sequence([
- SKAction.resize(byWidth: 2, height: 2, duration: 0.5),
- SKAction.resize(byWidth: -2, height: -2, duration: 0.5)
- ]))
- }
- }
- }
+ checkBases(bases: bases, touchLocation: touchLocation)
}
override func update(_ currentTime: TimeInterval) {
EntityManager.sharedInstance.getBackground()?.update(deltaTime: currentTime)
EntityManager.sharedInstance.getHUD()?.component(ofType: TimerComponent.self)?.update()
}
+
+ func addBaseDetails(touchLocation: CGPoint, spriteNode: SKNode?, touches: Set, event: UIEvent?, entity: GKEntity){
+ if atPoint(touchLocation) == spriteNode && !EntityManager.sharedInstance.isModal {
+ spriteNode?.touchesBegan(touches, with: event)
+ if !EntityManager.sharedInstance.isModal {
+ for child in self.children {
+ if(child.name != "fire"){
+ child.alpha = 0.3
+ }
+ }
+ EntityManager.sharedInstance.add(Modal(modaltype: .BaseDetails,
+ base: entity as! Base,
+ anchorPoint: CGPoint(x: self.size.width / 2 , y: self.size.height / 2),
+ gameScene: self, currentDraggedBase: currentDraggedBase, touchLocation: touchLocation, collisionBase: collisionBase))
+ }
+ }
+ }
+
+ func addAttackDetails(touchLocation: CGPoint){
+ for base in currentDraggedBase!.adjacencyList {
+ if atPoint(touchLocation) == base.component(ofType: DefaultBaseComponent.self)?.spriteNode {
+ collisionBase = base
+ // TODO: change interaction based on collision instead of touchlocation
+ EntityManager.sharedInstance.add(Modal(modaltype: .BaseAttack,
+ base: currentDraggedBase!,
+ anchorPoint: CGPoint(x: self.size.width / 2 , y: self.size.height / 2),
+ gameScene: self, currentDraggedBase: currentDraggedBase, touchLocation: touchLocation, collisionBase: collisionBase))
+ }
+ }
+ }
+
+ func checkSlider(){
+ for e in EntityManager.sharedInstance.entities{
+ if let body = e.component(ofType: ModalContentComponent.self)?.body{
+ GameScene.sendUnits = ((e.component(ofType: SliderComponent.self)?.sliderNode.getValue ?? 0) * CGFloat((e as! Modal).unitCount)).rounded(.up)
+ body.text = "Schicke \(GameScene.sendUnits) Einheiten "
+ }
+ }
+ }
+
+ func checkBases(bases: Set, touchLocation: CGPoint){
+ for base in bases {
+ if atPoint(touchLocation) == base.component(ofType: DefaultBaseComponent.self)?.spriteNode{ if !isMoveTouch {
+ currentDraggedBasePos = base.component(ofType: DefaultBaseComponent.self)!.spriteNode.position
+ currentDraggedBase = base
+ }
+ isMoveTouch = true
+ moveFireAndBase(base: base, touchLocation: touchLocation)
+ showNearestBases(base: base)
+ }
+ }
+ }
+
+ func moveFireAndBase(base: Base, touchLocation: CGPoint){
+ base.component(ofType: DefaultBaseComponent.self)?.spriteNode.position = touchLocation
+ base.component(ofType: TeamComponent.self)?.fire.position = touchLocation
+ }
+
+ func showNearestBases(base: Base){
+ for adjacencyBase in base.adjacencyList {
+ let node = adjacencyBase.component(ofType: DefaultBaseComponent.self)?.spriteNode
+ node?.run(SKAction.sequence([
+ SKAction.resize(byWidth: 2, height: 2, duration: 0.5),
+ SKAction.resize(byWidth: -2, height: -2, duration: 0.5)
+ ]))
+ }
+ }
}
diff --git a/GoldWars/GoldWars/SoundManager.swift b/GoldWars/GoldWars/SoundManager.swift
index 4f8f34d..b6cb5d4 100644
--- a/GoldWars/GoldWars/SoundManager.swift
+++ b/GoldWars/GoldWars/SoundManager.swift
@@ -23,7 +23,7 @@ class SoundManager {
do {
audioPlayer = try AVAudioPlayer(contentsOf: backgroundMainMenuAudio!)
} catch {
- print("Datei nicht gefunden!")
+ //TODO: Add logging
}
audioPlayer.numberOfLoops = -1
audioPlayer.prepareToPlay()
diff --git a/GoldWars/GoldWars/Storyboards/RoundSimulatorService.swift b/GoldWars/GoldWars/Storyboards/RoundSimulatorService.swift
new file mode 100644
index 0000000..4847831
--- /dev/null
+++ b/GoldWars/GoldWars/Storyboards/RoundSimulatorService.swift
@@ -0,0 +1,13 @@
+//
+// RoundSimulatorService.swift
+// GoldWars
+//
+// Created by student on 13.05.20.
+// Copyright © 2020 SP2. All rights reserved.
+//
+
+import Foundation
+
+class RoundSimulatorService {
+
+}