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 ebaec53..c92245c 100644
--- a/GoldWars/GoldWars.xcodeproj/project.pbxproj
+++ b/GoldWars/GoldWars.xcodeproj/project.pbxproj
@@ -16,10 +16,16 @@
110360EE244B101B008610AF /* GoldWarsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110360ED244B101B008610AF /* GoldWarsTests.swift */; };
11036113244B3E30008610AF /* MenuScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11036112244B3E30008610AF /* MenuScene.swift */; };
116060F7245C57D2004E5A36 /* EntityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 116060F6245C57D2004E5A36 /* EntityManager.swift */; };
- 11738A3B24508F68004426F1 /* Unit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11738A3A24508F68004426F1 /* Unit.swift */; };
+ 11738A3B24508F68004426F1 /* UnitType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11738A3A24508F68004426F1 /* UnitType.swift */; };
2086465C2461B66200817C23 /* TimerComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2086465B2461B66200817C23 /* TimerComponent.swift */; };
+ 3E67854024728368007B9DE4 /* CElements.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E67853F24728368007B9DE4 /* CElements.swift */; };
+ 3E6785422472CBEC007B9DE4 /* Way.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E6785412472CBEC007B9DE4 /* Way.swift */; };
+ 3E6785442472CC27007B9DE4 /* DefaultWayComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E6785432472CC27007B9DE4 /* DefaultWayComponent.swift */; };
3EBD242C245D8044003CECE7 /* GameCenterHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EBD242B245D8044003CECE7 /* GameCenterHelper.swift */; };
3EBD242E245D9332003CECE7 /* Team.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EBD242D245D9332003CECE7 /* Team.swift */; };
+ 3F745DF0246F48FC00CE7375 /* PlayerMoveType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F745DEF246F48FC00CE7375 /* PlayerMoveType.swift */; };
+ 3FE19DB5246C7A22004827AB /* RoundCalculatorService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FE19DB4246C7A22004827AB /* RoundCalculatorService.swift */; };
+ 8BB6FF402472B8F000162BBD /* SkillButtonNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8BB6FF3F2472B8F000162BBD /* SkillButtonNode.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 */; };
@@ -38,14 +44,27 @@
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 */; };
+ 9EC2FBA72476B1EC00ABF11F /* PlayerInfoComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EC2FBA62476B1EC00ABF11F /* PlayerInfoComponent.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 */; };
- AB1D759C245DD18100671525 /* MapProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB1D759A245DD18100671525 /* MapProtocol.swift */; };
+ 9EEDE02D246FCD770096C735 /* SpinningLogoEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EEDE02C246FCD770096C735 /* SpinningLogoEntity.swift */; };
+ 9EEDE02F246FCD800096C735 /* SpinningLogoComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EEDE02E246FCD800096C735 /* SpinningLogoComponent.swift */; };
AB1D759D245DD18100671525 /* TwoPlayerDefaultTestMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB1D759B245DD18100671525 /* TwoPlayerDefaultTestMap.swift */; };
AB1D75A0245DEC0500671525 /* MapFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB1D759F245DEC0500671525 /* MapFactory.swift */; };
+ AB21D7D5246C748A00B09CBA /* TwoPlayerMapGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB21D7D4246C748A00B09CBA /* TwoPlayerMapGenerator.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 */
@@ -72,10 +91,16 @@
110360EF244B101B008610AF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
11036112244B3E30008610AF /* MenuScene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuScene.swift; sourceTree = ""; };
116060F6245C57D2004E5A36 /* EntityManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntityManager.swift; sourceTree = ""; };
- 11738A3A24508F68004426F1 /* Unit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Unit.swift; sourceTree = ""; };
+ 11738A3A24508F68004426F1 /* UnitType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnitType.swift; sourceTree = ""; };
2086465B2461B66200817C23 /* TimerComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimerComponent.swift; sourceTree = ""; };
+ 3E67853F24728368007B9DE4 /* CElements.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CElements.swift; sourceTree = ""; };
+ 3E6785412472CBEC007B9DE4 /* Way.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Way.swift; sourceTree = ""; };
+ 3E6785432472CC27007B9DE4 /* DefaultWayComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultWayComponent.swift; sourceTree = ""; };
3EBD242B245D8044003CECE7 /* GameCenterHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameCenterHelper.swift; sourceTree = ""; };
3EBD242D245D9332003CECE7 /* Team.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Team.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 = ""; };
+ 8BB6FF3F2472B8F000162BBD /* SkillButtonNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkillButtonNode.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 = ""; };
@@ -89,20 +114,33 @@
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 = ""; };
+ 9EC2FBA62476B1EC00ABF11F /* PlayerInfoComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerInfoComponent.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 = ""; };
9ECD3699245C91F7008DEEBD /* GoldWars.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = GoldWars.entitlements; sourceTree = ""; };
- AB1D759A245DD18100671525 /* MapProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MapProtocol.swift; sourceTree = ""; };
+ 9EEDE02C246FCD770096C735 /* SpinningLogoEntity.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpinningLogoEntity.swift; sourceTree = ""; };
+ 9EEDE02E246FCD800096C735 /* SpinningLogoComponent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpinningLogoComponent.swift; sourceTree = ""; };
AB1D759B245DD18100671525 /* TwoPlayerDefaultTestMap.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TwoPlayerDefaultTestMap.swift; sourceTree = ""; };
AB1D759F245DEC0500671525 /* MapFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapFactory.swift; sourceTree = ""; };
+ AB21D7D4246C748A00B09CBA /* TwoPlayerMapGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoPlayerMapGenerator.swift; sourceTree = ""; };
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 */
@@ -146,6 +184,7 @@
110360D1244B101A008610AF /* GoldWars */ = {
isa = PBXGroup;
children = (
+ C04783ED2468583F004961FB /* intro-music.mp3 */,
9ECD3699245C91F7008DEEBD /* GoldWars.entitlements */,
9E11FF74245CD79100EED3BE /* Partikels */,
116060F5245C5709004E5A36 /* Entities */,
@@ -155,11 +194,21 @@
9EC86BA4245C8A1E00796EF3 /* Scenes */,
9EC86BA3245C89F400796EF3 /* Storyboards */,
110360D2244B101A008610AF /* AppDelegate.swift */,
+ 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 */,
+ C064E9AB246C151F0022B228 /* Label.swift */,
);
path = GoldWars;
sourceTree = "";
@@ -176,6 +225,7 @@
116060F4245C56EA004E5A36 /* Components */ = {
isa = PBXGroup;
children = (
+ 9EEDE02E246FCD800096C735 /* SpinningLogoComponent.swift */,
9E174C81245DD81D00209FF0 /* ButtonNode.swift */,
9EA3ABE8245C6DAA006BC61D /* DefaultBaseComponent.swift */,
9EA3ABEC245C8143006BC61D /* ModalBackgroundComponent.swift */,
@@ -191,6 +241,9 @@
2086465B2461B66200817C23 /* TimerComponent.swift */,
9EBFD7542462CF5A00E1E219 /* SliderComponent.swift */,
9EC7E48A2461FBF700396BCD /* SliderNode.swift */,
+ 3E6785432472CC27007B9DE4 /* DefaultWayComponent.swift */,
+ 8BB6FF3F2472B8F000162BBD /* SkillButtonNode.swift */,
+ 9EC2FBA62476B1EC00ABF11F /* PlayerInfoComponent.swift */,
);
path = Components;
sourceTree = "";
@@ -198,12 +251,14 @@
116060F5245C5709004E5A36 /* Entities */ = {
isa = PBXGroup;
children = (
+ 9E174C89245E1A0A00209FF0 /* Background.swift */,
ABA03D9F244BD54F00A66916 /* Base.swift */,
- 9EC86B9E245C88A300796EF3 /* Modal.swift */,
+ 9E174C83245DD8CE00209FF0 /* Button.swift */,
116060F6245C57D2004E5A36 /* EntityManager.swift */,
9E78ACB9245CBDAF00526FF7 /* HUD.swift */,
- 9E174C83245DD8CE00209FF0 /* Button.swift */,
- 9E174C89245E1A0A00209FF0 /* Background.swift */,
+ 9EC86B9E245C88A300796EF3 /* Modal.swift */,
+ 9EEDE02C246FCD770096C735 /* SpinningLogoEntity.swift */,
+ 3E6785412472CBEC007B9DE4 /* Way.swift */,
);
path = Entities;
sourceTree = "";
@@ -227,9 +282,10 @@
9EC86BA2245C89B200796EF3 /* Enums */ = {
isa = PBXGroup;
children = (
- 11738A3A24508F68004426F1 /* Unit.swift */,
+ 11738A3A24508F68004426F1 /* UnitType.swift */,
9EC86BA5245C8AD000796EF3 /* ModalType.swift */,
3EBD242D245D9332003CECE7 /* Team.swift */,
+ 3F745DEF246F48FC00CE7375 /* PlayerMoveType.swift */,
);
path = Enums;
sourceTree = "";
@@ -255,9 +311,10 @@
AB1D759E245DD2EA00671525 /* Map */ = {
isa = PBXGroup;
children = (
- AB1D759A245DD18100671525 /* MapProtocol.swift */,
+ 3E67853F24728368007B9DE4 /* CElements.swift */,
AB1D759F245DEC0500671525 /* MapFactory.swift */,
AB1D759B245DD18100671525 /* TwoPlayerDefaultTestMap.swift */,
+ AB21D7D4246C748A00B09CBA /* TwoPlayerMapGenerator.swift */,
);
path = Map;
sourceTree = "";
@@ -347,6 +404,7 @@
9E11FF79245CD81100EED3BE /* Fire.sks in Resources */,
110360E0244B101B008610AF /* Assets.xcassets in Resources */,
110360E3244B101B008610AF /* LaunchScreen.storyboard in Resources */,
+ C04783EE2468583F004961FB /* intro-music.mp3 in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -366,37 +424,55 @@
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 */,
9E04AFAF245E2B73002D5CFC /* AttackActionComponent.swift in Sources */,
+ 3E6785422472CBEC007B9DE4 /* Way.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 */,
- 11738A3B24508F68004426F1 /* Unit.swift in Sources */,
+ 9EC2FBA72476B1EC00ABF11F /* PlayerInfoComponent.swift in Sources */,
+ 9EEDE02D246FCD770096C735 /* SpinningLogoEntity.swift in Sources */,
+ 11738A3B24508F68004426F1 /* UnitType.swift in Sources */,
9E174C86245DD91500209FF0 /* ButtonComponent.swift in Sources */,
AE151589245F18EF001D363E /* MatchmakingHelper.swift in Sources */,
11036113244B3E30008610AF /* MenuScene.swift in Sources */,
+ C099579C246C5E5C0016AA22 /* DataService.swift in Sources */,
+ AB21D7D5246C748A00B09CBA /* TwoPlayerMapGenerator.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 */,
- AB1D759C245DD18100671525 /* MapProtocol.swift in Sources */,
+ 3F745DF0246F48FC00CE7375 /* PlayerMoveType.swift in Sources */,
+ AEBF3B01246EB187004F7CD5 /* CancelBtnComponent.swift in Sources */,
AB1D75A0245DEC0500671525 /* MapFactory.swift in Sources */,
AB1D759D245DD18100671525 /* TwoPlayerDefaultTestMap.swift in Sources */,
9EBFD7552462CF5A00E1E219 /* SliderComponent.swift in Sources */,
+ 3E67854024728368007B9DE4 /* CElements.swift in Sources */,
ABA03DA0244BD54F00A66916 /* Base.swift in Sources */,
+ C064E9AC246C151F0022B228 /* Label.swift in Sources */,
9E174C82245DD81D00209FF0 /* ButtonNode.swift in Sources */,
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 */,
+ 3E6785442472CC27007B9DE4 /* DefaultWayComponent.swift in Sources */,
2086465C2461B66200817C23 /* TimerComponent.swift in Sources */,
110360D3244B101A008610AF /* AppDelegate.swift in Sources */,
9EC86B9F245C88A300796EF3 /* Modal.swift in Sources */,
9E78ACC2245CC9EE00526FF7 /* DefBoostSkillComponent.swift in Sources */,
+ C05FAED62468559D0006AF2E /* SoundManager.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -557,9 +633,9 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = GoldWars/GoldWars.entitlements;
- CODE_SIGN_IDENTITY = "iPhone Developer";
- CODE_SIGN_STYLE = Manual;
- CURRENT_PROJECT_VERSION = 3;
+ CODE_SIGN_IDENTITY = "Apple Development";
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 4;
DEVELOPMENT_TEAM = DDKFQG46BQ;
INFOPLIST_FILE = GoldWars/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@@ -569,7 +645,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;
};
@@ -580,9 +656,9 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = GoldWars/GoldWars.entitlements;
- CODE_SIGN_IDENTITY = "iPhone Developer";
- CODE_SIGN_STYLE = Manual;
- CURRENT_PROJECT_VERSION = 3;
+ CODE_SIGN_IDENTITY = "Apple Development";
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 4;
DEVELOPMENT_TEAM = DDKFQG46BQ;
INFOPLIST_FILE = GoldWars/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@@ -592,7 +668,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;
};
diff --git a/GoldWars/GoldWars/Assets.xcassets/logo_kante.imageset/Contents.json b/GoldWars/GoldWars/Assets.xcassets/logo_kante.imageset/Contents.json
new file mode 100644
index 0000000..72ffd48
--- /dev/null
+++ b/GoldWars/GoldWars/Assets.xcassets/logo_kante.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "filename" : "logo_kante.jpg",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "logo_kante-1.jpg",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "logo_kante-2.jpg",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/GoldWars/GoldWars/Assets.xcassets/logo_kante.imageset/logo_kante-1.jpg b/GoldWars/GoldWars/Assets.xcassets/logo_kante.imageset/logo_kante-1.jpg
new file mode 100644
index 0000000..1ef166f
Binary files /dev/null and b/GoldWars/GoldWars/Assets.xcassets/logo_kante.imageset/logo_kante-1.jpg differ
diff --git a/GoldWars/GoldWars/Assets.xcassets/logo_kante.imageset/logo_kante-2.jpg b/GoldWars/GoldWars/Assets.xcassets/logo_kante.imageset/logo_kante-2.jpg
new file mode 100644
index 0000000..1ef166f
Binary files /dev/null and b/GoldWars/GoldWars/Assets.xcassets/logo_kante.imageset/logo_kante-2.jpg differ
diff --git a/GoldWars/GoldWars/Assets.xcassets/logo_kante.imageset/logo_kante.jpg b/GoldWars/GoldWars/Assets.xcassets/logo_kante.imageset/logo_kante.jpg
new file mode 100644
index 0000000..1ef166f
Binary files /dev/null and b/GoldWars/GoldWars/Assets.xcassets/logo_kante.imageset/logo_kante.jpg differ
diff --git a/GoldWars/GoldWars/Assets.xcassets/logo_no_background.imageset/Contents.json b/GoldWars/GoldWars/Assets.xcassets/logo_no_background.imageset/Contents.json
new file mode 100644
index 0000000..8401033
--- /dev/null
+++ b/GoldWars/GoldWars/Assets.xcassets/logo_no_background.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "filename" : "logo_no_background.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "logo_no_background-1.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "logo_no_background-2.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/GoldWars/GoldWars/Assets.xcassets/logo_no_background.imageset/logo_no_background-1.png b/GoldWars/GoldWars/Assets.xcassets/logo_no_background.imageset/logo_no_background-1.png
new file mode 100644
index 0000000..07b8c65
Binary files /dev/null and b/GoldWars/GoldWars/Assets.xcassets/logo_no_background.imageset/logo_no_background-1.png differ
diff --git a/GoldWars/GoldWars/Assets.xcassets/logo_no_background.imageset/logo_no_background-2.png b/GoldWars/GoldWars/Assets.xcassets/logo_no_background.imageset/logo_no_background-2.png
new file mode 100644
index 0000000..07b8c65
Binary files /dev/null and b/GoldWars/GoldWars/Assets.xcassets/logo_no_background.imageset/logo_no_background-2.png differ
diff --git a/GoldWars/GoldWars/Assets.xcassets/logo_no_background.imageset/logo_no_background.png b/GoldWars/GoldWars/Assets.xcassets/logo_no_background.imageset/logo_no_background.png
new file mode 100644
index 0000000..07b8c65
Binary files /dev/null and b/GoldWars/GoldWars/Assets.xcassets/logo_no_background.imageset/logo_no_background.png differ
diff --git a/GoldWars/GoldWars/CancelBtnComponent.swift b/GoldWars/GoldWars/CancelBtnComponent.swift
new file mode 100644
index 0000000..ae7d6a2
--- /dev/null
+++ b/GoldWars/GoldWars/CancelBtnComponent.swift
@@ -0,0 +1,28 @@
+//
+// 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)
+ cancelBtnNode.zPosition = 4
+ 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/AtkBoostSkillComponent.swift b/GoldWars/GoldWars/Components/AtkBoostSkillComponent.swift
index a2d36b3..8829c19 100644
--- a/GoldWars/GoldWars/Components/AtkBoostSkillComponent.swift
+++ b/GoldWars/GoldWars/Components/AtkBoostSkillComponent.swift
@@ -9,25 +9,30 @@
import GameplayKit
class AtkBoostSkillComponent: GKComponent{
-
- let shapeNode: SKShapeNode
- let labelNode: SKLabelNode
-
- init(text: String, texture: SKTexture?, anchorPoint: CGPoint) {
- self.labelNode = SKLabelNode(text: text)
- self.shapeNode = SKShapeNode(circleOfRadius: 30)
- self.shapeNode.position = anchorPoint
- self.labelNode.position = CGPoint(x: anchorPoint.x, y: anchorPoint.y - 15)
- if texture != nil {
- shapeNode.fillTexture = texture
- }else {
- shapeNode.fillColor = SKColor.gray
- }
- super.init()
- }
-
- required init?(coder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
-
+
+ var skillButtonNode: SkillButtonNode
+
+ init(iconName: String, text: String, position: CGPoint, isEnabled:Bool) {
+ skillButtonNode = SkillButtonNode(iconName: iconName,
+ text: text,
+ isEnabled: isEnabled,
+ position: position,
+ onButtonPress: {
+ var bases: Set = EntityManager.sharedInstance.getBasesByTeam(for: .team2)
+ bases.forEach{ base in
+ if(base.unitType == .Defence){
+ base.unitType = .AttackDefence
+ }else {
+ base.unitType = .Attack
+ }
+ }})
+ super.init()
+ }
+
+
+
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
}
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/ButtonComponent.swift b/GoldWars/GoldWars/Components/ButtonComponent.swift
index 0fe059f..2c2d82a 100644
--- a/GoldWars/GoldWars/Components/ButtonComponent.swift
+++ b/GoldWars/GoldWars/Components/ButtonComponent.swift
@@ -18,6 +18,7 @@ class ButtonComponent: GKComponent {
isEnabled: isEnabled,
position: position,
onButtonPress: onButtonPress)
+ buttonNode.zPosition = 4
super.init()
}
diff --git a/GoldWars/GoldWars/Components/DefBoostSkillComponent.swift b/GoldWars/GoldWars/Components/DefBoostSkillComponent.swift
index 01c0aef..66ddba8 100644
--- a/GoldWars/GoldWars/Components/DefBoostSkillComponent.swift
+++ b/GoldWars/GoldWars/Components/DefBoostSkillComponent.swift
@@ -9,25 +9,29 @@
import GameplayKit
class DefBoostSkillComponent: GKComponent{
-
- let shapeNode: SKShapeNode
- let labelNode: SKLabelNode
-
- init(text: String, texture: SKTexture?, anchorPoint: CGPoint) {
- self.labelNode = SKLabelNode(text: text)
- self.shapeNode = SKShapeNode(circleOfRadius: 30)
- self.shapeNode.position = anchorPoint
- self.labelNode.position = CGPoint(x: anchorPoint.x, y: anchorPoint.y - 15)
- if texture != nil {
- shapeNode.fillTexture = texture
- }else {
- shapeNode.fillColor = SKColor.gray
- }
- super.init()
- }
-
- required init?(coder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
-
+
+ var skillButtonNode: SkillButtonNode
+
+ init(iconName: String, text: String, position: CGPoint, isEnabled:Bool) {
+ skillButtonNode = SkillButtonNode(iconName: iconName,
+ text: text,
+ isEnabled: isEnabled,
+ position: position,
+ onButtonPress: {
+ var bases: Set = EntityManager.sharedInstance.getBasesByTeam(for: .team2)
+ bases.forEach{ base in
+ if(base.unitType == .Attack){
+ base.unitType = .AttackDefence
+ }else {
+ base.unitType = .Defence
+ }
+ }
+ })
+ super.init()
+ }
+
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
}
diff --git a/GoldWars/GoldWars/Components/DefaultBaseComponent.swift b/GoldWars/GoldWars/Components/DefaultBaseComponent.swift
index 715840b..2510ad8 100644
--- a/GoldWars/GoldWars/Components/DefaultBaseComponent.swift
+++ b/GoldWars/GoldWars/Components/DefaultBaseComponent.swift
@@ -8,17 +8,28 @@
import GameplayKit
import SpriteKit
+import GameKit
class DefaultBaseComponent: GKComponent {
- var spriteNode: BaseNode
-
- init(texture: SKTexture, position: CGPoint) {
- spriteNode = BaseNode(texture: texture, size: CGSize(width: 80, height: 80))
- spriteNode.position = position
- super.init()
- }
-
- required init?(coder aDecoder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
+ var spriteNode: BaseNode
+ var labelNode : SKLabelNode?
+
+ init(texture: SKTexture, position: CGPoint) {
+ spriteNode = BaseNode(texture: texture, size: CGSize(width: 80, height: 80))
+ spriteNode.position = position
+ spriteNode.zPosition = 2
+ super.init()
+ labelNode = SKLabelNode(text: "")
+ labelNode?.fontColor = SKColor.black
+ labelNode?.horizontalAlignmentMode = .left
+ labelNode?.verticalAlignmentMode = .center
+ labelNode?.fontName = "AvenirNext-Bold"
+ labelNode?.fontSize = 15
+ labelNode?.position = CGPoint(x: position.x + 30 , y: position.y - 50 )
+ labelNode?.zPosition = spriteNode.zPosition - 1
+ }
+
+ required init?(coder aDecoder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
}
diff --git a/GoldWars/GoldWars/Components/DefaultWayComponent.swift b/GoldWars/GoldWars/Components/DefaultWayComponent.swift
new file mode 100644
index 0000000..045ac04
--- /dev/null
+++ b/GoldWars/GoldWars/Components/DefaultWayComponent.swift
@@ -0,0 +1,28 @@
+//
+// DefaultWayComponent.swift
+// GoldWars
+//
+// Created by Jakob Haag on 18.05.20.
+// Copyright © 2020 SP2. All rights reserved.
+//
+
+import Foundation
+import GameplayKit
+import SpriteKit
+
+class DefaultWayComponent: GKComponent {
+ var shapeNode: SKShapeNode
+
+ init(pathToDraw: CGMutablePath) {
+ self.shapeNode = SKShapeNode()
+ shapeNode.path = pathToDraw
+ shapeNode.strokeColor = UIColor(red: 0.852, green: 0.649, blue: 0.123, alpha: 1)
+ shapeNode.lineWidth = 10
+ shapeNode.zPosition = 0
+ super.init()
+ }
+
+ required init?(coder aDecoder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+}
diff --git a/GoldWars/GoldWars/Components/ModalBackgroundComponent.swift b/GoldWars/GoldWars/Components/ModalBackgroundComponent.swift
index e81fcf9..c7edfae 100644
--- a/GoldWars/GoldWars/Components/ModalBackgroundComponent.swift
+++ b/GoldWars/GoldWars/Components/ModalBackgroundComponent.swift
@@ -17,6 +17,7 @@ class ModalBackgroundComponent: GKComponent {
spriteNode = SKSpriteNode(texture: texture, size: texture.size())
spriteNode.setScale(2)
spriteNode.position = anchorPoint
+ spriteNode.zPosition = 3
super.init()
}
diff --git a/GoldWars/GoldWars/Components/ModalContentComponent.swift b/GoldWars/GoldWars/Components/ModalContentComponent.swift
index df004a3..23c301e 100644
--- a/GoldWars/GoldWars/Components/ModalContentComponent.swift
+++ b/GoldWars/GoldWars/Components/ModalContentComponent.swift
@@ -20,6 +20,7 @@ class ModalContentComponent: GKComponent{
self.header.position = CGPoint(x: anchorPoint.x, y: anchorPoint.y + 125)
self.header.fontName = "HelveticaNeue-Bold"
self.header.fontSize = 40
+ self.header.zPosition = 4
self.body = SKLabelNode(text: body)
self.body.position = CGPoint(x: anchorPoint.x, y: anchorPoint.y - 20)
@@ -28,11 +29,13 @@ class ModalContentComponent: GKComponent{
self.body.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.center
self.body.fontName = "HelveticaNeue-Bold"
self.body.fontSize = 40
+ self.body.zPosition = 4
self.footer = SKLabelNode(text: footer)
self.footer.position = CGPoint(x: anchorPoint.x, y: anchorPoint.y - 40)
self.footer.fontName = "HelveticaNeue-Bold"
self.footer.fontSize = 40
+ self.footer.zPosition = 4
super.init()
}
diff --git a/GoldWars/GoldWars/Components/PlayerInfoComponent.swift b/GoldWars/GoldWars/Components/PlayerInfoComponent.swift
new file mode 100644
index 0000000..d48b6e9
--- /dev/null
+++ b/GoldWars/GoldWars/Components/PlayerInfoComponent.swift
@@ -0,0 +1,61 @@
+//
+// PlayerInfoComponent.swift
+// GoldWars
+//
+// Created by Niko Jochim on 21.05.20.
+// Copyright © 2020 SP2. All rights reserved.
+//
+
+import Foundation
+import GameplayKit
+import GameKit
+
+
+class PlayerInfoComponent: GKComponent {
+
+ var hostLabel:SKLabelNode
+ var hostUnitsLabel:SKLabelNode
+
+ var peerLabel:SKLabelNode
+ var peerUnitsLabel:SKLabelNode
+ var host: GKPlayer?
+ var peer: GKPlayer?
+
+ init(size: CGSize) {
+ if MatchmakingHelper.sharedInstance.isServer {
+ host = GKLocalPlayer.local
+ peer = MatchmakingHelper.sharedInstance.mpMatch?.players[0]
+ } else {
+ host = MatchmakingHelper.sharedInstance.mpMatch?.players[0]
+ peer = GKLocalPlayer.local
+ }
+ hostLabel = SKLabelNode(text: host?.displayName)
+ hostUnitsLabel = SKLabelNode(text: "500" )
+ peerLabel = SKLabelNode(text: peer?.displayName)
+ peerUnitsLabel = SKLabelNode(text: "500")
+ super.init()
+ hostLabel.position = CGPoint(x: size.width * 0.02, y: size.height * 0.95)
+ hostLabel.horizontalAlignmentMode = .left
+ peerLabel.position = CGPoint(x: size.width * 0.98, y: size.height * 0.95)
+ peerLabel.horizontalAlignmentMode = .right
+ hostUnitsLabel.position = CGPoint(x: size.width * 0.05, y: size.height * 0.9)
+ peerUnitsLabel.position = CGPoint(x: size.width * 0.95, y: size.height * 0.9)
+ setColor(labelNodes: [hostLabel,hostUnitsLabel,peerLabel,peerUnitsLabel])
+ }
+
+ func update(){
+ hostUnitsLabel.text = "\(EntityManager.sharedInstance.getUnitSum(by: host!))"
+ peerUnitsLabel.text = "\(EntityManager.sharedInstance.getUnitSum(by: peer!))"
+ }
+
+ func setColor(labelNodes: [SKLabelNode]) -> Void {
+ for label in labelNodes {
+ label.fontColor = SKColor.black
+ }
+ }
+
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+}
diff --git a/GoldWars/GoldWars/Components/SkillButtonNode.swift b/GoldWars/GoldWars/Components/SkillButtonNode.swift
new file mode 100644
index 0000000..1decb06
--- /dev/null
+++ b/GoldWars/GoldWars/Components/SkillButtonNode.swift
@@ -0,0 +1,76 @@
+//
+// SkillButtonNode.swift
+// GoldWars
+//
+// Created by Simon Kellner on 18.05.20.
+// Copyright © 2020 SP2. All rights reserved.
+//
+
+import SpriteKit
+
+class SkillButtonNode: 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_circle")
+ super.init(texture: texture, color: SKColor.white, size: texture.size())
+ self.position = position
+
+ let label = SKLabelNode(fontNamed: "Courier-Bold")
+ label.fontSize = 30
+ label.fontColor = SKColor.black
+ label.zPosition = 1
+ label.verticalAlignmentMode = .center
+ label.text = text
+ label.name = "label"
+
+ if iconName.isEmpty {
+ label.position = CGPoint(x: 0, y: 0)
+ } else {
+ label.position = CGPoint(x: size.width * 0.5, y: 0)
+ let icon = SKSpriteNode(imageNamed: iconName)
+ icon.position = CGPoint(x: -size.width * 0.5, y: 0)
+ icon.zPosition = 1
+ self.addChild(icon)
+ }
+ self.addChild(label)
+ 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)
+ self.isEnabled = false
+ onButtonPress()
+ }
+ }
+
+
+ required init?(coder aDecoder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+}
diff --git a/GoldWars/GoldWars/Components/SliderComponent.swift b/GoldWars/GoldWars/Components/SliderComponent.swift
index dc46145..9682f10 100644
--- a/GoldWars/GoldWars/Components/SliderComponent.swift
+++ b/GoldWars/GoldWars/Components/SliderComponent.swift
@@ -14,6 +14,7 @@ class SliderComponent: GKComponent {
init(width: CGFloat, position: CGPoint) {
sliderNode = SliderNode(width: width, position: position)
+ sliderNode.zPosition = 4
super.init()
}
diff --git a/GoldWars/GoldWars/Components/SliderNode.swift b/GoldWars/GoldWars/Components/SliderNode.swift
index 93f42d2..2ae988e 100644
--- a/GoldWars/GoldWars/Components/SliderNode.swift
+++ b/GoldWars/GoldWars/Components/SliderNode.swift
@@ -26,6 +26,7 @@ class SliderNode :SKNode {
sliderLine = SKShapeNode(rectOf: CGSize(width: width, height: 8))
sliderLine.position = position
sliderLine.fillColor = SKColor.white
+ sliderLine.zPosition = 4
sliderKnob = SliderKnob(circleOfRadius: 20)
sliderKnob.min = position.x - width / 2
sliderKnob.max = position.x + width / 2
diff --git a/GoldWars/GoldWars/Components/SpinningLogoComponent.swift b/GoldWars/GoldWars/Components/SpinningLogoComponent.swift
new file mode 100644
index 0000000..ab01672
--- /dev/null
+++ b/GoldWars/GoldWars/Components/SpinningLogoComponent.swift
@@ -0,0 +1,45 @@
+//
+// SpinningLogoComponent.swift
+// GoldWars
+//
+// Created by Niko Jochim on 15.05.20.
+// Copyright © 2020 SP2. All rights reserved.
+//
+
+import Foundation
+import GameKit
+
+class SpinningLogoComponent: GKComponent{
+
+ var node : SK3DNode
+
+ init(position: CGPoint) {
+
+ let scnScene: SCNScene = {
+ let scnScene = SCNScene()
+ let cylinder = SCNCylinder(radius: 250, height: 50)
+ let logoMaterial = SCNMaterial()
+ let colorMaterial = SCNMaterial()
+ logoMaterial.diffuse.contents = UIImage(named: "logo_no_background")
+ colorMaterial.diffuse.contents = UIColor(red: 0.852, green: 0.649, blue: 0.123, alpha: 1)
+ cylinder.materials = [colorMaterial,logoMaterial,logoMaterial]
+ let cylinderNode = SCNNode(geometry: cylinder)
+ cylinderNode.eulerAngles = SCNVector3(x: Float(CGFloat.pi / 2), y: 0, z: Float(CGFloat.pi / 2))
+ let action = SCNAction.rotateBy(x: CGFloat(GLKMathDegreesToRadians(360)), y:0 , z: 0, duration: 8)
+ let forever = SCNAction.repeatForever(action)
+ cylinderNode.runAction(forever)
+ scnScene.rootNode.addChildNode(cylinderNode)
+ return scnScene
+ }()
+
+ self.node = SK3DNode(viewportSize: CGSize(width: 250, height: 250))
+ node.scnScene = scnScene
+ node.position = position
+ super.init()
+ }
+
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+}
diff --git a/GoldWars/GoldWars/Components/TeamComponent.swift b/GoldWars/GoldWars/Components/TeamComponent.swift
index 379a1cc..87562af 100644
--- a/GoldWars/GoldWars/Components/TeamComponent.swift
+++ b/GoldWars/GoldWars/Components/TeamComponent.swift
@@ -8,32 +8,44 @@
import SpriteKit
import GameplayKit
+import GameKit
class TeamComponent: GKComponent {
- let team: Team
+ var team: Team
+ var player: GKPlayer
let fire: SKEmitterNode
-
- init(team: Team, position: CGPoint) {
+
+ init(team: Team, player: GKPlayer, position: CGPoint) {
fire = SKEmitterNode(fileNamed: "Fire")!
- fire.zPosition = -1
+ 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
- case .team3: fire.particleColor = SKColor.green
- case .team4: fire.particleColor = SKColor.gray
- }
-
+
self.team = team
+ self.player = player
super.init()
+ fire.particleColor = getColor(by: team)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
+
+ func getColor(by team: Team) -> SKColor {
+ switch team {
+ case .team1: return SKColor.red
+ case .team2: return SKColor.purple
+ case .team3: return SKColor.green
+ case .team4: return SKColor.gray
+ }
+ }
+
+ func change(to team: Team, to player: GKPlayer) -> Void {
+ self.team = team
+ self.player = player
+ self.fire.particleColor = getColor(by: team)
+ }
}
diff --git a/GoldWars/GoldWars/Components/TimerComponent.swift b/GoldWars/GoldWars/Components/TimerComponent.swift
index 816ca04..3d2579c 100644
--- a/GoldWars/GoldWars/Components/TimerComponent.swift
+++ b/GoldWars/GoldWars/Components/TimerComponent.swift
@@ -9,12 +9,13 @@
import GameplayKit
class TimerComponent: GKComponent {
-
+
let labelNode :SKLabelNode
var endTime :Date!
var duration :Double
-
- init(text: String, anchorPoint: CGPoint, duration: TimeInterval) {
+ var isRunning = false
+
+ init(text: String, anchorPoint: CGPoint, duration: TimeInterval) {
self.labelNode = SKLabelNode(text: text)
self.labelNode.fontColor = UIColor.black
self.labelNode.fontSize = CGFloat(45)
@@ -25,15 +26,24 @@ class TimerComponent: GKComponent {
}
func startWithDuration(duration: TimeInterval){
+ isRunning = true
endTime = Date().addingTimeInterval(duration)
+ RoundCalculatorService.sharedInstance.isCalculating = false
}
func timeLeft() -> Int {
- let remainingSeconds = Int(endTime.timeIntervalSince(Date()))
- if(remainingSeconds < 0 ){
- startWithDuration(duration: duration)
+ if isRunning {
+ let remainingSeconds = Int(endTime.timeIntervalSince(Date()))
+ if(remainingSeconds == 0) {
+ isRunning = false
+ }
+ return remainingSeconds
}
- return remainingSeconds
+
+ // if(remainingSeconds < 0){
+ // startWithDuration(duration: duration)
+ // }
+ return 0
}
func isFinished() -> Bool {
@@ -45,12 +55,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/Components/WayNode.swift b/GoldWars/GoldWars/Components/WayNode.swift
new file mode 100644
index 0000000..41559a6
--- /dev/null
+++ b/GoldWars/GoldWars/Components/WayNode.swift
@@ -0,0 +1,25 @@
+//
+// WayNode.swift
+// GoldWars
+//
+// Created by Jakob Haag on 18.05.20.
+// Copyright © 2020 SP2. All rights reserved.
+//
+
+import SpriteKit
+
+class WayNode: SKSpriteNode{
+
+ override func touchesBegan(_ touches: Set, with event: UIEvent?) {
+ print("touched Way")
+ // TODO: PopUp Einheiten + Close PopUp
+ }
+
+ override func touchesMoved(_ touches: Set, with event: UIEvent?) {
+ // TODO: zeige Angirff Effect
+ }
+
+ override func touchesEnded(_ touches: Set, with event: UIEvent?) {
+ // TODO: Open Slider PopUp
+ }
+}
diff --git a/GoldWars/GoldWars/DataService.swift b/GoldWars/GoldWars/DataService.swift
new file mode 100644
index 0000000..d94a992
--- /dev/null
+++ b/GoldWars/GoldWars/DataService.swift
@@ -0,0 +1,78 @@
+//
+// 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?
+ var mapModel: MapGenerationModel?
+
+ 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
+ }
+
+ func setMapModel(model: MapGenerationModel) {
+ self.mapModel = model
+ MapFactory(scene: EntityManager.sharedInstance.scene, entityManager: EntityManager.sharedInstance).loadMap(fromModel: DataService.sharedInstance.mapModel!)
+ }
+}
diff --git a/GoldWars/GoldWars/Entities/Base.swift b/GoldWars/GoldWars/Entities/Base.swift
index 70fe75d..41078fa 100644
--- a/GoldWars/GoldWars/Entities/Base.swift
+++ b/GoldWars/GoldWars/Entities/Base.swift
@@ -8,32 +8,54 @@
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 changeOwnership: Bool
+ var ownershipPlayer: GKPlayer?
+ var baseID: Int
+ var position: CGPoint
- init(position: CGPoint, team: Team! = nil) {
+ init(position: CGPoint, player: GKPlayer! = nil, team: Team! = nil) {
self.unitCount = 0
+ self.unitType = .General
self.adjacencyList = [Base]()
- self.changeOwnerShip = false
+ self.changeOwnership = false
+ self.ownershipPlayer = player
+ self.baseID = Base.BASE_ID_COUNT
+ Base.BASE_ID_COUNT += 1
+ self.position = position
super.init()
- addComponent(DefaultBaseComponent(texture: SKTexture(imageNamed: "Base"), position: position))
- if(team != nil){
- addComponent(TeamComponent(team: team!, position: position))
+ let spritePos = position
+ addComponent(DefaultBaseComponent(texture: SKTexture(imageNamed: "Base"), position: spritePos))
+ if(team != nil && player != nil){
+ addComponent(TeamComponent(team: team!, player: player!, position: spritePos))
self.unitCount = 500
}
+ if ownershipPlayer == GKLocalPlayer.local {
+ self.component(ofType: DefaultBaseComponent.self)?.labelNode?.text = "\(unitCount)"
+ }
+
+
}
- func attackBase(base: Base, units:Int) -> [GKEntity]{
- base.changeOwnerShip = true
- self.unitCount -= units
- base.unitCount += units
- return [self, base]
- }
+ func doPlayerMoveTypeToBase(base: Base, playerMoveType: PlayerMoveType, units: Int) -> [GKEntity]{
+ base.changeOwnership = true
+ base.ownershipPlayer = self.ownershipPlayer
+ self.unitCount -= units
+ base.unitCount += units
+ self.component(ofType: DefaultBaseComponent.self)?.labelNode?.text = "\(self.unitCount)"
+ base.component(ofType: DefaultBaseComponent.self)?.labelNode?.text = "\(base.unitCount)"
+ DataService.sharedInstance.addMove(playerMove: PlayerMove(fromBase: self.baseID,
+ toBase: base.baseID,
+ unitCount: units * playerMoveType.rawValue))
+ 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 0f7166c..a1c69d3 100644
--- a/GoldWars/GoldWars/Entities/EntityManager.swift
+++ b/GoldWars/GoldWars/Entities/EntityManager.swift
@@ -8,47 +8,56 @@
import SpriteKit
import GameplayKit
+import GameKit
class EntityManager {
- var entities = Set()
- let scene: SKScene
- var isModal: Bool
+ static let sharedInstance = EntityManager()
- init(scene: SKScene) {
- self.scene = scene
- isModal = false
+ var entities = Set()
+ var scene: SKScene
+ var isModal: Bool
+
+ private init() {
+ isModal = false
+ scene = SKScene.init()
}
+ func setScene(scene: SKScene){
+ self.scene = scene
+ }
+
+
func add(_ entity: GKEntity) {
entities.insert(entity)
- if let spriteNode = entity.component(ofType: DefaultBaseComponent.self)?.spriteNode {
- scene.addChild(spriteNode)
- }
- if let fire = entity.component(ofType: TeamComponent.self)?.fire{
- scene.addChild(fire)
- }
- 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)
- scene.addChild(modal.body)
- scene.addChild(modal.footer)
- }
- if let skill = entity.component(ofType: AtkBoostSkillComponent.self) {
- scene.addChild(skill.shapeNode)
- scene.addChild(skill.labelNode)
- }
- if let skill = entity.component(ofType: DefBoostSkillComponent.self) {
- scene.addChild(skill.shapeNode)
- scene.addChild(skill.labelNode)
- }
- if let skill = entity.component(ofType: SpySkillComponent.self) {
- scene.addChild(skill.shapeNode)
- scene.addChild(skill.labelNode)
- }
+ if let spriteNode = entity.component(ofType: DefaultBaseComponent.self)?.spriteNode {
+ scene.addChild(spriteNode)
+ }
+ if let label = entity.component(ofType: DefaultBaseComponent.self)?.labelNode {
+ scene.addChild(label)
+ }
+ if let fire = entity.component(ofType: TeamComponent.self)?.fire{
+ scene.addChild(fire)
+ }
+ if let spriteNode = entity.component(ofType: ModalBackgroundComponent.self)?.spriteNode {
+ scene.addChild(spriteNode)
+ }
+ if let modal = entity.component(ofType: ModalContentComponent.self) {
+ scene.addChild(modal.header)
+ scene.addChild(modal.body)
+ scene.addChild(modal.footer)
+ isModal = true
+ }
+ if let skillButtonNode = entity.component(ofType: AtkBoostSkillComponent.self)?.skillButtonNode {
+ scene.addChild(skillButtonNode)
+ }
+ if let skillButtonNode = entity.component(ofType: DefBoostSkillComponent.self)?.skillButtonNode {
+ scene.addChild(skillButtonNode)
+ }
+ if let skill = entity.component(ofType: SpySkillComponent.self) {
+ scene.addChild(skill.shapeNode)
+ scene.addChild(skill.labelNode)
+ }
if let timer = entity.component(ofType: TimerComponent.self) {
scene.addChild(timer.labelNode)
}
@@ -60,82 +69,191 @@ class EntityManager {
scene.addChild(node)
}
}
- if let sliderNode = entity.component(ofType: SliderComponent.self)?.sliderNode {
- scene.addChild(sliderNode.sliderKnob)
- scene.addChild(sliderNode.sliderLine)
- }
+ if let sliderNode = entity.component(ofType: SliderComponent.self)?.sliderNode {
+ scene.addChild(sliderNode.sliderKnob)
+ scene.addChild(sliderNode.sliderLine)
+ }
+ if let labelNode = entity.component(ofType: LabelComponent.self)?.labelNode {
+ scene.addChild(labelNode)
+ }
+ if let cancelBtnNode = entity.component(ofType: CancelBtnComponent.self)?.cancelBtnNode {
+ scene.addChild(cancelBtnNode)
+ }
+ if let node = entity.component(ofType: SpinningLogoComponent.self)?.node {
+ scene.addChild(node)
+ }
+ if let wayNode = entity.component(ofType: DefaultWayComponent.self)?.shapeNode {
+ scene.addChild(wayNode)
+ }
+ if let playerInfos = entity.component(ofType: PlayerInfoComponent.self) {
+ scene.addChild(playerInfos.hostLabel)
+ scene.addChild(playerInfos.hostUnitsLabel)
+ scene.addChild(playerInfos.peerLabel)
+ scene.addChild(playerInfos.peerUnitsLabel)
+ }
}
func remove(_ entity: GKEntity) {
if let spriteNode = entity.component(ofType: DefaultBaseComponent.self)?.spriteNode {
spriteNode.removeFromParent()
}
- if let spriteNode = entity.component(ofType: ModalBackgroundComponent.self)?.spriteNode {
- spriteNode.removeFromParent()
- isModal = false
- }
- if let modal = entity.component(ofType: ModalContentComponent.self) {
- modal.header.removeFromParent()
- modal.body.removeFromParent()
- modal.footer.removeFromParent()
- }
- if let sliderNode = entity.component(ofType: SliderComponent.self)?.sliderNode {
- sliderNode.sliderKnob.removeFromParent()
- sliderNode.sliderLine.removeFromParent()
- }
+ if let spriteNode = entity.component(ofType: ModalBackgroundComponent.self)?.spriteNode {
+ spriteNode.removeFromParent()
+ }
+ if let modal = entity.component(ofType: ModalContentComponent.self) {
+ modal.header.removeFromParent()
+ modal.body.removeFromParent()
+ modal.footer.removeFromParent()
+ isModal = false
+ }
+ if let sliderNode = entity.component(ofType: SliderComponent.self)?.sliderNode {
+ sliderNode.sliderKnob.removeFromParent()
+ sliderNode.sliderLine.removeFromParent()
+ }
+ if let modalButton = entity.component(ofType: ButtonComponent.self) {
+ modalButton.buttonNode.removeFromParent()
+ }
+ if let cancelBtnNode = entity.component(ofType: CancelBtnComponent.self)?.cancelBtnNode {
+ cancelBtnNode.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),
- 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 {
+ if (entity.component(ofType: TeamComponent.self) != nil) {
+ entity.component(ofType: TeamComponent.self)!.change(to: (entities[0] as! Base).component(ofType: TeamComponent.self)!.team, to: (entities[0] as! Base).component(ofType: TeamComponent.self)!.player)
+ } else {
+ 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
+ }
+ }
+ }
+
+ 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!)
+ } else {
+ entity.removeComponent(ofType: TeamComponent.self)
+ }
+ if getOwnerBySnapBase != nil {
+ if getOwnerBySnapBase == GKLocalPlayer.local {
+ base.component(ofType: DefaultBaseComponent.self)?.labelNode?.text = "\(base.unitCount)"
+ }else {
+ base.component(ofType: DefaultBaseComponent.self)?.labelNode?.text = ""
+ }
+ base.changeOwnership = true
+ base.ownershipPlayer = getOwnerBySnapBase
+ if (entity.component(ofType: TeamComponent.self) != nil) {
+ entity.component(ofType: TeamComponent.self)!.change(to: getTeamByPlayer(playerName: snapBase.ownership!), to: getOwnerBySnapBase!)
+ } else {
+ 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)
+ }
+ }
+ }
+ }
+
+ getHUD()?.component(ofType: PlayerInfoComponent.self)?.update()
+
+ }
+
+ func getSnapshotBaseById(baseId: Int, snapshotModel: SnapshotModel) -> BaseEntityModel{
+ return snapshotModel.baseEntites.filter { $0.baseId == baseId }[0]
+ }
+
+ func getBaseByPlayer(for player: GKPlayer) -> GKEntity? {
+ for entity in entities {
+ if let teamComponent = entity.component(ofType: TeamComponent.self),
+ let _ = entity.component(ofType: DefaultBaseComponent.self) {
+ if teamComponent.player == player {
+ return entity
+ }
+ }
+ }
+ return nil
+ }
+
+ 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
- }
- }
- }
- return nil
+ }
+ }
+ }
+ return nil
}
-
+
func getBasesByTeam(for team: Team) -> Set {
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 getBasesByPlayer(for player: GKPlayer) -> Set {
+ return entities.filter{$0 is Base && ($0 as! Base).component(ofType: TeamComponent.self)?.player == player } 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 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]
}
-
- func getBaseNodeByTeam(for team: Team) -> SKSpriteNode? {
- return getBaseByTeam(for: team)?.component(ofType: DefaultBaseComponent.self)?.spriteNode
- }
-
+
+ func getBaseNodeByTeam(for team: Team) -> SKSpriteNode? {
+ return getBaseByTeam(for: team)?.component(ofType: DefaultBaseComponent.self)?.spriteNode
+ }
+
func getButtonByName(buttonName:String) -> Button {
return entities.filter{$0 is Button && ($0 as! Button).name == buttonName }[0] as! Button
}
@@ -143,4 +261,29 @@ 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)
+ }
+
+ func getTimer() -> TimerComponent {
+ return entities.filter{$0 is HUD}[0].component(ofType: TimerComponent.self)!
+ }
+ func getUnitSum(by player: GKPlayer) -> Int{
+ let bases = getBasesByPlayer(for: player)
+
+ var sum = 0
+ for base in bases {
+ sum += base.unitCount
+ }
+ return sum
+ }
}
diff --git a/GoldWars/GoldWars/Entities/HUD.swift b/GoldWars/GoldWars/Entities/HUD.swift
index a161285..e2da8bf 100644
--- a/GoldWars/GoldWars/Entities/HUD.swift
+++ b/GoldWars/GoldWars/Entities/HUD.swift
@@ -9,29 +9,28 @@
import GameplayKit
class HUD: GKEntity {
-
- init(size: CGSize) {
- super.init()
- addComponent(SpySkillComponent(text: "Spy",
- texture: nil,
- anchorPoint: CGPoint(x: size.width * 0.75, y: size.height * 0.1)))
-
-
- addComponent(AtkBoostSkillComponent(text: "Atk",
- texture: nil,
- anchorPoint: CGPoint(x: size.width * 0.85, y: size.height * 0.1)))
-
-
- addComponent(DefBoostSkillComponent(text: "Def",
- texture: nil,
- anchorPoint: CGPoint(x: size.width * 0.95, y: size.height * 0.1)))
+
+ init(size: CGSize) {
+ super.init()
+ addComponent(SpySkillComponent(text: "Spy",
+ texture: nil,
+ anchorPoint: CGPoint(x: size.width * 0.75, y: size.height * 0.1)))
+
+
+ addComponent(AtkBoostSkillComponent(iconName: "", text: "Atk", position: CGPoint(x: size.width * 0.85, y: size.height * 0.1), isEnabled: true))
+
+
+ addComponent(DefBoostSkillComponent(iconName: "", text: "Def", position: CGPoint(x: size.width * 0.95, y: size.height * 0.1), isEnabled: true))
addComponent(TimerComponent(text: "",
- anchorPoint: CGPoint(x: size.width * 0.5, y: size.height * 0.9), duration: 30))
- }
-
- required init?(coder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
-
+ anchorPoint: CGPoint(x: size.width * 0.5, y: size.height * 0.9), duration: 30))
+
+ addComponent(PlayerInfoComponent(size: size))
+
+ }
+
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
}
diff --git a/GoldWars/GoldWars/Entities/Modal.swift b/GoldWars/GoldWars/Entities/Modal.swift
index cdafa53..489aed4 100644
--- a/GoldWars/GoldWars/Entities/Modal.swift
+++ b/GoldWars/GoldWars/Entities/Modal.swift
@@ -9,31 +9,57 @@
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))
- 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, gameScene: GameScene, currentDraggedBase: Base?, touchLocation: CGPoint, collisionBase: Base?) {
+ 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(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.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)
+ }))
+ }
+ }
+
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+ 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"){
+ child.alpha = 1
+ }
+ }
+ }
+ }
+
+ 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)))!)
+ GameScene.sendUnits = 0
+ }
+ }
+ }
}
diff --git a/GoldWars/GoldWars/Entities/SpinningLogoEntity.swift b/GoldWars/GoldWars/Entities/SpinningLogoEntity.swift
new file mode 100644
index 0000000..0e84923
--- /dev/null
+++ b/GoldWars/GoldWars/Entities/SpinningLogoEntity.swift
@@ -0,0 +1,22 @@
+//
+// SpinningLogoEntity.swift
+// GoldWars
+//
+// Created by Niko Jochim on 15.05.20.
+// Copyright © 2020 SP2. All rights reserved.
+//
+
+import Foundation
+import GameplayKit
+
+class SpinningLogoEntity: GKEntity {
+
+ init(position: CGPoint) {
+ super.init()
+ self.addComponent(SpinningLogoComponent(position: position))
+ }
+
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+}
diff --git a/GoldWars/GoldWars/Entities/Way.swift b/GoldWars/GoldWars/Entities/Way.swift
new file mode 100644
index 0000000..6a64eb6
--- /dev/null
+++ b/GoldWars/GoldWars/Entities/Way.swift
@@ -0,0 +1,30 @@
+//
+// Way.swift
+// GoldWars
+//
+// Created by Jakob Haag on 18.05.20.
+// Copyright © 2020 SP2. All rights reserved.
+//
+
+import Foundation
+import SpriteKit
+import GameplayKit
+
+class Way: GKEntity {
+
+ required init(fromBase: Base, toBase: Base) {
+ super.init()
+
+ let pathToDraw = CGMutablePath()
+ pathToDraw.move(to: fromBase.position)
+ pathToDraw.addLine(to: toBase.position)
+
+
+ addComponent(DefaultWayComponent(pathToDraw: pathToDraw))
+ }
+
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+}
+
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/Enums/Unit.swift b/GoldWars/GoldWars/Enums/UnitType.swift
similarity index 83%
rename from GoldWars/GoldWars/Enums/Unit.swift
rename to GoldWars/GoldWars/Enums/UnitType.swift
index a4fa851..aec5ccd 100644
--- a/GoldWars/GoldWars/Enums/Unit.swift
+++ b/GoldWars/GoldWars/Enums/UnitType.swift
@@ -6,8 +6,9 @@
// Copyright © 2020 SP2. All rights reserved.
//
-enum Unit{
+enum UnitType{
case General
case Defence
case Attack
+ case AttackDefence
}
diff --git a/GoldWars/GoldWars/GameViewController.swift b/GoldWars/GoldWars/GameViewController.swift
index e4a2f43..05b2706 100644
--- a/GoldWars/GoldWars/GameViewController.swift
+++ b/GoldWars/GoldWars/GameViewController.swift
@@ -11,7 +11,7 @@ import SpriteKit
import GameplayKit
class GameViewController: UIViewController {
-
+
override func viewDidLoad() {
super.viewDidLoad()
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/CElements.swift b/GoldWars/GoldWars/Map/CElements.swift
new file mode 100644
index 0000000..22fc4dc
--- /dev/null
+++ b/GoldWars/GoldWars/Map/CElements.swift
@@ -0,0 +1,1349 @@
+//
+// CElemente.swift
+// GoldWars
+//
+// Created by Jakob Haag on 18.05.20.
+// Copyright © 2020 SP2. All rights reserved.
+//
+
+import SpriteKit
+
+class CElement0: CenterElementProtocol {
+
+ var bases: [Base] = []
+ var centerBase: Base
+ var ways: [Way] = []
+ var id: Int = 0
+
+ required init(frame: CGRect) {
+ self.centerBase = Base(
+ position: CGPoint(
+ x: frame.midX,
+ y: frame.midY
+ )
+ )
+ self.bases.append(centerBase)
+ }
+
+ func getAllBases() -> [Base] {
+ return self.bases
+ }
+
+ func getInternalWays() -> [Way] {
+ return self.ways
+ }
+
+ func getTopConnection() -> Base? {
+ return self.centerBase
+ }
+
+ func getRightConnection() -> Base? {
+ return self.centerBase
+ }
+
+ func getBottomConnection() -> Base? {
+ return self.centerBase
+ }
+
+ func getLeftConnection() -> Base? {
+ return self.centerBase
+ }
+}
+
+class CElement1: CenterElementProtocol {
+ var bases: [Base] = []
+ var leftBase: Base
+ var rightBase: Base
+ var ways: [Way] = []
+ var id: Int = 1
+
+ required init(frame: CGRect) {
+ self.leftBase = Base(
+ position: CGPoint(
+ x: frame.minX,
+ y: frame.midY
+ )
+ )
+
+ self.rightBase = Base(
+ position: CGPoint(
+ x: frame.maxX,
+ y: frame.midY
+ )
+ )
+ self.bases.append(leftBase)
+ self.bases.append(rightBase)
+
+ self.connectInnerBases()
+ self.createInternalWays()
+ }
+
+ func connectInnerBases() {
+ self.leftBase.adjacencyList.append(self.rightBase)
+ self.rightBase.adjacencyList.append(self.leftBase)
+ }
+
+ func createInternalWays() {
+ ways.append(Way(fromBase: self.leftBase, toBase: self.rightBase))
+ }
+
+ func getAllBases() -> [Base] {
+ return self.bases
+ }
+
+ func getInternalWays() -> [Way] {
+ return self.ways
+ }
+
+ func getTopConnection() -> Base? {
+ return self.leftBase
+ }
+
+ func getRightConnection() -> Base? {
+ return self.rightBase
+ }
+
+ func getBottomConnection() -> Base? {
+ return self.rightBase
+ }
+
+ func getLeftConnection() -> Base? {
+ return self.leftBase
+ }
+}
+
+class CElement2: CenterElementProtocol {
+ var bases: [Base] = []
+ var leftBase: Base
+ var rightBase: Base
+ var ways: [Way] = []
+ var id: Int = 2
+
+ required init(frame: CGRect) {
+ self.leftBase = Base(
+ position: CGPoint(
+ x: frame.minX,
+ y: frame.midY
+ )
+ )
+
+ self.rightBase = Base(
+ position: CGPoint(
+ x: frame.maxX,
+ y: frame.midY
+ )
+ )
+ self.bases.append(leftBase)
+ self.bases.append(rightBase)
+
+ self.connectInnerBases()
+ self.createInternalWays()
+ }
+
+ func connectInnerBases() {
+ self.leftBase.adjacencyList.append(self.rightBase)
+ self.rightBase.adjacencyList.append(self.leftBase)
+ }
+
+ func createInternalWays() {
+ ways.append(Way(fromBase: self.leftBase, toBase: self.rightBase))
+ }
+
+ func getAllBases() -> [Base] {
+ return self.bases
+ }
+
+ func getInternalWays() -> [Way] {
+ return self.ways
+ }
+
+ func getTopConnection() -> Base? {
+ return self.rightBase
+ }
+
+ func getRightConnection() -> Base? {
+ return self.rightBase
+ }
+
+ func getBottomConnection() -> Base? {
+ return self.leftBase
+ }
+
+ func getLeftConnection() -> Base? {
+ return self.leftBase
+ }
+}
+
+class CElement3: CenterElementProtocol {
+ var bases: [Base] = []
+ var centerBase: Base
+ var leftBase: Base
+ var rightBase: Base
+ var ways: [Way] = []
+ var id: Int = 3
+
+ required init(frame: CGRect) {
+ self.centerBase = Base(
+ position: CGPoint(
+ x: frame.midX,
+ y: frame.maxY
+ )
+ )
+
+ self.leftBase = Base(
+ position: CGPoint(
+ x: frame.minX,
+ y: frame.minY
+ )
+ )
+
+ self.rightBase = Base(
+ position: CGPoint(
+ x: frame.maxX,
+ y: frame.minY
+ )
+ )
+ self.bases.append(centerBase)
+ self.bases.append(leftBase)
+ self.bases.append(rightBase)
+
+ self.connectInnerBases()
+ self.createInternalWays()
+ }
+
+ func connectInnerBases() {
+ self.leftBase.adjacencyList.append(self.rightBase)
+ self.leftBase.adjacencyList.append(self.centerBase)
+ self.rightBase.adjacencyList.append(self.leftBase)
+ self.rightBase.adjacencyList.append(self.centerBase)
+ self.centerBase.adjacencyList.append(self.leftBase)
+ self.centerBase.adjacencyList.append(self.rightBase)
+ }
+
+ func createInternalWays() {
+ ways.append(Way(fromBase: self.leftBase, toBase: self.rightBase))
+ ways.append(Way(fromBase: self.centerBase, toBase: self.rightBase))
+ ways.append(Way(fromBase: self.centerBase, toBase: self.leftBase))
+ }
+
+ func getAllBases() -> [Base] {
+ return self.bases
+ }
+
+ func getInternalWays() -> [Way] {
+ return self.ways
+ }
+
+ func getTopConnection() -> Base? {
+ return self.leftBase
+ }
+
+ func getRightConnection() -> Base? {
+ return self.rightBase
+ }
+
+ func getBottomConnection() -> Base? {
+ return self.centerBase
+ }
+
+ func getLeftConnection() -> Base? {
+ return self.leftBase
+ }
+}
+
+class CElement4: CenterElementProtocol {
+ var bases: [Base] = []
+ var centerBase: Base
+ var leftBase: Base
+ var rightBase: Base
+ var ways: [Way] = []
+ var id: Int = 4
+
+ required init(frame: CGRect) {
+ self.centerBase = Base(
+ position: CGPoint(
+ x: frame.midX,
+ y: frame.maxY
+ )
+ )
+
+ self.leftBase = Base(
+ position: CGPoint(
+ x: frame.minX,
+ y: frame.minY
+ )
+ )
+
+ self.rightBase = Base(
+ position: CGPoint(
+ x: frame.maxX,
+ y: frame.minY
+ )
+ )
+ self.bases.append(centerBase)
+ self.bases.append(leftBase)
+ self.bases.append(rightBase)
+
+ self.connectInnerBases()
+ self.createInternalWays()
+ }
+
+ func connectInnerBases() {
+ self.leftBase.adjacencyList.append(self.rightBase)
+ self.leftBase.adjacencyList.append(self.centerBase)
+ self.rightBase.adjacencyList.append(self.leftBase)
+ self.rightBase.adjacencyList.append(self.centerBase)
+ self.centerBase.adjacencyList.append(self.leftBase)
+ self.centerBase.adjacencyList.append(self.rightBase)
+ }
+
+ func createInternalWays() {
+ ways.append(Way(fromBase: self.leftBase, toBase: self.rightBase))
+ ways.append(Way(fromBase: self.centerBase, toBase: self.rightBase))
+ ways.append(Way(fromBase: self.centerBase, toBase: self.leftBase))
+ }
+
+ func getAllBases() -> [Base] {
+ return self.bases
+ }
+
+ func getInternalWays() -> [Way] {
+ return self.ways
+ }
+
+ func getTopConnection() -> Base? {
+ return self.rightBase
+ }
+
+ func getRightConnection() -> Base? {
+ return self.rightBase
+ }
+
+ func getBottomConnection() -> Base? {
+ return self.centerBase
+ }
+
+ func getLeftConnection() -> Base? {
+ return self.leftBase
+ }
+}
+
+class CElement5: CenterElementProtocol {
+ var bases: [Base] = []
+ var centerBase: Base
+ var leftBase: Base
+ var rightBase: Base
+ var ways: [Way] = []
+ var id: Int = 5
+
+ required init(frame: CGRect) {
+ self.centerBase = Base(
+ position: CGPoint(
+ x: frame.midX,
+ y: frame.minY
+ )
+ )
+
+ self.leftBase = Base(
+ position: CGPoint(
+ x: frame.minX,
+ y: frame.maxY
+ )
+ )
+
+ self.rightBase = Base(
+ position: CGPoint(
+ x: frame.maxX,
+ y: frame.maxY
+ )
+ )
+ self.bases.append(centerBase)
+ self.bases.append(leftBase)
+ self.bases.append(rightBase)
+
+ self.connectInnerBases()
+ self.createInternalWays()
+ }
+
+ func connectInnerBases() {
+ self.leftBase.adjacencyList.append(self.rightBase)
+ self.leftBase.adjacencyList.append(self.centerBase)
+ self.rightBase.adjacencyList.append(self.leftBase)
+ self.rightBase.adjacencyList.append(self.centerBase)
+ self.centerBase.adjacencyList.append(self.leftBase)
+ self.centerBase.adjacencyList.append(self.rightBase)
+ }
+
+ func createInternalWays() {
+ ways.append(Way(fromBase: self.leftBase, toBase: self.rightBase))
+ ways.append(Way(fromBase: self.centerBase, toBase: self.rightBase))
+ ways.append(Way(fromBase: self.centerBase, toBase: self.leftBase))
+ }
+
+ func getAllBases() -> [Base] {
+ return self.bases
+ }
+
+ func getInternalWays() -> [Way] {
+ return self.ways
+ }
+
+ func getTopConnection() -> Base? {
+ return self.centerBase
+ }
+
+ func getRightConnection() -> Base? {
+ return self.rightBase
+ }
+
+ func getBottomConnection() -> Base? {
+ return self.leftBase
+ }
+
+ func getLeftConnection() -> Base? {
+ return self.leftBase
+ }
+}
+
+class CElement6: CenterElementProtocol {
+ var bases: [Base] = []
+ var centerBase: Base
+ var leftBase: Base
+ var rightBase: Base
+ var ways: [Way] = []
+ var id: Int = 6
+
+ required init(frame: CGRect) {
+ self.centerBase = Base(
+ position: CGPoint(
+ x: frame.midX,
+ y: frame.minY
+ )
+ )
+
+ self.leftBase = Base(
+ position: CGPoint(
+ x: frame.minX,
+ y: frame.maxY
+ )
+ )
+
+ self.rightBase = Base(
+ position: CGPoint(
+ x: frame.maxX,
+ y: frame.maxY
+ )
+ )
+ self.bases.append(centerBase)
+ self.bases.append(leftBase)
+ self.bases.append(rightBase)
+
+ self.connectInnerBases()
+ self.createInternalWays()
+ }
+
+ func connectInnerBases() {
+ self.leftBase.adjacencyList.append(self.rightBase)
+ self.leftBase.adjacencyList.append(self.centerBase)
+ self.rightBase.adjacencyList.append(self.leftBase)
+ self.rightBase.adjacencyList.append(self.centerBase)
+ self.centerBase.adjacencyList.append(self.leftBase)
+ self.centerBase.adjacencyList.append(self.rightBase)
+ }
+
+ func createInternalWays() {
+ ways.append(Way(fromBase: self.leftBase, toBase: self.rightBase))
+ ways.append(Way(fromBase: self.centerBase, toBase: self.rightBase))
+ ways.append(Way(fromBase: self.centerBase, toBase: self.leftBase))
+ }
+
+ func getAllBases() -> [Base] {
+ return self.bases
+ }
+
+ func getInternalWays() -> [Way] {
+ return self.ways
+ }
+
+ func getTopConnection() -> Base? {
+ return self.centerBase
+ }
+
+ func getRightConnection() -> Base? {
+ return self.rightBase
+ }
+
+ func getBottomConnection() -> Base? {
+ return self.rightBase
+ }
+
+ func getLeftConnection() -> Base? {
+ return self.leftBase
+ }
+}
+
+class CElement7: CenterElementProtocol {
+ var bases: [Base] = []
+ var topBase: Base
+ var bottomBase: Base
+ var leftBase: Base
+ var rightBase: Base
+ var ways: [Way] = []
+ var id: Int = 7
+
+ required init(frame: CGRect) {
+ self.topBase = Base(
+ position: CGPoint(
+ x: frame.midX,
+ y: frame.minY
+ )
+ )
+
+ self.bottomBase = Base(
+ position: CGPoint(
+ x: frame.midX,
+ y: frame.maxY
+ )
+ )
+
+ self.leftBase = Base(
+ position: CGPoint(
+ x: frame.minX,
+ y: frame.midY
+ )
+ )
+
+ self.rightBase = Base(
+ position: CGPoint(
+ x: frame.maxX,
+ y: frame.midY
+ )
+ )
+ self.bases.append(topBase)
+ self.bases.append(bottomBase)
+ self.bases.append(leftBase)
+ self.bases.append(rightBase)
+
+ self.connectInnerBases()
+ self.createInternalWays()
+ }
+
+ func connectInnerBases() {
+ self.leftBase.adjacencyList.append(self.rightBase)
+ self.leftBase.adjacencyList.append(self.topBase)
+ self.leftBase.adjacencyList.append(self.bottomBase)
+ self.rightBase.adjacencyList.append(self.leftBase)
+ self.rightBase.adjacencyList.append(self.topBase)
+ self.rightBase.adjacencyList.append(self.bottomBase)
+ self.topBase.adjacencyList.append(self.leftBase)
+ self.topBase.adjacencyList.append(self.rightBase)
+ self.topBase.adjacencyList.append(self.bottomBase)
+ self.bottomBase.adjacencyList.append(self.topBase)
+ self.bottomBase.adjacencyList.append(self.rightBase)
+ self.bottomBase.adjacencyList.append(self.leftBase)
+ }
+
+ func createInternalWays() {
+ ways.append(Way(fromBase: self.topBase, toBase: self.rightBase))
+ ways.append(Way(fromBase: self.topBase, toBase: self.leftBase))
+ ways.append(Way(fromBase: self.bottomBase, toBase: self.rightBase))
+ ways.append(Way(fromBase: self.bottomBase, toBase: self.leftBase))
+ }
+
+ func getAllBases() -> [Base] {
+ return self.bases
+ }
+
+ func getInternalWays() -> [Way] {
+ return self.ways
+ }
+
+ func getTopConnection() -> Base? {
+ return self.topBase
+ }
+
+ func getRightConnection() -> Base? {
+ return self.rightBase
+ }
+
+ func getBottomConnection() -> Base? {
+ return self.bottomBase
+ }
+
+ func getLeftConnection() -> Base? {
+ return self.leftBase
+ }
+}
+
+class CElement8: CenterElementProtocol {
+ var bases: [Base] = []
+ var leftBase: Base
+ var rightBase: Base
+ var ways: [Way] = []
+ var id: Int = 8
+
+ required init(frame: CGRect) {
+ self.leftBase = Base(
+ position: CGPoint(
+ x: frame.minX,
+ y: frame.midY
+ )
+ )
+
+ self.rightBase = Base(
+ position: CGPoint(
+ x: frame.maxX,
+ y: frame.midY
+ )
+ )
+ self.bases.append(leftBase)
+ self.bases.append(rightBase)
+
+ self.connectInnerBases()
+ self.createInternalWays()
+ }
+
+ func connectInnerBases() {
+ self.leftBase.adjacencyList.append(self.rightBase)
+ self.rightBase.adjacencyList.append(self.leftBase)
+ }
+
+ func createInternalWays() {
+ ways.append(Way(fromBase: self.leftBase, toBase: self.rightBase))
+ }
+
+ func getAllBases() -> [Base] {
+ return self.bases
+ }
+
+ func getInternalWays() -> [Way] {
+ return self.ways
+ }
+
+ func getTopConnection() -> Base? {
+ return self.leftBase
+ }
+
+ func getRightConnection() -> Base? {
+ return self.rightBase
+ }
+
+ func getBottomConnection() -> Base? {
+ return nil
+ }
+
+ func getLeftConnection() -> Base? {
+ return self.leftBase
+ }
+}
+
+class CElement9: CenterElementProtocol {
+ var bases: [Base] = []
+ var leftBase: Base
+ var rightBase: Base
+ var ways: [Way] = []
+ var id: Int = 9
+
+ required init(frame: CGRect) {
+ self.leftBase = Base(
+ position: CGPoint(
+ x: frame.minX,
+ y: frame.midY
+ )
+ )
+
+ self.rightBase = Base(
+ position: CGPoint(
+ x: frame.maxX,
+ y: frame.midY
+ )
+ )
+ self.bases.append(leftBase)
+ self.bases.append(rightBase)
+
+ self.connectInnerBases()
+ self.createInternalWays()
+ }
+
+ func connectInnerBases() {
+ self.leftBase.adjacencyList.append(self.rightBase)
+ self.rightBase.adjacencyList.append(self.leftBase)
+ }
+
+ func createInternalWays() {
+ ways.append(Way(fromBase: self.leftBase, toBase: self.rightBase))
+ }
+
+ func getAllBases() -> [Base] {
+ return self.bases
+ }
+
+ func getInternalWays() -> [Way] {
+ return self.ways
+ }
+
+ func getTopConnection() -> Base? {
+ return nil
+ }
+
+ func getRightConnection() -> Base? {
+ return self.rightBase
+ }
+
+ func getBottomConnection() -> Base? {
+ return self.rightBase
+ }
+
+ func getLeftConnection() -> Base? {
+ return self.leftBase
+ }
+}
+
+class CElement10: CenterElementProtocol {
+ var bases: [Base] = []
+ var leftBase: Base
+ var rightBase: Base
+ var ways: [Way] = []
+ var id: Int = 10
+
+ required init(frame: CGRect) {
+ self.leftBase = Base(
+ position: CGPoint(
+ x: frame.minX,
+ y: frame.midY
+ )
+ )
+
+ self.rightBase = Base(
+ position: CGPoint(
+ x: frame.maxX,
+ y: frame.midY
+ )
+ )
+ self.bases.append(leftBase)
+ self.bases.append(rightBase)
+
+ self.connectInnerBases()
+ self.createInternalWays()
+ }
+
+ func connectInnerBases() {
+ self.leftBase.adjacencyList.append(self.rightBase)
+ self.rightBase.adjacencyList.append(self.leftBase)
+ }
+
+ func createInternalWays() {
+ ways.append(Way(fromBase: self.leftBase, toBase: self.rightBase))
+ }
+
+ func getAllBases() -> [Base] {
+ return self.bases
+ }
+
+ func getInternalWays() -> [Way] {
+ return self.ways
+ }
+
+ func getTopConnection() -> Base? {
+ return self.rightBase
+ }
+
+ func getRightConnection() -> Base? {
+ return self.rightBase
+ }
+
+ func getBottomConnection() -> Base? {
+ return nil
+ }
+
+ func getLeftConnection() -> Base? {
+ return self.leftBase
+ }
+}
+
+class CElement11: CenterElementProtocol {
+ var bases: [Base] = []
+ var centerBase: Base
+ var leftBase: Base
+ var rightBase: Base
+ var ways: [Way] = []
+ var id: Int = 11
+
+ required init(frame: CGRect) {
+ self.centerBase = Base(
+ position: CGPoint(
+ x: frame.midX,
+ y: frame.maxY
+ )
+ )
+
+ self.leftBase = Base(
+ position: CGPoint(
+ x: frame.minX,
+ y: frame.minY
+ )
+ )
+
+ self.rightBase = Base(
+ position: CGPoint(
+ x: frame.maxX,
+ y: frame.minY
+ )
+ )
+ self.bases.append(centerBase)
+ self.bases.append(leftBase)
+ self.bases.append(rightBase)
+
+ self.connectInnerBases()
+ self.createInternalWays()
+ }
+
+ func connectInnerBases() {
+ self.leftBase.adjacencyList.append(self.rightBase)
+ self.leftBase.adjacencyList.append(self.centerBase)
+ self.rightBase.adjacencyList.append(self.leftBase)
+ self.rightBase.adjacencyList.append(self.centerBase)
+ self.centerBase.adjacencyList.append(self.leftBase)
+ self.centerBase.adjacencyList.append(self.rightBase)
+ }
+
+ func createInternalWays() {
+ ways.append(Way(fromBase: self.leftBase, toBase: self.rightBase))
+ ways.append(Way(fromBase: self.centerBase, toBase: self.leftBase))
+ ways.append(Way(fromBase: self.centerBase, toBase: self.rightBase))
+ }
+
+ func getAllBases() -> [Base] {
+ return self.bases
+ }
+
+ func getInternalWays() -> [Way] {
+ return self.ways
+ }
+
+ func getTopConnection() -> Base? {
+ return nil
+ }
+
+ func getRightConnection() -> Base? {
+ return self.rightBase
+ }
+
+ func getBottomConnection() -> Base? {
+ return self.centerBase
+ }
+
+ func getLeftConnection() -> Base? {
+ return self.leftBase
+ }
+}
+
+class CElement12: CenterElementProtocol {
+ var bases: [Base] = []
+ var centerBase: Base
+ var leftBase: Base
+ var rightBase: Base
+ var ways: [Way] = []
+ var id: Int = 12
+
+ required init(frame: CGRect) {
+ self.centerBase = Base(
+ position: CGPoint(
+ x: frame.midX,
+ y: frame.maxY
+ )
+ )
+
+ self.leftBase = Base(
+ position: CGPoint(
+ x: frame.minX,
+ y: frame.minY
+ )
+ )
+
+ self.rightBase = Base(
+ position: CGPoint(
+ x: frame.maxX,
+ y: frame.minY
+ )
+ )
+ self.bases.append(centerBase)
+ self.bases.append(leftBase)
+ self.bases.append(rightBase)
+
+ self.connectInnerBases()
+ self.createInternalWays()
+ }
+
+ func connectInnerBases() {
+ self.leftBase.adjacencyList.append(self.rightBase)
+ self.leftBase.adjacencyList.append(self.centerBase)
+ self.rightBase.adjacencyList.append(self.leftBase)
+ self.rightBase.adjacencyList.append(self.centerBase)
+ self.centerBase.adjacencyList.append(self.leftBase)
+ self.centerBase.adjacencyList.append(self.rightBase)
+ }
+
+ func createInternalWays() {
+ ways.append(Way(fromBase: self.leftBase, toBase: self.rightBase))
+ ways.append(Way(fromBase: self.centerBase, toBase: self.leftBase))
+ ways.append(Way(fromBase: self.centerBase, toBase: self.rightBase))
+ }
+
+ func getAllBases() -> [Base] {
+ return self.bases
+ }
+
+ func getInternalWays() -> [Way] {
+ return self.ways
+ }
+
+ func getTopConnection() -> Base? {
+ return self.rightBase
+ }
+
+ func getRightConnection() -> Base? {
+ return self.rightBase
+ }
+
+ func getBottomConnection() -> Base? {
+ return nil
+ }
+
+ func getLeftConnection() -> Base? {
+ return self.leftBase
+ }
+}
+
+class CElement13: CenterElementProtocol {
+ var bases: [Base] = []
+ var centerBase: Base
+ var leftBase: Base
+ var rightBase: Base
+ var ways: [Way] = []
+ var id: Int = 13
+
+ required init(frame: CGRect) {
+ self.centerBase = Base(
+ position: CGPoint(
+ x: frame.midX,
+ y: frame.minY
+ )
+ )
+
+ self.leftBase = Base(
+ position: CGPoint(
+ x: frame.minX,
+ y: frame.maxY
+ )
+ )
+
+ self.rightBase = Base(
+ position: CGPoint(
+ x: frame.maxX,
+ y: frame.maxY
+ )
+ )
+ self.bases.append(centerBase)
+ self.bases.append(leftBase)
+ self.bases.append(rightBase)
+
+ self.connectInnerBases()
+ self.createInternalWays()
+ }
+
+ func connectInnerBases() {
+ self.leftBase.adjacencyList.append(self.rightBase)
+ self.leftBase.adjacencyList.append(self.centerBase)
+ self.rightBase.adjacencyList.append(self.leftBase)
+ self.rightBase.adjacencyList.append(self.centerBase)
+ self.centerBase.adjacencyList.append(self.leftBase)
+ self.centerBase.adjacencyList.append(self.rightBase)
+ }
+
+ func createInternalWays() {
+ ways.append(Way(fromBase: self.leftBase, toBase: self.rightBase))
+ ways.append(Way(fromBase: self.centerBase, toBase: self.leftBase))
+ ways.append(Way(fromBase: self.centerBase, toBase: self.rightBase))
+ }
+
+ func getAllBases() -> [Base] {
+ return self.bases
+ }
+
+ func getInternalWays() -> [Way] {
+ return self.ways
+ }
+
+ func getTopConnection() -> Base? {
+ return nil
+ }
+
+ func getRightConnection() -> Base? {
+ return self.rightBase
+ }
+
+ func getBottomConnection() -> Base? {
+ return self.leftBase
+ }
+
+ func getLeftConnection() -> Base? {
+ return self.leftBase
+ }
+}
+
+class CElement14: CenterElementProtocol {
+ var bases: [Base] = []
+ var centerBase: Base
+ var leftBase: Base
+ var rightBase: Base
+ var ways: [Way] = []
+ var id: Int = 14
+
+ required init(frame: CGRect) {
+ self.centerBase = Base(
+ position: CGPoint(
+ x: frame.midX,
+ y: frame.minY
+ )
+ )
+
+ self.leftBase = Base(
+ position: CGPoint(
+ x: frame.minX,
+ y: frame.maxY
+ )
+ )
+
+ self.rightBase = Base(
+ position: CGPoint(
+ x: frame.maxX,
+ y: frame.maxY
+ )
+ )
+ self.bases.append(centerBase)
+ self.bases.append(leftBase)
+ self.bases.append(rightBase)
+
+ self.connectInnerBases()
+ self.createInternalWays()
+ }
+
+ func connectInnerBases() {
+ self.leftBase.adjacencyList.append(self.rightBase)
+ self.leftBase.adjacencyList.append(self.centerBase)
+ self.rightBase.adjacencyList.append(self.leftBase)
+ self.rightBase.adjacencyList.append(self.centerBase)
+ self.centerBase.adjacencyList.append(self.leftBase)
+ self.centerBase.adjacencyList.append(self.rightBase)
+ }
+
+ func createInternalWays() {
+ ways.append(Way(fromBase: self.leftBase, toBase: self.rightBase))
+ ways.append(Way(fromBase: self.centerBase, toBase: self.rightBase))
+ ways.append(Way(fromBase: self.centerBase, toBase: self.leftBase))
+ }
+
+ func getAllBases() -> [Base] {
+ return self.bases
+ }
+
+ func getInternalWays() -> [Way] {
+ return self.ways
+ }
+
+ func getTopConnection() -> Base? {
+ return self.centerBase
+ }
+
+ func getRightConnection() -> Base? {
+ return self.rightBase
+ }
+
+ func getBottomConnection() -> Base? {
+ return nil
+ }
+
+ func getLeftConnection() -> Base? {
+ return self.leftBase
+ }
+}
+
+class CElement15: CenterElementProtocol {
+ var bases: [Base] = []
+ var topBase: Base
+ var bottomBase: Base
+ var leftBase: Base
+ var rightBase: Base
+ var ways: [Way] = []
+ var id: Int = 15
+
+ required init(frame: CGRect) {
+ self.topBase = Base(
+ position: CGPoint(
+ x: frame.midX,
+ y: frame.minY
+ )
+ )
+
+ self.bottomBase = Base(
+ position: CGPoint(
+ x: frame.midX,
+ y: frame.maxY
+ )
+ )
+
+ self.leftBase = Base(
+ position: CGPoint(
+ x: frame.minX,
+ y: frame.midY
+ )
+ )
+
+ self.rightBase = Base(
+ position: CGPoint(
+ x: frame.maxX,
+ y: frame.midY
+ )
+ )
+ self.bases.append(topBase)
+ self.bases.append(bottomBase)
+ self.bases.append(leftBase)
+ self.bases.append(rightBase)
+
+ self.connectInnerBases()
+ self.createInternalWays()
+ }
+
+ func connectInnerBases() {
+ self.leftBase.adjacencyList.append(self.rightBase)
+ self.leftBase.adjacencyList.append(self.topBase)
+ self.leftBase.adjacencyList.append(self.bottomBase)
+ self.rightBase.adjacencyList.append(self.leftBase)
+ self.rightBase.adjacencyList.append(self.topBase)
+ self.rightBase.adjacencyList.append(self.bottomBase)
+ self.topBase.adjacencyList.append(self.leftBase)
+ self.topBase.adjacencyList.append(self.rightBase)
+ self.topBase.adjacencyList.append(self.bottomBase)
+ self.bottomBase.adjacencyList.append(self.topBase)
+ self.bottomBase.adjacencyList.append(self.rightBase)
+ self.bottomBase.adjacencyList.append(self.leftBase)
+ }
+
+ func createInternalWays() {
+ ways.append(Way(fromBase: self.topBase, toBase: self.rightBase))
+ ways.append(Way(fromBase: self.topBase, toBase: self.leftBase))
+ ways.append(Way(fromBase: self.bottomBase, toBase: self.rightBase))
+ ways.append(Way(fromBase: self.bottomBase, toBase: self.leftBase))
+ }
+
+ func getAllBases() -> [Base] {
+ return self.bases
+ }
+
+ func getInternalWays() -> [Way] {
+ return self.ways
+ }
+
+ func getTopConnection() -> Base? {
+ return self.topBase
+ }
+
+ func getRightConnection() -> Base? {
+ return self.rightBase
+ }
+
+ func getBottomConnection() -> Base? {
+ return nil
+ }
+
+ func getLeftConnection() -> Base? {
+ return self.leftBase
+ }
+}
+
+class CElement16: CenterElementProtocol {
+ var bases: [Base] = []
+ var topBase: Base
+ var bottomBase: Base
+ var leftBase: Base
+ var rightBase: Base
+ var ways: [Way] = []
+ var id: Int = 16
+
+ required init(frame: CGRect) {
+ self.topBase = Base(
+ position: CGPoint(
+ x: frame.midX,
+ y: frame.minY
+ )
+ )
+
+ self.bottomBase = Base(
+ position: CGPoint(
+ x: frame.midX,
+ y: frame.maxY
+ )
+ )
+
+ self.leftBase = Base(
+ position: CGPoint(
+ x: frame.minX,
+ y: frame.midY
+ )
+ )
+
+ self.rightBase = Base(
+ position: CGPoint(
+ x: frame.maxX,
+ y: frame.midY
+ )
+ )
+ self.bases.append(topBase)
+ self.bases.append(bottomBase)
+ self.bases.append(leftBase)
+ self.bases.append(rightBase)
+
+ self.connectInnerBases()
+ self.createInternalWays()
+ }
+
+ func connectInnerBases() {
+ self.leftBase.adjacencyList.append(self.rightBase)
+ self.leftBase.adjacencyList.append(self.topBase)
+ self.leftBase.adjacencyList.append(self.bottomBase)
+ self.rightBase.adjacencyList.append(self.leftBase)
+ self.rightBase.adjacencyList.append(self.topBase)
+ self.rightBase.adjacencyList.append(self.bottomBase)
+ self.topBase.adjacencyList.append(self.leftBase)
+ self.topBase.adjacencyList.append(self.rightBase)
+ self.topBase.adjacencyList.append(self.bottomBase)
+ self.bottomBase.adjacencyList.append(self.topBase)
+ self.bottomBase.adjacencyList.append(self.rightBase)
+ self.bottomBase.adjacencyList.append(self.leftBase)
+ }
+
+ func createInternalWays() {
+ ways.append(Way(fromBase: self.topBase, toBase: self.rightBase))
+ ways.append(Way(fromBase: self.topBase, toBase: self.leftBase))
+ ways.append(Way(fromBase: self.bottomBase, toBase: self.rightBase))
+ ways.append(Way(fromBase: self.bottomBase, toBase: self.leftBase))
+ }
+
+ func getAllBases() -> [Base] {
+ return self.bases
+ }
+
+ func getInternalWays() -> [Way] {
+ return self.ways
+ }
+
+ func getTopConnection() -> Base? {
+ return nil
+ }
+
+ func getRightConnection() -> Base? {
+ return self.rightBase
+ }
+
+ func getBottomConnection() -> Base? {
+ return self.bottomBase
+ }
+
+ func getLeftConnection() -> Base? {
+ return self.leftBase
+ }
+}
+
+class CElement17: CenterElementProtocol {
+ var bases: [Base] = []
+ var topBase: Base
+ var bottomBase: Base
+ var leftBase: Base
+ var rightBase: Base
+ var ways: [Way] = []
+ var id: Int = 17
+
+ required init(frame: CGRect) {
+ self.topBase = Base(
+ position: CGPoint(
+ x: frame.midX,
+ y: frame.minY
+ )
+ )
+
+ self.bottomBase = Base(
+ position: CGPoint(
+ x: frame.midX,
+ y: frame.maxY
+ )
+ )
+
+ self.leftBase = Base(
+ position: CGPoint(
+ x: frame.minX,
+ y: frame.midY
+ )
+ )
+
+ self.rightBase = Base(
+ position: CGPoint(
+ x: frame.maxX,
+ y: frame.midY
+ )
+ )
+ self.bases.append(topBase)
+ self.bases.append(bottomBase)
+ self.bases.append(leftBase)
+ self.bases.append(rightBase)
+
+ self.connectInnerBases()
+ self.createInternalWays()
+ }
+
+ func connectInnerBases() {
+ self.leftBase.adjacencyList.append(self.rightBase)
+ self.leftBase.adjacencyList.append(self.topBase)
+ self.leftBase.adjacencyList.append(self.bottomBase)
+ self.rightBase.adjacencyList.append(self.leftBase)
+ self.rightBase.adjacencyList.append(self.topBase)
+ self.rightBase.adjacencyList.append(self.bottomBase)
+ self.topBase.adjacencyList.append(self.leftBase)
+ self.topBase.adjacencyList.append(self.rightBase)
+ self.topBase.adjacencyList.append(self.bottomBase)
+ self.bottomBase.adjacencyList.append(self.topBase)
+ self.bottomBase.adjacencyList.append(self.rightBase)
+ self.bottomBase.adjacencyList.append(self.leftBase)
+ }
+
+ func createInternalWays() {
+ ways.append(Way(fromBase: self.topBase, toBase: self.rightBase))
+ ways.append(Way(fromBase: self.topBase, toBase: self.leftBase))
+ ways.append(Way(fromBase: self.bottomBase, toBase: self.rightBase))
+ ways.append(Way(fromBase: self.bottomBase, toBase: self.leftBase))
+ }
+
+ func getAllBases() -> [Base] {
+ return self.bases
+ }
+
+ func getInternalWays() -> [Way] {
+ return self.ways
+ }
+
+ func getTopConnection() -> Base? {
+ return nil
+ }
+
+ func getRightConnection() -> Base? {
+ return self.rightBase
+ }
+
+ func getBottomConnection() -> Base? {
+ return nil
+ }
+
+ func getLeftConnection() -> Base? {
+ return self.leftBase
+ }
+}
diff --git a/GoldWars/GoldWars/Map/MapFactory.swift b/GoldWars/GoldWars/Map/MapFactory.swift
index ab4321a..fd7dc3c 100644
--- a/GoldWars/GoldWars/Map/MapFactory.swift
+++ b/GoldWars/GoldWars/Map/MapFactory.swift
@@ -8,29 +8,81 @@
import Foundation
import SpriteKit
+import os
+
+protocol MapProtocol {
+ var size: CGSize! {get set}
+ var entityManager: EntityManager! {get set}
+
+ init(scene: SKScene, entityManager: EntityManager)
+
+ func load(withModel mapModel: MapGenerationModel)
+}
+
+protocol CenterElementProtocol {
+
+ var bases: [Base] {get set}
+ var ways: [Way] {get set}
+ var id: Int { get }
+
+ init(frame: CGRect)
+
+ func getAllBases() -> [Base]
+ func getInternalWays() -> [Way]
+ func getTopConnection() -> Base?
+ func getRightConnection() -> Base?
+ func getBottomConnection() -> Base?
+ func getLeftConnection() -> Base?
+}
class MapFactory {
+ let LOG = OSLog.init(subsystem: "MapGenerator", category: "MapFactory")
- var twoPlayerMaps: [MapProtocol]!
- var threePlayerMaps: [MapProtocol]!
- var fourPlayerMaps: [MapProtocol]!
+ var twoPlayerMapGenerator: TwoPlayerMapGenerator
init(scene: SKScene, entityManager: EntityManager) {
- self.twoPlayerMaps = [
- TwoPlayerDefaultTestMap(scene: scene, entityManager: entityManager)
- ]
-
- self.threePlayerMaps = [MapProtocol]()
- self.fourPlayerMaps = [MapProtocol]()
+ self.twoPlayerMapGenerator = TwoPlayerMapGenerator(scene: scene, entityManager: entityManager)
}
- func loadMap(playerCount: Int) {
- if playerCount == 2 {
- twoPlayerMaps.randomElement()?.load()
- } else if playerCount == 3 {
- threePlayerMaps.randomElement()?.load()
- } else {
- fourPlayerMaps.randomElement()?.load()
- }
+ func loadMap() -> MapGenerationModel{
+ let mapModel = TwoPlayerMapGenerator.getNewMapModel()
+ loadMap(fromModel: mapModel)
+ return mapModel
+ }
+
+ func loadMap(fromModel model: MapGenerationModel) {
+ os_log("Loading two player map", log: LOG, type: .info)
+ twoPlayerMapGenerator.load(withModel: model)
+ }
+}
+
+class CenterElementProvider {
+ static let LOG = OSLog.init(subsystem: "MapGenerator", category: "CenterElementProvider")
+
+ static let centerElements: [CenterElementProtocol.Type] = [
+ CElement0.self,
+ CElement1.self,
+ CElement2.self,
+ CElement3.self,
+ CElement4.self,
+ CElement5.self,
+ CElement6.self,
+ CElement7.self,
+ CElement8.self,
+ CElement9.self,
+ CElement10.self,
+ CElement11.self,
+ CElement12.self,
+ CElement13.self,
+ CElement14.self,
+ CElement15.self,
+ CElement16.self,
+ CElement17.self
+ ]
+
+ static func get(inFrame frame: CGRect, withId id: Int) -> CenterElementProtocol {
+ os_log("Getting new predifined center element from provider", log: LOG, type: .info)
+
+ return centerElements[id].init(frame: frame)
}
}
diff --git a/GoldWars/GoldWars/Map/MapProtocol.swift b/GoldWars/GoldWars/Map/MapProtocol.swift
deleted file mode 100644
index 2560d39..0000000
--- a/GoldWars/GoldWars/Map/MapProtocol.swift
+++ /dev/null
@@ -1,20 +0,0 @@
-//
-// MapProtocoll.swift
-// GoldWars
-//
-// Created by Marcel Schwarz on 02.05.20.
-// Copyright © 2020 SP2. All rights reserved.
-//
-
-import Foundation
-import SpriteKit
-
-protocol MapProtocol {
-
- var size: CGSize! {get set}
- var entityManager: EntityManager! {get set}
-
- init(scene: SKScene, entityManager: EntityManager)
-
- func load()
-}
diff --git a/GoldWars/GoldWars/Map/SampleCElement.swift b/GoldWars/GoldWars/Map/SampleCElement.swift
new file mode 100644
index 0000000..e71d78c
--- /dev/null
+++ b/GoldWars/GoldWars/Map/SampleCElement.swift
@@ -0,0 +1,123 @@
+//
+// CElemente.swift
+// GoldWars
+//
+// Created by Jakob Haag on 14.05.20.
+// Copyright © 2020 SP2. All rights reserved.
+//
+
+import Foundation
+import SpriteKit
+
+class SampleCElement : CenterElementProtocol {
+ var frame: CGRect
+ var bases: [Base] = []
+ var centerBase: Base
+
+ required init(frame: CGRect) {
+ self.frame = frame
+ self.centerBase = Base(
+ position: CGPoint(
+ x: frame.midX,
+ y: frame.midY
+ )
+ )
+ self.bases.append(centerBase)
+ }
+
+ func getAllBases() -> [Base] {
+ return self.bases
+ }
+
+ func getTopConnection() -> Base? {
+ return self.centerBase
+ }
+
+ func getRightConnection() -> Base? {
+ return self.centerBase
+ }
+
+ func getBottomConnection() -> Base? {
+ return self.centerBase
+ }
+
+ func getLeftConnection() -> Base? {
+ return self.centerBase
+ }
+}
+
+//
+// CElement7.swift
+// GoldWars
+//
+// Created by Jakob Haag on 14.05.20.
+// Copyright © 2020 SP2. All rights reserved.
+//
+
+import Foundation
+import SpriteKit
+
+class CElement1700 : CenterElementProtocol {
+ var frame: CGRect
+ var bases: [Base] = []
+ var topBase: Base
+ var bottomBase: Base
+ var leftBase: Base
+ var rightBase: Base
+
+ required init(frame: CGRect) {
+ self.frame = frame
+ self.topBase = Base(
+ position: CGPoint(
+ x: frame.midX,
+ y: frame.minY
+ )
+ )
+
+ self.bottomBase = Base(
+ position: CGPoint(
+ x: frame.midX,
+ y: frame.maxY
+ )
+ )
+
+ self.leftBase = Base(
+ position: CGPoint(
+ x: frame.minX,
+ y: frame.midY
+ )
+ )
+
+ self.rightBase = Base(
+ position: CGPoint(
+ x: frame.maxX,
+ y: frame.midY
+ )
+ )
+ self.bases.append(topBase)
+ self.bases.append(bottomBase)
+ self.bases.append(leftBase)
+ self.bases.append(rightBase)
+ }
+
+ func getAllBases() -> [Base] {
+ return self.bases
+ }
+
+ func getTopConnection() -> Base? {
+ return self.topBase
+ }
+
+ func getRightConnection() -> Base? {
+ return self.rightBase
+ }
+
+ func getBottomConnection() -> Base? {
+ return self.bottomBase
+ }
+
+ func getLeftConnection() -> Base? {
+ return self.leftBase
+ }
+}
+
diff --git a/GoldWars/GoldWars/Map/TwoPlayerDefaultTestMap.swift b/GoldWars/GoldWars/Map/TwoPlayerDefaultTestMap.swift
index beff433..5f67cd7 100644
--- a/GoldWars/GoldWars/Map/TwoPlayerDefaultTestMap.swift
+++ b/GoldWars/GoldWars/Map/TwoPlayerDefaultTestMap.swift
@@ -8,6 +8,7 @@
import Foundation
import SpriteKit
+import GameKit
class TwoPlayerDefaultTestMap: MapProtocol {
@@ -19,11 +20,12 @@ class TwoPlayerDefaultTestMap: MapProtocol {
self.size = scene.size
}
- func load() {
+ func load(withModel mapModel: MapGenerationModel) {
// 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
)
@@ -46,6 +48,7 @@ class TwoPlayerDefaultTestMap: MapProtocol {
let basePlayerTwo = Base(
position: CGPoint(x: self.size.width * 0.9, y: self.size.height / 2),
+ player: (!MatchmakingHelper.sharedInstance.isServer) ? GKLocalPlayer.local : MatchmakingHelper.sharedInstance.mpMatch?.players[0],
team: .team2
)
diff --git a/GoldWars/GoldWars/Map/TwoPlayerMapGenerator.swift b/GoldWars/GoldWars/Map/TwoPlayerMapGenerator.swift
new file mode 100644
index 0000000..918bdf2
--- /dev/null
+++ b/GoldWars/GoldWars/Map/TwoPlayerMapGenerator.swift
@@ -0,0 +1,273 @@
+//
+// TwoPlayerMapGenerator.swift
+// GoldWars
+//
+// Created by Marcel Schwarz on 13.05.20.
+// Copyright © 2020 SP2. All rights reserved.
+//
+
+import Foundation
+import SpriteKit
+import GameKit
+import os
+
+struct MapGenerationModel: Codable {
+
+ let numBasesP1: Int
+ let numBasesP2: Int
+ let topLeftId: Int
+ let topRightId: Int
+ let bottomLeftId: Int
+ let bottomRightId: Int
+
+}
+
+class TwoPlayerMapGenerator: MapProtocol {
+
+ let LOG = OSLog.init(subsystem: "MapGenerator", category: "TwoPlayerMapGenerator")
+
+ var size: CGSize!
+ var entityManager: EntityManager!
+
+ static func getNewMapModel() -> MapGenerationModel {
+
+ let noOfCElements = CenterElementProvider.centerElements.count - 1
+
+ return MapGenerationModel(
+ numBasesP1: Int.random(in: 1...3),
+ numBasesP2: Int.random(in: 1...3),
+ topLeftId: Int.random(in: 0...noOfCElements),
+ topRightId: Int.random(in: 0...noOfCElements),
+ bottomLeftId: Int.random(in: 0...noOfCElements),
+ bottomRightId: Int.random(in: 0...noOfCElements)
+ )
+
+ }
+
+ required init(scene: SKScene, entityManager: EntityManager) {
+ self.size = scene.size
+ self.entityManager = entityManager
+ }
+
+ func load(withModel mapModel: MapGenerationModel) {
+ os_log("Loading from TwoPlayerMapFactory", log: LOG, type: .info)
+
+ // Generate bases structure
+ os_log("Get player one base", log: LOG, type: .info)
+ let basePlayerOne = Base(
+ position: CGPoint(x: self.size.width * 0.07, y: self.size.height / 2),
+ player: (MatchmakingHelper.sharedInstance.isServer) ? GKLocalPlayer.local : MatchmakingHelper.sharedInstance.mpMatch?.players[0],
+ team: .team1
+ )
+
+ os_log("Get player one's startbases", log: LOG, type: .info)
+ var p1StartBases = [String: Base]()
+ var ways = [Way]()
+
+ if (mapModel.numBasesP1 == 1) {
+ p1StartBases["mid"] = Base(position: CGPoint(x: self.size.width * 0.2, y: self.size.height * 0.5))
+ ways.append(Way(fromBase: basePlayerOne, toBase: p1StartBases["mid"]!))
+ } else if (mapModel.numBasesP1 == 2) {
+ p1StartBases["top"] = Base(position: CGPoint(x: self.size.width * 0.2, y: self.size.height * 0.333))
+ p1StartBases["bot"] = Base(position: CGPoint(x: self.size.width * 0.2, y: self.size.height * 0.666))
+ ways.append(Way(fromBase: basePlayerOne, toBase: p1StartBases["top"]!))
+ ways.append(Way(fromBase: basePlayerOne, toBase: p1StartBases["bot"]!))
+ } else {
+ p1StartBases["top"] = Base(position: CGPoint(x: self.size.width * 0.2, y: self.size.height * 0.25))
+ p1StartBases["mid"] = Base(position: CGPoint(x: self.size.width * 0.2, y: self.size.height * 0.5))
+ p1StartBases["bot"] = Base(position: CGPoint(x: self.size.width * 0.2, y: self.size.height * 0.75))
+ ways.append(Way(fromBase: basePlayerOne, toBase: p1StartBases["top"]!))
+ ways.append(Way(fromBase: basePlayerOne, toBase: p1StartBases["mid"]!))
+ ways.append(Way(fromBase: basePlayerOne, toBase: p1StartBases["bot"]!))
+ }
+
+ os_log("Generate Map center", log: LOG, type: .info)
+ let gridCellWidth = self.size.width * 0.2
+ let gridCellHeight = self.size.height * 0.4
+ let cellInsetX = CGFloat(self.size.width * 0.05)
+ let cellInsetY = CGFloat(self.size.height * 0.07)
+
+ let gridTopLeft = CGRect(
+ x: self.size.width * 0.3,
+ y: self.size.height * 0.1,
+ width: gridCellWidth,
+ height: gridCellHeight
+ ).insetBy(dx: cellInsetX, dy: cellInsetY)
+
+ let gridTopRight = CGRect(
+ x: self.size.width * 0.5,
+ y: self.size.height * 0.1,
+ width: gridCellWidth,
+ height: gridCellHeight
+ ).insetBy(dx: cellInsetX, dy: cellInsetY)
+
+ let gridBottomLeft = CGRect(
+ x: self.size.width * 0.3,
+ y: self.size.height * 0.5,
+ width: gridCellWidth,
+ height: gridCellHeight
+ ).insetBy(dx: cellInsetX, dy: cellInsetY)
+
+ let gridBottomRight = CGRect(
+ x: self.size.width * 0.5,
+ y: self.size.height * 0.5,
+ width: gridCellWidth,
+ height: gridCellHeight
+ ).insetBy(dx: cellInsetX, dy: cellInsetY)
+
+ let topLeft = CenterElementProvider.get(inFrame: gridTopLeft, withId: mapModel.topLeftId)
+ let topRight = CenterElementProvider.get(inFrame: gridTopRight, withId: mapModel.topRightId)
+ let bottomLeft = CenterElementProvider.get(inFrame: gridBottomLeft, withId: mapModel.bottomLeftId)
+ let bottomRight = CenterElementProvider.get(inFrame: gridBottomRight, withId: mapModel.bottomRightId)
+
+ ways.append(contentsOf: topLeft.getInternalWays())
+ ways.append(contentsOf: topRight.getInternalWays())
+ ways.append(contentsOf: bottomLeft.getInternalWays())
+ ways.append(contentsOf: bottomRight.getInternalWays())
+
+ os_log("Get player two base", log: LOG, type: .info)
+ let basePlayerTwo = Base(
+ position: CGPoint(x: self.size.width * 0.93, y: self.size.height / 2),
+ player: (!MatchmakingHelper.sharedInstance.isServer) ? GKLocalPlayer.local : MatchmakingHelper.sharedInstance.mpMatch?.players[0],
+ team: .team2
+ )
+
+ os_log("Get player two's startbases", log: LOG, type: .info)
+ var p2StartBases = [String: Base]()
+
+ if (mapModel.numBasesP2 == 1) {
+ p2StartBases["mid"] = Base(position: CGPoint(x: self.size.width * 0.8, y: self.size.height * 0.5))
+ ways.append(Way(fromBase: basePlayerTwo, toBase: p2StartBases["mid"]!))
+ } else if (mapModel.numBasesP2 == 2) {
+ p2StartBases["top"] = Base(position: CGPoint(x: self.size.width * 0.8, y: self.size.height * 0.333))
+ p2StartBases["bot"] = Base(position: CGPoint(x: self.size.width * 0.8, y: self.size.height * 0.666))
+ ways.append(Way(fromBase: basePlayerTwo, toBase: p2StartBases["top"]!))
+ ways.append(Way(fromBase: basePlayerTwo, toBase: p2StartBases["bot"]!))
+ } else {
+ p2StartBases["top"] = Base(position: CGPoint(x: self.size.width * 0.8, y: self.size.height * 0.25))
+ p2StartBases["mid"] = Base(position: CGPoint(x: self.size.width * 0.8, y: self.size.height * 0.5))
+ p2StartBases["bot"] = Base(position: CGPoint(x: self.size.width * 0.8, y: self.size.height * 0.75))
+ ways.append(Way(fromBase: basePlayerTwo, toBase: p2StartBases["top"]!))
+ ways.append(Way(fromBase: basePlayerTwo, toBase: p2StartBases["mid"]!))
+ ways.append(Way(fromBase: basePlayerTwo, toBase: p2StartBases["bot"]!))
+ }
+
+ // Create adjacency mapping
+ os_log("Connecting base p1 and start bases", log: LOG, type: .info)
+ basePlayerOne.adjacencyList.append(contentsOf: p1StartBases.values)
+ p1StartBases.values.forEach({base in base.adjacencyList.append(basePlayerOne)})
+
+ if (p1StartBases["top"] != nil && topLeft.getLeftConnection() != nil) {
+ os_log("Connecting p1 startbase top with topLeft segment", log: LOG, type: .info)
+ p1StartBases["top"]!.adjacencyList.append(topLeft.getLeftConnection()!)
+ topLeft.getLeftConnection()!.adjacencyList.append(p1StartBases["top"]!)
+ ways.append(Way(fromBase: p1StartBases["top"]!, toBase: topLeft.getLeftConnection()!))
+ }
+
+ if (p1StartBases["mid"] != nil) {
+ if (topLeft.getLeftConnection() != nil) {
+ os_log("Connecting p1 startbase mid with topLeft segment", log: LOG, type: .info)
+ p1StartBases["mid"]!.adjacencyList.append(topLeft.getLeftConnection()!)
+ topLeft.getLeftConnection()!.adjacencyList.append(p1StartBases["mid"]!)
+ ways.append(Way(fromBase: p1StartBases["mid"]!, toBase: topLeft.getLeftConnection()!))
+ }
+
+ if (bottomLeft.getLeftConnection() != nil) {
+ os_log("Connecting p1 startbase mid with bottomLeft segment", log: LOG, type: .info)
+ p1StartBases["mid"]!.adjacencyList.append(bottomLeft.getLeftConnection()!)
+ bottomLeft.getLeftConnection()!.adjacencyList.append(p1StartBases["mid"]!)
+ ways.append(Way(fromBase: p1StartBases["mid"]!, toBase: bottomLeft.getLeftConnection()!))
+ }
+ }
+
+ if (p1StartBases["bot"] != nil && bottomLeft.getLeftConnection() != nil) {
+ os_log("Connecting p1 startbase bot with bottomLeft segment", log: LOG, type: .info)
+ p1StartBases["bot"]!.adjacencyList.append(bottomLeft.getLeftConnection()!)
+ bottomLeft.getLeftConnection()!.adjacencyList.append(p1StartBases["bot"]!)
+ ways.append(Way(fromBase: p1StartBases["bot"]!, toBase: bottomLeft.getLeftConnection()!))
+ }
+
+ if (topLeft.getRightConnection() != nil && topRight.getLeftConnection() != nil) {
+ os_log("Connecting topLeft with topRight segment horizontally", log: LOG, type: .info)
+ topLeft.getRightConnection()!.adjacencyList.append(topRight.getLeftConnection()!)
+ topRight.getLeftConnection()!.adjacencyList.append(topLeft.getRightConnection()!)
+ ways.append(Way(fromBase: topLeft.getRightConnection()!, toBase: topRight.getLeftConnection()!))
+ }
+
+ if (bottomLeft.getRightConnection() != nil && bottomRight.getLeftConnection() != nil) {
+ os_log("Connecting bottomLeft with bottomRight segment horizontally", log: LOG, type: .info)
+ bottomLeft.getRightConnection()!.adjacencyList.append(bottomRight.getLeftConnection()!)
+ bottomRight.getLeftConnection()!.adjacencyList.append(bottomLeft.getRightConnection()!)
+ ways.append(Way(fromBase: bottomLeft.getRightConnection()!, toBase: bottomRight.getLeftConnection()!))
+ }
+
+ if (topLeft.getBottomConnection() != nil && bottomLeft.getTopConnection() != nil) {
+ os_log("Connecting topLeft with bottomLeft segment vertically", log: LOG, type: .info)
+ topLeft.getBottomConnection()!.adjacencyList.append(bottomLeft.getTopConnection()!)
+ bottomLeft.getTopConnection()!.adjacencyList.append(topLeft.getBottomConnection()!)
+ ways.append(Way(fromBase: topLeft.getBottomConnection()!, toBase: bottomLeft.getTopConnection()!))
+ }
+
+ if (topRight.getBottomConnection() != nil && bottomRight.getTopConnection() != nil) {
+ os_log("Connecting topRight with bottomRight segment vertically", log: LOG, type: .info)
+ topRight.getBottomConnection()!.adjacencyList.append(bottomRight.getTopConnection()!)
+ bottomRight.getTopConnection()!.adjacencyList.append(topRight.getBottomConnection()!)
+ ways.append(Way(fromBase: topRight.getBottomConnection()!, toBase: bottomRight.getTopConnection()!))
+ }
+
+ os_log("Connecting base p2 and start bases", log: LOG, type: .info)
+ basePlayerTwo.adjacencyList.append(contentsOf: p2StartBases.values)
+ p2StartBases.values.forEach({base in base.adjacencyList.append(basePlayerTwo)})
+
+ if (p2StartBases["top"] != nil && topRight.getRightConnection() != nil) {
+ os_log("Connecting p2 startbase top with topRight segment", log: LOG, type: .info)
+ p2StartBases["top"]!.adjacencyList.append(topRight.getRightConnection()!)
+ topRight.getRightConnection()!.adjacencyList.append(p2StartBases["top"]!)
+ ways.append(Way(fromBase: p2StartBases["top"]!, toBase: topRight.getRightConnection()!))
+ }
+
+ if (p2StartBases["mid"] != nil) {
+ if (topRight.getRightConnection() != nil) {
+ os_log("Connecting p2 startbase mid with topRight segment", log: LOG, type: .info)
+ p2StartBases["mid"]!.adjacencyList.append(topRight.getRightConnection()!)
+ topRight.getRightConnection()!.adjacencyList.append(p2StartBases["mid"]!)
+ ways.append(Way(fromBase: topRight.getRightConnection()!, toBase: p2StartBases["mid"]!))
+ }
+
+ if (bottomRight.getRightConnection() != nil) {
+ os_log("Connecting p2 startbase mid with bottomRight segment", log: LOG, type: .info)
+ p2StartBases["mid"]!.adjacencyList.append(bottomRight.getRightConnection()!)
+ bottomRight.getRightConnection()!.adjacencyList.append(p2StartBases["mid"]!)
+ ways.append(Way(fromBase: p2StartBases["mid"]!, toBase: bottomRight.getRightConnection()!))
+ }
+ }
+
+ if (p2StartBases["bot"] != nil && bottomRight.getRightConnection() != nil) {
+ os_log("Connecting p2 startbase bot with bottomRight segment", log: LOG, type: .info)
+ p2StartBases["bot"]!.adjacencyList.append(bottomRight.getRightConnection()!)
+ bottomRight.getRightConnection()!.adjacencyList.append(p2StartBases["bot"]!)
+ ways.append(Way(fromBase: p2StartBases["bot"]!, toBase: bottomRight.getRightConnection()!))
+ }
+
+
+ // Add all bases to the scene
+ entityManager.add(basePlayerOne)
+ p1StartBases.forEach({(key, base) in entityManager.add(base)})
+
+ topLeft.getAllBases().forEach({base in entityManager.add(base)})
+ topRight.getAllBases().forEach({base in entityManager.add(base)})
+ bottomLeft.getAllBases().forEach({base in entityManager.add(base)})
+ bottomRight.getAllBases().forEach({base in entityManager.add(base)})
+
+ entityManager.add(basePlayerTwo)
+ p2StartBases.forEach({(key, base) in entityManager.add(base)})
+
+ ways.forEach({way in entityManager.add(way)})
+ }
+
+
+ func createPathFromBaseToBase(fromBase: Base, toBase: Base) {
+ let path = Way(fromBase: fromBase, toBase: toBase)
+ entityManager.add(path)
+ }
+}
diff --git a/GoldWars/GoldWars/MatchmakingHelper.swift b/GoldWars/GoldWars/MatchmakingHelper.swift
index 48628ce..60dc5d2 100644
--- a/GoldWars/GoldWars/MatchmakingHelper.swift
+++ b/GoldWars/GoldWars/MatchmakingHelper.swift
@@ -102,12 +102,32 @@ 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)
+ EntityManager.sharedInstance.getTimer().startWithDuration(duration: 31)
+ }
+
+ if let mapModel = try? jsonDecoder.decode(MapGenerationModel.self, from: data) {
+ DataService.sharedInstance.setMapModel(model: mapModel)
+ }
+
+ MultiplayerNetwork.sharedInstance.isSending = false
}
/*
@@ -156,16 +176,31 @@ class MatchmakingHelper: NSObject, GKMatchmakerViewControllerDelegate, GKMatchDe
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..5cf2937
--- /dev/null
+++ b/GoldWars/GoldWars/MultiplayerNetwork.swift
@@ -0,0 +1,70 @@
+//
+// 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)
+ }
+
+ func sendMapModelToPlayers(mapModel: MapGenerationModel) {
+ let encoder = JSONEncoder()
+ let encoded = (try? encoder.encode(mapModel))!
+ sendData(data: encoded)
+ }
+
+}
diff --git a/GoldWars/GoldWars/Partikels/Fire.sks b/GoldWars/GoldWars/Partikels/Fire.sks
index f25e78f..1f31d2e 100644
Binary files a/GoldWars/GoldWars/Partikels/Fire.sks and b/GoldWars/GoldWars/Partikels/Fire.sks differ
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..b9186c6
--- /dev/null
+++ b/GoldWars/GoldWars/RoundCalculatorService.swift
@@ -0,0 +1,139 @@
+//
+// 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 {
+ if base.ownership == nil {
+ base.unitCount += playerMoveWithMaxUnits.value.unitCount
+ if playerMoveWithMaxUnits.value.unitCount == 0 {
+ base.ownership = nil
+ } else {
+ base.ownership = playerMoveWithMaxUnits.key
+ }
+ } else {
+ if base.unitCount < playerMoveWithMaxUnits.value.unitCount {
+ base.unitCount = playerMoveWithMaxUnits.value.unitCount - base.unitCount
+ base.ownership = playerMoveWithMaxUnits.key
+ } else if (base.unitCount == playerMoveWithMaxUnits.value.unitCount) {
+ base.ownership = nil
+ } else {
+ base.unitCount -= playerMoveWithMaxUnits.value.unitCount
+ }
+ }
+ }
+ }
+ }
+ baseSpecificMoves.removeValue(forKey: baseId)
+ }
+ allPlayerMoves.removeAll()
+ DataService.sharedInstance.localPlayerMoves.removeAll()
+ MultiplayerNetwork.sharedInstance.sendSnapshotModelToPlayers()
+ DataService.sharedInstance.snapshotModel = currentSnapshotModel
+ EntityManager.sharedInstance.updateSnapshotModel(snapshotModel: currentSnapshotModel!)
+ sleep(1)
+ EntityManager.sharedInstance.getTimer().startWithDuration(duration: 31)
+ 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 b306854..7618d1a 100644
--- a/GoldWars/GoldWars/Scenes/GameScene.swift
+++ b/GoldWars/GoldWars/Scenes/GameScene.swift
@@ -8,128 +8,160 @@
import SpriteKit
import GameplayKit
+import GameKit
class GameScene: SKScene{
- var entityManager: EntityManager!
var isMoveTouch = false
- var currentDraggedBasePos = CGPoint()
var currentDraggedBase : Base?
+ static var sendUnits: CGFloat = 0
+ var collisionBase: Base?
override func sceneDidLoad() {
- entityManager = EntityManager(scene: self)
- entityManager.add(HUD(size: self.size))
- entityManager.add(Background(size: self.size))
+ EntityManager.sharedInstance.setScene(scene: self)
+ EntityManager.sharedInstance.add(HUD(size: self.size))
+ EntityManager.sharedInstance.add(Background(size: self.size))
initMap()
}
-
+
func initMap() {
- MapFactory(scene: self, entityManager: self.entityManager).loadMap(playerCount: 2)
+ if (DataService.sharedInstance.gameHost?.playerName == GKLocalPlayer.local.displayName) {
+ let mapModel = MapFactory(scene: self, entityManager: EntityManager.sharedInstance).loadMap()
+ MultiplayerNetwork.sharedInstance.sendMapModelToPlayers(mapModel: mapModel)
+ DataService.sharedInstance.setSnapshotModel(snapshotModel: EntityManager.sharedInstance.getSnapshotModel())
+ }
+ if CommandLine.arguments.contains("--no-matchmaking") {
+ MapFactory(scene: self, entityManager: EntityManager.sharedInstance).loadMap()
+ }
}
-
+
override func touchesEnded(_ touches: Set, with event: UIEvent?) {
guard let touch = touches.first else {
return
}
-
+
let touchLocation = touch.location(in: self)
-
- 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)))
- }
-
- }
- }
- }
+
+ if isMoveTouch{
+ isMoveTouch = false
+ currentDraggedBase!.component(ofType: DefaultBaseComponent.self)?.spriteNode.position = currentDraggedBase!.position
+ currentDraggedBase!.component(ofType: TeamComponent.self)?.fire.position = currentDraggedBase!.position
+ currentDraggedBase!.component(ofType: DefaultBaseComponent.self)?.labelNode?.position = CGPoint(x: currentDraggedBase!.position.x + 30, y: currentDraggedBase!.position.y - 50)
+ addAttackDetails(touchLocation: touchLocation)
+ }
else {
- for entity in entityManager.entities {
+ for entity in EntityManager.sharedInstance.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 {
- for child in self.children {
- if(child.name != "fire"){
- child.alpha = 0.3
- }
- }
- entityManager.add(Modal(modaltype: .BaseDetails,
- base: entity as! Base,
- anchorPoint: CGPoint(x: self.size.width / 2 , y: self.size.height / 2)))
- }
- }
+
+ //FIXME: this is confusing
+ addBaseDetails(touchLocation: touchLocation, spriteNode: spriteNode, touches: touches, event: event, entity: entity)
}
}
-
+
}
-
+
override func touchesMoved(_ touches: Set, with event: UIEvent?) {
guard let touch = touches.first else {
return
}
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 {
- 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)
- ]))
+
+ for child in children {
+ if atPoint(touchLocation) == child {
+ child.touchesMoved(touches, with: event)
+ }
+ }
+ checkSlider()
+
+ let bases = EntityManager.sharedInstance.getBasesByPlayer(for: GKLocalPlayer.local)
+
+ 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 let baseEntity = entity as? Base {
+ if baseEntity.ownershipPlayer == GKLocalPlayer.local {
+ 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))
+
}
}
}
}
- override func update(_ currentTime: TimeInterval) {
- entityManager.getBackground()?.update(deltaTime: currentTime)
- entityManager.getHUD()?.component(ofType: TimerComponent.self)?.update()
+ 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
+ if currentDraggedBase!.unitCount > 1 {
+ 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))
+ GameScene.sendUnits = CGFloat(currentDraggedBase!.unitCount / 2)
+ }
+ }
+ }
+ }
+
+ 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)
+
+ //TODO: refactor this quick and dirty fix
+ if GameScene.sendUnits == 0 {
+ GameScene.sendUnits = 1
+ } else if Int(GameScene.sendUnits) == currentDraggedBase?.unitCount {
+ GameScene.sendUnits -= 1
+ }
+ 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 {
+ 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
+ base.component(ofType: DefaultBaseComponent.self)?.labelNode?.position = CGPoint(x:touchLocation.x + 30, y: touchLocation.y - 50)
+ }
+
+ 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/Scenes/MenuScene.swift b/GoldWars/GoldWars/Scenes/MenuScene.swift
index edf6bb9..764a1da 100644
--- a/GoldWars/GoldWars/Scenes/MenuScene.swift
+++ b/GoldWars/GoldWars/Scenes/MenuScene.swift
@@ -7,43 +7,47 @@
//
import SpriteKit
-
+import SceneKit
class MenuScene: SKScene {
-
- var entityManager: EntityManager!
-
+
override func sceneDidLoad() {
- entityManager = EntityManager(scene: self)
+ EntityManager.sharedInstance.setScene(scene: self)
let midX = self.size.width / 2
let midY = self.size.height / 2
- entityManager.add(Button(name: "startGameButton",
+ EntityManager.sharedInstance.add(Button(name: "startGameButton",
iconName: "",
text: "Start Game",
position: CGPoint(x: midX, y: midY),
onButtonPress: {
if CommandLine.arguments.contains("--no-matchmaking") {
self.loadScene(scene: GameScene(size: self.size))
+ SoundManager.sharedInstance.stopMenuMusic()
} else {
- MatchmakingHelper.sharedInstance.presentMatchmaker(scene: self)
+ MatchmakingHelper.sharedInstance.presentMatchmaker(scene: self)
}
- }))
- entityManager.add(Button(name: "settingsButton",
+ }))
+ EntityManager.sharedInstance.add(Button(name: "settingsButton",
iconName: "",
text: "Settings",
position: CGPoint(x: midX, y: midY - 80 ),
onButtonPress: {
- //TODO: create Settings Scene
- }))
- entityManager.add(Background(size: self.size))
+ self.loadScene(scene: SettingsScene(size: self.size))
+ }))
+ EntityManager.sharedInstance.add(Background(size: self.size))
+ EntityManager.sharedInstance.add(SpinningLogoEntity(position: CGPoint(x: midX, y: midY + 200)))
+
+ if SoundManager.sharedInstance.isMusicPlaying == false && SoundManager.sharedInstance.isMusicEnabled == true {
+ SoundManager.sharedInstance.startMenuMusic()
+ }
}
-
+
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)
- entityManager.getButtonByName(buttonName: "startGameButton").component(ofType: ButtonComponent.self)?.buttonNode.isEnabled = GameCenterHelper.isAuthenticated
+ EntityManager.sharedInstance.getBackground()!.update(deltaTime: currentTime)
+ EntityManager.sharedInstance.getButtonByName(buttonName: "startGameButton").component(ofType: ButtonComponent.self)?.buttonNode.isEnabled = GameCenterHelper.isAuthenticated
}
}
diff --git a/GoldWars/GoldWars/SettingsScene.swift b/GoldWars/GoldWars/SettingsScene.swift
new file mode 100644
index 0000000..a9cd9e0
--- /dev/null
+++ b/GoldWars/GoldWars/SettingsScene.swift
@@ -0,0 +1,93 @@
+//
+// SettingsScene.swift
+// GoldWars
+//
+// Created by Tim Herbst on 10.05.20.
+// Copyright © 2020 SP2. All rights reserved.
+//
+
+import SpriteKit
+
+class SettingsScene: SKScene {
+
+ override func sceneDidLoad() {
+ EntityManager.sharedInstance.setScene(scene: self)
+ let positionX = self.size.width * 0.1
+ let positionY = self.size.height * 0.05
+
+ EntityManager.sharedInstance.add(Button(name: "backToMenuScene",
+ iconName: "",
+ text: "Back",
+ position: CGPoint(x: positionX, y: positionY),
+ onButtonPress: {
+ self.loadScene(scene: MenuScene(size: self.size))
+ }))
+ EntityManager.sharedInstance.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.sharedInstance.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.sharedInstance.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.sharedInstance.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.sharedInstance.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.sharedInstance.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.sharedInstance.getBackground()!.update(deltaTime: currentTime)
+ }
+
+}
diff --git a/GoldWars/GoldWars/SoundManager.swift b/GoldWars/GoldWars/SoundManager.swift
new file mode 100644
index 0000000..b6cb5d4
--- /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 {
+ //TODO: Add logging
+ }
+ 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/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 {
+
+}
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