Compare commits

..

24 Commits

Author SHA1 Message Date
Chauntalle Schüle
7050fd1b8f last changes 2020-06-03 13:19:56 +02:00
Chauntalle Schüle
74a7df551c Resolve rebase problems 2020-06-03 01:18:17 +02:00
Chauntalle Schüle
9ec6a252ee changes after review 2020-06-03 01:09:06 +02:00
Chauntalle Schüle
aee6ec1ac1 adding bigger changes after review, deleted enum und methods enter&changeState 2020-06-03 01:09:06 +02:00
Chauntalle Schüle
9eb06b54fd made smaller changes after review 2020-06-03 01:07:45 +02:00
Chauntalle Schüle
c5867f12e3 removed unnecessary file 2020-06-03 01:06:34 +02:00
Chauntalle Schüle
c4a4a8f755 deleted comments 2020-06-03 01:06:34 +02:00
Chauntalle Schüle
35ff2208fb found right trigger for syncingSt and gameSt after finishing a Round 2020-06-03 01:03:17 +02:00
Chauntalle Schüle
079ae4a6f6 still halting game when syncing 2020-06-03 01:03:17 +02:00
Chauntalle Schüle
b23071bb08 menuSt, syncSt and gameSt now correctly triggered even in MM, menuSc and gameSc loaded in states, still need to find trigger for syncSt after finishing one timer cycle / round 2020-06-03 01:00:34 +02:00
Chauntalle Schüle
f4847e79d7 update the first three states before trying sth different 2020-06-03 01:00:34 +02:00
Chauntalle Schüle
3ea48c399e added info that you're once again entering the same state you're already in 2020-06-03 00:59:56 +02:00
Chauntalle Schüle
0492ab7724 updated update method of menuState 2020-06-03 00:59:56 +02:00
Chauntalle Schüle
78c5016576 new group states 2020-06-03 00:59:56 +02:00
Chauntalle Schüle
8537dee231 game scene and menu scene are now initialized in states, still need to test for 2 player 2020-06-03 00:59:35 +02:00
Chauntalle Schüle
0296edb080 adding var current- and previousState - set in enterState, adding func changeState 2020-06-03 00:59:35 +02:00
Chauntalle Schüle
6be5325d86 added EndGameState, deleted imports from enum StateTypes 2020-06-03 00:59:35 +02:00
Chauntalle Schüle
ce2d847393 added GameState 2020-06-03 00:58:15 +02:00
Chauntalle Schüle
50fa1b6cc6 just changed name of variable allowedState to wantedState for better understanding and correctness 2020-06-03 00:58:15 +02:00
Chauntalle Schüle
f008ecafa7 added SyncingState 2020-06-03 00:58:15 +02:00
Chauntalle Schüle
d7d17dba2b added MenuState, is initial State 2020-06-03 00:58:15 +02:00
Chauntalle Schüle
3bbae779af added Statemanager with Singleton, used to create and enter states, already with logging if entering state is un/successful 2020-06-03 00:57:49 +02:00
Chauntalle Schüle
767548cb82 bulk update, gonna break it up with new files in following commits 2020-06-03 00:56:37 +02:00
Chauntalle Schüle
6b602e6af2 Made first states and initialized them 2020-06-03 00:55:42 +02:00
107 changed files with 765 additions and 1662 deletions

View File

@ -16,16 +16,14 @@
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 */; };
20F1990724A4FAC1004B7A30 /* new_round.wav in Resources */ = {isa = PBXBuildFile; fileRef = 20F1990424A4FAC1004B7A30 /* new_round.wav */; };
20F1990824A4FAC1004B7A30 /* use_boost.wav in Resources */ = {isa = PBXBuildFile; fileRef = 20F1990524A4FAC1004B7A30 /* use_boost.wav */; };
20F1990924A4FAC1004B7A30 /* attack_base.wav in Resources */ = {isa = PBXBuildFile; fileRef = 20F1990624A4FAC1004B7A30 /* attack_base.wav */; };
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 */; };
3EAD889524801B6A0048A10A /* RoundTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EAD889424801B6A0048A10A /* RoundTimer.swift */; };
3EBD242E245D9332003CECE7 /* Team.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EBD242D245D9332003CECE7 /* Team.swift */; };
3F745DF0246F48FC00CE7375 /* PlayerMoveType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F745DEF246F48FC00CE7375 /* PlayerMoveType.swift */; };
3F79FFE02486F7CD003F79C3 /* Explosion.sks in Resources */ = {isa = PBXBuildFile; fileRef = 3F79FFDF2486F7CD003F79C3 /* Explosion.sks */; };
3FE19DB5246C7A22004827AB /* RoundCalculatorService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FE19DB4246C7A22004827AB /* RoundCalculatorService.swift */; };
8B9CA5F1249A3C2E00561704 /* SkillButtonNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B9CA5F0249A3C2E00561704 /* SkillButtonNode.swift */; };
8BB6FF402472B8F000162BBD /* SingeClickButtonNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8BB6FF3F2472B8F000162BBD /* SingeClickButtonNode.swift */; };
9E0E459724796262009817A6 /* GameCenterManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E0E459624796262009817A6 /* GameCenterManager.swift */; };
9E11FF79245CD81100EED3BE /* Fire.sks in Resources */ = {isa = PBXBuildFile; fileRef = 9E11FF77245CD81100EED3BE /* Fire.sks */; };
@ -34,8 +32,6 @@
9E174C86245DD91500209FF0 /* ButtonComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E174C85245DD91500209FF0 /* ButtonComponent.swift */; };
9E174C88245DF1FF00209FF0 /* BackgroundComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E174C87245DF1FF00209FF0 /* BackgroundComponent.swift */; };
9E174C8A245E1A0A00209FF0 /* Background.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E174C89245E1A0A00209FF0 /* Background.swift */; };
9E61EAC4249BAC9100334DDE /* LoserFire.sks in Resources */ = {isa = PBXBuildFile; fileRef = 9E61EAC2249BAC9100334DDE /* LoserFire.sks */; };
9E61EAC7249BB61A00334DDE /* SpinningLogo3DNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E61EAC6249BB61A00334DDE /* SpinningLogo3DNode.swift */; };
9E78ACB6245C9A5300526FF7 /* GameKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E78ACB5245C9A5300526FF7 /* GameKit.framework */; };
9E78ACB8245CB75B00526FF7 /* TeamComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E78ACB7245CB75B00526FF7 /* TeamComponent.swift */; };
9E78ACBA245CBDAF00526FF7 /* HUD.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E78ACB9245CBDAF00526FF7 /* HUD.swift */; };
@ -46,11 +42,15 @@
9EC7E48B2461FBF700396BCD /* SliderNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EC7E48A2461FBF700396BCD /* SliderNode.swift */; };
9EC86B9F245C88A300796EF3 /* Modal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EC86B9E245C88A300796EF3 /* Modal.swift */; };
9EEDE02D246FCD770096C735 /* SpinningLogoEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EEDE02C246FCD770096C735 /* SpinningLogoEntity.swift */; };
9EEDE02F246FCD800096C735 /* SpinningLogoComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EEDE02E246FCD800096C735 /* SpinningLogoComponent.swift */; };
AB21D7D5246C748A00B09CBA /* MapFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB21D7D4246C748A00B09CBA /* MapFactory.swift */; };
AB671B252494ECF0003FBE8D /* EloHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB671B242494ECF0003FBE8D /* EloHelper.swift */; };
ABA03DA0244BD54F00A66916 /* Base.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABA03D9F244BD54F00A66916 /* Base.swift */; };
ABC0C3732481509300387B8F /* MapUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABC0C3722481509300387B8F /* MapUtils.swift */; };
AE0C8E2F249BCC2A00996360 /* RulesScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE0C8E2E249BCC2A00996360 /* RulesScene.swift */; };
AE57F11D248713D7003F0802 /* StateManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE57F118248713D7003F0802 /* StateManager.swift */; };
AE57F11E248713D7003F0802 /* SyncingState.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE57F119248713D7003F0802 /* SyncingState.swift */; };
AE57F11F248713D7003F0802 /* EndGameState.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE57F11A248713D7003F0802 /* EndGameState.swift */; };
AE57F120248713D7003F0802 /* GameState.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE57F11B248713D7003F0802 /* GameState.swift */; };
AE57F121248713D7003F0802 /* MenuState.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE57F11C248713D7003F0802 /* MenuState.swift */; };
C04783EE2468583F004961FB /* intro-music.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = C04783ED2468583F004961FB /* intro-music.mp3 */; };
C04783F024685995004961FB /* SettingsScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = C04783EF24685995004961FB /* SettingsScene.swift */; };
C05BB9C4247D890C00411249 /* SliderComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C05BB9C3247D890C00411249 /* SliderComponent.swift */; };
@ -85,16 +85,14 @@
110360EF244B101B008610AF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
11036112244B3E30008610AF /* MenuScene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuScene.swift; sourceTree = "<group>"; };
116060F6245C57D2004E5A36 /* EntityManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntityManager.swift; sourceTree = "<group>"; };
20F1990424A4FAC1004B7A30 /* new_round.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = new_round.wav; sourceTree = "<group>"; };
20F1990524A4FAC1004B7A30 /* use_boost.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = use_boost.wav; sourceTree = "<group>"; };
20F1990624A4FAC1004B7A30 /* attack_base.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = attack_base.wav; sourceTree = "<group>"; };
3E67853F24728368007B9DE4 /* CElements.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CElements.swift; sourceTree = "<group>"; };
3E6785412472CBEC007B9DE4 /* Way.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Way.swift; sourceTree = "<group>"; };
3E6785432472CC27007B9DE4 /* DefaultWayComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultWayComponent.swift; sourceTree = "<group>"; };
3EAD889424801B6A0048A10A /* RoundTimer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoundTimer.swift; sourceTree = "<group>"; };
3EBD242D245D9332003CECE7 /* Team.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Team.swift; sourceTree = "<group>"; };
3F745DEF246F48FC00CE7375 /* PlayerMoveType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerMoveType.swift; sourceTree = "<group>"; };
3F79FFDF2486F7CD003F79C3 /* Explosion.sks */ = {isa = PBXFileReference; lastKnownFileType = file.sks; path = Explosion.sks; sourceTree = "<group>"; };
3FE19DB4246C7A22004827AB /* RoundCalculatorService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoundCalculatorService.swift; sourceTree = "<group>"; };
8B9CA5F0249A3C2E00561704 /* SkillButtonNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkillButtonNode.swift; sourceTree = "<group>"; };
8BB6FF3F2472B8F000162BBD /* SingeClickButtonNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingeClickButtonNode.swift; sourceTree = "<group>"; };
9E0E459624796262009817A6 /* GameCenterManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameCenterManager.swift; sourceTree = "<group>"; };
9E11FF77245CD81100EED3BE /* Fire.sks */ = {isa = PBXFileReference; lastKnownFileType = file.sks; path = Fire.sks; sourceTree = "<group>"; };
@ -103,8 +101,6 @@
9E174C85245DD91500209FF0 /* ButtonComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonComponent.swift; sourceTree = "<group>"; };
9E174C87245DF1FF00209FF0 /* BackgroundComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundComponent.swift; sourceTree = "<group>"; };
9E174C89245E1A0A00209FF0 /* Background.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Background.swift; sourceTree = "<group>"; };
9E61EAC2249BAC9100334DDE /* LoserFire.sks */ = {isa = PBXFileReference; lastKnownFileType = file.sks; path = LoserFire.sks; sourceTree = "<group>"; };
9E61EAC6249BB61A00334DDE /* SpinningLogo3DNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpinningLogo3DNode.swift; sourceTree = "<group>"; };
9E78ACB5245C9A5300526FF7 /* GameKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameKit.framework; path = System/Library/Frameworks/GameKit.framework; sourceTree = SDKROOT; };
9E78ACB7245CB75B00526FF7 /* TeamComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TeamComponent.swift; sourceTree = "<group>"; };
9E78ACB9245CBDAF00526FF7 /* HUD.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HUD.swift; sourceTree = "<group>"; };
@ -116,11 +112,15 @@
9EC86B9E245C88A300796EF3 /* Modal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Modal.swift; sourceTree = "<group>"; };
9ECD3699245C91F7008DEEBD /* GoldWars.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = GoldWars.entitlements; sourceTree = "<group>"; };
9EEDE02C246FCD770096C735 /* SpinningLogoEntity.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpinningLogoEntity.swift; sourceTree = "<group>"; };
9EEDE02E246FCD800096C735 /* SpinningLogoComponent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpinningLogoComponent.swift; sourceTree = "<group>"; };
AB21D7D4246C748A00B09CBA /* MapFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapFactory.swift; sourceTree = "<group>"; };
AB671B242494ECF0003FBE8D /* EloHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EloHelper.swift; sourceTree = "<group>"; };
ABA03D9F244BD54F00A66916 /* Base.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Base.swift; sourceTree = "<group>"; };
ABC0C3722481509300387B8F /* MapUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapUtils.swift; sourceTree = "<group>"; };
AE0C8E2E249BCC2A00996360 /* RulesScene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RulesScene.swift; sourceTree = "<group>"; };
AE57F118248713D7003F0802 /* StateManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StateManager.swift; sourceTree = "<group>"; };
AE57F119248713D7003F0802 /* SyncingState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SyncingState.swift; sourceTree = "<group>"; };
AE57F11A248713D7003F0802 /* EndGameState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EndGameState.swift; sourceTree = "<group>"; };
AE57F11B248713D7003F0802 /* GameState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GameState.swift; sourceTree = "<group>"; };
AE57F11C248713D7003F0802 /* MenuState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MenuState.swift; sourceTree = "<group>"; };
C04783ED2468583F004961FB /* intro-music.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = "intro-music.mp3"; sourceTree = "<group>"; };
C04783EF24685995004961FB /* SettingsScene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsScene.swift; sourceTree = "<group>"; };
C05BB9C3247D890C00411249 /* SliderComponent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SliderComponent.swift; sourceTree = "<group>"; };
@ -172,10 +172,8 @@
110360D1244B101A008610AF /* GoldWars */ = {
isa = PBXGroup;
children = (
AE6BB1CB2481941D0063ECAE /* States */,
C04783ED2468583F004961FB /* intro-music.mp3 */,
20F1990624A4FAC1004B7A30 /* attack_base.wav */,
20F1990424A4FAC1004B7A30 /* new_round.wav */,
20F1990524A4FAC1004B7A30 /* use_boost.wav */,
9ECD3699245C91F7008DEEBD /* GoldWars.entitlements */,
9E11FF74245CD79100EED3BE /* Partikels */,
116060F5245C5709004E5A36 /* Entities */,
@ -195,8 +193,6 @@
9E0E459624796262009817A6 /* GameCenterManager.swift */,
C04783EF24685995004961FB /* SettingsScene.swift */,
3EAD889424801B6A0048A10A /* RoundTimer.swift */,
AB671B242494ECF0003FBE8D /* EloHelper.swift */,
AE0C8E2E249BCC2A00996360 /* RulesScene.swift */,
);
path = GoldWars;
sourceTree = "<group>";
@ -218,15 +214,15 @@
9E174C85245DD91500209FF0 /* ButtonComponent.swift */,
9E174C81245DD81D00209FF0 /* ButtonNode.swift */,
9EA3ABE8245C6DAA006BC61D /* DefaultBaseComponent.swift */,
3E6785432472CC27007B9DE4 /* DefaultWayComponent.swift */,
C064E9A9246C114C0022B228 /* LabelComponent.swift */,
C064E9A7246C0EA50022B228 /* LabelNode.swift */,
9EC2FBA62476B1EC00ABF11F /* PlayerInfoComponent.swift */,
8BB6FF3F2472B8F000162BBD /* SingeClickButtonNode.swift */,
8B9CA5F0249A3C2E00561704 /* SkillButtonNode.swift */,
C05BB9C3247D890C00411249 /* SliderComponent.swift */,
9EC7E48A2461FBF700396BCD /* SliderNode.swift */,
9EEDE02E246FCD800096C735 /* SpinningLogoComponent.swift */,
9E78ACB7245CB75B00526FF7 /* TeamComponent.swift */,
9E61EAC6249BB61A00334DDE /* SpinningLogo3DNode.swift */,
);
path = Components;
sourceTree = "<group>";
@ -252,7 +248,6 @@
children = (
3F79FFDF2486F7CD003F79C3 /* Explosion.sks */,
9E11FF77245CD81100EED3BE /* Fire.sks */,
9E61EAC2249BAC9100334DDE /* LoserFire.sks */,
);
path = Partikels;
sourceTree = "<group>";
@ -269,6 +264,7 @@
isa = PBXGroup;
children = (
3EBD242D245D9332003CECE7 /* Team.swift */,
3F745DEF246F48FC00CE7375 /* PlayerMoveType.swift */,
);
path = Enums;
sourceTree = "<group>";
@ -301,6 +297,18 @@
path = Map;
sourceTree = "<group>";
};
AE6BB1CB2481941D0063ECAE /* States */ = {
isa = PBXGroup;
children = (
AE57F11A248713D7003F0802 /* EndGameState.swift */,
AE57F11B248713D7003F0802 /* GameState.swift */,
AE57F11C248713D7003F0802 /* MenuState.swift */,
AE57F118248713D7003F0802 /* StateManager.swift */,
AE57F119248713D7003F0802 /* SyncingState.swift */,
);
path = States;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@ -383,13 +391,9 @@
buildActionMask = 2147483647;
files = (
110360DE244B101A008610AF /* Main.storyboard in Resources */,
20F1990924A4FAC1004B7A30 /* attack_base.wav in Resources */,
9E11FF79245CD81100EED3BE /* Fire.sks in Resources */,
20F1990724A4FAC1004B7A30 /* new_round.wav in Resources */,
110360E0244B101B008610AF /* Assets.xcassets in Resources */,
110360E3244B101B008610AF /* LaunchScreen.storyboard in Resources */,
9E61EAC4249BAC9100334DDE /* LoserFire.sks in Resources */,
20F1990824A4FAC1004B7A30 /* use_boost.wav in Resources */,
C04783EE2468583F004961FB /* intro-music.mp3 in Resources */,
3F79FFE02486F7CD003F79C3 /* Explosion.sks in Resources */,
);
@ -423,9 +427,12 @@
9E174C88245DF1FF00209FF0 /* BackgroundComponent.swift in Sources */,
9E78ACBA245CBDAF00526FF7 /* HUD.swift in Sources */,
9EC2FBA72476B1EC00ABF11F /* PlayerInfoComponent.swift in Sources */,
AE57F11F248713D7003F0802 /* EndGameState.swift in Sources */,
9EEDE02D246FCD770096C735 /* SpinningLogoEntity.swift in Sources */,
AE57F11D248713D7003F0802 /* StateManager.swift in Sources */,
AE57F11E248713D7003F0802 /* SyncingState.swift in Sources */,
AE57F120248713D7003F0802 /* GameState.swift in Sources */,
9E174C86245DD91500209FF0 /* ButtonComponent.swift in Sources */,
AB671B252494ECF0003FBE8D /* EloHelper.swift in Sources */,
11036113244B3E30008610AF /* MenuScene.swift in Sources */,
C099579C246C5E5C0016AA22 /* DataService.swift in Sources */,
AB21D7D5246C748A00B09CBA /* MapFactory.swift in Sources */,
@ -433,21 +440,22 @@
9E174C8A245E1A0A00209FF0 /* Background.swift in Sources */,
8BB6FF402472B8F000162BBD /* SingeClickButtonNode.swift in Sources */,
C064E9A8246C0EA50022B228 /* LabelNode.swift in Sources */,
8B9CA5F1249A3C2E00561704 /* SkillButtonNode.swift in Sources */,
3F745DF0246F48FC00CE7375 /* PlayerMoveType.swift in Sources */,
3EAD889524801B6A0048A10A /* RoundTimer.swift in Sources */,
AE0C8E2F249BCC2A00996360 /* RulesScene.swift in Sources */,
3E67854024728368007B9DE4 /* CElements.swift in Sources */,
ABA03DA0244BD54F00A66916 /* Base.swift in Sources */,
C064E9AC246C151F0022B228 /* Label.swift in Sources */,
ABC0C3732481509300387B8F /* MapUtils.swift in Sources */,
9E174C82245DD81D00209FF0 /* ButtonNode.swift in Sources */,
9EC7E48B2461FBF700396BCD /* SliderNode.swift in Sources */,
9E61EAC7249BB61A00334DDE /* SpinningLogo3DNode.swift in Sources */,
9EEDE02F246FCD800096C735 /* SpinningLogoComponent.swift in Sources */,
9E174C84245DD8CE00209FF0 /* Button.swift in Sources */,
110360DB244B101A008610AF /* GameViewController.swift in Sources */,
3E6785442472CC27007B9DE4 /* DefaultWayComponent.swift in Sources */,
C05BB9C4247D890C00411249 /* SliderComponent.swift in Sources */,
110360D3244B101A008610AF /* AppDelegate.swift in Sources */,
9EC86B9F245C88A300796EF3 /* Modal.swift in Sources */,
AE57F121248713D7003F0802 /* MenuState.swift in Sources */,
C05FAED62468559D0006AF2E /* SoundManager.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -609,9 +617,9 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = GoldWars/GoldWars.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 4;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 3;
DEVELOPMENT_TEAM = DDKFQG46BQ;
INFOPLIST_FILE = GoldWars/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@ -621,7 +629,7 @@
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = de.hft.stuttgart.ip2.goldwars;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
PROVISIONING_PROFILE_SPECIFIER = "Developer Profile";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 2;
};
@ -632,9 +640,9 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = GoldWars/GoldWars.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 4;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 3;
DEVELOPMENT_TEAM = DDKFQG46BQ;
INFOPLIST_FILE = GoldWars/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@ -644,7 +652,7 @@
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = de.hft.stuttgart.ip2.goldwars;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
PROVISIONING_PROFILE_SPECIFIER = "Developer Profile";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 2;
};

View File

@ -7,45 +7,35 @@
//
import UIKit
import os
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
let LOG = OSLog.init(subsystem: "AppDelegate", category: "AppDelegate")
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
os_log("application", log: LOG, type: .info)
return true
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
os_log("applicationWillResignActive", log: LOG, type: .debug)
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
os_log("applicationDidEnterBackground", log: LOG, type: .debug)
NotificationCenter.default.post(name: Notification.Name(rawValue: "pauseGame"), object: nil)
MultiplayerNetwork.sharedInstance.sendNotificationToPlayer(name: "pauseGame")
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
os_log("applicationWillEnterForeground", log: LOG, type: .debug)
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
os_log("applicationDidBecomeActive", log: LOG, type: .debug)
NotificationCenter.default.post(name: Notification.Name(rawValue: "resumeGame"), object: nil)
MultiplayerNetwork.sharedInstance.sendNotificationToPlayer(name: "resumeGame")
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

View File

@ -1,17 +1,17 @@
{
"images" : [
{
"filename" : "BaseTexture.png",
"filename" : "Base.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "BaseTexture-1.png",
"filename" : "Base-1.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "BaseTexture-2.png",
"filename" : "Base-2.png",
"idiom" : "universal",
"scale" : "3x"
}

View File

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "Credits.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 997 KiB

View File

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "RulesBasen.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

View File

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "RulesBoost.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 KiB

View File

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "RulesEinheiten.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

View File

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "RulesErfolge.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 KiB

View File

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "RulesSpiel.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

View File

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "RulesSpielende.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

View File

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "atk_button.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

View File

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "def_button.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

View File

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "exitButton.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "finish_button 2.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -1,23 +0,0 @@
{
"images" : [
{
"filename" : "goldLettering.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "goldLettering-1.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "goldLettering-2.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

View File

@ -1,23 +0,0 @@
{
"images" : [
{
"filename" : "goldWarsName.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "goldWarsName-1.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "goldWarsName-2.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 234 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 234 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 234 KiB

View File

@ -1,23 +0,0 @@
{
"images" : [
{
"filename" : "gold_button00.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "gold_button00-1.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "gold_button00-2.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "gold_button_2.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

View File

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "gold_button_4.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

View File

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "gold_button_4.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

View File

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "questionmark.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

View File

@ -1,23 +0,0 @@
{
"images" : [
{
"filename" : "roundInfoTexture.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "roundInfoTexture-1.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "roundInfoTexture-2.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "spy_button.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

View File

@ -1,23 +0,0 @@
{
"images" : [
{
"filename" : "warsLettering.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "warsLettering-1.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "warsLettering-2.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 KiB

View File

@ -1,23 +0,0 @@
{
"images" : [
{
"filename" : "winner.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "winner-1.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "winner-2.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 448 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 448 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 448 KiB

View File

@ -0,0 +1,27 @@
//
// AttackActionComponent.swift
// GoldWars
//
// Created by Niko Jochim on 03.05.20.
// Copyright © 2020 SP2. All rights reserved.
//
import GameplayKit
class AttackActionComponent: GKComponent {
init(unitCount: Int, adjacencyList: Array<Base>, position: CGPoint) {
super.init()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func action() {
// Not implemented yet
}
}

View File

@ -21,15 +21,17 @@ class ButtonNode: SKSpriteNode {
}
}
}
var label: SKLabelNode
var onButtonPress: () -> ()
init(textureName: String, text: String, isEnabled: Bool, position: CGPoint, onButtonPress: @escaping () -> ()) {
self.onButtonPress = onButtonPress
self.isEnabled = isEnabled
let texture = SKTexture(imageNamed: textureName)
super.init(texture: texture, color: SKColor.white, size: texture.size())
self.position = position
label = SKLabelNode(fontNamed: "Courier-Bold")
let label = SKLabelNode(fontNamed: "Courier-Bold")
label.fontSize = 30
label.fontColor = SKColor.black
label.zPosition = 1
@ -37,17 +39,10 @@ class ButtonNode: SKSpriteNode {
label.text = text
label.name = "label"
super.init(texture: texture, color: SKColor.white, size: texture.size())
self.position = position
self.addChild(label)
isUserInteractionEnabled = true
}
func setTexture(textureName: String) {
super.texture = SKTexture(imageNamed: textureName)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if isEnabled {
let action = SKAction.sequence(

View File

@ -12,11 +12,20 @@ import GameKit
class DefaultBaseComponent: GKComponent {
var spriteNode: BaseNode
var labelNode : SKLabelNode
init(texture: SKTexture, position: CGPoint) {
spriteNode = BaseNode(texture: texture, size: CGSize(width: 100, height: 100))
spriteNode.position = position
spriteNode.zPosition = 2
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
super.init()
}

View File

@ -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")
}
}

View File

@ -1,58 +0,0 @@
//
// SkillButtonNode.swift
// GoldWars
//
// Created by Simon Kellner on 17.06.20.
// Copyright © 2020 SP2. All rights reserved.
//
import SpriteKit
class SkillButtonNode: ButtonNode {
var cooldownCounter = 0
var hasCooled: Bool = false
let cooldown: Int
let displayText: String
init(textureName: String, text: String, isEnabled: Bool, cooldown: Int, position: CGPoint, onButtonPress: @escaping () -> ()) {
self.cooldown = cooldown
self.displayText = text
super.init(textureName: textureName, text: text, isEnabled: isEnabled, position: position, onButtonPress: onButtonPress)
self.size = CGSize(width: 100, height: 100)
self.label.fontSize = 25
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
super.isEnabled = false
self.cooldownCounter = self.cooldown
self.hasCooled = true
}
func decreaseCooldown() {
if self.cooldownCounter <= 1 {
super.isEnabled = true
super.label.text = self.displayText
let newRoundAction = SKAction.sequence([
SKAction.scale(by: 1.5, duration: 1),
SKAction.scale(by: 1/1.5, duration: 1),
])
if hasCooled {
self.run(newRoundAction)
self.hasCooled = false
}
} else {
super.isEnabled = false
self.cooldownCounter -= 1
super.label.text = self.cooldownCounter.description
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

View File

@ -0,0 +1,25 @@
//
// SkillComponent.swift
// GoldWars
//
// Created by Marcel Schwarz on 24.05.20.
// Copyright © 2020 SP2. All rights reserved.
//
import Foundation
import GameKit
import GameplayKit
class SkillComponent: GKComponent {
var skillButtonNode: SingeClickButtonNode
init(textureName: String, text: String, position: CGPoint, isEnabled: Bool, onButtonPress: @escaping () -> ()) {
skillButtonNode = SingeClickButtonNode(textureName: textureName, text: text, isEnabled: isEnabled, position: position, onButtonPress: onButtonPress)
super.init()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

View File

@ -12,14 +12,12 @@ import SpriteKit
class SliderNode :SKNode {
var sliderLine :SKShapeNode
var hiddenKnob :SliderKnob
var silderKnob :SKSpriteNode
var sliderKnob :SliderKnob
var width: CGFloat
var getValue: CGFloat{
get{
silderKnob.position = hiddenKnob.position
return ((hiddenKnob.position.x.rounded() - hiddenKnob.min) / width)
return ((sliderKnob.position.x.rounded() - sliderKnob.min) / width)
}
}
@ -29,28 +27,19 @@ class SliderNode :SKNode {
sliderLine.position = position
sliderLine.fillColor = SKColor.white
sliderLine.zPosition = 4
hiddenKnob = SliderKnob(circleOfRadius: 58 )
hiddenKnob.min = position.x - width / 2
hiddenKnob.max = position.x + width / 2
hiddenKnob.fillColor = SKColor.red
hiddenKnob.alpha = 0.001
hiddenKnob.zPosition = sliderLine.zPosition + 1
hiddenKnob.position = CGPoint(x: sliderLine.position.x, y: sliderLine.position.y + 1)
silderKnob = SKSpriteNode(texture: SKTexture(imageNamed: "yellow_boxTick"))
silderKnob.position = hiddenKnob.position
silderKnob.zPosition = hiddenKnob.zPosition - 1
silderKnob.size = CGSize(width: 50, height: 50)
sliderKnob = SliderKnob(circleOfRadius: 20)
sliderKnob.min = position.x - width / 2
sliderKnob.max = position.x + width / 2
sliderKnob.fillColor = SKColor.red
sliderKnob.zPosition = sliderLine.zPosition + 1
sliderKnob.position = CGPoint(x: sliderLine.position.x, y: sliderLine.position.y + 1)
super.init()
self.name = "slider"
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class SliderKnob: SKShapeNode {
@ -71,7 +60,6 @@ class SliderKnob: SKShapeNode {
}
if(self.position.x >= max){
self.position.x = max
}
}
}

View File

@ -1,40 +0,0 @@
//
// SpinningLogo3DNode.swift
// GoldWars
//
// Created by Niko Jochim on 18.06.20.
// Copyright © 2020 SP2. All rights reserved.
//
import Foundation
import SpriteKit
import GameKit
class SpinningLogo3DNode : SK3DNode {
init() {
super.init(viewportSize: CGSize(width: 250, height: 250))
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.scnScene = scnScene
self.position = position
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

View File

@ -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")
}
}

View File

@ -14,7 +14,6 @@ class TeamComponent: GKComponent {
var team: Team
var player: GKPlayer
let fire: SKEmitterNode
var unitcountLabel : SKLabelNode
init(team: Team, player: GKPlayer, position: CGPoint) {
fire = SKEmitterNode(fileNamed: "Fire")!
@ -26,15 +25,6 @@ class TeamComponent: GKComponent {
self.team = team
self.player = player
unitcountLabel = SKLabelNode(text: "")
unitcountLabel.fontColor = SKColor.black
unitcountLabel.horizontalAlignmentMode = .left
unitcountLabel.verticalAlignmentMode = .center
unitcountLabel.fontName = "AvenirNext-Bold"
unitcountLabel.fontSize = 15
unitcountLabel.position = CGPoint(x: position.x + 30 , y: position.y - 50 )
unitcountLabel.zPosition = 3
super.init()
fire.particleColor = getColor(by: team)
}
@ -47,6 +37,8 @@ class TeamComponent: GKComponent {
switch team {
case .team1: return SKColor.red
case .team2: return SKColor.purple
case .team3: return SKColor.green
case .team4: return SKColor.gray
}
}

View File

@ -5,19 +5,6 @@
// Created by Tim Herbst on 13.05.20.
// Copyright © 2020 SP2. All rights reserved.
//
import Foundation
struct Heartbeat: Codable {
var date: Date
}
struct NotificationModel: Codable {
let name: String
init(name: String) {
self.name = name
}
}
struct PlayerMove: Codable {
let fromBase: Int
@ -68,11 +55,11 @@ class DataService {
var entityManager = EntityManager.gameEMInstance
func addMove(playerMove: PlayerMove) {
let equalMoveIdx = localRoundData.localPlayerMoves.firstIndex(where: { (localPlayerMove) -> Bool in
localPlayerMove.toBase == playerMove.toBase && localPlayerMove.fromBase == playerMove.fromBase
})
if equalMoveIdx != nil {
localRoundData.localPlayerMoves[equalMoveIdx!].unitCount = Int(localRoundData.localPlayerMoves[equalMoveIdx!].unitCount) + Int(playerMove.unitCount)
var equalMove = localRoundData.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.localRoundData.localPlayerMoves.append(playerMove)
}

View File

@ -1,70 +0,0 @@
//
// EloHelper.swift
// GoldWars
//
// Created by Marcel Schwarz on 13.06.20.
// Copyright © 2020 SP2. All rights reserved.
//
import GameKit
import os
struct EloDataForPeer : Codable {
let scoreToReport: Int64
}
class EloHelper {
static private let LOG = OSLog.init(subsystem: "EloHelper", category: "EloHelper")
static let IDENTIFIER_ALL_ELO = "de.hft.stuttgart.ip2.goldwars.bestelo"
static let IDENTIFIER_ELO = "de.hft.stuttgart.ip2.goldwars.matchmaking"
static func updateEloScore(winner: GKPlayer, hatDenNikoGemacht looser: GKPlayer) {
let leaderboard = GKLeaderboard.init(players: [winner, looser])
leaderboard.identifier = EloHelper.IDENTIFIER_ELO
leaderboard.loadScores{scores, error in
// Get Scores
let R_looser = scores?.filter { $0.player == looser }.first ?? GKScore(leaderboardIdentifier: EloHelper.IDENTIFIER_ELO, player: looser)
let R_winner = scores?.filter { $0.player == winner }.first ?? GKScore(leaderboardIdentifier: EloHelper.IDENTIFIER_ELO, player: winner)
// Calc ELO
let Q_looser = pow(10.0, Double(R_looser.value) / 400.0)
let Q_winner = pow(10.0, Double(R_winner.value) / 400.0)
let E_looser = Q_looser / (Q_looser + Q_winner)
let E_winner = Q_winner / (Q_looser + Q_winner)
let R_winner_new = Int64(Double(R_winner.value) + 10.0 * (1.0 - E_winner))
let R_looser_new = Int64(Double(R_looser.value) + 10.0 * (0.0 - E_looser))
// Update Elo on leaderboard
let winner_new = GKScore(leaderboardIdentifier: EloHelper.IDENTIFIER_ELO, player: winner)
winner_new.value = R_winner_new
let looser_new = GKScore(leaderboardIdentifier: EloHelper.IDENTIFIER_ELO, player: looser)
looser_new.value = R_looser_new
let scoreForPeer = winner == GameCenterManager.sharedInstance.localPlayer ? looser_new : winner_new
let scoreForHost = winner == GameCenterManager.sharedInstance.localPlayer ? winner_new : looser_new
MultiplayerNetwork.sharedInstance.sendEloData(scoreToReport: scoreForPeer)
reportScore(score: scoreForHost.value)
}
}
static func reportScore(score: Int64) {
let gkScoreElo = GKScore(leaderboardIdentifier: EloHelper.IDENTIFIER_ELO, player: GKLocalPlayer.local)
gkScoreElo.value = score
let gkScoreAll = GKScore(leaderboardIdentifier: EloHelper.IDENTIFIER_ALL_ELO, player: GKLocalPlayer.local)
gkScoreAll.value = score
GKScore.report([gkScoreAll, gkScoreElo], withCompletionHandler: { error in
if error != nil {
os_log("Could not report %@", log: LOG, type: .error, error!.localizedDescription)
} else {
os_log("New Scores reported to EloSystem", log: self.LOG, type: .info)
}
})
}
}

View File

@ -38,28 +38,22 @@ class Base: GKEntity{
self.unitCount = 500
}
if ownershipPlayer == GKLocalPlayer.local {
self.component(ofType: TeamComponent.self)?.unitcountLabel.text = "\(unitCount)"
self.component(ofType: DefaultBaseComponent.self)?.labelNode.text = "\(unitCount)"
}
}
func doPlayerMoveTypeToBase(base: Base, units: Int) -> [GKEntity]{
func doPlayerMoveTypeToBase(base: Base, playerMoveType: PlayerMoveType, units: Int) -> [GKEntity]{
if base.ownershipPlayer != GKLocalPlayer.local {
base.changeOwnership = true
}
base.ownershipPlayer = self.ownershipPlayer
self.unitCount -= units
base.unitCount += units
self.component(ofType: TeamComponent.self)?.unitcountLabel.text = "\(self.unitCount)"
if base.component(ofType: TeamComponent.self)?.unitcountLabel.text != "" {
if base.ownershipPlayer != self.ownershipPlayer {
base.component(ofType: TeamComponent.self)?.unitcountLabel.text = "\(abs(base.unitCount - units * 2))"
} else {
base.component(ofType: TeamComponent.self)?.unitcountLabel.text = "\(base.unitCount)"
}
}
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)
unitCount: units * playerMoveType.rawValue)
)
return [self, base]
}

View File

@ -15,7 +15,6 @@ class EntityManager {
static let gameEMInstance = EntityManager()
static let menuEMInstance = EntityManager()
static let settingsEMInstance = EntityManager()
static let rulesEMInstance = EntityManager()
var entities = Set<GKEntity>()
var scene: SKScene
@ -49,7 +48,6 @@ class EntityManager {
scene.addChild(hudEntitiy.hostUnitsLabel)
scene.addChild(hudEntitiy.peerLabel)
scene.addChild(hudEntitiy.peerUnitsLabel)
scene.addChild(hudEntitiy.leaveGame)
scene.addChild(hudEntitiy.defSkill)
scene.addChild(hudEntitiy.atkSkill)
scene.addChild(hudEntitiy.spySkill)
@ -59,28 +57,15 @@ class EntityManager {
scene.addChild(hudEntitiy.currentRoundLabel)
scene.addChild(hudEntitiy.roundsLabel)
scene.addChild(hudEntitiy.roundLabel)
scene.addChild(hudEntitiy.blockWholeScreenPane)
}
if let spinningLogoEntity = entity as? SpinningLogoEntity {
scene.addChild(spinningLogoEntity.spinningLogoNode)
scene.addChild(spinningLogoEntity.goldLetteringNode)
scene.addChild(spinningLogoEntity.warsLetteringNode)
}
if let wayEntity = entity as? Way {
scene.addChild(wayEntity.localWayComponent)
}
if let spriteNode = entity.component(ofType: DefaultBaseComponent.self) {
scene.addChild(spriteNode.labelNode)
scene.addChild(spriteNode.spriteNode)
}
if let spriteNode = entity.component(ofType: TeamComponent.self) {
scene.addChild(spriteNode.unitcountLabel)
scene.addChild(spriteNode.fire)
if let fire = entity.component(ofType: TeamComponent.self)?.fire{
scene.addChild(fire)
}
if let buttonNode = entity.component(ofType: ButtonComponent.self)?.buttonNode {
scene.addChild(buttonNode)
}
@ -90,14 +75,18 @@ class EntityManager {
}
}
if let sliderNode = entity.component(ofType: SliderComponent.self)?.sliderNode {
scene.addChild(sliderNode.hiddenKnob)
scene.addChild(sliderNode.sliderKnob)
scene.addChild(sliderNode.sliderLine)
scene.addChild(sliderNode.silderKnob)
}
if let labelNode = entity.component(ofType: LabelComponent.self)?.labelNode {
scene.addChild(labelNode)
}
if let node = entity.component(ofType: SpinningLogoComponent.self)?.node {
scene.addChild(node)
}
if let wayNode = entity.component(ofType: DefaultWayComponent.self)?.shapeNode {
scene.addChild(wayNode)
}
}
func remove(_ entity: GKEntity) {
@ -105,9 +94,8 @@ class EntityManager {
spriteNode.removeFromParent()
}
if let sliderNode = entity.component(ofType: SliderComponent.self)?.sliderNode {
sliderNode.hiddenKnob.removeFromParent()
sliderNode.sliderKnob.removeFromParent()
sliderNode.sliderLine.removeFromParent()
sliderNode.silderKnob.removeFromParent()
}
if let modalButton = entity.component(ofType: ButtonComponent.self) {
modalButton.buttonNode.removeFromParent()
@ -130,11 +118,9 @@ class EntityManager {
position: (base.component(ofType: DefaultBaseComponent.self)?.spriteNode.position)!
)
)
if let spriteNode = entity.component(ofType: TeamComponent.self) {
scene.addChild(spriteNode.unitcountLabel)
scene.addChild(spriteNode.fire)
if let fire = entity.component(ofType: TeamComponent.self)?.fire{
scene.addChild(fire)
}
SoundManager.sharedInstance.playSoundEffect(pathToFile: "attack_base",fileExtension: "wav",volumeLevel: -3.0)
}
GameCenterManager.sharedInstance.addAchievementProgress(identifier: "de.hft.stuttgart.ip2.goldwars.capture.fifty.bases", increasePercentComplete: 2)
}
@ -153,49 +139,12 @@ class EntityManager {
if snapBase.ownership != nil {
getOwnerBySnapBase = GameCenterManager.sharedInstance.getGKPlayerByUsername(displayName: snapBase.ownership!)
} else {
if entity.component(ofType: TeamComponent.self) != nil {
runExplosion(base: base)
entity.component(ofType: TeamComponent.self)!.fire.removeFromParent()
entity.component(ofType: TeamComponent.self)!.unitcountLabel.removeFromParent()
entity.removeComponent(ofType: TeamComponent.self)
}
base.ownershipPlayer = nil
}
if getOwnerBySnapBase != nil {
if base.ownershipPlayer != getOwnerBySnapBase {
//TODO: Outsource following with a AnimationManager
runExplosion(base: base)
}
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 spriteNode = entity.component(ofType: TeamComponent.self) {
scene.addChild(spriteNode.unitcountLabel)
scene.addChild(spriteNode.fire)
}
}
if getOwnerBySnapBase == GKLocalPlayer.local {
base.component(ofType: TeamComponent.self)?.unitcountLabel.text = "\(base.unitCount)"
} else {
base.component(ofType: TeamComponent.self)?.unitcountLabel.text = ""
}
}
}
getHUD()!.updateUnitSum()
}
func runExplosion(base: Base) {
let explosion = SKEmitterNode(fileNamed: "Explosion")!
scene.addChild(explosion)
explosion.zPosition = 2
@ -209,6 +158,33 @@ class EntityManager {
explosion.run(sequence)
}
if getOwnerBySnapBase == GKLocalPlayer.local {
base.component(ofType: DefaultBaseComponent.self)?.labelNode.text = "\(base.unitCount)"
} else {
base.component(ofType: DefaultBaseComponent.self)?.labelNode.text = ""
}
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()!.updateUnitSum()
}
func getSnapshotBaseById(baseId: Int, snapshotModel: SnapshotModel) -> BaseEntityModel{
return snapshotModel.baseEntites.filter { $0.baseId == baseId }[0]
}
@ -284,7 +260,7 @@ class EntityManager {
}
func getBackground() -> GKEntity? {
return entities.filter{$0 is Background}.first
return entities.filter{$0 is Background}[0]
}
func getBaseNodeByTeam(for team: Team) -> SKSpriteNode? {
@ -295,13 +271,8 @@ class EntityManager {
return entities.filter{$0 is Button && ($0 as! Button).name == buttonName }[0] as! Button
}
func changeSettingsButtonText(buttonName: String, text: String) {
let button = entities.filter{$0 is Button && ($0 as! Button).name == buttonName }[0] as! Button
button.component(ofType: ButtonComponent.self)?.buttonNode.label.text = text
}
func getHUD() -> HUD? {
return entities.filter{$0 is HUD}.first as? HUD
return entities.filter{$0 is HUD}[0] as? HUD
}
func getSnapshotModel() -> SnapshotModel {
@ -346,7 +317,7 @@ class EntityManager {
if let slider = modal.component(ofType: SliderComponent.self) {
slider.sliderNode.removeFromParent()
slider.sliderNode.hiddenKnob.removeFromParent()
slider.sliderNode.sliderKnob.removeFromParent()
slider.sliderNode.sliderLine.removeFromParent()
}
@ -354,20 +325,18 @@ class EntityManager {
button.buttonNode.removeFromParent()
}
self.remove(modal)
for child in scene.children {
if(child.name != "fire"){
child.alpha = 1
}
}
isModal = false
}
})
}
func exitToMenu() {
GameCenterManager.sharedInstance.reset()
EntityManager.gameEMInstance.getTimer()?.stopTimer()
RoundCalculatorService.sharedInstance.currentRound = 1
EntityManager.gameEMInstance.scene.view?.presentScene(EntityManager.menuEMInstance.scene)
EntityManager.gameEMInstance.entities.removeAll()
EntityManager.gameEMInstance.scene.removeFromParent()
}
func getTimer() -> RoundTimer? {
return getHUD()?.roundTimer
}

View File

@ -17,12 +17,12 @@ class HUD: GKEntity {
var peerLabel:SKLabelNode
var peerUnitsLabel:SKLabelNode
var host: GKPlayer?
var peer: GKPlayer?
var leaveGame: ButtonNode
var spySkill: SkillButtonNode
var defSkill: SkillButtonNode
var atkSkill: SkillButtonNode
var spySkill: SingeClickButtonNode
var defSkill: SingeClickButtonNode
var atkSkill: SingeClickButtonNode
var roundTimerLabel: SKLabelNode
let roundTimer: RoundTimer
@ -33,92 +33,76 @@ class HUD: GKEntity {
var roundLabel: SKLabelNode
var finishButton: ButtonNode
var blockWholeScreenPane: SKSpriteNode
init(size: CGSize) {
hostLabel = SKLabelNode(text: GameCenterManager.sharedInstance.hostingPlayer?.displayName)
hostLabel.name = "hostLabel"
host = GameCenterManager.sharedInstance.hostingPlayer
peer = GameCenterManager.sharedInstance.peerPlayer
hostLabel = SKLabelNode(text: host?.displayName)
hostUnitsLabel = SKLabelNode(text: "500" )
peerLabel = SKLabelNode(text: GameCenterManager.sharedInstance.peerPlayer?.displayName)
peerLabel.name = "peerLabel"
peerLabel = SKLabelNode(text: peer?.displayName)
peerUnitsLabel = SKLabelNode(text: "500")
roundTimerLabel = SKLabelNode(text: "")
roundTimerLabel.fontColor = UIColor.black
roundTimerLabel.fontSize = CGFloat(45)
roundTimerLabel.position = CGPoint(x: size.width * 0.5, y: size.height * 0.9)
roundTimerLabel.zPosition = 900
roundTimerLabel.horizontalAlignmentMode = .center
self.roundTimer = RoundTimer()
finishButton = SingeClickButtonNode(
textureName: "finish_button",
text: "",
spySkill = SingeClickButtonNode(
textureName: "yellow_circle",
text: "Spy",
isEnabled: true,
position: CGPoint(
x: EntityManager.gameEMInstance.scene.size.width * 0.95 ,
y: EntityManager.gameEMInstance.scene.size.height * 0.1),
onButtonPress: { }
position: CGPoint(x: EntityManager.gameEMInstance.scene.size.width * 0.75, y: EntityManager.gameEMInstance.scene.size.height * 0.1),
onButtonPress: {
EntityManager.gameEMInstance.getOpponentBases(for: EntityManager.gameEMInstance.getTeam()).forEach({base in base.component(ofType: DefaultBaseComponent.self)?.labelNode.text = "\(base.unitCount)"})
GameCenterManager.sharedInstance.addAchievementProgress(identifier: "de.hft.stuttgart.ip2.goldwars.skill.first.time", increasePercentComplete: 100)
GameCenterManager.sharedInstance.addAchievementProgress(identifier: "de.hft.stuttgart.ip2.goldwars.skill.spy.ten", increasePercentComplete: 10)
}
)
leaveGame = ButtonNode(textureName: "exitButton", text: "" , isEnabled: true, position: CGPoint(x: EntityManager.gameEMInstance.scene.size.width * 0.05, y: EntityManager.gameEMInstance.scene.size.height * 0.11), onButtonPress: {
EntityManager.gameEMInstance.add(Modal(modaltype: .QuitGame, base: nil, anchorPoint: CGPoint(x: EntityManager.gameEMInstance.scene.size.width / 2 , y: EntityManager.gameEMInstance.scene.size.height / 2), gameScene: EntityManager.gameEMInstance.scene, currentDraggedBase: nil, touchLocation: nil, collisionBase: nil))
})
leaveGame.size = CGSize(width: 120, height: 120);
defSkill = SkillButtonNode(
textureName: "def_button",
defSkill = SingeClickButtonNode(
textureName: "yellow_circle",
text: "Def",
isEnabled: true,
cooldown: 4,
position: CGPoint(x: finishButton.position.x - 85, y: finishButton.position.y),
position: CGPoint(x: EntityManager.gameEMInstance.scene.size.width * 0.85, y: EntityManager.gameEMInstance.scene.size.height * 0.1),
onButtonPress: {
DataService.sharedInstance.localRoundData.hasDefenceBoost = true
GameCenterManager.sharedInstance.addAchievementProgress(identifier: "de.hft.stuttgart.ip2.goldwars.skill.first.time", increasePercentComplete: 100)
GameCenterManager.sharedInstance.addAchievementProgress(identifier: "de.hft.stuttgart.ip2.goldwars.skill.def.ten", increasePercentComplete: 10)
SoundManager.sharedInstance.playSoundEffect(pathToFile: "use_boost",fileExtension: "wav",volumeLevel: 0.0)
}
)
spySkill = SkillButtonNode(
textureName: "spy_button",
text: "Spy",
isEnabled: true,
cooldown: 3,
position: CGPoint(x: defSkill.position.x - 85, y: defSkill.position.y),
onButtonPress: {
EntityManager.gameEMInstance.getOpponentBases(for: EntityManager.gameEMInstance.getTeam()).forEach({base in base.component(ofType: TeamComponent.self)?.unitcountLabel.text = "\(base.unitCount)"})
GameCenterManager.sharedInstance.addAchievementProgress(identifier: "de.hft.stuttgart.ip2.goldwars.skill.first.time", increasePercentComplete: 100)
GameCenterManager.sharedInstance.addAchievementProgress(identifier: "de.hft.stuttgart.ip2.goldwars.skill.spy.ten", increasePercentComplete: 10)
SoundManager.sharedInstance.playSoundEffect(pathToFile: "use_boost",fileExtension: "wav",volumeLevel: 0.0)
}
)
atkSkill = SkillButtonNode(
textureName: "atk_button",
atkSkill = SingeClickButtonNode(
textureName: "yellow_circle",
text: "Atk",
isEnabled: true,
cooldown: 4,
position: CGPoint(x: spySkill.position.x - 85, y: spySkill.position.y),
position: CGPoint(x: EntityManager.gameEMInstance.scene.size.width * 0.95, y: EntityManager.gameEMInstance.scene.size.height * 0.1),
onButtonPress: {
DataService.sharedInstance.localRoundData.hasAttackBoost = true
GameCenterManager.sharedInstance.addAchievementProgress(identifier: "de.hft.stuttgart.ip2.goldwars.skill.first.time", increasePercentComplete: 100)
GameCenterManager.sharedInstance.addAchievementProgress(identifier: "de.hft.stuttgart.ip2.goldwars.skill.atk.ten", increasePercentComplete: 10)
SoundManager.sharedInstance.playSoundEffect(pathToFile: "use_boost",fileExtension: "wav",volumeLevel: 0.0)
}
)
finishButton.size = CGSize(width: 100, height: 100)
finishButton = SingeClickButtonNode(
textureName: "yellow_button04",
text: "Done",
isEnabled: true,
position: CGPoint(
x: EntityManager.gameEMInstance.scene.size.width * 0.15,
y: EntityManager.gameEMInstance.scene.size.height * 0.06),
onButtonPress: { }
)
finishButton.size = CGSize(width: 80, height: 40)
finishButton.zPosition = 2
backgroundRoundCounter = SKSpriteNode(texture: SKTexture(imageNamed: "roundInfoTexture"))
backgroundRoundCounter = SKSpriteNode(texture: SKTexture(imageNamed: "roundInfo_texture"))
currentRoundLabel = SKLabelNode(fontNamed: "Courier-Bold")
roundsLabel = SKLabelNode(fontNamed: "Courier-Bold")
roundLabel = SKLabelNode(fontNamed: "Courier-Bold")
blockWholeScreenPane = SKSpriteNode(color: UIColor.init(red: 0, green: 0, blue: 0, alpha: 0), size: size)
blockWholeScreenPane.position = CGPoint(x: size.width * 0.5, y: size.height * 0.5)
blockWholeScreenPane.zPosition = 899
blockWholeScreenPane.isHidden = true
super.init()
initRoundInfo(size: size)
finishButton.onButtonPress = { [unowned self] in
self.finishRound()
}
@ -130,13 +114,14 @@ class HUD: GKEntity {
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])
roundTimer.initTimer()
startWithDuration()
}
func updateUnitSum(){
hostUnitsLabel.text = "\(entityManager.getUnitSum(by: GameCenterManager.sharedInstance.hostingPlayer!))"
peerUnitsLabel.text = "\(entityManager.getUnitSum(by: GameCenterManager.sharedInstance.peerPlayer!))"
hostUnitsLabel.text = "\(entityManager.getUnitSum(by: host!))"
peerUnitsLabel.text = "\(entityManager.getUnitSum(by: peer!))"
}
func setColor(labelNodes: [SKLabelNode]) -> Void {
@ -152,37 +137,35 @@ class HUD: GKEntity {
func startWithDuration(){
roundTimer.startTimer()
finishButton.isEnabled = true
self.roundTimer.roundEnded = "Berechnung"
self.roundTimer.roundEnded = "Syncing"
RoundCalculatorService.sharedInstance.isCalculating = false
blockWholeScreenPane.isHidden = true
}
func finishRound() -> () {
self.blockWholeScreenPane.isHidden = false
self.roundTimer.timeLeft = 1;
self.roundTimer.roundEnded = "Warte auf Gegner..."
self.roundTimer.roundEnded = "Waiting for other player..."
}
func initRoundInfo(size: CGSize) -> () {
backgroundRoundCounter.zPosition = 2
backgroundRoundCounter.position = CGPoint(x: leaveGame.position.x + 63, y: leaveGame.position.y)
backgroundRoundCounter.size = CGSize(width: 120, height: 120)
backgroundRoundCounter.position = CGPoint(x: Double(size.width) * 0.06, y: Double(size.height) * 0.08)
currentRoundLabel.text = "\(RoundCalculatorService.sharedInstance.currentRound)"
currentRoundLabel.fontSize = 50
currentRoundLabel.fontColor = SKColor.black
currentRoundLabel.verticalAlignmentMode = .center
currentRoundLabel.position = CGPoint(x: backgroundRoundCounter.position.x, y: backgroundRoundCounter.position.y - 4)
currentRoundLabel.position = CGPoint(x: backgroundRoundCounter.position.x, y: backgroundRoundCounter.position.y - 5)
currentRoundLabel.zPosition = backgroundRoundCounter.zPosition + 1
roundsLabel.zPosition = backgroundRoundCounter.zPosition + 1
roundsLabel.text = "von \(RoundCalculatorService.sharedInstance.MAX_ROUNDS)"
roundsLabel.text = "of \(RoundCalculatorService.sharedInstance.MAX_ROUNDS)"
roundsLabel.fontColor = SKColor.black
roundsLabel.verticalAlignmentMode = .center
roundsLabel.fontSize = 12
roundsLabel.position = CGPoint(x: currentRoundLabel.position.x, y: currentRoundLabel.position.y - 25)
roundLabel.zPosition = backgroundRoundCounter.zPosition + 1
roundLabel.text = "Runde"
roundLabel.text = "Round"
roundLabel.fontColor = SKColor.black
roundLabel.verticalAlignmentMode = .center
roundLabel.fontSize = 12
@ -196,13 +179,5 @@ class HUD: GKEntity {
SKAction.scale(by: 0.5, duration: 1),
])
currentRoundLabel.run(newRoundAction)
SoundManager.sharedInstance.playSoundEffect(pathToFile: "new_round", fileExtension: "wav", volumeLevel: 0.0)
self.decreaseSkillRoundCooldownCounter()
}
func decreaseSkillRoundCooldownCounter() {
self.spySkill.decreaseCooldown()
self.atkSkill.decreaseCooldown()
self.defSkill.decreaseCooldown()
}
}

View File

@ -9,10 +9,9 @@
import GameplayKit
enum ModalType: String{
case BaseDetails
case BaseAttack
case BaseMoveOwnUnits
case PauseGame
case QuitGame
}
class Modal: GKEntity{
@ -25,15 +24,9 @@ class Modal: GKEntity{
var body: SKLabelNode
var footer: SKLabelNode
var overlay: SKSpriteNode
var type: ModalType
init(modaltype: ModalType, base: Base?, anchorPoint: CGPoint, gameScene: SKScene, currentDraggedBase: Base?, touchLocation: CGPoint?, collisionBase: Base?) {
self.type = modaltype
unitCount = 0
if base != nil {
unitCount = base!.unitCount
}
init(modaltype: ModalType, base: Base, anchorPoint: CGPoint, gameScene: GameScene, currentDraggedBase: Base?, touchLocation: CGPoint, collisionBase: Base?) {
unitCount = base.unitCount
let texture = SKTexture(imageNamed:"ModalBackground")
background = SKSpriteNode(texture: texture, size: texture.size())
@ -52,22 +45,17 @@ class Modal: GKEntity{
overlay.zPosition = 3
switch modaltype {
case .BaseDetails:
header = SKLabelNode(text: "Information")
body = SKLabelNode(text: "Diese Basis enthält \(base.unitCount) Einheiten")
footer = SKLabelNode()
case .BaseAttack:
header = SKLabelNode(text: "Angriff")
body = SKLabelNode(text: "\(unitCount / 2) Einheiten")
body = SKLabelNode(text: "Schicke \(unitCount / 2)\nEinheiten")
footer = SKLabelNode()
case .BaseMoveOwnUnits:
header = SKLabelNode(text: "Formation")
body = SKLabelNode(text: "\(unitCount / 2) Einheiten")
footer = SKLabelNode()
case .PauseGame:
header = SKLabelNode(text: "Pause")
body = SKLabelNode(text: "Warte auf Gegner...")
footer = SKLabelNode()
closeButton.zPosition = -1
case .QuitGame:
header = SKLabelNode(text: "Spiel verlassen")
body = SKLabelNode(text: "Sicher verlassen?")
body = SKLabelNode(text: "Sende \(unitCount / 2)\nEinheiten")
footer = SKLabelNode()
}
@ -76,7 +64,7 @@ class Modal: GKEntity{
self.header.fontSize = 40
self.header.zPosition = 5
self.body.position = CGPoint(x: anchorPoint.x, y: anchorPoint.y + 15)
self.body.position = CGPoint(x: anchorPoint.x, y: anchorPoint.y - 20)
self.body.numberOfLines = 2
self.body.preferredMaxLayoutWidth = 390
self.body.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.center
@ -92,25 +80,18 @@ class Modal: GKEntity{
super.init()
switch modaltype{
case .BaseDetails:
addComponent(ButtonComponent(textureName: "yellow_button04", text: "Zurück", position: CGPoint(x: anchorPoint.x , y: anchorPoint.y - 105), isEnabled: true, onButtonPress: {
EntityManager.gameEMInstance.removeModal()
}))
case .BaseAttack, .BaseMoveOwnUnits:
let text = (modaltype == .BaseAttack) ? "Angriff" : "Senden"
addComponent(SliderComponent(width: 300, position: CGPoint(x: anchorPoint.x , y: anchorPoint.y - 15)))
addComponent(ButtonComponent(textureName: "yellow_button04", text: text, position: CGPoint(x: anchorPoint.x , y: anchorPoint.y - 95), isEnabled: true, onButtonPress: {
self.sendUnits(currentDraggedBase: currentDraggedBase, touchLocation: touchLocation!, gameScene: gameScene, collisionBase: collisionBase)
addComponent(SliderComponent(width: 300, position: CGPoint(x: anchorPoint.x , y: anchorPoint.y - 50)))
addComponent(ButtonComponent(textureName: "yellow_button04", text: text, position: CGPoint(x: anchorPoint.x , y: anchorPoint.y - 105), isEnabled: true, onButtonPress: {
self.sendUnits(currentDraggedBase: currentDraggedBase, touchLocation: touchLocation, gameScene: gameScene, collisionBase: collisionBase)
EntityManager.gameEMInstance.removeModal()
}))
case .QuitGame:
addComponent(ButtonComponent(textureName: "yellow_button04", text: "Verlassen", position: CGPoint(x: anchorPoint.x , y: anchorPoint.y - 95), isEnabled: true, onButtonPress: {
EntityManager.gameEMInstance.removeModal()
GameCenterManager.sharedInstance.sendStateToPeers(state: State(state: 6))
GameCenterManager.sharedInstance.opponentQuit = false
GameCenterManager.sharedInstance.quitGame = true
}))
case .PauseGame:
break
}
}
required init?(coder: NSCoder) {
@ -125,11 +106,11 @@ class Modal: GKEntity{
}
}
func sendUnits(currentDraggedBase: Base?, touchLocation: CGPoint, gameScene: SKScene, collisionBase: Base?){
func sendUnits(currentDraggedBase: Base?, touchLocation: CGPoint, gameScene: GameScene, collisionBase: Base?){
for base in currentDraggedBase!.adjacencyList {
if base == collisionBase {
RoundCalculatorService.sharedInstance.increaseMoveCounter(ownBase: currentDraggedBase?.ownershipPlayer == base.ownershipPlayer)
entityManager.update((currentDraggedBase?.doPlayerMoveTypeToBase(base: base, units: Int(GameScene.sendUnits)))!)
entityManager.update((currentDraggedBase?.doPlayerMoveTypeToBase(base: base, playerMoveType: PlayerMoveType.AtkMove, units: Int(GameScene.sendUnits)))!)
GameScene.sendUnits = 0
}
}

View File

@ -11,25 +11,9 @@ import GameplayKit
class SpinningLogoEntity: GKEntity {
let spinningLogoNode: SpinningLogo3DNode
let goldLetteringNode: SKSpriteNode
let warsLetteringNode: SKSpriteNode
init(sceneSize size: CGSize) {
goldLetteringNode = SKSpriteNode(texture: SKTexture(imageNamed: "goldLettering"))
goldLetteringNode.position = CGPoint(x: size.width / 2 , y: size.height * 0.83)
goldLetteringNode.size = CGSize(width: size.width / 2.02, height: size.height / 3.6)
warsLetteringNode = SKSpriteNode(texture: SKTexture(imageNamed: "warsLettering"))
warsLetteringNode.position = CGPoint(x: size.width / 2, y: size.height * 0.17)
warsLetteringNode.size = CGSize(width: size.width / 2.02, height: size.height / 3.6)
spinningLogoNode = SpinningLogo3DNode()
spinningLogoNode.viewportSize = CGSize(width: size.width / 5.12 * 0.69, height: size.height / 3.84 * 0.69)
spinningLogoNode.zPosition = goldLetteringNode.zPosition - 1
spinningLogoNode.position = CGPoint(x: size.width * 0.455, y: size.height * 0.83)
init(position: CGPoint) {
super.init()
self.addComponent(SpinningLogoComponent(position: position))
}
required init?(coder: NSCoder) {

View File

@ -12,52 +12,19 @@ import GameplayKit
class Way: GKEntity {
var localWayComponent: SKShapeNode
required init(fromBase: Base, toBase: Base) {
let fromBaseX = fromBase.position.x
let fromBaseY = fromBase.position.y
let toBaseX = toBase.position.x
let toBaseY = toBase.position.y
let xControll1 = Way.computeX(x1: fromBaseX, x2: toBaseX, y1: fromBaseY, y2: toBaseY, factor: 2/5)
let yControll1 = Way.computeY(x1: fromBaseX, x2: toBaseX, y1: fromBaseY, y2: toBaseY, factor: 2/5)
let xControll2 = Way.computeX(x1: fromBaseX, x2: toBaseX, y1: fromBaseY, y2: toBaseY, factor: 3/5)
let yControll2 = Way.computeY(x1: fromBaseX, x2: toBaseX, y1: fromBaseY, y2: toBaseY, factor: 3/5)
super.init()
let pathToDraw = CGMutablePath()
pathToDraw.move(to: fromBase.position)
pathToDraw.addCurve(
to: toBase.position,
control1: CGPoint(x: xControll1, y: yControll1),
control2: CGPoint(x: xControll2, y: yControll2)
)
pathToDraw.addLine(to: toBase.position)
self.localWayComponent = SKShapeNode()
self.localWayComponent.path = pathToDraw
self.localWayComponent.strokeColor = UIColor(red: 0.852, green: 0.649, blue: 0.123, alpha: 1)
self.localWayComponent.lineWidth = 10
self.localWayComponent.zPosition = 0
self.localWayComponent.name = "way"
super.init()
addComponent(DefaultWayComponent(pathToDraw: pathToDraw))
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
static var wayDelta: CGFloat = 5
static func computeX(x1: CGFloat, x2: CGFloat, y1: CGFloat, y2: CGFloat, factor: CGFloat) -> CGFloat {
let mix:CGFloat = Bool.random() ? -1/wayDelta : 1/wayDelta
let x = x1 + factor * (x2 - x1) + mix * -(y2-y1)
return x
}
static func computeY(x1: CGFloat, x2: CGFloat, y1: CGFloat, y2: CGFloat, factor: CGFloat) -> CGFloat {
let mix:CGFloat = Bool.random() ? -1/wayDelta : 1/wayDelta
let y = y1 + factor * (y2 - y1) + mix * (x2-x1)
return y
}
}

View File

@ -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
}

View File

@ -9,6 +9,8 @@
enum Team: Int {
case team1 = 1
case team2 = 2
case team3 = 3
case team4 = 4
static let allValues = [team1, team2]
static let allValues = [team1, team2,team3,team4]
}

View File

@ -24,13 +24,12 @@ struct State: Codable {
// 3 Host hat Spiel gestartet
// 4 Peer hat verloren
// 5 Peer hat gewonnen
// 6 Peer hat Spiel verlassen
let state: Int
}
final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate, GKGameCenterControllerDelegate ,GKMatchDelegate,GKLocalPlayerListener{
static var sharedInstance = GameCenterManager()
static let sharedInstance = GameCenterManager()
let LOG = OSLog.init(subsystem: "GameCenterManager", category: "GameCenterManager")
@ -45,11 +44,7 @@ final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate, GKG
var entityManager = EntityManager.gameEMInstance
var localPlayerRandomNumber: RandomNumber?
var initIsFinish = false
var gameEnded = false
var winner: String?
var gameScene: GameScene?
var quitGame: Bool = false
var opponentQuit: Bool = false
static var isAuthenticated: Bool {
return GKLocalPlayer.local.isAuthenticated
}
@ -61,16 +56,6 @@ final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate, GKG
localPlayerRandomNumber = RandomNumber()
}
func reset() {
isMatchStarted = false
isServer = false
localPlayerRandomNumber = RandomNumber()
initIsFinish = false
gameEnded = false
winner = nil
gameScene = nil
}
func authUser() -> Void {
GKLocalPlayer.local.authenticateHandler = { gcAuthVC, error in
NotificationCenter.default
@ -103,6 +88,7 @@ final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate, GKG
GKAchievement.loadAchievements { (achievements: [GKAchievement]?, err: Error?) in
var achievementExists: Bool = false
achievements?.forEach({ (achievement: GKAchievement) in
print(achievement.identifier)
if achievement.identifier == identifier {
achievementExists = true
achievement.percentComplete += increasePercentComplete
@ -161,23 +147,21 @@ final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate, GKG
os_log("State 2 erhalten", log: LOG, type: .info)
sendStateToPeers(state: State(state: 3))
initIsFinish = true
print("entered gameSt in case 2 match")
StateManager.sharedInstance.stateMachine?.enter(GameState.self)
os_log("Spiel startet", log: LOG, type: .info)
case 3:
os_log("State 3 erhalten", log: LOG, type: .info)
initIsFinish = true
print("entered gameSt in case 3 match")
StateManager.sharedInstance.stateMachine?.enter(GameState.self)
os_log("Spiel startet", log: LOG, type: .info)
case 4:
os_log("State 4 erhalten, Peer hat verloren", log: LOG, type: .info)
winner = hostingPlayer?.displayName
gameEnded = true
// TODO: Trigger Loser Scene
case 5:
os_log("State 5 erhalten, Peer hat gewonnen", log: LOG, type: .info)
winner = peerPlayer?.displayName
gameEnded = true
case 6:
os_log("State 6 erhalten, Peer hat Spiel verlassen ", log: LOG, type: .info)
opponentQuit = true
quitGame = true
// TODO: Trigger Winner Scene
default:
break
}
@ -186,11 +170,13 @@ final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate, GKG
DataService.sharedInstance.addRemotePlayerMoves(playerName: player.displayName, localRoundData: roundData)
}
if let snapshotModel = try? jsonDecoder.decode(SnapshotModel.self, from: data) {
StateManager.sharedInstance.stateMachine?.enter(SyncingState.self)
DataService.sharedInstance.snapshotModel = snapshotModel
RoundCalculatorService.sharedInstance.currentRound += 1
entityManager.getHUD()?.setCurrentRound(round: RoundCalculatorService.sharedInstance.currentRound)
entityManager.updateSnapshotModel(snapshotModel: snapshotModel)
entityManager.getHUD()?.startWithDuration()
StateManager.sharedInstance.stateMachine?.enter(GameState.self)
}
if let mapModel = try? jsonDecoder.decode(MapGenerationModel.self, from: data) {
os_log("Peer hat Map erhalten", log: LOG, type: .info)
@ -200,44 +186,18 @@ final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate, GKG
os_log("Map model wurde gesetzt", log: LOG, type: .info)
GameCenterManager.sharedInstance.isMatchStarted = true
self.gameScene = scene
StateManager.sharedInstance.gameSc = scene
sendStateToPeers(state: State(state: 2))
os_log("State 2 wurde an Host gesendet", log: LOG, type: .info)
initIsFinish = true
os_log("Peer startet Spiel", log: LOG, type: .info)
}
if let notification = try? jsonDecoder.decode(NotificationModel.self, from: data) {
os_log("Notification erhalten", log: LOG, type: .info)
NotificationCenter.default.post(name: Notification.Name(rawValue: notification.name), object: nil)
}
if let eloData = try? jsonDecoder.decode(EloDataForPeer.self, from: data) {
print("Recieved elo data: \(eloData.scoreToReport)")
EloHelper.reportScore(score: eloData.scoreToReport)
}
if let heartbeat = try? jsonDecoder.decode(Heartbeat.self, from: data) {
entityManager.getHUD()?.roundTimer.isHeartbeatLocked = false
let df = DateFormatter()
df.dateFormat = "yyyy-MM-dd HH:mm:ss"
let dateString = df.string(from: heartbeat.date)
print("Received last Heartbeat at \(dateString)")
}
MultiplayerNetwork.sharedInstance.isSending = false
}
func match(_ match: GKMatch, player: GKPlayer, didChange state: GKPlayerConnectionState) {
if myMatch != match { return }
if state == GKPlayerConnectionState.disconnected {
self.opponentQuit = true;
gameScene?.gameQuit()
}
}
func initAndSendMap() -> Void {
self.gameScene = GameScene(size: self.menusc!.size)
let mapModel = MapFactory(scene: self.gameScene!, entityManager: entityManager).load()
os_log("Map wurde erstellt", log: LOG, type: .info)
StateManager.sharedInstance.gameSc = gameScene
MultiplayerNetwork.sharedInstance.sendMapModelToPlayers(mapModel: mapModel)
os_log("Map wurde an Peer gesendet", log: LOG, type: .info)
DataService.sharedInstance.setSnapshotModel(snapshotModel: entityManager.getSnapshotModel())
@ -258,7 +218,6 @@ final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate, GKG
}
return nilGK
}
func sendStateToPeers(state: State){
let encoder = JSONEncoder()
let encoded = (try? encoder.encode(state))!
@ -277,16 +236,18 @@ final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate, GKG
matchmakerVC!.matchmakerDelegate = self
viewController?.present(matchmakerVC!, animated: true, completion: nil)
}
func matchmakerViewControllerWasCancelled(_ viewController: GKMatchmakerViewController) {
viewController.dismiss(animated: true, completion: nil)
StateManager.sharedInstance.stateMachine?.enter(MenuState.self)
}
func matchmakerViewController(_ viewController: GKMatchmakerViewController, didFailWithError error: Error) {
viewController.dismiss(animated: true, completion: nil)
StateManager.sharedInstance.stateMachine?.enter(MenuState.self)
}
func matchmakerViewController(_ viewController: GKMatchmakerViewController, didFind match: GKMatch) {
StateManager.sharedInstance.stateMachine?.enter(SyncingState.self)
viewController.dismiss(animated: true, completion: nil)
myMatch = match
if !isMatchStarted && match.expectedPlayerCount == 0 {

View File

@ -6,25 +6,17 @@
// Copyright © 2020 SP2. All rights reserved.
//
import UIKit
import SpriteKit
import GameplayKit
class GameViewController: UIViewController {
var currentScene: SKView?
override func viewDidLoad() {
super.viewDidLoad()
if let view = self.view as! SKView? {
let scene = MenuScene(size: self.view.bounds.size)
EntityManager.menuEMInstance.setScene(scene: scene)
scene.scaleMode = .aspectFill
view.presentScene(scene)
//TODO: create dev profile or remove on delivery
view.showsFPS = true
view.showsNodeCount = true
}
StateManager.sharedInstance.gameVC = self
StateManager.sharedInstance.stateMachine?.enter(MenuState.self)
GameCenterManager.sharedInstance.viewController = self
}
@ -43,5 +35,4 @@ class GameViewController: UIViewController {
override var prefersStatusBarHidden: Bool {
return true
}
}

View File

@ -183,25 +183,24 @@ class CElement3: CenterElementProtocol {
var id: Int = 3
required init(frame: CGRect) {
let delta = (frame.maxY - frame.minY) * 0.15
self.centerBase = Base(
position: CGPoint(
x: frame.midX,
y: frame.maxY - delta
y: frame.maxY
)
)
self.leftBase = Base(
position: CGPoint(
x: frame.minX,
y: frame.minY + delta
y: frame.minY
)
)
self.rightBase = Base(
position: CGPoint(
x: frame.maxX,
y: frame.minY + delta
y: frame.minY
)
)
self.bases.append(centerBase)
@ -261,25 +260,24 @@ class CElement4: CenterElementProtocol {
var id: Int = 4
required init(frame: CGRect) {
let delta = (frame.maxY - frame.minY) * 0.15
self.centerBase = Base(
position: CGPoint(
x: frame.midX,
y: frame.maxY - delta
y: frame.maxY
)
)
self.leftBase = Base(
position: CGPoint(
x: frame.minX,
y: frame.minY + delta
y: frame.minY
)
)
self.rightBase = Base(
position: CGPoint(
x: frame.maxX,
y: frame.minY + delta
y: frame.minY
)
)
self.bases.append(centerBase)
@ -339,25 +337,24 @@ class CElement5: CenterElementProtocol {
var id: Int = 5
required init(frame: CGRect) {
let delta = (frame.maxY - frame.minY) * 0.15
self.centerBase = Base(
position: CGPoint(
x: frame.midX,
y: frame.minY + delta
y: frame.minY
)
)
self.leftBase = Base(
position: CGPoint(
x: frame.minX,
y: frame.maxY - delta
y: frame.maxY
)
)
self.rightBase = Base(
position: CGPoint(
x: frame.maxX,
y: frame.maxY - delta
y: frame.maxY
)
)
self.bases.append(centerBase)
@ -417,25 +414,24 @@ class CElement6: CenterElementProtocol {
var id: Int = 6
required init(frame: CGRect) {
let delta = (frame.maxY - frame.minY) * 0.15
self.centerBase = Base(
position: CGPoint(
x: frame.midX,
y: frame.minY + delta
y: frame.minY
)
)
self.leftBase = Base(
position: CGPoint(
x: frame.minX,
y: frame.maxY - delta
y: frame.maxY
)
)
self.rightBase = Base(
position: CGPoint(
x: frame.maxX,
y: frame.maxY - delta
y: frame.maxY
)
)
self.bases.append(centerBase)
@ -770,25 +766,24 @@ class CElement11: CenterElementProtocol {
var id: Int = 11
required init(frame: CGRect) {
let delta = (frame.maxY - frame.minY) * 0.15
self.centerBase = Base(
position: CGPoint(
x: frame.midX,
y: frame.maxY - delta
y: frame.maxY
)
)
self.leftBase = Base(
position: CGPoint(
x: frame.minX,
y: frame.minY + delta
y: frame.minY
)
)
self.rightBase = Base(
position: CGPoint(
x: frame.maxX,
y: frame.minY + delta
y: frame.minY
)
)
self.bases.append(centerBase)
@ -848,25 +843,24 @@ class CElement12: CenterElementProtocol {
var id: Int = 12
required init(frame: CGRect) {
let delta = (frame.maxY - frame.minY) * 0.15
self.centerBase = Base(
position: CGPoint(
x: frame.midX,
y: frame.maxY - delta
y: frame.maxY
)
)
self.leftBase = Base(
position: CGPoint(
x: frame.minX,
y: frame.minY + delta
y: frame.minY
)
)
self.rightBase = Base(
position: CGPoint(
x: frame.maxX,
y: frame.minY + delta
y: frame.minY
)
)
self.bases.append(centerBase)
@ -926,25 +920,24 @@ class CElement13: CenterElementProtocol {
var id: Int = 13
required init(frame: CGRect) {
let delta = (frame.maxY - frame.minY) * 0.15
self.centerBase = Base(
position: CGPoint(
x: frame.midX,
y: frame.minY + delta
y: frame.minY
)
)
self.leftBase = Base(
position: CGPoint(
x: frame.minX,
y: frame.maxY - delta
y: frame.maxY
)
)
self.rightBase = Base(
position: CGPoint(
x: frame.maxX,
y: frame.maxY - delta
y: frame.maxY
)
)
self.bases.append(centerBase)
@ -1004,25 +997,24 @@ class CElement14: CenterElementProtocol {
var id: Int = 14
required init(frame: CGRect) {
let delta = (frame.maxY - frame.minY) * 0.15
self.centerBase = Base(
position: CGPoint(
x: frame.midX,
y: frame.minY + delta
y: frame.minY
)
)
self.leftBase = Base(
position: CGPoint(
x: frame.minX,
y: frame.maxY - delta
y: frame.maxY
)
)
self.rightBase = Base(
position: CGPoint(
x: frame.maxX,
y: frame.maxY - delta
y: frame.maxY
)
)
self.bases.append(centerBase)

View File

@ -38,6 +38,7 @@ class MultiplayerNetwork{
func sendPlayerMoves(localRoundData: LocalRoundData) {
if GameCenterManager.sharedInstance.isServer == false {
print("I am client")
self.isSending = true
let encoder = JSONEncoder()
let encoded = (try? encoder.encode(localRoundData))!
@ -60,21 +61,4 @@ class MultiplayerNetwork{
sendData(data: encoded)
}
func sendEloData(scoreToReport: GKScore) {
let encoder = JSONEncoder()
let encoded = (try? encoder.encode(EloDataForPeer(scoreToReport: scoreToReport.value)))!
sendData(data: encoded)
}
func sendNotificationToPlayer(name: String) {
let encoder = JSONEncoder()
let encoded = (try? encoder.encode(NotificationModel(name: name)))!
sendData(data: encoded)
}
func sendHeartbeatToPlayer() {
let encoder = JSONEncoder()
let encoded = (try? encoder.encode(Heartbeat(date: Date())))!
sendData(data: encoded)
}
}

Binary file not shown.

View File

@ -23,14 +23,16 @@ class RoundCalculatorService {
let MAX_ROUNDS = 20
var currentRound = 1
var isCalculating = false
var numberOfAttacks = 0
var numberOfOwnUnitMoves = 0
func calculateRound() {
StateManager.sharedInstance.stateMachine?.enter(SyncingState.self)
os_log("Started calculating Round", log: RoundCalculatorService.LOG, type: .info)
isCalculating = true
let currentSnapshotModel = DataService.sharedInstance.snapshotModel
var baseSpecificMoves = collectBaseSpecificMoves()
// TODO: Refactor to a less complex way
@ -158,16 +160,7 @@ class RoundCalculatorService {
winner = determineWinner(by: "capture")
}
winner == GameCenterManager.sharedInstance.hostingPlayer?.displayName ? GameCenterManager.sharedInstance.sendStateToPeers(state: State(state: 4)) : GameCenterManager.sharedInstance.sendStateToPeers(state: State(state: 5))
GameCenterManager.sharedInstance.winner = winner
GameCenterManager.sharedInstance.gameEnded = true
// Update EloSystem
if winner == GameCenterManager.sharedInstance.hostingPlayer?.displayName {
EloHelper.updateEloScore(winner: GameCenterManager.sharedInstance.hostingPlayer!, hatDenNikoGemacht: GameCenterManager.sharedInstance.peerPlayer!)
} else {
EloHelper.updateEloScore(winner: GameCenterManager.sharedInstance.peerPlayer!, hatDenNikoGemacht: GameCenterManager.sharedInstance.hostingPlayer!)
}
//TODO: Trigger Winner/Loser-Scene for Server
return
}
currentRound += 1
@ -178,6 +171,7 @@ class RoundCalculatorService {
entityManager.updateSnapshotModel(snapshotModel: currentSnapshotModel!)
entityManager.getHUD()?.startWithDuration()
os_log("Finished calculating Round", log: RoundCalculatorService.LOG, type: .info)
StateManager.sharedInstance.stateMachine?.enter(GameState.self)
}
func collectBaseSpecificMoves() -> [Int: [String: [PlayerMove]]] {

View File

@ -12,7 +12,6 @@ class RoundTimer: Timer {
var timer: Timer?
var timeLeft: Int = 0
var isHeartbeatLocked = false
var calculate = false
var roundEnded = "Syncing"
@ -30,36 +29,19 @@ class RoundTimer: Timer {
timeLeft = 30
}
func stopTimer() {
guard timer != nil else { return }
timer?.invalidate()
timer = nil
}
func resumeTimer() {
timer = Timer.scheduledTimer(
timeInterval: 1.0,
target: self,
selector: #selector(onTimerFires),
userInfo: nil,
repeats: true
)
}
@objc func onTimerFires()
{
timeLeft -= 1
EntityManager.gameEMInstance.updateTime(time: (timeLeft > 0 ? String(timeLeft) : roundEnded))
if timeLeft == 0 {
EntityManager.gameEMInstance.removeModal()
RoundCalculatorService.sharedInstance.resetNumberOfAttacksAndFormats()
if !MultiplayerNetwork.sharedInstance.isSending {
MultiplayerNetwork.sharedInstance.sendPlayerMoves(localRoundData: DataService.sharedInstance.localRoundData)
}
calculate = true
}
if timeLeft <= 0 {
if calculate
&& !RoundCalculatorService.sharedInstance.isCalculating
@ -69,10 +51,5 @@ class RoundTimer: Timer {
calculate = false
}
}
if (!isHeartbeatLocked && (timeLeft % 7 == 0)){
MultiplayerNetwork.sharedInstance.sendHeartbeatToPlayer()
isHeartbeatLocked = true;
}
}
}

View File

@ -1,118 +0,0 @@
//
// RulesScene.swift
// GoldWars
//
// Created by Chauntalle Schüle on 18.06.20.
// Copyright © 2020 SP2. All rights reserved.
//
import SpriteKit
import GameplayKit
class RulesScene: SKScene {
var image: SKSpriteNode?
override func sceneDidLoad() {
EntityManager.rulesEMInstance.setScene(scene: self)
EntityManager.rulesEMInstance.add(
Button(name: "backToMenuScene",
textureName: "questionmark",
text: "",
position: CGPoint(x: self.size.width - 50, y: self.size.height - 50),
onButtonPress: {
EntityManager.rulesEMInstance.entities.removeAll()
self.view?.presentScene(
MenuScene(size: self.size),
transition: SKTransition.flipVertical(withDuration: 0.5)
)
}
)
)
EntityManager.rulesEMInstance.add(
Label(fontnamed: "Courier-Bold",
name: "rulesLabel",
text: "Regelwerk",
fontSize: 90,
fontColor: .black,
position: CGPoint(x: self.size.width * 0.5, y: self.size.height - 100),
horizontalAlignmentMode: .center,
vertikalAligmentMode: .baseline,
isAnimationEnabled: true,
isAnimationInfinite: true
)
)
image = SKSpriteNode(imageNamed: "RulesSpiel")
image!.size = CGSize(width: size.width * 0.8, height: size.height * 0.8)
image!.position = CGPoint(x: size.width * 0.6, y: size.height * 0.6 - 150)
image!.zPosition = 4
self.addChild(image!)
EntityManager.rulesEMInstance.add(
Button(name: "Spiel",
textureName: "yellow_button13",
text: "Spiel",
position: CGPoint(x: self.size.width * 0.1, y: self.size.height * 0.5 + 150),
onButtonPress: { self.image!.texture = SKTexture(imageNamed: "RulesSpiel") }
)
)
EntityManager.rulesEMInstance.add(
Button(name: "Basen",
textureName: "yellow_button13",
text: "Basen",
position: CGPoint(x: self.size.width * 0.1, y: self.size.height * 0.5 + 85),
onButtonPress: { self.image!.texture = SKTexture(imageNamed: "RulesBasen") }
)
)
EntityManager.rulesEMInstance.add(
Button(name: "Einheiten",
textureName: "yellow_button13",
text: "Einheiten",
position: CGPoint(x: self.size.width * 0.1, y: self.size.height * 0.5 + 20),
onButtonPress: { self.image!.texture = SKTexture(imageNamed: "RulesEinheiten") }
)
)
EntityManager.rulesEMInstance.add(
Button(name: "Spielende",
textureName: "yellow_button13",
text: "Spielende",
position: CGPoint(x: self.size.width * 0.1, y: self.size.height * 0.5 - 45),
onButtonPress: { self.image!.texture = SKTexture(imageNamed: "RulesSpielende") }
)
)
EntityManager.rulesEMInstance.add(
Button(name: "Boost",
textureName: "yellow_button13",
text: "Boost",
position: CGPoint(x: self.size.width * 0.1, y: self.size.height * 0.5 - 110),
onButtonPress: { self.image!.texture = SKTexture(imageNamed: "RulesBoost") }
)
)
EntityManager.rulesEMInstance.add(
Button(name: "Erfolge",
textureName: "yellow_button13",
text: "Erfolge",
position: CGPoint(x: self.size.width * 0.1, y: self.size.height * 0.5 - 175),
onButtonPress: { self.image!.texture = SKTexture(imageNamed: "RulesErfolge") }
)
)
EntityManager.rulesEMInstance.add(
Button(name: "Credits",
textureName: "yellow_button13",
text: "Credits",
position: CGPoint(x: self.size.width * 0.1, y: self.size.height * 0.1 - 20),
onButtonPress: { self.image!.texture = SKTexture(imageNamed: "Credits") }
)
)
EntityManager.rulesEMInstance.add(Background(size: self.size))
}
override func update(_ currentTime: TimeInterval) {
if EntityManager.rulesEMInstance.entities.count != 0 {
EntityManager.rulesEMInstance.getBackground()!.update(deltaTime: currentTime)
}
}
}

View File

@ -16,9 +16,8 @@ class GameScene: SKScene{
var isMoveTouch = false
var currentDraggedBase : Base?
static var sendUnits: Int = 0
static var sendUnits: CGFloat = 0
var collisionBase: Base?
var gameEndEffects = false
override func sceneDidLoad() {
entityManager.setScene(scene: self)
@ -26,13 +25,8 @@ class GameScene: SKScene{
entityManager.add(Background(size: self.size))
if CommandLine.arguments.contains("--no-matchmaking") {
_ = MapFactory(scene: self, entityManager: entityManager).load()
}
return
}
override func didMove(to view: SKView) {
NotificationCenter.default.addObserver(self, selector: #selector(pauseGame), name: Notification.Name("pauseGame"), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(resumeGame), name: Notification.Name("resumeGame"), object: nil)
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
@ -51,11 +45,12 @@ class GameScene: SKScene{
entityManager.getBasesByPlayer(for: GKLocalPlayer.local).forEach({base in
moveFireAndBase(base: base, touchLocation: base.position)
})
} else {
for entity in entityManager.entities {
if atPoint(touchLocation) == entity.component(ofType: DefaultBaseComponent.self)?.spriteNode {
entity.component(ofType: DefaultBaseComponent.self)?.spriteNode.touchesBegan(touches, with: event)
}
else {
for entity in entityManager.entities {
let spriteNode = entity.component(ofType: DefaultBaseComponent.self)?.spriteNode
//FIXME: this is confusing
addBaseDetails(touchLocation: touchLocation, spriteNode: spriteNode, touches: touches, event: event, entity: entity)
}
}
}
@ -77,15 +72,23 @@ class GameScene: SKScene{
}
override func update(_ currentTime: TimeInterval) {
entityManager.getBackground()?.update(deltaTime: currentTime)
if GameCenterManager.sharedInstance.gameEnded && !gameEndEffects {
gameEnd()
}
if GameCenterManager.sharedInstance.quitGame {
gameQuit()
}
StateManager.sharedInstance.stateMachine!.update(deltaTime: currentTime)
}
func addBaseDetails(touchLocation: CGPoint, spriteNode: SKNode?, touches: Set<UITouch>, event: UIEvent?, entity: GKEntity){
if atPoint(touchLocation) == spriteNode && !entityManager.isModal {
spriteNode?.touchesBegan(touches, with: event)
if let baseEntity = entity as? Base {
if baseEntity.ownershipPlayer == GKLocalPlayer.local {
entityManager.add(Modal(modaltype: .BaseDetails,
base: entity as! Base,
anchorPoint: CGPoint(x: self.size.width / 2 , y: self.size.height / 2),
gameScene: self,
currentDraggedBase: currentDraggedBase, touchLocation: touchLocation, collisionBase: collisionBase))
}
}
}
}
func addAttackDetails(touchLocation: CGPoint){
for base in currentDraggedBase!.adjacencyList {
@ -105,7 +108,7 @@ class GameScene: SKScene{
touchLocation: touchLocation,
collisionBase: collisionBase)
)
GameScene.sendUnits = Int(currentDraggedBase!.unitCount / 2)
GameScene.sendUnits = CGFloat(currentDraggedBase!.unitCount / 2)
}
}
}
@ -114,8 +117,7 @@ class GameScene: SKScene{
func checkSlider(){
for e in entityManager.entities{
if let modal = e as? Modal {
if modal.type == ModalType.BaseAttack || modal.type == ModalType.BaseMoveOwnUnits {
GameScene.sendUnits = Int(((e.component(ofType: SliderComponent.self)?.sliderNode.getValue ?? 0) * CGFloat((e as! Modal).unitCount)).rounded(.up))
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 {
@ -123,161 +125,10 @@ class GameScene: SKScene{
} else if Int(GameScene.sendUnits) == currentDraggedBase?.unitCount {
GameScene.sendUnits -= 1
}
modal.body.text = "\(GameScene.sendUnits) Einheiten "
modal.body.text = "Schicke \(GameScene.sendUnits) Einheiten "
}
}
}
}
func gameEnd(){
entityManager.getHUD()?.blockWholeScreenPane.isHidden = true
gameEndEffects = true
GameCenterManager.sharedInstance.gameEnded = false
let move = SKAction.move(to: CGPoint(x: self.size.width / 2, y: self.size.height / 2), duration: 1)
let removeParticle = SKAction.removeFromParent()
let sequence = SKAction.sequence([move, removeParticle])
var actionAdded = false
for nodeChild in children {
if nodeChild.name == "peerLabel" || nodeChild.name == "hostLabel"{
continue
}
if nodeChild.name == "way" {
nodeChild.run(SKAction.removeFromParent())
continue
}
if nodeChild.name != "clouds"{
nodeChild.run(sequence) {
if !actionAdded {
let explosion = self.getFinalExplosion()
self.addChild(explosion)
let action = SKAction.afterDelay(2) {
(self.childNode(withName: "hostLabel") as! SKLabelNode).horizontalAlignmentMode = .center
(self.childNode(withName: "peerLabel") as! SKLabelNode).horizontalAlignmentMode = .center
self.childNode(withName: "hostLabel")?.run(SKAction.move(to: CGPoint(x: self.size.width * 0.25, y: self.size.height * 0.25), duration: 1))
self.childNode(withName: "peerLabel")?.run(SKAction.move(to: CGPoint(x: self.size.width * 0.75, y: self.size.height * 0.25), duration: 1))
self.initGameEndIcons()
let node = ButtonNode(textureName: "yellow_button05", text: "Menü", isEnabled: true, position: CGPoint(x: self.size.width / 2, y: self.size.height / 2 - 300), onButtonPress: {
self.backToMenuAction()
})
node.name = "BackButton"
self.addChild(node)
}
explosion.run(action)
actionAdded = true
}
}
}
}
}
func gameQuit() {
entityManager.getHUD()?.blockWholeScreenPane.isHidden = true
gameEndEffects = true
GameCenterManager.sharedInstance.quitGame = false
let move = SKAction.move(to: CGPoint(x: self.size.width / 2, y: self.size.height / 2), duration: 1)
let removeParticle = SKAction.removeFromParent()
let sequence = SKAction.sequence([move, removeParticle])
var actionAdded = false
for nodeChild in children {
if nodeChild.name == "peerLabel" || nodeChild.name == "hostLabel"{
nodeChild.removeFromParent()
}
if nodeChild.name == "way" {
nodeChild.run(SKAction.removeFromParent())
continue
}
if nodeChild.name != "clouds"{
nodeChild.run(sequence) {
if !actionAdded {
let explosion = self.getFinalExplosion()
self.addChild(explosion)
let action = SKAction.afterDelay(2) {
let node = ButtonNode(textureName: "yellow_button05", text: "Menü", isEnabled: true, position: CGPoint(x: self.size.width / 2, y: self.size.height / 2 - 300), onButtonPress: {
self.backToMenuAction()
})
node.name = "BackButton"
self.addChild(node)
}
explosion.run(action)
actionAdded = true
}
}
}
}
let disconnectLabel = SKLabelNode.init(fontNamed: "Courier-Bold")
disconnectLabel.position = CGPoint(x: self.size.width/2, y: self.size.height/2)
disconnectLabel.horizontalAlignmentMode = .center
disconnectLabel.fontColor = UIColor.black
disconnectLabel.alpha = 0
disconnectLabel.setScale(0.1)
if GameCenterManager.sharedInstance.opponentQuit {
if GameCenterManager.sharedInstance.localPlayer == GameCenterManager.sharedInstance.hostingPlayer {
disconnectLabel.text = GameCenterManager.sharedInstance.peerPlayer?.displayName
} else {
disconnectLabel.text = GameCenterManager.sharedInstance.hostingPlayer?.displayName
}
disconnectLabel.text?.append(" hat das Spiel verlassen!")
} else {
disconnectLabel.text = "Du hast das Spiel verlassen!"
}
let showUpAnimation = SKAction.sequence([
SKAction.fadeAlpha(by: 1, duration: 2.5),
SKAction.scale(by: 10, duration: 1),
])
disconnectLabel.run(showUpAnimation)
self.addChild(disconnectLabel)
}
func initGameEndIcons() {
let iclonSize = CGSize(width: 400, height: 400)
let winnerIcon = SKSpriteNode(texture: SKTexture(imageNamed: "winner"));
winnerIcon.size = iclonSize
let loserIcon = SKSpriteNode(texture: SKTexture(imageNamed: "BaseTexture"))
loserIcon.size = iclonSize
let loserFire = SKEmitterNode(fileNamed: "LoserFire")
loserFire?.zPosition = loserIcon.zPosition - 1
loserFire?.run(SKAction.scale(by: 4, duration: 8))
let iconPosition1 = CGPoint(x: self.size.width * 0.25, y: self.size.height * 0.55)
let iconPosition2 = CGPoint(x: self.size.width * 0.75, y: self.size.height * 0.55)
let coin = SpinningLogo3DNode()
if GameCenterManager.sharedInstance.winner == GameCenterManager.sharedInstance.hostingPlayer?.displayName {
winnerIcon.position = iconPosition1
coin.position = iconPosition1
loserIcon.position = iconPosition2
loserFire?.position = iconPosition2
} else {
winnerIcon.position = iconPosition2
coin.position = iconPosition2
loserIcon.position = iconPosition1
loserFire?.position = iconPosition1
}
self.addChild(winnerIcon)
self.addChild(coin)
self.addChild(loserIcon)
self.addChild(loserFire!)
}
func getFinalExplosion() -> SKEmitterNode {
let explosion = SKEmitterNode(fileNamed: "Explosion")!
explosion.zPosition = 2
explosion.position = CGPoint(x: self.size.width / 2, y: self.size.height / 2)
explosion.name = "explosion"
explosion.particleColorSequence = nil
explosion.particleColorBlendFactor = 1.0
return explosion
}
func backToMenuAction() {
GameCenterManager.sharedInstance.reset()
self.gameEndEffects = false
entityManager.getTimer()?.stopTimer()
RoundCalculatorService.sharedInstance.currentRound = 1
self.view?.presentScene(MenuScene(size: self.size))
entityManager.entities.removeAll()
self.removeFromParent()
}
func checkBases(bases: Set<Base>, touchLocation: CGPoint){
for base in bases {
@ -297,7 +148,7 @@ class GameScene: SKScene{
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: TeamComponent.self)?.unitcountLabel.position = CGPoint(x:touchLocation.x + 30, y: touchLocation.y - 50)
base.component(ofType: DefaultBaseComponent.self)?.labelNode.position = CGPoint(x:touchLocation.x + 30, y: touchLocation.y - 50)
}
func showNearestBases(base: Base){
@ -327,32 +178,6 @@ class GameScene: SKScene{
}
func isAttackMove() -> Bool {
if collisionBase?.ownershipPlayer == nil {
return true
}
return collisionBase?.ownershipPlayer != currentDraggedBase?.ownershipPlayer && !(collisionBase?.changeOwnership ?? false)
}
@objc func pauseGame() -> Void {
if !self.gameEndEffects{
entityManager.removeModal()
entityManager.getHUD()?.roundTimer.stopTimer()
entityManager.add(Modal(modaltype: .PauseGame,
base: nil,
anchorPoint: CGPoint(x: self.size.width / 2 , y: self.size.height / 2),
gameScene: self,
currentDraggedBase: nil,
touchLocation: nil,
collisionBase: nil
))
return collisionBase?.ownershipPlayer != currentDraggedBase?.ownershipPlayer
}
}
@objc func resumeGame() -> Void {
entityManager.removeModal()
entityManager.getHUD()?.roundTimer.resumeTimer()
}
}

View File

@ -8,23 +8,24 @@
import SpriteKit
import SceneKit
class MenuScene: SKScene {
var entityManager = EntityManager.menuEMInstance
override func sceneDidLoad() {
GameCenterManager.sharedInstance.menusc = self
StateManager.sharedInstance.menuSc = self
entityManager.setScene(scene: self)
let midX = self.size.width / 2
let midY = self.size.height / 2
entityManager.add(
Button(name: "startGameButton",
textureName: "gold_button_3",
entityManager.add(Button(name: "startGameButton",
textureName: "yellow_button04",
text: "Start Game",
position: CGPoint(x: midX, y: midY + 90),
position: CGPoint(x: midX, y: midY),
onButtonPress: {
if CommandLine.arguments.contains("--no-matchmaking") {
self.loadScene(scene: GameScene(size: self.size))
StateManager.sharedInstance.stateMachine?.enter(GameState.self)
SoundManager.sharedInstance.stopMenuMusic()
} else {
if GameCenterManager.isAuthenticated {
@ -33,43 +34,30 @@ class MenuScene: SKScene {
GameCenterManager.sharedInstance.authUser()
}
}
}
)
)
entityManager.add(
Button(name: "settingsButton",
textureName: "gold_button_3",
text: "Einstellungen",
position: CGPoint(x: midX, y: midY ),
onButtonPress: { self.loadScene(scene: SettingsScene(size: self.size))}
)
)
entityManager.add(
Button(name: "gameCenterButton",
textureName: "gold_button_3",
}))
entityManager.add(Button(name: "settingsButton",
textureName: "yellow_button04",
text: "Settings",
position: CGPoint(x: midX, y: midY - 80 ),
onButtonPress: {
let scene = SettingsScene(size: self.size)
self.loadScene(scene: scene)
}))
entityManager.add(Button(name: "gameCenterButton",
textureName: "yellow_button04",
text: "GameCenter",
position: CGPoint(x: midX, y: midY - 90),
position: CGPoint(x: midX, y: midY - 160),
onButtonPress: {
if GameCenterManager.isAuthenticated {
GameCenterManager.sharedInstance.presentGameCenter()
}else {
GameCenterManager.sharedInstance.authUser()
}
}
)
)
entityManager.add(
Button(name: "regelwerkButton",
textureName: "questionmark",
text: "",
position: CGPoint(x: self.size.width - 50, y: self.size.height - 50),
onButtonPress: { self.loadScene(scene: RulesScene(size: self.size)) }
)
)
}))
entityManager.add(Background(size: self.size))
entityManager.add(SpinningLogoEntity(sceneSize: self.size))
entityManager.add(SpinningLogoEntity(position: CGPoint(x: midX, y: midY + 200)))
if SoundManager.sharedInstance.isMusicPlaying == false && SoundManager.sharedInstance.isMusicEnabled == true && !CommandLine.arguments.contains("--no-music") && !UserDefaults.standard.bool(forKey: "noMusic"){
if SoundManager.sharedInstance.isMusicPlaying == false && SoundManager.sharedInstance.isMusicEnabled == true {
SoundManager.sharedInstance.startMenuMusic()
}
}
@ -81,14 +69,7 @@ class MenuScene: SKScene {
}
override func update(_ currentTime: TimeInterval) {
if entityManager.entities.count != 0 {
entityManager.getBackground()!.update(deltaTime: currentTime)
entityManager.getButtonByName(buttonName: "startGameButton").component(ofType: ButtonComponent.self)?.buttonNode.isEnabled = GameCenterManager.isAuthenticated
}
if GameCenterManager.sharedInstance.initIsFinish {
self.loadScene(scene: GameCenterManager.sharedInstance.gameScene!)
StateManager.sharedInstance.stateMachine!.update(deltaTime: currentTime)
}
}
}

View File

@ -11,17 +11,14 @@ import SpriteKit
class SettingsScene: SKScene {
var entityManager = EntityManager.settingsEMInstance
var musicButtonText = ""
var isMusicDeactivatedByUserDefault = UserDefaults.standard.bool(forKey: "noMusic")
override func sceneDidLoad() {
entityManager.setScene(scene: self)
let positionX = self.size.width * 0.1
let positionY = self.size.height * 0.05
isMusicDeactivatedByUserDefault ? setMusicButtonTextByUserDefault(text: "Aus") : setMusicButtonTextByUserDefault(text: "An")
entityManager.add(Button(name: "backToMenuScene",
textureName: "yellow_button04",
text: "Zurück",
text: "Back",
position: CGPoint(x: positionX, y: positionY),
onButtonPress: {
let scene = MenuScene(size: self.size)
@ -29,36 +26,32 @@ class SettingsScene: SKScene {
}))
entityManager.add(Button(name: "StopMenuMusic",
textureName: "yellow_button04",
text: musicButtonText,
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
self.entityManager.changeSettingsButtonText(buttonName: "StopMenuMusic", text: "Aus")
} else {
SoundManager.sharedInstance.isMusicEnabled = true
SoundManager.sharedInstance.startMenuMusic()
self.entityManager.changeSettingsButtonText(buttonName: "StopMenuMusic", text: "An")
}
}))
entityManager.add(Button(name: "StopMovingBackground",
textureName: "yellow_button04",
text: "An",
text: "MOVE/STOP",
position: CGPoint(x: self.size.width * 0.6, y: self.size.height / 2 - 100),
onButtonPress: {
if BackgroundComponent.isMovingBackgroundEnabled {
BackgroundComponent.isMovingBackgroundEnabled = false
self.entityManager.changeSettingsButtonText(buttonName: "StopMovingBackground", text: "Aus")
} else {
BackgroundComponent.isMovingBackgroundEnabled = true
self.entityManager.changeSettingsButtonText(buttonName: "StopMovingBackground", text: "An")
}
}))
entityManager.add(Label(fontnamed: "Courier-Bold",
name: "SettingsLabel",
text: "Einstellungen",
fontSize: 150.0,
text: "Settings",
fontSize: 200.0,
fontColor: .black,
position: CGPoint(x: self.size.width * 0.5, y: self.size.height * 0.7),
horizontalAlignmentMode: .center,
@ -68,7 +61,7 @@ class SettingsScene: SKScene {
)
entityManager.add(Label(fontnamed: "Courier-Bold",
name: "LabelMusic",
text: "Sounds", fontSize: 50.0,
text: "Music", fontSize: 50.0,
fontColor: .black,
position: CGPoint(x: self.size.width * 0.5, y: self.size.height / 2 - 15),
horizontalAlignmentMode: .right,
@ -78,7 +71,7 @@ class SettingsScene: SKScene {
)
entityManager.add(Label(fontnamed: "Courier-Bold",
name: "LabelBackground",
text: "Wind",
text: "Background",
fontSize: 50.0,
fontColor: .black,
position: CGPoint(x: self.size.width * 0.5, y: self.size.height / 2 - 115),
@ -90,10 +83,6 @@ class SettingsScene: SKScene {
entityManager.add(Background(size: self.size))
}
func setMusicButtonTextByUserDefault(text: String) {
self.musicButtonText = text
}
func loadScene(scene: SKScene) {
let transition = SKTransition.flipVertical(withDuration: 0.5)
entityManager.entities.removeAll()

View File

@ -8,16 +8,12 @@
import SpriteKit
import AVFoundation
import os
class SoundManager {
public static var sharedInstance = SoundManager()
let LOG = OSLog.init(subsystem: "SoundManager", category: "SoundManager")
var audioPlayer = AVAudioPlayer()
var effectPlayer = AVAudioPlayer()
var backgroundMainMenuAudio: URL?
var soundEffect: URL?
var isMusicPlaying = false
var isMusicEnabled = true
@ -27,34 +23,18 @@ class SoundManager {
do {
audioPlayer = try AVAudioPlayer(contentsOf: backgroundMainMenuAudio!)
} catch {
os_log("backgroundMusic is broken", log: LOG, type: .error)
//TODO: Add logging
}
audioPlayer.numberOfLoops = -1
audioPlayer.prepareToPlay()
if self.isMusicEnabled == true {
audioPlayer.play()
UserDefaults.standard.set(false, forKey: "noMusic")
}
}
func playSoundEffect(pathToFile: String, fileExtension: String, volumeLevel: Float){
soundEffect = Bundle.main.url(forResource: pathToFile, withExtension: fileExtension)
do {
effectPlayer = try AVAudioPlayer(contentsOf: soundEffect!)
} catch {
os_log("Could not load sound file %@", log: LOG, type: .error, pathToFile)
}
effectPlayer.volume += volumeLevel
effectPlayer.prepareToPlay()
if self.isMusicEnabled == true {
effectPlayer.play()
}
}
func stopMenuMusic() {
audioPlayer.pause()
self.isMusicPlaying = false
UserDefaults.standard.set(true, forKey: "noMusic")
}
func setVolume(_ volume: Float) {

View File

@ -0,0 +1,37 @@
//
// EndGameState.swift
// GoldWars
//
// Created by Chauntalle Schüle on 29.05.20.
// Copyright © 2020 SP2. All rights reserved.
//
import GameKit
import os
class EndGameState: GKState {
let LOG = OSLog.init(subsystem: "EndGameState", category: "EndGameState")
override func isValidNextState(_ stateClass: AnyClass) -> Bool {
if stateMachine?.currentState is EndGameState && stateClass is EndGameState.Type {
os_log("Already in EndGame State", log: LOG, type: .info)
return false
}
if stateClass is SyncingState.Type || stateClass is GameState.Type {
os_log("Failed: Entering SyncingState and GameState after EndGameState is not allowed", log: LOG, type: .info)
return false
}
return stateClass is MenuState.Type
}
override func update(deltaTime seconds: TimeInterval) {
}
override func didEnter(from previousState: GKState?) {
os_log("Entered EndGame State", log: LOG, type: .info)
}
override func willExit(to nextState: GKState) {
}
}

Some files were not shown because too many files have changed in this diff Show More