Merge branch 'development'
@ -16,17 +16,16 @@
|
|||||||
110360EE244B101B008610AF /* GoldWarsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110360ED244B101B008610AF /* GoldWarsTests.swift */; };
|
110360EE244B101B008610AF /* GoldWarsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110360ED244B101B008610AF /* GoldWarsTests.swift */; };
|
||||||
11036113244B3E30008610AF /* MenuScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11036112244B3E30008610AF /* MenuScene.swift */; };
|
11036113244B3E30008610AF /* MenuScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11036112244B3E30008610AF /* MenuScene.swift */; };
|
||||||
116060F7245C57D2004E5A36 /* EntityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 116060F6245C57D2004E5A36 /* EntityManager.swift */; };
|
116060F7245C57D2004E5A36 /* EntityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 116060F6245C57D2004E5A36 /* EntityManager.swift */; };
|
||||||
11738A3B24508F68004426F1 /* UnitType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11738A3A24508F68004426F1 /* UnitType.swift */; };
|
|
||||||
2086465C2461B66200817C23 /* TimerComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2086465B2461B66200817C23 /* TimerComponent.swift */; };
|
|
||||||
3E67854024728368007B9DE4 /* CElements.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E67853F24728368007B9DE4 /* CElements.swift */; };
|
3E67854024728368007B9DE4 /* CElements.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E67853F24728368007B9DE4 /* CElements.swift */; };
|
||||||
3E6785422472CBEC007B9DE4 /* Way.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E6785412472CBEC007B9DE4 /* Way.swift */; };
|
3E6785422472CBEC007B9DE4 /* Way.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E6785412472CBEC007B9DE4 /* Way.swift */; };
|
||||||
3E6785442472CC27007B9DE4 /* DefaultWayComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E6785432472CC27007B9DE4 /* DefaultWayComponent.swift */; };
|
3E6785442472CC27007B9DE4 /* DefaultWayComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E6785432472CC27007B9DE4 /* DefaultWayComponent.swift */; };
|
||||||
3EBD242C245D8044003CECE7 /* GameCenterHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EBD242B245D8044003CECE7 /* GameCenterHelper.swift */; };
|
3EAD889524801B6A0048A10A /* RoundTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EAD889424801B6A0048A10A /* RoundTimer.swift */; };
|
||||||
3EBD242E245D9332003CECE7 /* Team.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EBD242D245D9332003CECE7 /* Team.swift */; };
|
3EBD242E245D9332003CECE7 /* Team.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EBD242D245D9332003CECE7 /* Team.swift */; };
|
||||||
3F745DF0246F48FC00CE7375 /* PlayerMoveType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F745DEF246F48FC00CE7375 /* PlayerMoveType.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 */; };
|
3FE19DB5246C7A22004827AB /* RoundCalculatorService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FE19DB4246C7A22004827AB /* RoundCalculatorService.swift */; };
|
||||||
8BB6FF402472B8F000162BBD /* SkillButtonNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8BB6FF3F2472B8F000162BBD /* SkillButtonNode.swift */; };
|
8BB6FF402472B8F000162BBD /* SingeClickButtonNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8BB6FF3F2472B8F000162BBD /* SingeClickButtonNode.swift */; };
|
||||||
9E04AFAF245E2B73002D5CFC /* AttackActionComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E04AFAE245E2B73002D5CFC /* AttackActionComponent.swift */; };
|
9E0E459724796262009817A6 /* GameCenterManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E0E459624796262009817A6 /* GameCenterManager.swift */; };
|
||||||
9E11FF79245CD81100EED3BE /* Fire.sks in Resources */ = {isa = PBXBuildFile; fileRef = 9E11FF77245CD81100EED3BE /* Fire.sks */; };
|
9E11FF79245CD81100EED3BE /* Fire.sks in Resources */ = {isa = PBXBuildFile; fileRef = 9E11FF77245CD81100EED3BE /* Fire.sks */; };
|
||||||
9E174C82245DD81D00209FF0 /* ButtonNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E174C81245DD81D00209FF0 /* ButtonNode.swift */; };
|
9E174C82245DD81D00209FF0 /* ButtonNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E174C81245DD81D00209FF0 /* ButtonNode.swift */; };
|
||||||
9E174C84245DD8CE00209FF0 /* Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E174C83245DD8CE00209FF0 /* Button.swift */; };
|
9E174C84245DD8CE00209FF0 /* Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E174C83245DD8CE00209FF0 /* Button.swift */; };
|
||||||
@ -36,30 +35,20 @@
|
|||||||
9E78ACB6245C9A5300526FF7 /* GameKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E78ACB5245C9A5300526FF7 /* GameKit.framework */; };
|
9E78ACB6245C9A5300526FF7 /* GameKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E78ACB5245C9A5300526FF7 /* GameKit.framework */; };
|
||||||
9E78ACB8245CB75B00526FF7 /* TeamComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E78ACB7245CB75B00526FF7 /* TeamComponent.swift */; };
|
9E78ACB8245CB75B00526FF7 /* TeamComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E78ACB7245CB75B00526FF7 /* TeamComponent.swift */; };
|
||||||
9E78ACBA245CBDAF00526FF7 /* HUD.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E78ACB9245CBDAF00526FF7 /* HUD.swift */; };
|
9E78ACBA245CBDAF00526FF7 /* HUD.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E78ACB9245CBDAF00526FF7 /* HUD.swift */; };
|
||||||
9E78ACBE245CC9C000526FF7 /* AtkBoostSkillComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E78ACBD245CC9C000526FF7 /* AtkBoostSkillComponent.swift */; };
|
|
||||||
9E78ACC2245CC9EE00526FF7 /* DefBoostSkillComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E78ACC1245CC9EE00526FF7 /* DefBoostSkillComponent.swift */; };
|
|
||||||
9E78ACC4245CCA3600526FF7 /* SpySkillComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E78ACC3245CCA3600526FF7 /* SpySkillComponent.swift */; };
|
|
||||||
9EA3ABE9245C6DAA006BC61D /* DefaultBaseComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA3ABE8245C6DAA006BC61D /* DefaultBaseComponent.swift */; };
|
9EA3ABE9245C6DAA006BC61D /* DefaultBaseComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA3ABE8245C6DAA006BC61D /* DefaultBaseComponent.swift */; };
|
||||||
9EA3ABEB245C6DFA006BC61D /* BaseNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA3ABEA245C6DFA006BC61D /* BaseNode.swift */; };
|
9EA3ABEB245C6DFA006BC61D /* BaseNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA3ABEA245C6DFA006BC61D /* BaseNode.swift */; };
|
||||||
9EA3ABED245C8143006BC61D /* ModalBackgroundComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA3ABEC245C8143006BC61D /* ModalBackgroundComponent.swift */; };
|
|
||||||
9EA3ABEF245C834B006BC61D /* ModalContentComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA3ABEE245C834B006BC61D /* ModalContentComponent.swift */; };
|
|
||||||
9EBFD7552462CF5A00E1E219 /* SliderComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EBFD7542462CF5A00E1E219 /* SliderComponent.swift */; };
|
|
||||||
9EC239E1246878A900952F74 /* MultiplayerNetwork.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EC239E0246878A900952F74 /* MultiplayerNetwork.swift */; };
|
9EC239E1246878A900952F74 /* MultiplayerNetwork.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EC239E0246878A900952F74 /* MultiplayerNetwork.swift */; };
|
||||||
9EC2FBA72476B1EC00ABF11F /* PlayerInfoComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EC2FBA62476B1EC00ABF11F /* PlayerInfoComponent.swift */; };
|
9EC2FBA72476B1EC00ABF11F /* PlayerInfoComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EC2FBA62476B1EC00ABF11F /* PlayerInfoComponent.swift */; };
|
||||||
9EC7E48B2461FBF700396BCD /* SliderNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EC7E48A2461FBF700396BCD /* SliderNode.swift */; };
|
9EC7E48B2461FBF700396BCD /* SliderNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EC7E48A2461FBF700396BCD /* SliderNode.swift */; };
|
||||||
9EC86B9F245C88A300796EF3 /* Modal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EC86B9E245C88A300796EF3 /* Modal.swift */; };
|
9EC86B9F245C88A300796EF3 /* Modal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EC86B9E245C88A300796EF3 /* Modal.swift */; };
|
||||||
9EC86BA6245C8AD000796EF3 /* ModalType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EC86BA5245C8AD000796EF3 /* ModalType.swift */; };
|
|
||||||
9EEDE02D246FCD770096C735 /* SpinningLogoEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EEDE02C246FCD770096C735 /* SpinningLogoEntity.swift */; };
|
9EEDE02D246FCD770096C735 /* SpinningLogoEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EEDE02C246FCD770096C735 /* SpinningLogoEntity.swift */; };
|
||||||
9EEDE02F246FCD800096C735 /* SpinningLogoComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EEDE02E246FCD800096C735 /* SpinningLogoComponent.swift */; };
|
9EEDE02F246FCD800096C735 /* SpinningLogoComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EEDE02E246FCD800096C735 /* SpinningLogoComponent.swift */; };
|
||||||
AB1D759D245DD18100671525 /* TwoPlayerDefaultTestMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB1D759B245DD18100671525 /* TwoPlayerDefaultTestMap.swift */; };
|
AB21D7D5246C748A00B09CBA /* MapFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB21D7D4246C748A00B09CBA /* MapFactory.swift */; };
|
||||||
AB1D75A0245DEC0500671525 /* MapFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB1D759F245DEC0500671525 /* MapFactory.swift */; };
|
|
||||||
AB21D7D5246C748A00B09CBA /* TwoPlayerMapGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB21D7D4246C748A00B09CBA /* TwoPlayerMapGenerator.swift */; };
|
|
||||||
ABA03DA0244BD54F00A66916 /* Base.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABA03D9F244BD54F00A66916 /* Base.swift */; };
|
ABA03DA0244BD54F00A66916 /* Base.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABA03D9F244BD54F00A66916 /* Base.swift */; };
|
||||||
AE151589245F18EF001D363E /* MatchmakingHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE151588245F18EF001D363E /* MatchmakingHelper.swift */; };
|
ABC0C3732481509300387B8F /* MapUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABC0C3722481509300387B8F /* MapUtils.swift */; };
|
||||||
AEBF3AFF246EB146004F7CD5 /* CancelBtnNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEBF3AFE246EB146004F7CD5 /* CancelBtnNode.swift */; };
|
|
||||||
AEBF3B01246EB187004F7CD5 /* CancelBtnComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEBF3B00246EB187004F7CD5 /* CancelBtnComponent.swift */; };
|
|
||||||
C04783EE2468583F004961FB /* intro-music.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = C04783ED2468583F004961FB /* intro-music.mp3 */; };
|
C04783EE2468583F004961FB /* intro-music.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = C04783ED2468583F004961FB /* intro-music.mp3 */; };
|
||||||
C04783F024685995004961FB /* SettingsScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = C04783EF24685995004961FB /* SettingsScene.swift */; };
|
C04783F024685995004961FB /* SettingsScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = C04783EF24685995004961FB /* SettingsScene.swift */; };
|
||||||
|
C05BB9C4247D890C00411249 /* SliderComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C05BB9C3247D890C00411249 /* SliderComponent.swift */; };
|
||||||
C05FAED62468559D0006AF2E /* SoundManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C05FAED52468559D0006AF2E /* SoundManager.swift */; };
|
C05FAED62468559D0006AF2E /* SoundManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C05FAED52468559D0006AF2E /* SoundManager.swift */; };
|
||||||
C064E9A8246C0EA50022B228 /* LabelNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = C064E9A7246C0EA50022B228 /* LabelNode.swift */; };
|
C064E9A8246C0EA50022B228 /* LabelNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = C064E9A7246C0EA50022B228 /* LabelNode.swift */; };
|
||||||
C064E9AA246C114C0022B228 /* LabelComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C064E9A9246C114C0022B228 /* LabelComponent.swift */; };
|
C064E9AA246C114C0022B228 /* LabelComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C064E9A9246C114C0022B228 /* LabelComponent.swift */; };
|
||||||
@ -91,17 +80,16 @@
|
|||||||
110360EF244B101B008610AF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
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>"; };
|
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>"; };
|
116060F6245C57D2004E5A36 /* EntityManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntityManager.swift; sourceTree = "<group>"; };
|
||||||
11738A3A24508F68004426F1 /* UnitType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnitType.swift; sourceTree = "<group>"; };
|
|
||||||
2086465B2461B66200817C23 /* TimerComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimerComponent.swift; sourceTree = "<group>"; };
|
|
||||||
3E67853F24728368007B9DE4 /* CElements.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CElements.swift; 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>"; };
|
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>"; };
|
3E6785432472CC27007B9DE4 /* DefaultWayComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultWayComponent.swift; sourceTree = "<group>"; };
|
||||||
3EBD242B245D8044003CECE7 /* GameCenterHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameCenterHelper.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>"; };
|
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>"; };
|
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>"; };
|
3FE19DB4246C7A22004827AB /* RoundCalculatorService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoundCalculatorService.swift; sourceTree = "<group>"; };
|
||||||
8BB6FF3F2472B8F000162BBD /* 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>"; };
|
||||||
9E04AFAE245E2B73002D5CFC /* AttackActionComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttackActionComponent.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>"; };
|
9E11FF77245CD81100EED3BE /* Fire.sks */ = {isa = PBXFileReference; lastKnownFileType = file.sks; path = Fire.sks; sourceTree = "<group>"; };
|
||||||
9E174C81245DD81D00209FF0 /* ButtonNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ButtonNode.swift; sourceTree = "<group>"; };
|
9E174C81245DD81D00209FF0 /* ButtonNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ButtonNode.swift; sourceTree = "<group>"; };
|
||||||
9E174C83245DD8CE00209FF0 /* Button.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Button.swift; sourceTree = "<group>"; };
|
9E174C83245DD8CE00209FF0 /* Button.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Button.swift; sourceTree = "<group>"; };
|
||||||
@ -111,31 +99,21 @@
|
|||||||
9E78ACB5245C9A5300526FF7 /* GameKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameKit.framework; path = System/Library/Frameworks/GameKit.framework; sourceTree = SDKROOT; };
|
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>"; };
|
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>"; };
|
9E78ACB9245CBDAF00526FF7 /* HUD.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HUD.swift; sourceTree = "<group>"; };
|
||||||
9E78ACBD245CC9C000526FF7 /* AtkBoostSkillComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtkBoostSkillComponent.swift; sourceTree = "<group>"; };
|
|
||||||
9E78ACC1245CC9EE00526FF7 /* DefBoostSkillComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefBoostSkillComponent.swift; sourceTree = "<group>"; };
|
|
||||||
9E78ACC3245CCA3600526FF7 /* SpySkillComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpySkillComponent.swift; sourceTree = "<group>"; };
|
|
||||||
9EA3ABE8245C6DAA006BC61D /* DefaultBaseComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultBaseComponent.swift; sourceTree = "<group>"; wrapsLines = 1; };
|
9EA3ABE8245C6DAA006BC61D /* DefaultBaseComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultBaseComponent.swift; sourceTree = "<group>"; wrapsLines = 1; };
|
||||||
9EA3ABEA245C6DFA006BC61D /* BaseNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseNode.swift; sourceTree = "<group>"; };
|
9EA3ABEA245C6DFA006BC61D /* BaseNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseNode.swift; sourceTree = "<group>"; };
|
||||||
9EA3ABEC245C8143006BC61D /* ModalBackgroundComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalBackgroundComponent.swift; sourceTree = "<group>"; };
|
|
||||||
9EA3ABEE245C834B006BC61D /* ModalContentComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalContentComponent.swift; sourceTree = "<group>"; };
|
|
||||||
9EBFD7542462CF5A00E1E219 /* SliderComponent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SliderComponent.swift; sourceTree = "<group>"; };
|
|
||||||
9EC239E0246878A900952F74 /* MultiplayerNetwork.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiplayerNetwork.swift; sourceTree = "<group>"; };
|
9EC239E0246878A900952F74 /* MultiplayerNetwork.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiplayerNetwork.swift; sourceTree = "<group>"; };
|
||||||
9EC2FBA62476B1EC00ABF11F /* PlayerInfoComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerInfoComponent.swift; sourceTree = "<group>"; };
|
9EC2FBA62476B1EC00ABF11F /* PlayerInfoComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerInfoComponent.swift; sourceTree = "<group>"; };
|
||||||
9EC7E48A2461FBF700396BCD /* SliderNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SliderNode.swift; sourceTree = "<group>"; };
|
9EC7E48A2461FBF700396BCD /* SliderNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SliderNode.swift; sourceTree = "<group>"; };
|
||||||
9EC86B9E245C88A300796EF3 /* Modal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Modal.swift; sourceTree = "<group>"; };
|
9EC86B9E245C88A300796EF3 /* Modal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Modal.swift; sourceTree = "<group>"; };
|
||||||
9EC86BA5245C8AD000796EF3 /* ModalType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalType.swift; sourceTree = "<group>"; };
|
|
||||||
9ECD3699245C91F7008DEEBD /* GoldWars.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = GoldWars.entitlements; 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>"; };
|
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>"; };
|
9EEDE02E246FCD800096C735 /* SpinningLogoComponent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpinningLogoComponent.swift; sourceTree = "<group>"; };
|
||||||
AB1D759B245DD18100671525 /* TwoPlayerDefaultTestMap.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TwoPlayerDefaultTestMap.swift; sourceTree = "<group>"; };
|
AB21D7D4246C748A00B09CBA /* MapFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapFactory.swift; sourceTree = "<group>"; };
|
||||||
AB1D759F245DEC0500671525 /* MapFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapFactory.swift; sourceTree = "<group>"; };
|
|
||||||
AB21D7D4246C748A00B09CBA /* TwoPlayerMapGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoPlayerMapGenerator.swift; sourceTree = "<group>"; };
|
|
||||||
ABA03D9F244BD54F00A66916 /* Base.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Base.swift; sourceTree = "<group>"; };
|
ABA03D9F244BD54F00A66916 /* Base.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Base.swift; sourceTree = "<group>"; };
|
||||||
AE151588245F18EF001D363E /* MatchmakingHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatchmakingHelper.swift; sourceTree = "<group>"; };
|
ABC0C3722481509300387B8F /* MapUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapUtils.swift; sourceTree = "<group>"; };
|
||||||
AEBF3AFE246EB146004F7CD5 /* CancelBtnNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CancelBtnNode.swift; sourceTree = "<group>"; };
|
|
||||||
AEBF3B00246EB187004F7CD5 /* CancelBtnComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CancelBtnComponent.swift; sourceTree = "<group>"; };
|
|
||||||
C04783ED2468583F004961FB /* intro-music.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = "intro-music.mp3"; 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>"; };
|
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>"; };
|
||||||
C05FAED52468559D0006AF2E /* SoundManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SoundManager.swift; sourceTree = "<group>"; };
|
C05FAED52468559D0006AF2E /* SoundManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SoundManager.swift; sourceTree = "<group>"; };
|
||||||
C064E9A7246C0EA50022B228 /* LabelNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelNode.swift; sourceTree = "<group>"; };
|
C064E9A7246C0EA50022B228 /* LabelNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelNode.swift; sourceTree = "<group>"; };
|
||||||
C064E9A9246C114C0022B228 /* LabelComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelComponent.swift; sourceTree = "<group>"; };
|
C064E9A9246C114C0022B228 /* LabelComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelComponent.swift; sourceTree = "<group>"; };
|
||||||
@ -200,15 +178,10 @@
|
|||||||
9EC239E0246878A900952F74 /* MultiplayerNetwork.swift */,
|
9EC239E0246878A900952F74 /* MultiplayerNetwork.swift */,
|
||||||
C099579B246C5E5C0016AA22 /* DataService.swift */,
|
C099579B246C5E5C0016AA22 /* DataService.swift */,
|
||||||
110360E4244B101B008610AF /* Info.plist */,
|
110360E4244B101B008610AF /* Info.plist */,
|
||||||
AE151588245F18EF001D363E /* MatchmakingHelper.swift */,
|
|
||||||
3FE19DB4246C7A22004827AB /* RoundCalculatorService.swift */,
|
3FE19DB4246C7A22004827AB /* RoundCalculatorService.swift */,
|
||||||
3EBD242B245D8044003CECE7 /* GameCenterHelper.swift */,
|
9E0E459624796262009817A6 /* GameCenterManager.swift */,
|
||||||
AEBF3B00246EB187004F7CD5 /* CancelBtnComponent.swift */,
|
|
||||||
AEBF3AFE246EB146004F7CD5 /* CancelBtnNode.swift */,
|
|
||||||
C04783EF24685995004961FB /* SettingsScene.swift */,
|
C04783EF24685995004961FB /* SettingsScene.swift */,
|
||||||
C064E9A7246C0EA50022B228 /* LabelNode.swift */,
|
3EAD889424801B6A0048A10A /* RoundTimer.swift */,
|
||||||
C064E9A9246C114C0022B228 /* LabelComponent.swift */,
|
|
||||||
C064E9AB246C151F0022B228 /* Label.swift */,
|
|
||||||
);
|
);
|
||||||
path = GoldWars;
|
path = GoldWars;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -225,25 +198,20 @@
|
|||||||
116060F4245C56EA004E5A36 /* Components */ = {
|
116060F4245C56EA004E5A36 /* Components */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
9EEDE02E246FCD800096C735 /* SpinningLogoComponent.swift */,
|
9E174C87245DF1FF00209FF0 /* BackgroundComponent.swift */,
|
||||||
|
9EA3ABEA245C6DFA006BC61D /* BaseNode.swift */,
|
||||||
|
9E174C85245DD91500209FF0 /* ButtonComponent.swift */,
|
||||||
9E174C81245DD81D00209FF0 /* ButtonNode.swift */,
|
9E174C81245DD81D00209FF0 /* ButtonNode.swift */,
|
||||||
9EA3ABE8245C6DAA006BC61D /* DefaultBaseComponent.swift */,
|
9EA3ABE8245C6DAA006BC61D /* DefaultBaseComponent.swift */,
|
||||||
9EA3ABEC245C8143006BC61D /* ModalBackgroundComponent.swift */,
|
|
||||||
9EA3ABEE245C834B006BC61D /* ModalContentComponent.swift */,
|
|
||||||
9EA3ABEA245C6DFA006BC61D /* BaseNode.swift */,
|
|
||||||
9E78ACB7245CB75B00526FF7 /* TeamComponent.swift */,
|
|
||||||
9E78ACBD245CC9C000526FF7 /* AtkBoostSkillComponent.swift */,
|
|
||||||
9E78ACC3245CCA3600526FF7 /* SpySkillComponent.swift */,
|
|
||||||
9E78ACC1245CC9EE00526FF7 /* DefBoostSkillComponent.swift */,
|
|
||||||
9E174C85245DD91500209FF0 /* ButtonComponent.swift */,
|
|
||||||
9E174C87245DF1FF00209FF0 /* BackgroundComponent.swift */,
|
|
||||||
9E04AFAE245E2B73002D5CFC /* AttackActionComponent.swift */,
|
|
||||||
2086465B2461B66200817C23 /* TimerComponent.swift */,
|
|
||||||
9EBFD7542462CF5A00E1E219 /* SliderComponent.swift */,
|
|
||||||
9EC7E48A2461FBF700396BCD /* SliderNode.swift */,
|
|
||||||
3E6785432472CC27007B9DE4 /* DefaultWayComponent.swift */,
|
3E6785432472CC27007B9DE4 /* DefaultWayComponent.swift */,
|
||||||
8BB6FF3F2472B8F000162BBD /* SkillButtonNode.swift */,
|
C064E9A9246C114C0022B228 /* LabelComponent.swift */,
|
||||||
|
C064E9A7246C0EA50022B228 /* LabelNode.swift */,
|
||||||
9EC2FBA62476B1EC00ABF11F /* PlayerInfoComponent.swift */,
|
9EC2FBA62476B1EC00ABF11F /* PlayerInfoComponent.swift */,
|
||||||
|
8BB6FF3F2472B8F000162BBD /* SingeClickButtonNode.swift */,
|
||||||
|
C05BB9C3247D890C00411249 /* SliderComponent.swift */,
|
||||||
|
9EC7E48A2461FBF700396BCD /* SliderNode.swift */,
|
||||||
|
9EEDE02E246FCD800096C735 /* SpinningLogoComponent.swift */,
|
||||||
|
9E78ACB7245CB75B00526FF7 /* TeamComponent.swift */,
|
||||||
);
|
);
|
||||||
path = Components;
|
path = Components;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -259,6 +227,7 @@
|
|||||||
9EC86B9E245C88A300796EF3 /* Modal.swift */,
|
9EC86B9E245C88A300796EF3 /* Modal.swift */,
|
||||||
9EEDE02C246FCD770096C735 /* SpinningLogoEntity.swift */,
|
9EEDE02C246FCD770096C735 /* SpinningLogoEntity.swift */,
|
||||||
3E6785412472CBEC007B9DE4 /* Way.swift */,
|
3E6785412472CBEC007B9DE4 /* Way.swift */,
|
||||||
|
C064E9AB246C151F0022B228 /* Label.swift */,
|
||||||
);
|
);
|
||||||
path = Entities;
|
path = Entities;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -266,6 +235,7 @@
|
|||||||
9E11FF74245CD79100EED3BE /* Partikels */ = {
|
9E11FF74245CD79100EED3BE /* Partikels */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
3F79FFDF2486F7CD003F79C3 /* Explosion.sks */,
|
||||||
9E11FF77245CD81100EED3BE /* Fire.sks */,
|
9E11FF77245CD81100EED3BE /* Fire.sks */,
|
||||||
);
|
);
|
||||||
path = Partikels;
|
path = Partikels;
|
||||||
@ -282,8 +252,6 @@
|
|||||||
9EC86BA2245C89B200796EF3 /* Enums */ = {
|
9EC86BA2245C89B200796EF3 /* Enums */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
11738A3A24508F68004426F1 /* UnitType.swift */,
|
|
||||||
9EC86BA5245C8AD000796EF3 /* ModalType.swift */,
|
|
||||||
3EBD242D245D9332003CECE7 /* Team.swift */,
|
3EBD242D245D9332003CECE7 /* Team.swift */,
|
||||||
3F745DEF246F48FC00CE7375 /* PlayerMoveType.swift */,
|
3F745DEF246F48FC00CE7375 /* PlayerMoveType.swift */,
|
||||||
);
|
);
|
||||||
@ -312,9 +280,8 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
3E67853F24728368007B9DE4 /* CElements.swift */,
|
3E67853F24728368007B9DE4 /* CElements.swift */,
|
||||||
AB1D759F245DEC0500671525 /* MapFactory.swift */,
|
AB21D7D4246C748A00B09CBA /* MapFactory.swift */,
|
||||||
AB1D759B245DD18100671525 /* TwoPlayerDefaultTestMap.swift */,
|
ABC0C3722481509300387B8F /* MapUtils.swift */,
|
||||||
AB21D7D4246C748A00B09CBA /* TwoPlayerMapGenerator.swift */,
|
|
||||||
);
|
);
|
||||||
path = Map;
|
path = Map;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -405,6 +372,7 @@
|
|||||||
110360E0244B101B008610AF /* Assets.xcassets in Resources */,
|
110360E0244B101B008610AF /* Assets.xcassets in Resources */,
|
||||||
110360E3244B101B008610AF /* LaunchScreen.storyboard in Resources */,
|
110360E3244B101B008610AF /* LaunchScreen.storyboard in Resources */,
|
||||||
C04783EE2468583F004961FB /* intro-music.mp3 in Resources */,
|
C04783EE2468583F004961FB /* intro-music.mp3 in Resources */,
|
||||||
|
3F79FFE02486F7CD003F79C3 /* Explosion.sks in Resources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@ -423,14 +391,10 @@
|
|||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
9E78ACB8245CB75B00526FF7 /* TeamComponent.swift in Sources */,
|
9E78ACB8245CB75B00526FF7 /* TeamComponent.swift in Sources */,
|
||||||
9EA3ABEF245C834B006BC61D /* ModalContentComponent.swift in Sources */,
|
9E0E459724796262009817A6 /* GameCenterManager.swift in Sources */,
|
||||||
3FE19DB5246C7A22004827AB /* RoundCalculatorService.swift in Sources */,
|
3FE19DB5246C7A22004827AB /* RoundCalculatorService.swift in Sources */,
|
||||||
9EC86BA6245C8AD000796EF3 /* ModalType.swift in Sources */,
|
|
||||||
9EC239E1246878A900952F74 /* MultiplayerNetwork.swift in Sources */,
|
9EC239E1246878A900952F74 /* MultiplayerNetwork.swift in Sources */,
|
||||||
9E78ACBE245CC9C000526FF7 /* AtkBoostSkillComponent.swift in Sources */,
|
|
||||||
9E78ACC4245CCA3600526FF7 /* SpySkillComponent.swift in Sources */,
|
|
||||||
9EA3ABEB245C6DFA006BC61D /* BaseNode.swift in Sources */,
|
9EA3ABEB245C6DFA006BC61D /* BaseNode.swift in Sources */,
|
||||||
9E04AFAF245E2B73002D5CFC /* AttackActionComponent.swift in Sources */,
|
|
||||||
3E6785422472CBEC007B9DE4 /* Way.swift in Sources */,
|
3E6785422472CBEC007B9DE4 /* Way.swift in Sources */,
|
||||||
110360D9244B101A008610AF /* GameScene.swift in Sources */,
|
110360D9244B101A008610AF /* GameScene.swift in Sources */,
|
||||||
C04783F024685995004961FB /* SettingsScene.swift in Sources */,
|
C04783F024685995004961FB /* SettingsScene.swift in Sources */,
|
||||||
@ -441,37 +405,29 @@
|
|||||||
9E78ACBA245CBDAF00526FF7 /* HUD.swift in Sources */,
|
9E78ACBA245CBDAF00526FF7 /* HUD.swift in Sources */,
|
||||||
9EC2FBA72476B1EC00ABF11F /* PlayerInfoComponent.swift in Sources */,
|
9EC2FBA72476B1EC00ABF11F /* PlayerInfoComponent.swift in Sources */,
|
||||||
9EEDE02D246FCD770096C735 /* SpinningLogoEntity.swift in Sources */,
|
9EEDE02D246FCD770096C735 /* SpinningLogoEntity.swift in Sources */,
|
||||||
11738A3B24508F68004426F1 /* UnitType.swift in Sources */,
|
|
||||||
9E174C86245DD91500209FF0 /* ButtonComponent.swift in Sources */,
|
9E174C86245DD91500209FF0 /* ButtonComponent.swift in Sources */,
|
||||||
AE151589245F18EF001D363E /* MatchmakingHelper.swift in Sources */,
|
|
||||||
11036113244B3E30008610AF /* MenuScene.swift in Sources */,
|
11036113244B3E30008610AF /* MenuScene.swift in Sources */,
|
||||||
C099579C246C5E5C0016AA22 /* DataService.swift in Sources */,
|
C099579C246C5E5C0016AA22 /* DataService.swift in Sources */,
|
||||||
AB21D7D5246C748A00B09CBA /* TwoPlayerMapGenerator.swift in Sources */,
|
AB21D7D5246C748A00B09CBA /* MapFactory.swift in Sources */,
|
||||||
9EA3ABE9245C6DAA006BC61D /* DefaultBaseComponent.swift in Sources */,
|
9EA3ABE9245C6DAA006BC61D /* DefaultBaseComponent.swift in Sources */,
|
||||||
9E174C8A245E1A0A00209FF0 /* Background.swift in Sources */,
|
9E174C8A245E1A0A00209FF0 /* Background.swift in Sources */,
|
||||||
8BB6FF402472B8F000162BBD /* SkillButtonNode.swift in Sources */,
|
8BB6FF402472B8F000162BBD /* SingeClickButtonNode.swift in Sources */,
|
||||||
9EA3ABED245C8143006BC61D /* ModalBackgroundComponent.swift in Sources */,
|
|
||||||
C064E9A8246C0EA50022B228 /* LabelNode.swift in Sources */,
|
C064E9A8246C0EA50022B228 /* LabelNode.swift in Sources */,
|
||||||
3EBD242C245D8044003CECE7 /* GameCenterHelper.swift in Sources */,
|
|
||||||
3F745DF0246F48FC00CE7375 /* PlayerMoveType.swift in Sources */,
|
3F745DF0246F48FC00CE7375 /* PlayerMoveType.swift in Sources */,
|
||||||
AEBF3B01246EB187004F7CD5 /* CancelBtnComponent.swift in Sources */,
|
3EAD889524801B6A0048A10A /* RoundTimer.swift in Sources */,
|
||||||
AB1D75A0245DEC0500671525 /* MapFactory.swift in Sources */,
|
|
||||||
AB1D759D245DD18100671525 /* TwoPlayerDefaultTestMap.swift in Sources */,
|
|
||||||
9EBFD7552462CF5A00E1E219 /* SliderComponent.swift in Sources */,
|
|
||||||
3E67854024728368007B9DE4 /* CElements.swift in Sources */,
|
3E67854024728368007B9DE4 /* CElements.swift in Sources */,
|
||||||
ABA03DA0244BD54F00A66916 /* Base.swift in Sources */,
|
ABA03DA0244BD54F00A66916 /* Base.swift in Sources */,
|
||||||
C064E9AC246C151F0022B228 /* Label.swift in Sources */,
|
C064E9AC246C151F0022B228 /* Label.swift in Sources */,
|
||||||
|
ABC0C3732481509300387B8F /* MapUtils.swift in Sources */,
|
||||||
9E174C82245DD81D00209FF0 /* ButtonNode.swift in Sources */,
|
9E174C82245DD81D00209FF0 /* ButtonNode.swift in Sources */,
|
||||||
9EC7E48B2461FBF700396BCD /* SliderNode.swift in Sources */,
|
9EC7E48B2461FBF700396BCD /* SliderNode.swift in Sources */,
|
||||||
9EEDE02F246FCD800096C735 /* SpinningLogoComponent.swift in Sources */,
|
9EEDE02F246FCD800096C735 /* SpinningLogoComponent.swift in Sources */,
|
||||||
9E174C84245DD8CE00209FF0 /* Button.swift in Sources */,
|
9E174C84245DD8CE00209FF0 /* Button.swift in Sources */,
|
||||||
AEBF3AFF246EB146004F7CD5 /* CancelBtnNode.swift in Sources */,
|
|
||||||
110360DB244B101A008610AF /* GameViewController.swift in Sources */,
|
110360DB244B101A008610AF /* GameViewController.swift in Sources */,
|
||||||
3E6785442472CC27007B9DE4 /* DefaultWayComponent.swift in Sources */,
|
3E6785442472CC27007B9DE4 /* DefaultWayComponent.swift in Sources */,
|
||||||
2086465C2461B66200817C23 /* TimerComponent.swift in Sources */,
|
C05BB9C4247D890C00411249 /* SliderComponent.swift in Sources */,
|
||||||
110360D3244B101A008610AF /* AppDelegate.swift in Sources */,
|
110360D3244B101A008610AF /* AppDelegate.swift in Sources */,
|
||||||
9EC86B9F245C88A300796EF3 /* Modal.swift in Sources */,
|
9EC86B9F245C88A300796EF3 /* Modal.swift in Sources */,
|
||||||
9E78ACC2245CC9EE00526FF7 /* DefBoostSkillComponent.swift in Sources */,
|
|
||||||
C05FAED62468559D0006AF2E /* SoundManager.swift in Sources */,
|
C05FAED62468559D0006AF2E /* SoundManager.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
Before Width: | Height: | Size: 202 KiB |
Before Width: | Height: | Size: 202 KiB |
Before Width: | Height: | Size: 202 KiB |
BIN
GoldWars/GoldWars/Assets.xcassets/BaseTexture.imageset/Base-1.png
vendored
Normal file
After Width: | Height: | Size: 209 KiB |
BIN
GoldWars/GoldWars/Assets.xcassets/BaseTexture.imageset/Base-2.png
vendored
Normal file
After Width: | Height: | Size: 209 KiB |
BIN
GoldWars/GoldWars/Assets.xcassets/BaseTexture.imageset/Base.png
vendored
Normal file
After Width: | Height: | Size: 209 KiB |
@ -1,17 +1,17 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"filename" : "base.png",
|
"filename" : "Base.png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"scale" : "1x"
|
"scale" : "1x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "base-1.png",
|
"filename" : "Base-1.png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"scale" : "2x"
|
"scale" : "2x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "base-2.png",
|
"filename" : "Base-2.png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"scale" : "3x"
|
"scale" : "3x"
|
||||||
}
|
}
|
BIN
GoldWars/GoldWars/Assets.xcassets/BaseTexture_2.imageset/Base_2-1.png
vendored
Normal file
After Width: | Height: | Size: 191 KiB |
BIN
GoldWars/GoldWars/Assets.xcassets/BaseTexture_2.imageset/Base_2-2.png
vendored
Normal file
After Width: | Height: | Size: 191 KiB |
BIN
GoldWars/GoldWars/Assets.xcassets/BaseTexture_2.imageset/Base_2.png
vendored
Normal file
After Width: | Height: | Size: 191 KiB |
23
GoldWars/GoldWars/Assets.xcassets/BaseTexture_2.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "Base_2.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "Base_2-1.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "Base_2-2.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
@ -1,17 +1,17 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"filename" : "PopUpBackground.png",
|
"filename" : "ModalBackground.png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"scale" : "1x"
|
"scale" : "1x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "PopUpBackground-1.png",
|
"filename" : "ModalBackground-1.png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"scale" : "2x"
|
"scale" : "2x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "PopUpBackground-2.png",
|
"filename" : "ModalBackground-2.png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"scale" : "3x"
|
"scale" : "3x"
|
||||||
}
|
}
|
||||||
|
BIN
GoldWars/GoldWars/Assets.xcassets/ModalBackground.imageset/ModalBackground-1.png
vendored
Normal file
After Width: | Height: | Size: 165 KiB |
BIN
GoldWars/GoldWars/Assets.xcassets/ModalBackground.imageset/ModalBackground-2.png
vendored
Normal file
After Width: | Height: | Size: 165 KiB |
BIN
GoldWars/GoldWars/Assets.xcassets/ModalBackground.imageset/ModalBackground.png
vendored
Normal file
After Width: | Height: | Size: 165 KiB |
Before Width: | Height: | Size: 400 KiB |
Before Width: | Height: | Size: 400 KiB |
Before Width: | Height: | Size: 400 KiB |
@ -1,15 +1,17 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"filename" : "SkyBackground.jpg",
|
"filename" : "SkyBackground.png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"scale" : "1x"
|
"scale" : "1x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"filename" : "SkyBackground-1.png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"scale" : "2x"
|
"scale" : "2x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"filename" : "SkyBackground-2.png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"scale" : "3x"
|
"scale" : "3x"
|
||||||
}
|
}
|
||||||
|
BIN
GoldWars/GoldWars/Assets.xcassets/SkyBackground.imageset/SkyBackground-1.png
vendored
Normal file
After Width: | Height: | Size: 55 KiB |
BIN
GoldWars/GoldWars/Assets.xcassets/SkyBackground.imageset/SkyBackground-2.png
vendored
Normal file
After Width: | Height: | Size: 55 KiB |
Before Width: | Height: | Size: 20 KiB |
BIN
GoldWars/GoldWars/Assets.xcassets/SkyBackground.imageset/SkyBackground.png
vendored
Normal file
After Width: | Height: | Size: 55 KiB |
21
GoldWars/GoldWars/Assets.xcassets/UITexture.spriteatlas/red_cross.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "red_cross.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
GoldWars/GoldWars/Assets.xcassets/UITexture.spriteatlas/red_cross.imageset/red_cross.png
vendored
Normal file
After Width: | Height: | Size: 1003 B |
23
GoldWars/GoldWars/Assets.xcassets/roundInfo_texture.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "roundInfo_texture.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "roundInfo_texture-1.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "roundInfo_texture-2.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
GoldWars/GoldWars/Assets.xcassets/roundInfo_texture.imageset/roundInfo_texture-1.png
vendored
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
GoldWars/GoldWars/Assets.xcassets/roundInfo_texture.imageset/roundInfo_texture-2.png
vendored
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
GoldWars/GoldWars/Assets.xcassets/roundInfo_texture.imageset/roundInfo_texture.png
vendored
Normal file
After Width: | Height: | Size: 19 KiB |
@ -12,8 +12,8 @@ class ButtonComponent: GKComponent {
|
|||||||
|
|
||||||
var buttonNode: ButtonNode
|
var buttonNode: ButtonNode
|
||||||
|
|
||||||
init(iconName: String, text: String, position: CGPoint, isEnabled:Bool, onButtonPress: @escaping () -> ()) {
|
init(textureName: String, text: String, position: CGPoint, isEnabled:Bool, onButtonPress: @escaping () -> ()) {
|
||||||
buttonNode = ButtonNode(iconName: iconName,
|
buttonNode = ButtonNode(textureName: textureName,
|
||||||
text: text,
|
text: text,
|
||||||
isEnabled: isEnabled,
|
isEnabled: isEnabled,
|
||||||
position: position,
|
position: position,
|
||||||
|
@ -22,12 +22,12 @@ class ButtonNode: SKSpriteNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let onButtonPress: () -> ()
|
var onButtonPress: () -> ()
|
||||||
|
|
||||||
init(iconName: String, text: String, isEnabled: Bool, position: CGPoint, onButtonPress: @escaping () -> ()) {
|
init(textureName: String, text: String, isEnabled: Bool, position: CGPoint, onButtonPress: @escaping () -> ()) {
|
||||||
self.onButtonPress = onButtonPress
|
self.onButtonPress = onButtonPress
|
||||||
self.isEnabled = isEnabled
|
self.isEnabled = isEnabled
|
||||||
let texture = SKTexture(imageNamed: "yellow_button04")
|
let texture = SKTexture(imageNamed: textureName)
|
||||||
super.init(texture: texture, color: SKColor.white, size: texture.size())
|
super.init(texture: texture, color: SKColor.white, size: texture.size())
|
||||||
self.position = position
|
self.position = position
|
||||||
|
|
||||||
@ -38,16 +38,7 @@ class ButtonNode: SKSpriteNode {
|
|||||||
label.verticalAlignmentMode = .center
|
label.verticalAlignmentMode = .center
|
||||||
label.text = text
|
label.text = text
|
||||||
label.name = "label"
|
label.name = "label"
|
||||||
|
|
||||||
if iconName.isEmpty {
|
|
||||||
label.position = CGPoint(x: 0, y: 0)
|
|
||||||
} else {
|
|
||||||
label.position = CGPoint(x: size.width * 0.25, y: 0)
|
|
||||||
let icon = SKSpriteNode(imageNamed: iconName)
|
|
||||||
icon.position = CGPoint(x: -size.width * 0.25, y: 0)
|
|
||||||
icon.zPosition = 1
|
|
||||||
self.addChild(icon)
|
|
||||||
}
|
|
||||||
self.addChild(label)
|
self.addChild(label)
|
||||||
isUserInteractionEnabled = true
|
isUserInteractionEnabled = true
|
||||||
}
|
}
|
||||||
|
@ -12,21 +12,21 @@ import GameKit
|
|||||||
|
|
||||||
class DefaultBaseComponent: GKComponent {
|
class DefaultBaseComponent: GKComponent {
|
||||||
var spriteNode: BaseNode
|
var spriteNode: BaseNode
|
||||||
var labelNode : SKLabelNode?
|
var labelNode : SKLabelNode
|
||||||
|
|
||||||
init(texture: SKTexture, position: CGPoint) {
|
init(texture: SKTexture, position: CGPoint) {
|
||||||
spriteNode = BaseNode(texture: texture, size: CGSize(width: 80, height: 80))
|
spriteNode = BaseNode(texture: texture, size: CGSize(width: 100, height: 100))
|
||||||
spriteNode.position = position
|
spriteNode.position = position
|
||||||
spriteNode.zPosition = 2
|
spriteNode.zPosition = 2
|
||||||
super.init()
|
|
||||||
labelNode = SKLabelNode(text: "")
|
labelNode = SKLabelNode(text: "")
|
||||||
labelNode?.fontColor = SKColor.black
|
labelNode.fontColor = SKColor.black
|
||||||
labelNode?.horizontalAlignmentMode = .left
|
labelNode.horizontalAlignmentMode = .left
|
||||||
labelNode?.verticalAlignmentMode = .center
|
labelNode.verticalAlignmentMode = .center
|
||||||
labelNode?.fontName = "AvenirNext-Bold"
|
labelNode.fontName = "AvenirNext-Bold"
|
||||||
labelNode?.fontSize = 15
|
labelNode.fontSize = 15
|
||||||
labelNode?.position = CGPoint(x: position.x + 30 , y: position.y - 50 )
|
labelNode.position = CGPoint(x: position.x + 30 , y: position.y - 50 )
|
||||||
labelNode?.zPosition = spriteNode.zPosition - 1
|
labelNode.zPosition = spriteNode.zPosition - 1
|
||||||
|
super.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
required init?(coder aDecoder: NSCoder) {
|
required init?(coder aDecoder: NSCoder) {
|
||||||
|
32
GoldWars/GoldWars/Components/LabelComponent.swift
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
//
|
||||||
|
// LabelComponent.swift
|
||||||
|
// GoldWars
|
||||||
|
//
|
||||||
|
// Created by Tim Herbst on 13.05.20.
|
||||||
|
// Copyright © 2020 SP2. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import GameplayKit
|
||||||
|
|
||||||
|
class LabelComponent: GKComponent {
|
||||||
|
var labelNode: LabelNode
|
||||||
|
|
||||||
|
init(fontnamed: String?, name: String, text: String, fontSize: CGFloat, fontColor: UIColor, position: CGPoint, horizontalAlignmentMode: SKLabelHorizontalAlignmentMode, vertikalAligmentMode: SKLabelVerticalAlignmentMode, isAnimationEnabled: Bool, isAnimationInfinite: Bool) {
|
||||||
|
labelNode = LabelNode(fontNamed: fontnamed)
|
||||||
|
labelNode.name = name
|
||||||
|
labelNode.text = text
|
||||||
|
labelNode.fontSize = fontSize
|
||||||
|
labelNode.fontColor = fontColor
|
||||||
|
labelNode.horizontalAlignmentMode = horizontalAlignmentMode
|
||||||
|
labelNode.verticalAlignmentMode = vertikalAligmentMode
|
||||||
|
labelNode.position = position
|
||||||
|
if isAnimationEnabled {
|
||||||
|
labelNode.sequentiallyBouncingZoom(delay: 0.3, infinite: isAnimationInfinite)
|
||||||
|
}
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
}
|
152
GoldWars/GoldWars/Components/LabelNode.swift
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
//
|
||||||
|
// LabelNode.swift
|
||||||
|
// GoldWars
|
||||||
|
//
|
||||||
|
// Created by Tim Herbst on 13.05.20.
|
||||||
|
// Copyright © 2020 SP2. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SpriteKit
|
||||||
|
|
||||||
|
class LabelNode: SKNode {
|
||||||
|
let colt = SKLabelNode()
|
||||||
|
var labels = [SKLabelNode]()
|
||||||
|
var text = "" {
|
||||||
|
didSet {
|
||||||
|
refreshLabels()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var fontName = "HelveticaNeue-UltraLight" {
|
||||||
|
didSet {
|
||||||
|
_ = labels.compactMap({ $0.fontName = fontName })
|
||||||
|
refreshLabels()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var fontSize = CGFloat(30.0) {
|
||||||
|
didSet {
|
||||||
|
_ = labels.compactMap({ $0.fontSize = fontSize })
|
||||||
|
refreshLabels()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var fontColor = UIColor.init(white: 1.0, alpha: 1.0) {
|
||||||
|
didSet {
|
||||||
|
_ = labels.compactMap({ $0.fontColor = fontColor })
|
||||||
|
refreshLabels()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.init(rawValue: 0) { // left
|
||||||
|
didSet {
|
||||||
|
_ = labels.compactMap({ $0.horizontalAlignmentMode = horizontalAlignmentMode! })
|
||||||
|
refreshLabels()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var verticalAlignmentMode = SKLabelVerticalAlignmentMode.init(rawValue: 0) { // center
|
||||||
|
didSet {
|
||||||
|
_ = labels.compactMap({ $0.verticalAlignmentMode = verticalAlignmentMode! })
|
||||||
|
refreshLabels()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var lineSpacingFactor: CGFloat = -1.3 {
|
||||||
|
didSet {
|
||||||
|
refreshLabels()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
override init() {
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
convenience init(text: String) {
|
||||||
|
self.init()
|
||||||
|
self.text = text
|
||||||
|
}
|
||||||
|
convenience init(fontNamed fontName: String?) {
|
||||||
|
self.init(text: "")
|
||||||
|
if let f = fontName {
|
||||||
|
self.fontName = f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
required init?(coder aDecoder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func refreshLabels() {
|
||||||
|
_ = labels.compactMap({ $0.removeFromParent() })
|
||||||
|
labels.removeAll()
|
||||||
|
if text.count > 0 {
|
||||||
|
var newX: CGFloat = 0.0
|
||||||
|
var gapX: CGFloat = 0.0
|
||||||
|
let ghostSpace = SKLabelNode(text: ".")
|
||||||
|
ghostSpace.fontName = fontName
|
||||||
|
ghostSpace.fontSize = fontSize
|
||||||
|
let ghostSpaceWidth = ghostSpace.frame.size.width
|
||||||
|
var fullNodeWidth:CGFloat = 0.0
|
||||||
|
for char in text {
|
||||||
|
if String(char) != " " {
|
||||||
|
let charLabelNode = SKLabelNode(text: String(char))
|
||||||
|
charLabelNode.fontName = fontName
|
||||||
|
charLabelNode.fontSize = fontSize
|
||||||
|
fullNodeWidth += charLabelNode.frame.size.width + lineSpacingFactor
|
||||||
|
} else {
|
||||||
|
fullNodeWidth += ghostSpaceWidth + lineSpacingFactor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch horizontalAlignmentMode {
|
||||||
|
case .left? : gapX = 0.0
|
||||||
|
case .center? : gapX = fullNodeWidth/2
|
||||||
|
case .right? : gapX = fullNodeWidth
|
||||||
|
default: break
|
||||||
|
}
|
||||||
|
var index: Int = 0
|
||||||
|
for char in text {
|
||||||
|
if String(char) != " " {
|
||||||
|
let charLabelNode = SKLabelNode(text: String(char))
|
||||||
|
charLabelNode.fontName = fontName
|
||||||
|
charLabelNode.fontSize = fontSize
|
||||||
|
charLabelNode.fontColor = fontColor
|
||||||
|
charLabelNode.horizontalAlignmentMode = .left
|
||||||
|
charLabelNode.verticalAlignmentMode = verticalAlignmentMode!
|
||||||
|
charLabelNode.position.x = newX - gapX
|
||||||
|
charLabelNode.alpha = 1
|
||||||
|
self.addChild(charLabelNode)
|
||||||
|
labels.append(charLabelNode)
|
||||||
|
newX += charLabelNode.frame.size.width + lineSpacingFactor
|
||||||
|
} else {
|
||||||
|
ghostSpace.horizontalAlignmentMode = .left
|
||||||
|
ghostSpace.verticalAlignmentMode = verticalAlignmentMode!
|
||||||
|
ghostSpace.position.x = newX - gapX
|
||||||
|
labels.append(ghostSpace)
|
||||||
|
newX += ghostSpaceWidth + lineSpacingFactor
|
||||||
|
}
|
||||||
|
index += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func sequentiallyBouncingZoom(delay:TimeInterval, infinite:Bool = false) {
|
||||||
|
if labels.count > 0 && self.action(forKey: "sequentiallyBouncingZoom") == nil {
|
||||||
|
let main = SKAction.run { [weak self] in
|
||||||
|
guard let strongSelf = self else { return }
|
||||||
|
for i in 0..<strongSelf.labels.count {
|
||||||
|
let zoomIn = SKAction.scale(to: 2.0, duration: delay)
|
||||||
|
let zoomOut = SKAction.scale(to: 1.0, duration: delay)
|
||||||
|
let currentDuration = delay * TimeInterval(i)
|
||||||
|
let wait = SKAction.wait(forDuration: currentDuration)
|
||||||
|
let seq = SKAction.sequence([wait,zoomIn,zoomOut])
|
||||||
|
let currentLab = strongSelf.labels[i]
|
||||||
|
currentLab.run(seq, withKey: "seq\(i)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let waitAfter = SKAction.wait(forDuration: delay * TimeInterval(self.labels.count+1))
|
||||||
|
let seq = SKAction.sequence([main,waitAfter])
|
||||||
|
let finalAction = infinite ? SKAction.repeatForever(seq) : main
|
||||||
|
self.run(finalAction, withKey: "sequentiallyBouncingZoom")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
extension SKAction {
|
||||||
|
class func afterDelay(_ delay: TimeInterval, performAction action: SKAction) -> SKAction {
|
||||||
|
return SKAction.sequence([SKAction.wait(forDuration: delay), action])
|
||||||
|
}
|
||||||
|
class func afterDelay(_ delay: TimeInterval, runBlock block: @escaping () -> Void) -> SKAction {
|
||||||
|
return SKAction.afterDelay(delay, performAction: SKAction.run(block))
|
||||||
|
}
|
||||||
|
}
|
@ -10,52 +10,3 @@ import Foundation
|
|||||||
import GameplayKit
|
import GameplayKit
|
||||||
import GameKit
|
import GameKit
|
||||||
|
|
||||||
|
|
||||||
class PlayerInfoComponent: GKComponent {
|
|
||||||
|
|
||||||
var hostLabel:SKLabelNode
|
|
||||||
var hostUnitsLabel:SKLabelNode
|
|
||||||
|
|
||||||
var peerLabel:SKLabelNode
|
|
||||||
var peerUnitsLabel:SKLabelNode
|
|
||||||
var host: GKPlayer?
|
|
||||||
var peer: GKPlayer?
|
|
||||||
|
|
||||||
init(size: CGSize) {
|
|
||||||
if MatchmakingHelper.sharedInstance.isServer {
|
|
||||||
host = GKLocalPlayer.local
|
|
||||||
peer = MatchmakingHelper.sharedInstance.mpMatch?.players[0]
|
|
||||||
} else {
|
|
||||||
host = MatchmakingHelper.sharedInstance.mpMatch?.players[0]
|
|
||||||
peer = GKLocalPlayer.local
|
|
||||||
}
|
|
||||||
hostLabel = SKLabelNode(text: host?.displayName)
|
|
||||||
hostUnitsLabel = SKLabelNode(text: "500" )
|
|
||||||
peerLabel = SKLabelNode(text: peer?.displayName)
|
|
||||||
peerUnitsLabel = SKLabelNode(text: "500")
|
|
||||||
super.init()
|
|
||||||
hostLabel.position = CGPoint(x: size.width * 0.02, y: size.height * 0.95)
|
|
||||||
hostLabel.horizontalAlignmentMode = .left
|
|
||||||
peerLabel.position = CGPoint(x: size.width * 0.98, y: size.height * 0.95)
|
|
||||||
peerLabel.horizontalAlignmentMode = .right
|
|
||||||
hostUnitsLabel.position = CGPoint(x: size.width * 0.05, y: size.height * 0.9)
|
|
||||||
peerUnitsLabel.position = CGPoint(x: size.width * 0.95, y: size.height * 0.9)
|
|
||||||
setColor(labelNodes: [hostLabel,hostUnitsLabel,peerLabel,peerUnitsLabel])
|
|
||||||
}
|
|
||||||
|
|
||||||
func update(){
|
|
||||||
hostUnitsLabel.text = "\(EntityManager.sharedInstance.getUnitSum(by: host!))"
|
|
||||||
peerUnitsLabel.text = "\(EntityManager.sharedInstance.getUnitSum(by: peer!))"
|
|
||||||
}
|
|
||||||
|
|
||||||
func setColor(labelNodes: [SKLabelNode]) -> Void {
|
|
||||||
for label in labelNodes {
|
|
||||||
label.fontColor = SKColor.black
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
required init?(coder: NSCoder) {
|
|
||||||
fatalError("init(coder:) has not been implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
18
GoldWars/GoldWars/Components/SingeClickButtonNode.swift
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// SkillButtonNode.swift
|
||||||
|
// GoldWars
|
||||||
|
//
|
||||||
|
// Created by Simon Kellner on 18.05.20.
|
||||||
|
// Copyright © 2020 SP2. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SpriteKit
|
||||||
|
|
||||||
|
class SingeClickButtonNode: ButtonNode {
|
||||||
|
|
||||||
|
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||||
|
super.touchesBegan(touches, with: event)
|
||||||
|
self.isEnabled = false
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
25
GoldWars/GoldWars/Components/SkillComponent.swift
Normal 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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,23 +2,24 @@
|
|||||||
// SliderComponent.swift
|
// SliderComponent.swift
|
||||||
// GoldWars
|
// GoldWars
|
||||||
//
|
//
|
||||||
// Created by Niko Jochim on 05.05.20.
|
// Created by Marcel Schwarz on 24.05.20.
|
||||||
// Copyright © 2020 SP2. All rights reserved.
|
// Copyright © 2020 SP2. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
import GameplayKit
|
import GameplayKit
|
||||||
|
|
||||||
|
|
||||||
class SliderComponent: GKComponent {
|
class SliderComponent: GKComponent {
|
||||||
|
|
||||||
var sliderNode: SliderNode
|
var sliderNode: SliderNode
|
||||||
|
|
||||||
init(width: CGFloat, position: CGPoint) {
|
init(width: CGFloat, position: CGPoint) {
|
||||||
sliderNode = SliderNode(width: width, position: position)
|
sliderNode = SliderNode(width: width, position: position)
|
||||||
sliderNode.zPosition = 4
|
sliderNode.zPosition = 5
|
||||||
super.init()
|
super.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
required init?(coder: NSCoder) {
|
required init?(coder: NSCoder) {
|
||||||
fatalError("init(coder:) has not been implemented")
|
fatalError("init(coder:) has not been implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
//
|
|
||||||
// SpySkillComponent.swift
|
|
||||||
// GoldWars
|
|
||||||
//
|
|
||||||
// Created by Niko Jochim on 01.05.20.
|
|
||||||
// Copyright © 2020 SP2. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import GameplayKit
|
|
||||||
|
|
||||||
class SpySkillComponent: GKComponent{
|
|
||||||
|
|
||||||
let shapeNode: SKShapeNode
|
|
||||||
let labelNode: SKLabelNode
|
|
||||||
|
|
||||||
init(text: String, texture: SKTexture?, anchorPoint: CGPoint) {
|
|
||||||
self.labelNode = SKLabelNode(text: text)
|
|
||||||
self.shapeNode = SKShapeNode(circleOfRadius: 30)
|
|
||||||
self.shapeNode.position = anchorPoint
|
|
||||||
self.labelNode.position = CGPoint(x: anchorPoint.x, y: anchorPoint.y - 15)
|
|
||||||
if texture != nil {
|
|
||||||
shapeNode.fillTexture = texture
|
|
||||||
}else {
|
|
||||||
shapeNode.fillColor = SKColor.gray
|
|
||||||
}
|
|
||||||
super.init()
|
|
||||||
}
|
|
||||||
|
|
||||||
required init?(coder: NSCoder) {
|
|
||||||
fatalError("init(coder:) has not been implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,74 +0,0 @@
|
|||||||
//
|
|
||||||
// TimerComponent.swift
|
|
||||||
// GoldWars
|
|
||||||
//
|
|
||||||
// Created by Daniel Steckert on 05.05.20.
|
|
||||||
// Copyright © 2020 SP2. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import GameplayKit
|
|
||||||
|
|
||||||
class TimerComponent: GKComponent {
|
|
||||||
|
|
||||||
let labelNode :SKLabelNode
|
|
||||||
var endTime :Date!
|
|
||||||
var duration :Double
|
|
||||||
var isRunning = false
|
|
||||||
|
|
||||||
init(text: String, anchorPoint: CGPoint, duration: TimeInterval) {
|
|
||||||
self.labelNode = SKLabelNode(text: text)
|
|
||||||
self.labelNode.fontColor = UIColor.black
|
|
||||||
self.labelNode.fontSize = CGFloat(45)
|
|
||||||
self.labelNode.position = CGPoint(x: anchorPoint.x, y: anchorPoint.y - 15)
|
|
||||||
self.duration = duration + 1
|
|
||||||
super.init()
|
|
||||||
startWithDuration(duration: self.duration)
|
|
||||||
}
|
|
||||||
|
|
||||||
func startWithDuration(duration: TimeInterval){
|
|
||||||
isRunning = true
|
|
||||||
endTime = Date().addingTimeInterval(duration)
|
|
||||||
RoundCalculatorService.sharedInstance.isCalculating = false
|
|
||||||
}
|
|
||||||
|
|
||||||
func timeLeft() -> Int {
|
|
||||||
if isRunning {
|
|
||||||
let remainingSeconds = Int(endTime.timeIntervalSince(Date()))
|
|
||||||
if(remainingSeconds == 0) {
|
|
||||||
isRunning = false
|
|
||||||
}
|
|
||||||
return remainingSeconds
|
|
||||||
}
|
|
||||||
|
|
||||||
// if(remainingSeconds < 0){
|
|
||||||
// startWithDuration(duration: duration)
|
|
||||||
// }
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func isFinished() -> Bool {
|
|
||||||
return timeLeft() == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func update() {
|
|
||||||
self.labelNode.text = String(timeLeft())
|
|
||||||
|
|
||||||
if(isFinished()){
|
|
||||||
self.labelNode.text = "Synching"
|
|
||||||
if !MultiplayerNetwork.sharedInstance.isSending {
|
|
||||||
MultiplayerNetwork.sharedInstance.sendPlayerMoves(playerMoves: DataService.sharedInstance.localPlayerMoves)
|
|
||||||
}
|
|
||||||
if !RoundCalculatorService.sharedInstance.isCalculating
|
|
||||||
&& DataService.sharedInstance.didReceiveAllData()
|
|
||||||
&& MatchmakingHelper.sharedInstance.isServer {
|
|
||||||
RoundCalculatorService.sharedInstance.calculateRound()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
required init?(coder: NSCoder) {
|
|
||||||
fatalError("init(coder:) has not been implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -6,14 +6,22 @@
|
|||||||
// Copyright © 2020 SP2. All rights reserved.
|
// Copyright © 2020 SP2. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
struct PlayerMove: Codable{
|
struct PlayerMove: Codable {
|
||||||
let fromBase: Int
|
let fromBase: Int
|
||||||
let toBase: Int
|
let toBase: Int
|
||||||
var unitCount: Int
|
var unitCount: Int
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Host: Codable {
|
struct LocalRoundData: Codable {
|
||||||
let playerName: String
|
var localPlayerMoves: [PlayerMove]
|
||||||
|
var hasAttackBoost: Bool
|
||||||
|
var hasDefenceBoost: Bool
|
||||||
|
|
||||||
|
init() {
|
||||||
|
localPlayerMoves = []
|
||||||
|
hasAttackBoost = false
|
||||||
|
hasDefenceBoost = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SnapshotModel: Codable {
|
class SnapshotModel: Codable {
|
||||||
@ -29,7 +37,7 @@ class BaseEntityModel: Codable {
|
|||||||
var unitCount: Int
|
var unitCount: Int
|
||||||
var ownership: String?
|
var ownership: String?
|
||||||
|
|
||||||
init(baseId: Int, unitCount: Int, ownership: String?) {
|
init(baseId: Int, unitCount: Int, ownership: String?, hasAttackBoost: Bool, hasDefenceBoost: Bool) {
|
||||||
self.baseId = baseId
|
self.baseId = baseId
|
||||||
self.unitCount = unitCount
|
self.unitCount = unitCount
|
||||||
self.ownership = ownership
|
self.ownership = ownership
|
||||||
@ -38,41 +46,39 @@ class BaseEntityModel: Codable {
|
|||||||
|
|
||||||
class DataService {
|
class DataService {
|
||||||
static let sharedInstance = DataService()
|
static let sharedInstance = DataService()
|
||||||
var localPlayerMoves: [PlayerMove] = []
|
var localRoundData: LocalRoundData = LocalRoundData()
|
||||||
var remotePlayerMoves: [String: [PlayerMove]] = [:]
|
var remotePlayerMoves: [String: LocalRoundData] = [:]
|
||||||
var snapshotModel: SnapshotModel?
|
var snapshotModel: SnapshotModel?
|
||||||
var gameHost: Host?
|
var hostingPlayer = GameCenterManager.sharedInstance.hostingPlayer
|
||||||
var mapModel: MapGenerationModel?
|
|
||||||
|
|
||||||
|
var mapModel: MapGenerationModel?
|
||||||
|
var entityManager = EntityManager.gameEMInstance
|
||||||
|
|
||||||
func addMove(playerMove: PlayerMove) {
|
func addMove(playerMove: PlayerMove) {
|
||||||
var equalMove = localPlayerMoves.filter { (ele) -> Bool in
|
var equalMove = localRoundData.localPlayerMoves.filter { (ele) -> Bool in
|
||||||
ele.fromBase == playerMove.fromBase && ele.toBase == playerMove.toBase
|
ele.fromBase == playerMove.fromBase && ele.toBase == playerMove.toBase
|
||||||
}
|
}
|
||||||
if equalMove.count == 1 {
|
if equalMove.count == 1 {
|
||||||
equalMove[0].unitCount = Int(equalMove[0].unitCount) + Int(playerMove.unitCount)
|
equalMove[0].unitCount = Int(equalMove[0].unitCount) + Int(playerMove.unitCount)
|
||||||
} else {
|
} else {
|
||||||
self.localPlayerMoves.append(playerMove)
|
self.localRoundData.localPlayerMoves.append(playerMove)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func addRemotePlayerMoves(playerName: String, playerMoves: [PlayerMove]) {
|
func addRemotePlayerMoves(playerName: String, localRoundData: LocalRoundData) {
|
||||||
self.remotePlayerMoves[playerName] = playerMoves
|
self.remotePlayerMoves[playerName] = localRoundData
|
||||||
}
|
}
|
||||||
|
|
||||||
func didReceiveAllData() -> Bool {
|
func didReceiveAllData() -> Bool {
|
||||||
return remotePlayerMoves.count == MatchmakingHelper.sharedInstance.mpMatch?.players.count
|
return remotePlayerMoves.count == GameCenterManager.sharedInstance.myMatch?.players.count
|
||||||
}
|
}
|
||||||
|
|
||||||
func setGameHost(host: Host) {
|
|
||||||
self.gameHost = host
|
|
||||||
}
|
|
||||||
|
|
||||||
func setSnapshotModel(snapshotModel: SnapshotModel) {
|
func setSnapshotModel(snapshotModel: SnapshotModel) {
|
||||||
self.snapshotModel = snapshotModel
|
self.snapshotModel = snapshotModel
|
||||||
}
|
}
|
||||||
|
|
||||||
func setMapModel(model: MapGenerationModel) {
|
func setMapModel(model: MapGenerationModel) {
|
||||||
self.mapModel = model
|
self.mapModel = model
|
||||||
MapFactory(scene: EntityManager.sharedInstance.scene, entityManager: EntityManager.sharedInstance).loadMap(fromModel: DataService.sharedInstance.mapModel!)
|
MapFactory(scene: entityManager.scene, entityManager: entityManager).load(fromModel: DataService.sharedInstance.mapModel!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,8 @@ import GameKit
|
|||||||
class Base: GKEntity{
|
class Base: GKEntity{
|
||||||
static var BASE_ID_COUNT: Int = 0
|
static var BASE_ID_COUNT: Int = 0
|
||||||
var unitCount: Int
|
var unitCount: Int
|
||||||
var unitType: UnitType
|
var hasAttackBoost = false
|
||||||
|
var hasDefenseBoost = false
|
||||||
var adjacencyList: Array<Base>
|
var adjacencyList: Array<Base>
|
||||||
var changeOwnership: Bool
|
var changeOwnership: Bool
|
||||||
var ownershipPlayer: GKPlayer?
|
var ownershipPlayer: GKPlayer?
|
||||||
@ -22,7 +23,6 @@ class Base: GKEntity{
|
|||||||
|
|
||||||
init(position: CGPoint, player: GKPlayer! = nil, team: Team! = nil) {
|
init(position: CGPoint, player: GKPlayer! = nil, team: Team! = nil) {
|
||||||
self.unitCount = 0
|
self.unitCount = 0
|
||||||
self.unitType = .General
|
|
||||||
self.adjacencyList = [Base]()
|
self.adjacencyList = [Base]()
|
||||||
self.changeOwnership = false
|
self.changeOwnership = false
|
||||||
self.ownershipPlayer = player
|
self.ownershipPlayer = player
|
||||||
@ -32,28 +32,29 @@ class Base: GKEntity{
|
|||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
let spritePos = position
|
let spritePos = position
|
||||||
addComponent(DefaultBaseComponent(texture: SKTexture(imageNamed: "Base"), position: spritePos))
|
addComponent(DefaultBaseComponent(texture: SKTexture(imageNamed: "BaseTexture"), position: spritePos))
|
||||||
if(team != nil && player != nil){
|
if(team != nil && player != nil){
|
||||||
addComponent(TeamComponent(team: team!, player: player!, position: spritePos))
|
addComponent(TeamComponent(team: team!, player: player!, position: spritePos))
|
||||||
self.unitCount = 500
|
self.unitCount = 500
|
||||||
}
|
}
|
||||||
if ownershipPlayer == GKLocalPlayer.local {
|
if ownershipPlayer == GKLocalPlayer.local {
|
||||||
self.component(ofType: DefaultBaseComponent.self)?.labelNode?.text = "\(unitCount)"
|
self.component(ofType: DefaultBaseComponent.self)?.labelNode.text = "\(unitCount)"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func doPlayerMoveTypeToBase(base: Base, playerMoveType: PlayerMoveType, units: Int) -> [GKEntity]{
|
func doPlayerMoveTypeToBase(base: Base, playerMoveType: PlayerMoveType, units: Int) -> [GKEntity]{
|
||||||
base.changeOwnership = true
|
if base.ownershipPlayer != GKLocalPlayer.local {
|
||||||
|
base.changeOwnership = true
|
||||||
|
}
|
||||||
base.ownershipPlayer = self.ownershipPlayer
|
base.ownershipPlayer = self.ownershipPlayer
|
||||||
self.unitCount -= units
|
self.unitCount -= units
|
||||||
base.unitCount += units
|
base.unitCount += units
|
||||||
self.component(ofType: DefaultBaseComponent.self)?.labelNode?.text = "\(self.unitCount)"
|
self.component(ofType: DefaultBaseComponent.self)?.labelNode.text = "\(self.unitCount)"
|
||||||
base.component(ofType: DefaultBaseComponent.self)?.labelNode?.text = "\(base.unitCount)"
|
base.component(ofType: DefaultBaseComponent.self)?.labelNode.text = "\(base.unitCount)"
|
||||||
DataService.sharedInstance.addMove(playerMove: PlayerMove(fromBase: self.baseID,
|
DataService.sharedInstance.addMove(playerMove: PlayerMove(fromBase: self.baseID,
|
||||||
toBase: base.baseID,
|
toBase: base.baseID,
|
||||||
unitCount: units * playerMoveType.rawValue))
|
unitCount: units * playerMoveType.rawValue)
|
||||||
|
)
|
||||||
return [self, base]
|
return [self, base]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,10 +13,10 @@ class Button: GKEntity{
|
|||||||
let name: String
|
let name: String
|
||||||
var isEnabled = true
|
var isEnabled = true
|
||||||
|
|
||||||
init(name: String, iconName: String, text: String, position: CGPoint, onButtonPress: @escaping () -> ()) {
|
init(name: String, textureName: String, text: String, position: CGPoint, onButtonPress: @escaping () -> ()) {
|
||||||
self.name = name
|
self.name = name
|
||||||
super.init()
|
super.init()
|
||||||
self.addComponent(ButtonComponent(iconName: iconName, text: text, position: position, isEnabled: isEnabled, onButtonPress: onButtonPress))
|
self.addComponent(ButtonComponent(textureName: textureName, text: text, position: position, isEnabled: isEnabled, onButtonPress: onButtonPress))
|
||||||
}
|
}
|
||||||
|
|
||||||
required init?(coder: NSCoder) {
|
required init?(coder: NSCoder) {
|
||||||
|
@ -12,7 +12,9 @@ import GameKit
|
|||||||
|
|
||||||
class EntityManager {
|
class EntityManager {
|
||||||
|
|
||||||
static let sharedInstance = EntityManager()
|
static let gameEMInstance = EntityManager()
|
||||||
|
static let menuEMInstance = EntityManager()
|
||||||
|
static let settingsEMInstance = EntityManager()
|
||||||
|
|
||||||
var entities = Set<GKEntity>()
|
var entities = Set<GKEntity>()
|
||||||
var scene: SKScene
|
var scene: SKScene
|
||||||
@ -30,37 +32,40 @@ class EntityManager {
|
|||||||
|
|
||||||
func add(_ entity: GKEntity) {
|
func add(_ entity: GKEntity) {
|
||||||
entities.insert(entity)
|
entities.insert(entity)
|
||||||
if let spriteNode = entity.component(ofType: DefaultBaseComponent.self)?.spriteNode {
|
|
||||||
scene.addChild(spriteNode)
|
if let modalEntitiy = entity as? Modal {
|
||||||
|
scene.addChild(modalEntitiy.background)
|
||||||
|
scene.addChild(modalEntitiy.closeButton)
|
||||||
|
scene.addChild(modalEntitiy.header)
|
||||||
|
scene.addChild(modalEntitiy.body)
|
||||||
|
scene.addChild(modalEntitiy.footer)
|
||||||
|
scene.addChild(modalEntitiy.overlay)
|
||||||
|
isModal = true
|
||||||
}
|
}
|
||||||
if let label = entity.component(ofType: DefaultBaseComponent.self)?.labelNode {
|
|
||||||
scene.addChild(label)
|
if let hudEntitiy = entity as? HUD {
|
||||||
|
scene.addChild(hudEntitiy.hostLabel)
|
||||||
|
scene.addChild(hudEntitiy.hostUnitsLabel)
|
||||||
|
scene.addChild(hudEntitiy.peerLabel)
|
||||||
|
scene.addChild(hudEntitiy.peerUnitsLabel)
|
||||||
|
scene.addChild(hudEntitiy.defSkill)
|
||||||
|
scene.addChild(hudEntitiy.atkSkill)
|
||||||
|
scene.addChild(hudEntitiy.spySkill)
|
||||||
|
scene.addChild(hudEntitiy.roundTimerLabel)
|
||||||
|
scene.addChild(hudEntitiy.finishButton)
|
||||||
|
scene.addChild(hudEntitiy.backgroundRoundCounter)
|
||||||
|
scene.addChild(hudEntitiy.currentRoundLabel)
|
||||||
|
scene.addChild(hudEntitiy.roundsLabel)
|
||||||
|
scene.addChild(hudEntitiy.roundLabel)
|
||||||
|
}
|
||||||
|
|
||||||
|
if let spriteNode = entity.component(ofType: DefaultBaseComponent.self) {
|
||||||
|
scene.addChild(spriteNode.labelNode)
|
||||||
|
scene.addChild(spriteNode.spriteNode)
|
||||||
}
|
}
|
||||||
if let fire = entity.component(ofType: TeamComponent.self)?.fire{
|
if let fire = entity.component(ofType: TeamComponent.self)?.fire{
|
||||||
scene.addChild(fire)
|
scene.addChild(fire)
|
||||||
}
|
}
|
||||||
if let spriteNode = entity.component(ofType: ModalBackgroundComponent.self)?.spriteNode {
|
|
||||||
scene.addChild(spriteNode)
|
|
||||||
}
|
|
||||||
if let modal = entity.component(ofType: ModalContentComponent.self) {
|
|
||||||
scene.addChild(modal.header)
|
|
||||||
scene.addChild(modal.body)
|
|
||||||
scene.addChild(modal.footer)
|
|
||||||
isModal = true
|
|
||||||
}
|
|
||||||
if let skillButtonNode = entity.component(ofType: AtkBoostSkillComponent.self)?.skillButtonNode {
|
|
||||||
scene.addChild(skillButtonNode)
|
|
||||||
}
|
|
||||||
if let skillButtonNode = entity.component(ofType: DefBoostSkillComponent.self)?.skillButtonNode {
|
|
||||||
scene.addChild(skillButtonNode)
|
|
||||||
}
|
|
||||||
if let skill = entity.component(ofType: SpySkillComponent.self) {
|
|
||||||
scene.addChild(skill.shapeNode)
|
|
||||||
scene.addChild(skill.labelNode)
|
|
||||||
}
|
|
||||||
if let timer = entity.component(ofType: TimerComponent.self) {
|
|
||||||
scene.addChild(timer.labelNode)
|
|
||||||
}
|
|
||||||
if let buttonNode = entity.component(ofType: ButtonComponent.self)?.buttonNode {
|
if let buttonNode = entity.component(ofType: ButtonComponent.self)?.buttonNode {
|
||||||
scene.addChild(buttonNode)
|
scene.addChild(buttonNode)
|
||||||
}
|
}
|
||||||
@ -76,36 +81,18 @@ class EntityManager {
|
|||||||
if let labelNode = entity.component(ofType: LabelComponent.self)?.labelNode {
|
if let labelNode = entity.component(ofType: LabelComponent.self)?.labelNode {
|
||||||
scene.addChild(labelNode)
|
scene.addChild(labelNode)
|
||||||
}
|
}
|
||||||
if let cancelBtnNode = entity.component(ofType: CancelBtnComponent.self)?.cancelBtnNode {
|
|
||||||
scene.addChild(cancelBtnNode)
|
|
||||||
}
|
|
||||||
if let node = entity.component(ofType: SpinningLogoComponent.self)?.node {
|
if let node = entity.component(ofType: SpinningLogoComponent.self)?.node {
|
||||||
scene.addChild(node)
|
scene.addChild(node)
|
||||||
}
|
}
|
||||||
if let wayNode = entity.component(ofType: DefaultWayComponent.self)?.shapeNode {
|
if let wayNode = entity.component(ofType: DefaultWayComponent.self)?.shapeNode {
|
||||||
scene.addChild(wayNode)
|
scene.addChild(wayNode)
|
||||||
}
|
}
|
||||||
if let playerInfos = entity.component(ofType: PlayerInfoComponent.self) {
|
|
||||||
scene.addChild(playerInfos.hostLabel)
|
|
||||||
scene.addChild(playerInfos.hostUnitsLabel)
|
|
||||||
scene.addChild(playerInfos.peerLabel)
|
|
||||||
scene.addChild(playerInfos.peerUnitsLabel)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func remove(_ entity: GKEntity) {
|
func remove(_ entity: GKEntity) {
|
||||||
if let spriteNode = entity.component(ofType: DefaultBaseComponent.self)?.spriteNode {
|
if let spriteNode = entity.component(ofType: DefaultBaseComponent.self)?.spriteNode {
|
||||||
spriteNode.removeFromParent()
|
spriteNode.removeFromParent()
|
||||||
}
|
}
|
||||||
if let spriteNode = entity.component(ofType: ModalBackgroundComponent.self)?.spriteNode {
|
|
||||||
spriteNode.removeFromParent()
|
|
||||||
}
|
|
||||||
if let modal = entity.component(ofType: ModalContentComponent.self) {
|
|
||||||
modal.header.removeFromParent()
|
|
||||||
modal.body.removeFromParent()
|
|
||||||
modal.footer.removeFromParent()
|
|
||||||
isModal = false
|
|
||||||
}
|
|
||||||
if let sliderNode = entity.component(ofType: SliderComponent.self)?.sliderNode {
|
if let sliderNode = entity.component(ofType: SliderComponent.self)?.sliderNode {
|
||||||
sliderNode.sliderKnob.removeFromParent()
|
sliderNode.sliderKnob.removeFromParent()
|
||||||
sliderNode.sliderLine.removeFromParent()
|
sliderNode.sliderLine.removeFromParent()
|
||||||
@ -113,9 +100,6 @@ class EntityManager {
|
|||||||
if let modalButton = entity.component(ofType: ButtonComponent.self) {
|
if let modalButton = entity.component(ofType: ButtonComponent.self) {
|
||||||
modalButton.buttonNode.removeFromParent()
|
modalButton.buttonNode.removeFromParent()
|
||||||
}
|
}
|
||||||
if let cancelBtnNode = entity.component(ofType: CancelBtnComponent.self)?.cancelBtnNode {
|
|
||||||
cancelBtnNode.removeFromParent()
|
|
||||||
}
|
|
||||||
entities.remove(entity)
|
entities.remove(entity)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,7 +122,7 @@ class EntityManager {
|
|||||||
scene.addChild(fire)
|
scene.addChild(fire)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
base.changeOwnership = false
|
GameCenterManager.sharedInstance.addAchievementProgress(identifier: "de.hft.stuttgart.ip2.goldwars.capture.fifty.bases", increasePercentComplete: 2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -150,19 +134,36 @@ class EntityManager {
|
|||||||
let snapBase = self.getSnapshotBaseById(baseId: base.baseID, snapshotModel: snapshotModel)
|
let snapBase = self.getSnapshotBaseById(baseId: base.baseID, snapshotModel: snapshotModel)
|
||||||
var getOwnerBySnapBase: GKPlayer? = nil
|
var getOwnerBySnapBase: GKPlayer? = nil
|
||||||
base.unitCount = snapBase.unitCount
|
base.unitCount = snapBase.unitCount
|
||||||
|
base.changeOwnership = false
|
||||||
|
|
||||||
if snapBase.ownership != nil {
|
if snapBase.ownership != nil {
|
||||||
getOwnerBySnapBase = MatchmakingHelper.sharedInstance.getGKPlayerByUsername(displayName: snapBase.ownership!)
|
getOwnerBySnapBase = GameCenterManager.sharedInstance.getGKPlayerByUsername(displayName: snapBase.ownership!)
|
||||||
} else {
|
} else {
|
||||||
entity.removeComponent(ofType: TeamComponent.self)
|
entity.removeComponent(ofType: TeamComponent.self)
|
||||||
|
base.ownershipPlayer = nil
|
||||||
}
|
}
|
||||||
if getOwnerBySnapBase != nil {
|
if getOwnerBySnapBase != nil {
|
||||||
if getOwnerBySnapBase == GKLocalPlayer.local {
|
if base.ownershipPlayer != getOwnerBySnapBase {
|
||||||
base.component(ofType: DefaultBaseComponent.self)?.labelNode?.text = "\(base.unitCount)"
|
//TODO: Outsource following with a AnimationManager
|
||||||
}else {
|
let explosion = SKEmitterNode(fileNamed: "Explosion")!
|
||||||
base.component(ofType: DefaultBaseComponent.self)?.labelNode?.text = ""
|
scene.addChild(explosion)
|
||||||
|
explosion.zPosition = 2
|
||||||
|
explosion.position = base.position
|
||||||
|
explosion.name = "explosion"
|
||||||
|
explosion.particleColorSequence = nil
|
||||||
|
explosion.particleColorBlendFactor = 1.0
|
||||||
|
let wait = SKAction.wait(forDuration: 1)
|
||||||
|
let removeParticle = SKAction.removeFromParent()
|
||||||
|
let sequence = SKAction.sequence([wait, removeParticle])
|
||||||
|
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.changeOwnership = true
|
|
||||||
base.ownershipPlayer = getOwnerBySnapBase
|
base.ownershipPlayer = getOwnerBySnapBase
|
||||||
if (entity.component(ofType: TeamComponent.self) != nil) {
|
if (entity.component(ofType: TeamComponent.self) != nil) {
|
||||||
entity.component(ofType: TeamComponent.self)!.change(to: getTeamByPlayer(playerName: snapBase.ownership!), to: getOwnerBySnapBase!)
|
entity.component(ofType: TeamComponent.self)!.change(to: getTeamByPlayer(playerName: snapBase.ownership!), to: getOwnerBySnapBase!)
|
||||||
@ -180,7 +181,7 @@ class EntityManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getHUD()?.component(ofType: PlayerInfoComponent.self)?.update()
|
getHUD()!.updateUnitSum()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,6 +217,14 @@ class EntityManager {
|
|||||||
return entities.filter{$0 is Base && ($0 as! Base).component(ofType: TeamComponent.self)?.team == team } as! Set<Base>
|
return entities.filter{$0 is Base && ($0 as! Base).component(ofType: TeamComponent.self)?.team == team } as! Set<Base>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getOpponentBases(for team: Team) -> Set<Base> {
|
||||||
|
if(team == .team1){
|
||||||
|
return getBasesByTeam(for: .team2)
|
||||||
|
}else {
|
||||||
|
return getBasesByTeam(for: .team1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func getBasesByPlayer(for player: GKPlayer) -> Set<Base> {
|
func getBasesByPlayer(for player: GKPlayer) -> Set<Base> {
|
||||||
return entities.filter{$0 is Base && ($0 as! Base).component(ofType: TeamComponent.self)?.player == player } as! Set<Base>
|
return entities.filter{$0 is Base && ($0 as! Base).component(ofType: TeamComponent.self)?.player == player } as! Set<Base>
|
||||||
}
|
}
|
||||||
@ -237,6 +246,10 @@ class EntityManager {
|
|||||||
return entities.filter { $0 is Base && ($0 as! Base).component(ofType: TeamComponent.self)?.player.displayName == playerName }[0].component(ofType: TeamComponent.self)!.team
|
return entities.filter { $0 is Base && ($0 as! Base).component(ofType: TeamComponent.self)?.player.displayName == playerName }[0].component(ofType: TeamComponent.self)!.team
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getTeam() -> Team {
|
||||||
|
return entities.filter { $0 is Base && ($0 as! Base).component(ofType: TeamComponent.self)?.player.displayName == GKLocalPlayer.local.displayName }[0].component(ofType: TeamComponent.self)!.team
|
||||||
|
}
|
||||||
|
|
||||||
func getBasebyID(id: Int) -> Base?{
|
func getBasebyID(id: Int) -> Base?{
|
||||||
for entity in entities {
|
for entity in entities {
|
||||||
if entity is Base && (entity as! Base).baseID == id {
|
if entity is Base && (entity as! Base).baseID == id {
|
||||||
@ -258,8 +271,8 @@ class EntityManager {
|
|||||||
return entities.filter{$0 is Button && ($0 as! Button).name == buttonName }[0] as! Button
|
return entities.filter{$0 is Button && ($0 as! Button).name == buttonName }[0] as! Button
|
||||||
}
|
}
|
||||||
|
|
||||||
func getHUD() -> GKEntity? {
|
func getHUD() -> HUD? {
|
||||||
return entities.filter{$0 is HUD}[0]
|
return entities.filter{$0 is HUD}[0] as? HUD
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSnapshotModel() -> SnapshotModel {
|
func getSnapshotModel() -> SnapshotModel {
|
||||||
@ -268,15 +281,20 @@ class EntityManager {
|
|||||||
|
|
||||||
for entity in bases {
|
for entity in bases {
|
||||||
let base = entity as! Base
|
let base = entity as! Base
|
||||||
snapBase.append(BaseEntityModel(baseId: base.baseID, unitCount: base.unitCount, ownership: base.ownershipPlayer?.displayName))
|
snapBase.append(
|
||||||
|
BaseEntityModel(
|
||||||
|
baseId: base.baseID,
|
||||||
|
unitCount: base.unitCount,
|
||||||
|
ownership: base.ownershipPlayer?.displayName,
|
||||||
|
hasAttackBoost: base.hasAttackBoost,
|
||||||
|
hasDefenceBoost: base.hasDefenseBoost
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return SnapshotModel(baseEntites: snapBase)
|
return SnapshotModel(baseEntites: snapBase)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTimer() -> TimerComponent {
|
|
||||||
return entities.filter{$0 is HUD}[0].component(ofType: TimerComponent.self)!
|
|
||||||
}
|
|
||||||
func getUnitSum(by player: GKPlayer) -> Int{
|
func getUnitSum(by player: GKPlayer) -> Int{
|
||||||
let bases = getBasesByPlayer(for: player)
|
let bases = getBasesByPlayer(for: player)
|
||||||
|
|
||||||
@ -286,4 +304,44 @@ class EntityManager {
|
|||||||
}
|
}
|
||||||
return sum
|
return sum
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func removeModal() {
|
||||||
|
entities.forEach({entity in
|
||||||
|
if let modal = entity as? Modal {
|
||||||
|
modal.background.removeFromParent()
|
||||||
|
modal.closeButton.removeFromParent()
|
||||||
|
modal.header.removeFromParent()
|
||||||
|
modal.body.removeFromParent()
|
||||||
|
modal.footer.removeFromParent()
|
||||||
|
modal.overlay.removeFromParent()
|
||||||
|
|
||||||
|
if let slider = modal.component(ofType: SliderComponent.self) {
|
||||||
|
slider.sliderNode.removeFromParent()
|
||||||
|
slider.sliderNode.sliderKnob.removeFromParent()
|
||||||
|
slider.sliderNode.sliderLine.removeFromParent()
|
||||||
|
}
|
||||||
|
|
||||||
|
if let button = modal.component(ofType: ButtonComponent.self) {
|
||||||
|
button.buttonNode.removeFromParent()
|
||||||
|
}
|
||||||
|
self.remove(modal)
|
||||||
|
|
||||||
|
for child in scene.children {
|
||||||
|
if(child.name != "fire"){
|
||||||
|
child.alpha = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isModal = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTimer() -> RoundTimer? {
|
||||||
|
return getHUD()?.roundTimer
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateTime(time: String) {
|
||||||
|
getHUD()?.roundTimerLabel.text = time
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,30 +7,177 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import GameplayKit
|
import GameplayKit
|
||||||
|
import GameKit
|
||||||
|
|
||||||
class HUD: GKEntity {
|
class HUD: GKEntity {
|
||||||
|
|
||||||
|
var entityManager = EntityManager.gameEMInstance
|
||||||
|
var hostLabel:SKLabelNode
|
||||||
|
var hostUnitsLabel:SKLabelNode
|
||||||
|
|
||||||
|
var peerLabel:SKLabelNode
|
||||||
|
var peerUnitsLabel:SKLabelNode
|
||||||
|
var host: GKPlayer?
|
||||||
|
var peer: GKPlayer?
|
||||||
|
|
||||||
|
var spySkill: SingeClickButtonNode
|
||||||
|
var defSkill: SingeClickButtonNode
|
||||||
|
var atkSkill: SingeClickButtonNode
|
||||||
|
|
||||||
|
var roundTimerLabel: SKLabelNode
|
||||||
|
let roundTimer: RoundTimer
|
||||||
|
|
||||||
|
var backgroundRoundCounter: SKSpriteNode
|
||||||
|
var currentRoundLabel: SKLabelNode
|
||||||
|
var roundsLabel: SKLabelNode
|
||||||
|
var roundLabel: SKLabelNode
|
||||||
|
|
||||||
|
var finishButton: ButtonNode
|
||||||
|
|
||||||
init(size: CGSize) {
|
init(size: CGSize) {
|
||||||
|
host = GameCenterManager.sharedInstance.hostingPlayer
|
||||||
|
peer = GameCenterManager.sharedInstance.peerPlayer
|
||||||
|
hostLabel = SKLabelNode(text: host?.displayName)
|
||||||
|
hostUnitsLabel = SKLabelNode(text: "500" )
|
||||||
|
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.horizontalAlignmentMode = .center
|
||||||
|
|
||||||
|
self.roundTimer = RoundTimer()
|
||||||
|
|
||||||
|
spySkill = SingeClickButtonNode(
|
||||||
|
textureName: "yellow_circle",
|
||||||
|
text: "Spy",
|
||||||
|
isEnabled: true,
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
defSkill = SingeClickButtonNode(
|
||||||
|
textureName: "yellow_circle",
|
||||||
|
text: "Def",
|
||||||
|
isEnabled: true,
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
atkSkill = SingeClickButtonNode(
|
||||||
|
textureName: "yellow_circle",
|
||||||
|
text: "Atk",
|
||||||
|
isEnabled: true,
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
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: "roundInfo_texture"))
|
||||||
|
currentRoundLabel = SKLabelNode(fontNamed: "Courier-Bold")
|
||||||
|
roundsLabel = SKLabelNode(fontNamed: "Courier-Bold")
|
||||||
|
roundLabel = SKLabelNode(fontNamed: "Courier-Bold")
|
||||||
super.init()
|
super.init()
|
||||||
addComponent(SpySkillComponent(text: "Spy",
|
initRoundInfo(size: size)
|
||||||
texture: nil,
|
|
||||||
anchorPoint: CGPoint(x: size.width * 0.75, y: size.height * 0.1)))
|
|
||||||
|
|
||||||
|
finishButton.onButtonPress = { [unowned self] in
|
||||||
|
self.finishRound()
|
||||||
|
}
|
||||||
|
|
||||||
addComponent(AtkBoostSkillComponent(iconName: "", text: "Atk", position: CGPoint(x: size.width * 0.85, y: size.height * 0.1), isEnabled: true))
|
hostLabel.position = CGPoint(x: size.width * 0.02, y: size.height * 0.95)
|
||||||
|
hostLabel.horizontalAlignmentMode = .left
|
||||||
|
peerLabel.position = CGPoint(x: size.width * 0.98, y: size.height * 0.95)
|
||||||
addComponent(DefBoostSkillComponent(iconName: "", text: "Def", position: CGPoint(x: size.width * 0.95, y: size.height * 0.1), isEnabled: true))
|
peerLabel.horizontalAlignmentMode = .right
|
||||||
|
hostUnitsLabel.position = CGPoint(x: size.width * 0.05, y: size.height * 0.9)
|
||||||
addComponent(TimerComponent(text: "",
|
peerUnitsLabel.position = CGPoint(x: size.width * 0.95, y: size.height * 0.9)
|
||||||
anchorPoint: CGPoint(x: size.width * 0.5, y: size.height * 0.9), duration: 30))
|
setColor(labelNodes: [hostLabel,hostUnitsLabel,peerLabel,peerUnitsLabel])
|
||||||
|
|
||||||
addComponent(PlayerInfoComponent(size: size))
|
|
||||||
|
|
||||||
|
roundTimer.initTimer()
|
||||||
|
startWithDuration()
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateUnitSum(){
|
||||||
|
hostUnitsLabel.text = "\(entityManager.getUnitSum(by: host!))"
|
||||||
|
peerUnitsLabel.text = "\(entityManager.getUnitSum(by: peer!))"
|
||||||
|
}
|
||||||
|
|
||||||
|
func setColor(labelNodes: [SKLabelNode]) -> Void {
|
||||||
|
for label in labelNodes {
|
||||||
|
label.fontColor = SKColor.black
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
required init?(coder: NSCoder) {
|
required init?(coder: NSCoder) {
|
||||||
fatalError("init(coder:) has not been implemented")
|
fatalError("init(coder:) has not been implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func startWithDuration(){
|
||||||
|
roundTimer.startTimer()
|
||||||
|
finishButton.isEnabled = true
|
||||||
|
self.roundTimer.roundEnded = "Syncing"
|
||||||
|
RoundCalculatorService.sharedInstance.isCalculating = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func finishRound() -> () {
|
||||||
|
self.roundTimer.timeLeft = 1;
|
||||||
|
self.roundTimer.roundEnded = "Waiting for other player..."
|
||||||
|
}
|
||||||
|
|
||||||
|
func initRoundInfo(size: CGSize) -> () {
|
||||||
|
backgroundRoundCounter.zPosition = 2
|
||||||
|
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 - 5)
|
||||||
|
currentRoundLabel.zPosition = backgroundRoundCounter.zPosition + 1
|
||||||
|
|
||||||
|
roundsLabel.zPosition = backgroundRoundCounter.zPosition + 1
|
||||||
|
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 = "Round"
|
||||||
|
roundLabel.fontColor = SKColor.black
|
||||||
|
roundLabel.verticalAlignmentMode = .center
|
||||||
|
roundLabel.fontSize = 12
|
||||||
|
roundLabel.position = CGPoint(x: currentRoundLabel.position.x, y: currentRoundLabel.position.y + 25)
|
||||||
|
}
|
||||||
|
|
||||||
|
func setCurrentRound(round: Int) -> Void {
|
||||||
|
currentRoundLabel.text = "\(round)"
|
||||||
|
let newRoundAction = SKAction.sequence([
|
||||||
|
SKAction.scale(by: 2, duration: 1),
|
||||||
|
SKAction.scale(by: 0.5, duration: 1),
|
||||||
|
])
|
||||||
|
currentRoundLabel.run(newRoundAction)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
21
GoldWars/GoldWars/Entities/Label.swift
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
//
|
||||||
|
// Label.swift
|
||||||
|
// GoldWars
|
||||||
|
//
|
||||||
|
// Created by Tim Herbst on 13.05.20.
|
||||||
|
// Copyright © 2020 SP2. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import GameplayKit
|
||||||
|
|
||||||
|
class Label: GKEntity {
|
||||||
|
|
||||||
|
init(fontnamed: String, name: String, text: String, fontSize: CGFloat, fontColor: UIColor, position: CGPoint, horizontalAlignmentMode: SKLabelHorizontalAlignmentMode, vertikalAligmentMode: SKLabelVerticalAlignmentMode, isAnimationEnabled: Bool, isAnimationInfinite: Bool) {
|
||||||
|
super.init()
|
||||||
|
self.addComponent(LabelComponent(fontnamed: fontnamed, name: name, text: text, fontSize: fontSize, fontColor: fontColor, position: position, horizontalAlignmentMode: horizontalAlignmentMode, vertikalAligmentMode: vertikalAligmentMode, isAnimationEnabled: isAnimationEnabled, isAnimationInfinite: isAnimationInfinite))
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
}
|
@ -8,31 +8,88 @@
|
|||||||
|
|
||||||
import GameplayKit
|
import GameplayKit
|
||||||
|
|
||||||
|
enum ModalType: String{
|
||||||
|
case BaseDetails
|
||||||
|
case BaseAttack
|
||||||
|
case BaseMoveOwnUnits
|
||||||
|
}
|
||||||
|
|
||||||
class Modal: GKEntity{
|
class Modal: GKEntity{
|
||||||
|
|
||||||
var unitCount:Int
|
var entityManager = EntityManager.gameEMInstance
|
||||||
|
var unitCount: Int
|
||||||
|
var background: SKSpriteNode
|
||||||
|
var closeButton: ButtonNode
|
||||||
|
var header: SKLabelNode
|
||||||
|
var body: SKLabelNode
|
||||||
|
var footer: SKLabelNode
|
||||||
|
var overlay: SKSpriteNode
|
||||||
|
|
||||||
init(modaltype: ModalType, base: Base, anchorPoint: CGPoint, gameScene: GameScene, currentDraggedBase: Base?, touchLocation: CGPoint, collisionBase: Base?) {
|
init(modaltype: ModalType, base: Base, anchorPoint: CGPoint, gameScene: GameScene, currentDraggedBase: Base?, touchLocation: CGPoint, collisionBase: Base?) {
|
||||||
unitCount = base.unitCount
|
unitCount = base.unitCount
|
||||||
|
|
||||||
|
let texture = SKTexture(imageNamed:"ModalBackground")
|
||||||
|
background = SKSpriteNode(texture: texture, size: texture.size())
|
||||||
|
background.setScale(2.4)
|
||||||
|
background.position = anchorPoint
|
||||||
|
background.zPosition = 4
|
||||||
|
|
||||||
|
closeButton = ButtonNode(textureName: "red_cross", text: "", isEnabled: true, position: CGPoint(x: anchorPoint.x + 195, y: anchorPoint.y + 178), onButtonPress: {
|
||||||
|
EntityManager.gameEMInstance.removeModal()
|
||||||
|
})
|
||||||
|
closeButton.size = CGSize(width: 26, height: 26)
|
||||||
|
closeButton.zPosition = 5
|
||||||
|
|
||||||
|
overlay = SKSpriteNode(color: UIColor.init(red: 0, green: 0, blue: 0, alpha: 0.7), size: gameScene.size)
|
||||||
|
overlay.anchorPoint = gameScene.anchorPoint
|
||||||
|
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: "Schicke \(unitCount / 2)\nEinheiten")
|
||||||
|
footer = SKLabelNode()
|
||||||
|
case .BaseMoveOwnUnits:
|
||||||
|
header = SKLabelNode(text: "Formation")
|
||||||
|
body = SKLabelNode(text: "Sende \(unitCount / 2)\nEinheiten")
|
||||||
|
footer = SKLabelNode()
|
||||||
|
}
|
||||||
|
|
||||||
|
self.header.position = CGPoint(x: anchorPoint.x, y: anchorPoint.y + 90)
|
||||||
|
self.header.fontName = "HelveticaNeue-Bold"
|
||||||
|
self.header.fontSize = 40
|
||||||
|
self.header.zPosition = 5
|
||||||
|
|
||||||
|
self.body.position = CGPoint(x: anchorPoint.x, y: anchorPoint.y - 20)
|
||||||
|
self.body.numberOfLines = 2
|
||||||
|
self.body.preferredMaxLayoutWidth = 390
|
||||||
|
self.body.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.center
|
||||||
|
self.body.fontName = "HelveticaNeue-Bold"
|
||||||
|
self.body.fontSize = 40
|
||||||
|
self.body.zPosition = 5
|
||||||
|
|
||||||
|
self.footer.position = CGPoint(x: anchorPoint.x, y: anchorPoint.y - 40)
|
||||||
|
self.footer.fontName = "HelveticaNeue-Bold"
|
||||||
|
self.footer.fontSize = 40
|
||||||
|
self.footer.zPosition = 5
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
switch modaltype{
|
switch modaltype{
|
||||||
case .BaseDetails:
|
case .BaseDetails:
|
||||||
addComponent(ModalBackgroundComponent(anchorPoint: anchorPoint))
|
addComponent(ButtonComponent(textureName: "yellow_button04", text: "Zurück", position: CGPoint(x: anchorPoint.x , y: anchorPoint.y - 105), isEnabled: true, onButtonPress: {
|
||||||
addComponent(ModalContentComponent(header: "Basis Information", body: "Diese Basis enthält \(base.unitCount) Einheiten", footer: "", anchorPoint: anchorPoint))
|
EntityManager.gameEMInstance.removeModal()
|
||||||
addComponent(ButtonComponent(iconName: "", text: "Zurück", position: CGPoint(x: anchorPoint.x , y: anchorPoint.y - 120), isEnabled: true, onButtonPress: {
|
|
||||||
self.removeModalEntities(gameScene: gameScene)
|
|
||||||
}))
|
}))
|
||||||
case .BaseAttack:
|
case .BaseAttack, .BaseMoveOwnUnits:
|
||||||
addComponent(ModalBackgroundComponent(anchorPoint: anchorPoint))
|
let text = (modaltype == .BaseAttack) ? "Angriff" : "Senden"
|
||||||
addComponent(SliderComponent(width: 300, position: CGPoint(x: anchorPoint.x , y: anchorPoint.y - 50)))
|
addComponent(SliderComponent(width: 300, position: CGPoint(x: anchorPoint.x , y: anchorPoint.y - 50)))
|
||||||
addComponent(ModalContentComponent(header: "Angriff", body: "Schicke \(unitCount / 2) Einheiten",
|
addComponent(ButtonComponent(textureName: "yellow_button04", text: text, position: CGPoint(x: anchorPoint.x , y: anchorPoint.y - 105), isEnabled: true, onButtonPress: {
|
||||||
footer: "", anchorPoint: anchorPoint))
|
|
||||||
addComponent(ButtonComponent(iconName: "", text: "Senden", position: CGPoint(x: anchorPoint.x , y: anchorPoint.y - 120), isEnabled: true, onButtonPress: {
|
|
||||||
self.sendUnits(currentDraggedBase: currentDraggedBase, touchLocation: touchLocation, gameScene: gameScene, collisionBase: collisionBase)
|
self.sendUnits(currentDraggedBase: currentDraggedBase, touchLocation: touchLocation, gameScene: gameScene, collisionBase: collisionBase)
|
||||||
self.removeModalEntities(gameScene: gameScene)
|
EntityManager.gameEMInstance.removeModal()
|
||||||
}))
|
|
||||||
addComponent(CancelBtnComponent(iconName: "", text: "", position: CGPoint(x: anchorPoint.x + 160, y: anchorPoint.y + 140), isEnabled: true, onButtonPress: {
|
|
||||||
self.removeModalEntities(gameScene: gameScene)
|
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -42,14 +99,9 @@ class Modal: GKEntity{
|
|||||||
}
|
}
|
||||||
|
|
||||||
func removeModalEntities(gameScene: SKScene){
|
func removeModalEntities(gameScene: SKScene){
|
||||||
for entity in EntityManager.sharedInstance.entities {
|
for entity in entityManager.entities {
|
||||||
if EntityManager.sharedInstance.isModal && entity.isMember(of: Modal.self) {
|
if entityManager.isModal && entity.isMember(of: Modal.self) {
|
||||||
EntityManager.sharedInstance.remove(entity)
|
entityManager.remove(entity)
|
||||||
}
|
|
||||||
for child in gameScene.children {
|
|
||||||
if(child.name != "fire"){
|
|
||||||
child.alpha = 1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -57,7 +109,8 @@ class Modal: GKEntity{
|
|||||||
func sendUnits(currentDraggedBase: Base?, touchLocation: CGPoint, gameScene: GameScene, collisionBase: Base?){
|
func sendUnits(currentDraggedBase: Base?, touchLocation: CGPoint, gameScene: GameScene, collisionBase: Base?){
|
||||||
for base in currentDraggedBase!.adjacencyList {
|
for base in currentDraggedBase!.adjacencyList {
|
||||||
if base == collisionBase {
|
if base == collisionBase {
|
||||||
EntityManager.sharedInstance.update((currentDraggedBase?.doPlayerMoveTypeToBase(base: base, playerMoveType: PlayerMoveType.AtkMove, units: Int(GameScene.sendUnits)))!)
|
RoundCalculatorService.sharedInstance.increaseMoveCounter(ownBase: currentDraggedBase?.ownershipPlayer == base.ownershipPlayer)
|
||||||
|
entityManager.update((currentDraggedBase?.doPlayerMoveTypeToBase(base: base, playerMoveType: PlayerMoveType.AtkMove, units: Int(GameScene.sendUnits)))!)
|
||||||
GameScene.sendUnits = 0
|
GameScene.sendUnits = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
//
|
|
||||||
// ModalType.swift
|
|
||||||
// GoldWars
|
|
||||||
//
|
|
||||||
// Created by Niko Jochim on 01.05.20.
|
|
||||||
// Copyright © 2020 SP2. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
enum ModalType: String{
|
|
||||||
case BaseDetails
|
|
||||||
case BaseAttack
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
//
|
|
||||||
// GameCenterHelper.swift
|
|
||||||
// GoldWars
|
|
||||||
//
|
|
||||||
// Created by Jakob Haag on 02.05.20.
|
|
||||||
// Copyright © 2020 SP2. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import GameKit
|
|
||||||
|
|
||||||
final class GameCenterHelper: NSObject {
|
|
||||||
typealias CompletionBlock = (Error?) -> Void
|
|
||||||
|
|
||||||
static let helper = GameCenterHelper()
|
|
||||||
|
|
||||||
var viewController: UIViewController?
|
|
||||||
|
|
||||||
static var isAuthenticated: Bool {
|
|
||||||
return GKLocalPlayer.local.isAuthenticated
|
|
||||||
}
|
|
||||||
|
|
||||||
override init() {
|
|
||||||
super.init()
|
|
||||||
|
|
||||||
GKLocalPlayer.local.authenticateHandler = { gcAuthVC, error in
|
|
||||||
NotificationCenter.default
|
|
||||||
.post(name: .authenticationChanged, object: GKLocalPlayer.local.isAuthenticated)
|
|
||||||
|
|
||||||
if GKLocalPlayer.local.isAuthenticated {
|
|
||||||
print("Authenticated to Game Center!")
|
|
||||||
} else if let vc = gcAuthVC {
|
|
||||||
self.viewController?.present(vc, animated: true)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
print("Error authentication to GameCenter: " +
|
|
||||||
"\(error?.localizedDescription ?? "none")")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Notification.Name {
|
|
||||||
static let presentGame = Notification.Name(rawValue: "presentGame")
|
|
||||||
static let authenticationChanged = Notification.Name(rawValue: "authenticationChanged")
|
|
||||||
}
|
|
265
GoldWars/GoldWars/GameCenterManager.swift
Normal file
@ -0,0 +1,265 @@
|
|||||||
|
//
|
||||||
|
// GameCenter.swift
|
||||||
|
// GoldWars
|
||||||
|
//
|
||||||
|
// Created by Niko Jochim on 23.05.20.
|
||||||
|
// Copyright © 2020 SP2. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import GameKit
|
||||||
|
import os
|
||||||
|
|
||||||
|
struct RandomNumber: Codable {
|
||||||
|
let number: Int
|
||||||
|
init() {
|
||||||
|
number = Int.random(in: 0...999999)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct State: Codable {
|
||||||
|
// 0 PlayerInit fertig
|
||||||
|
// 1 RemotePlayerInit fertig
|
||||||
|
// 2 Peer hat Map erhalten
|
||||||
|
// 3 Host hat Spiel gestartet
|
||||||
|
// 4 Peer hat verloren
|
||||||
|
// 5 Peer hat gewonnen
|
||||||
|
let state: Int
|
||||||
|
}
|
||||||
|
|
||||||
|
final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate, GKGameCenterControllerDelegate ,GKMatchDelegate,GKLocalPlayerListener{
|
||||||
|
|
||||||
|
static let sharedInstance = GameCenterManager()
|
||||||
|
|
||||||
|
let LOG = OSLog.init(subsystem: "GameCenterManager", category: "GameCenterManager")
|
||||||
|
|
||||||
|
var viewController: UIViewController?
|
||||||
|
let localPlayer: GKLocalPlayer = GKLocalPlayer.local
|
||||||
|
var myMatch: GKMatch?
|
||||||
|
var isMatchStarted = false
|
||||||
|
var isServer = false
|
||||||
|
var hostingPlayer: GKPlayer?
|
||||||
|
var peerPlayer: GKPlayer?
|
||||||
|
var menusc: MenuScene?
|
||||||
|
var entityManager = EntityManager.gameEMInstance
|
||||||
|
var localPlayerRandomNumber: RandomNumber?
|
||||||
|
var initIsFinish = false
|
||||||
|
var gameScene: GameScene?
|
||||||
|
static var isAuthenticated: Bool {
|
||||||
|
return GKLocalPlayer.local.isAuthenticated
|
||||||
|
}
|
||||||
|
|
||||||
|
override init() {
|
||||||
|
super.init()
|
||||||
|
localPlayer.register(self)
|
||||||
|
authUser();
|
||||||
|
localPlayerRandomNumber = RandomNumber()
|
||||||
|
}
|
||||||
|
|
||||||
|
func authUser() -> Void {
|
||||||
|
GKLocalPlayer.local.authenticateHandler = { gcAuthVC, error in
|
||||||
|
NotificationCenter.default
|
||||||
|
.post(name: .authenticationChanged, object: GKLocalPlayer.local.isAuthenticated)
|
||||||
|
if let vc = gcAuthVC {
|
||||||
|
self.viewController?.present(vc, animated: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func presentMatchmaker() {
|
||||||
|
let request = GKMatchRequest()
|
||||||
|
request.minPlayers = 2
|
||||||
|
request.maxPlayers = 2
|
||||||
|
request.defaultNumberOfPlayers = 2
|
||||||
|
request.inviteMessage = "Willst du GoldWars spielen?"
|
||||||
|
let matchmakerVC = GKMatchmakerViewController.init(matchRequest: request)
|
||||||
|
matchmakerVC!.matchmakerDelegate = self
|
||||||
|
viewController?.present(matchmakerVC!, animated: true, completion: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func presentGameCenter() {
|
||||||
|
let gameCenterController: GKGameCenterViewController = GKGameCenterViewController.init()
|
||||||
|
gameCenterController.gameCenterDelegate = self
|
||||||
|
gameCenterController.viewState = .achievements
|
||||||
|
viewController?.present(gameCenterController, animated: true, completion: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func addAchievementProgress(identifier: String, increasePercentComplete: Double) {
|
||||||
|
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
|
||||||
|
achievement.showsCompletionBanner = true
|
||||||
|
GKAchievement.report([achievement]) { (error) in
|
||||||
|
print(error?.localizedDescription ?? "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if !achievementExists {
|
||||||
|
let newAchievement: GKAchievement = GKAchievement.init(identifier: identifier)
|
||||||
|
newAchievement.showsCompletionBanner = true
|
||||||
|
newAchievement.percentComplete = increasePercentComplete
|
||||||
|
GKAchievement.report([newAchievement]) { (error) in
|
||||||
|
print(error?.localizedDescription ?? "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func match(_ match: GKMatch, didReceive data: Data, fromRemotePlayer player: GKPlayer) {
|
||||||
|
if myMatch != match { return }
|
||||||
|
let jsonDecoder = JSONDecoder()
|
||||||
|
if let randomNumberFromPeer = try? jsonDecoder.decode(RandomNumber.self, from: data) {
|
||||||
|
os_log("Random Number des anderen Spielers erhalten", log: LOG, type: .info)
|
||||||
|
if randomNumberFromPeer.number <= localPlayerRandomNumber!.number {
|
||||||
|
isServer = true
|
||||||
|
self.hostingPlayer = GKLocalPlayer.local
|
||||||
|
self.peerPlayer = player
|
||||||
|
os_log("Dieser Spieler wurde zum HostingPlayer gewählt", log: LOG, type: .info)
|
||||||
|
} else {
|
||||||
|
isServer = false
|
||||||
|
self.hostingPlayer = player
|
||||||
|
self.peerPlayer = GKLocalPlayer.local
|
||||||
|
os_log("Dieser Spieler wurde zum PeerPlayer gewählt", log: LOG, type: .info)
|
||||||
|
}
|
||||||
|
os_log("Setzen von Peer und Host abgeschlossen", log: LOG, type: .info)
|
||||||
|
sendStateToPeers(state: State(state: 0))
|
||||||
|
os_log("State 0 wurde an anderen Spieler gesendet", log: LOG, type: .info)
|
||||||
|
}
|
||||||
|
if let state = try? jsonDecoder.decode(State.self, from: data) {
|
||||||
|
switch state.state {
|
||||||
|
case 0:
|
||||||
|
os_log("State 0 erhalten", log: LOG, type: .info)
|
||||||
|
sendStateToPeers(state: State(state: 1))
|
||||||
|
case 1:
|
||||||
|
os_log("State 1 erhalten", log: LOG, type: .info)
|
||||||
|
|
||||||
|
if isServer {
|
||||||
|
os_log("Peer hat Player initialisiert", log: LOG, type: .info)
|
||||||
|
initAndSendMap()
|
||||||
|
}else {
|
||||||
|
os_log("Host hat Player initialisiert", log: LOG, type: .info)
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
os_log("State 2 erhalten", log: LOG, type: .info)
|
||||||
|
sendStateToPeers(state: State(state: 3))
|
||||||
|
initIsFinish = true
|
||||||
|
os_log("Spiel startet", log: LOG, type: .info)
|
||||||
|
case 3:
|
||||||
|
os_log("State 3 erhalten", log: LOG, type: .info)
|
||||||
|
initIsFinish = true
|
||||||
|
os_log("Spiel startet", log: LOG, type: .info)
|
||||||
|
case 4:
|
||||||
|
os_log("State 4 erhalten, Peer hat verloren", log: LOG, type: .info)
|
||||||
|
// TODO: Trigger Loser Scene
|
||||||
|
case 5:
|
||||||
|
os_log("State 5 erhalten, Peer hat gewonnen", log: LOG, type: .info)
|
||||||
|
// TODO: Trigger Winner Scene
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let roundData = try? jsonDecoder.decode(LocalRoundData.self, from: data) {
|
||||||
|
DataService.sharedInstance.addRemotePlayerMoves(playerName: player.displayName, localRoundData: roundData)
|
||||||
|
}
|
||||||
|
if let snapshotModel = try? jsonDecoder.decode(SnapshotModel.self, from: data) {
|
||||||
|
DataService.sharedInstance.snapshotModel = snapshotModel
|
||||||
|
RoundCalculatorService.sharedInstance.currentRound += 1
|
||||||
|
entityManager.getHUD()?.setCurrentRound(round: RoundCalculatorService.sharedInstance.currentRound)
|
||||||
|
entityManager.updateSnapshotModel(snapshotModel: snapshotModel)
|
||||||
|
entityManager.getHUD()?.startWithDuration()
|
||||||
|
}
|
||||||
|
if let mapModel = try? jsonDecoder.decode(MapGenerationModel.self, from: data) {
|
||||||
|
os_log("Peer hat Map erhalten", log: LOG, type: .info)
|
||||||
|
let scene = GameScene(size: self.menusc!.size)
|
||||||
|
EntityManager.gameEMInstance.setScene(scene: scene)
|
||||||
|
DataService.sharedInstance.setMapModel(model: mapModel)
|
||||||
|
os_log("Map model wurde gesetzt", log: LOG, type: .info)
|
||||||
|
GameCenterManager.sharedInstance.isMatchStarted = true
|
||||||
|
self.gameScene = 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)
|
||||||
|
}
|
||||||
|
MultiplayerNetwork.sharedInstance.isSending = false
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
MultiplayerNetwork.sharedInstance.sendMapModelToPlayers(mapModel: mapModel)
|
||||||
|
os_log("Map wurde an Peer gesendet", log: LOG, type: .info)
|
||||||
|
DataService.sharedInstance.setSnapshotModel(snapshotModel: entityManager.getSnapshotModel())
|
||||||
|
os_log("SnapshotModel wurde erstellt", log: LOG, type: .info)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getGKPlayerByUsername(displayName: String) -> GKPlayer? {
|
||||||
|
let nilGK : GKPlayer? = nil
|
||||||
|
|
||||||
|
if GKLocalPlayer.local.displayName == displayName {
|
||||||
|
return GKLocalPlayer.local
|
||||||
|
}
|
||||||
|
|
||||||
|
for player in myMatch!.players {
|
||||||
|
if player.displayName == displayName {
|
||||||
|
return player
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nilGK
|
||||||
|
}
|
||||||
|
func sendStateToPeers(state: State){
|
||||||
|
let encoder = JSONEncoder()
|
||||||
|
let encoded = (try? encoder.encode(state))!
|
||||||
|
MultiplayerNetwork.sharedInstance.sendData(data: encoded)
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendRandomNumberToAllPeers(in match: GKMatch){
|
||||||
|
let encoder = JSONEncoder()
|
||||||
|
let encoded = (try? encoder.encode(localPlayerRandomNumber))!
|
||||||
|
MultiplayerNetwork.sharedInstance.sendData(data: encoded)
|
||||||
|
}
|
||||||
|
|
||||||
|
func player(_ player: GKPlayer, didAccept invite: GKInvite) {
|
||||||
|
os_log("Einladung angenommen", log: LOG, type: .info)
|
||||||
|
let matchmakerVC = GKMatchmakerViewController.init(invite: invite)
|
||||||
|
matchmakerVC!.matchmakerDelegate = self
|
||||||
|
viewController?.present(matchmakerVC!, animated: true, completion: nil)
|
||||||
|
}
|
||||||
|
func matchmakerViewControllerWasCancelled(_ viewController: GKMatchmakerViewController) {
|
||||||
|
viewController.dismiss(animated: true, completion: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func matchmakerViewController(_ viewController: GKMatchmakerViewController, didFailWithError error: Error) {
|
||||||
|
viewController.dismiss(animated: true, completion: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func matchmakerViewController(_ viewController: GKMatchmakerViewController, didFind match: GKMatch) {
|
||||||
|
viewController.dismiss(animated: true, completion: nil)
|
||||||
|
myMatch = match
|
||||||
|
if !isMatchStarted && match.expectedPlayerCount == 0 {
|
||||||
|
myMatch?.delegate = self
|
||||||
|
sendRandomNumberToAllPeers(in: self.myMatch!)
|
||||||
|
os_log("Random Number wurde an den anderen Spieler gesendet", log: LOG, type: .info)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func gameCenterViewControllerDidFinish(_ gameCenterViewController: GKGameCenterViewController) {
|
||||||
|
gameCenterViewController.dismiss(animated: true, completion: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func disconnect() {
|
||||||
|
if myMatch != nil {
|
||||||
|
myMatch?.disconnect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Notification.Name {
|
||||||
|
static let presentGame = Notification.Name(rawValue: "presentGame")
|
||||||
|
static let authenticationChanged = Notification.Name(rawValue: "authenticationChanged")
|
||||||
|
}
|
@ -14,24 +14,24 @@ class GameViewController: UIViewController {
|
|||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
|
||||||
if let view = self.view as! SKView? {
|
if let view = self.view as! SKView? {
|
||||||
let scene = MenuScene(size: self.view.bounds.size)
|
let scene = MenuScene(size: self.view.bounds.size)
|
||||||
|
EntityManager.menuEMInstance.setScene(scene: scene)
|
||||||
scene.scaleMode = .aspectFill
|
scene.scaleMode = .aspectFill
|
||||||
view.presentScene(scene)
|
view.presentScene(scene)
|
||||||
//TODO: create dev profile or remove on delivery
|
//TODO: create dev profile or remove on delivery
|
||||||
view.showsFPS = true
|
view.showsFPS = true
|
||||||
view.showsNodeCount = true
|
view.showsNodeCount = true
|
||||||
|
}
|
||||||
GameCenterHelper.helper.viewController = self
|
GameCenterManager.sharedInstance.viewController = self
|
||||||
MatchmakingHelper.sharedInstance.viewController = self
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override var shouldAutorotate: Bool {
|
override var shouldAutorotate: Bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
|
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
|
||||||
if UIDevice.current.userInterfaceIdiom == .phone {
|
if UIDevice.current.userInterfaceIdiom == .phone {
|
||||||
return .allButUpsideDown
|
return .allButUpsideDown
|
||||||
@ -39,7 +39,7 @@ class GameViewController: UIViewController {
|
|||||||
return .all
|
return .all
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override var prefersStatusBarHidden: Bool {
|
override var prefersStatusBarHidden: Bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -529,16 +529,12 @@ class CElement7: CenterElementProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func connectInnerBases() {
|
func connectInnerBases() {
|
||||||
self.leftBase.adjacencyList.append(self.rightBase)
|
|
||||||
self.leftBase.adjacencyList.append(self.topBase)
|
self.leftBase.adjacencyList.append(self.topBase)
|
||||||
self.leftBase.adjacencyList.append(self.bottomBase)
|
self.leftBase.adjacencyList.append(self.bottomBase)
|
||||||
self.rightBase.adjacencyList.append(self.leftBase)
|
|
||||||
self.rightBase.adjacencyList.append(self.topBase)
|
self.rightBase.adjacencyList.append(self.topBase)
|
||||||
self.rightBase.adjacencyList.append(self.bottomBase)
|
self.rightBase.adjacencyList.append(self.bottomBase)
|
||||||
self.topBase.adjacencyList.append(self.leftBase)
|
self.topBase.adjacencyList.append(self.leftBase)
|
||||||
self.topBase.adjacencyList.append(self.rightBase)
|
self.topBase.adjacencyList.append(self.rightBase)
|
||||||
self.topBase.adjacencyList.append(self.bottomBase)
|
|
||||||
self.bottomBase.adjacencyList.append(self.topBase)
|
|
||||||
self.bottomBase.adjacencyList.append(self.rightBase)
|
self.bottomBase.adjacencyList.append(self.rightBase)
|
||||||
self.bottomBase.adjacencyList.append(self.leftBase)
|
self.bottomBase.adjacencyList.append(self.leftBase)
|
||||||
}
|
}
|
||||||
@ -1116,16 +1112,12 @@ class CElement15: CenterElementProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func connectInnerBases() {
|
func connectInnerBases() {
|
||||||
self.leftBase.adjacencyList.append(self.rightBase)
|
|
||||||
self.leftBase.adjacencyList.append(self.topBase)
|
self.leftBase.adjacencyList.append(self.topBase)
|
||||||
self.leftBase.adjacencyList.append(self.bottomBase)
|
self.leftBase.adjacencyList.append(self.bottomBase)
|
||||||
self.rightBase.adjacencyList.append(self.leftBase)
|
|
||||||
self.rightBase.adjacencyList.append(self.topBase)
|
self.rightBase.adjacencyList.append(self.topBase)
|
||||||
self.rightBase.adjacencyList.append(self.bottomBase)
|
self.rightBase.adjacencyList.append(self.bottomBase)
|
||||||
self.topBase.adjacencyList.append(self.leftBase)
|
self.topBase.adjacencyList.append(self.leftBase)
|
||||||
self.topBase.adjacencyList.append(self.rightBase)
|
self.topBase.adjacencyList.append(self.rightBase)
|
||||||
self.topBase.adjacencyList.append(self.bottomBase)
|
|
||||||
self.bottomBase.adjacencyList.append(self.topBase)
|
|
||||||
self.bottomBase.adjacencyList.append(self.rightBase)
|
self.bottomBase.adjacencyList.append(self.rightBase)
|
||||||
self.bottomBase.adjacencyList.append(self.leftBase)
|
self.bottomBase.adjacencyList.append(self.leftBase)
|
||||||
}
|
}
|
||||||
@ -1209,16 +1201,12 @@ class CElement16: CenterElementProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func connectInnerBases() {
|
func connectInnerBases() {
|
||||||
self.leftBase.adjacencyList.append(self.rightBase)
|
|
||||||
self.leftBase.adjacencyList.append(self.topBase)
|
self.leftBase.adjacencyList.append(self.topBase)
|
||||||
self.leftBase.adjacencyList.append(self.bottomBase)
|
self.leftBase.adjacencyList.append(self.bottomBase)
|
||||||
self.rightBase.adjacencyList.append(self.leftBase)
|
|
||||||
self.rightBase.adjacencyList.append(self.topBase)
|
self.rightBase.adjacencyList.append(self.topBase)
|
||||||
self.rightBase.adjacencyList.append(self.bottomBase)
|
self.rightBase.adjacencyList.append(self.bottomBase)
|
||||||
self.topBase.adjacencyList.append(self.leftBase)
|
self.topBase.adjacencyList.append(self.leftBase)
|
||||||
self.topBase.adjacencyList.append(self.rightBase)
|
self.topBase.adjacencyList.append(self.rightBase)
|
||||||
self.topBase.adjacencyList.append(self.bottomBase)
|
|
||||||
self.bottomBase.adjacencyList.append(self.topBase)
|
|
||||||
self.bottomBase.adjacencyList.append(self.rightBase)
|
self.bottomBase.adjacencyList.append(self.rightBase)
|
||||||
self.bottomBase.adjacencyList.append(self.leftBase)
|
self.bottomBase.adjacencyList.append(self.leftBase)
|
||||||
}
|
}
|
||||||
@ -1302,16 +1290,12 @@ class CElement17: CenterElementProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func connectInnerBases() {
|
func connectInnerBases() {
|
||||||
self.leftBase.adjacencyList.append(self.rightBase)
|
|
||||||
self.leftBase.adjacencyList.append(self.topBase)
|
self.leftBase.adjacencyList.append(self.topBase)
|
||||||
self.leftBase.adjacencyList.append(self.bottomBase)
|
self.leftBase.adjacencyList.append(self.bottomBase)
|
||||||
self.rightBase.adjacencyList.append(self.leftBase)
|
|
||||||
self.rightBase.adjacencyList.append(self.topBase)
|
self.rightBase.adjacencyList.append(self.topBase)
|
||||||
self.rightBase.adjacencyList.append(self.bottomBase)
|
self.rightBase.adjacencyList.append(self.bottomBase)
|
||||||
self.topBase.adjacencyList.append(self.leftBase)
|
self.topBase.adjacencyList.append(self.leftBase)
|
||||||
self.topBase.adjacencyList.append(self.rightBase)
|
self.topBase.adjacencyList.append(self.rightBase)
|
||||||
self.topBase.adjacencyList.append(self.bottomBase)
|
|
||||||
self.bottomBase.adjacencyList.append(self.topBase)
|
|
||||||
self.bottomBase.adjacencyList.append(self.rightBase)
|
self.bottomBase.adjacencyList.append(self.rightBase)
|
||||||
self.bottomBase.adjacencyList.append(self.leftBase)
|
self.bottomBase.adjacencyList.append(self.leftBase)
|
||||||
}
|
}
|
||||||
|
@ -1,88 +1,247 @@
|
|||||||
//
|
//
|
||||||
// MapFactory.swift
|
// TwoPlayerMapGenerator.swift
|
||||||
// GoldWars
|
// GoldWars
|
||||||
//
|
//
|
||||||
// Created by Marcel Schwarz on 02.05.20.
|
// Created by Marcel Schwarz on 13.05.20.
|
||||||
// Copyright © 2020 SP2. All rights reserved.
|
// Copyright © 2020 SP2. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import SpriteKit
|
import SpriteKit
|
||||||
|
import GameKit
|
||||||
import os
|
import os
|
||||||
|
|
||||||
protocol MapProtocol {
|
|
||||||
var size: CGSize! {get set}
|
|
||||||
var entityManager: EntityManager! {get set}
|
|
||||||
|
|
||||||
init(scene: SKScene, entityManager: EntityManager)
|
|
||||||
|
|
||||||
func load(withModel mapModel: MapGenerationModel)
|
|
||||||
}
|
|
||||||
|
|
||||||
protocol CenterElementProtocol {
|
|
||||||
|
|
||||||
var bases: [Base] {get set}
|
|
||||||
var ways: [Way] {get set}
|
|
||||||
var id: Int { get }
|
|
||||||
|
|
||||||
init(frame: CGRect)
|
|
||||||
|
|
||||||
func getAllBases() -> [Base]
|
|
||||||
func getInternalWays() -> [Way]
|
|
||||||
func getTopConnection() -> Base?
|
|
||||||
func getRightConnection() -> Base?
|
|
||||||
func getBottomConnection() -> Base?
|
|
||||||
func getLeftConnection() -> Base?
|
|
||||||
}
|
|
||||||
|
|
||||||
class MapFactory {
|
class MapFactory {
|
||||||
|
|
||||||
let LOG = OSLog.init(subsystem: "MapGenerator", category: "MapFactory")
|
let LOG = OSLog.init(subsystem: "MapGenerator", category: "MapFactory")
|
||||||
|
|
||||||
var twoPlayerMapGenerator: TwoPlayerMapGenerator
|
var size: CGSize!
|
||||||
|
var entityManager: EntityManager!
|
||||||
|
|
||||||
init(scene: SKScene, entityManager: EntityManager) {
|
required init(scene: SKScene, entityManager: EntityManager) {
|
||||||
self.twoPlayerMapGenerator = TwoPlayerMapGenerator(scene: scene, entityManager: entityManager)
|
self.size = scene.size
|
||||||
|
self.entityManager = entityManager
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadMap() -> MapGenerationModel{
|
func load() -> MapGenerationModel {
|
||||||
let mapModel = TwoPlayerMapGenerator.getNewMapModel()
|
let mapModel = MapGenerationModel.new()
|
||||||
loadMap(fromModel: mapModel)
|
load(fromModel: mapModel)
|
||||||
return mapModel
|
return mapModel
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadMap(fromModel model: MapGenerationModel) {
|
func load(fromModel mapModel: MapGenerationModel) {
|
||||||
os_log("Loading two player map", log: LOG, type: .info)
|
os_log("Loading from TwoPlayerMapFactory", log: LOG, type: .info)
|
||||||
twoPlayerMapGenerator.load(withModel: model)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class CenterElementProvider {
|
|
||||||
static let LOG = OSLog.init(subsystem: "MapGenerator", category: "CenterElementProvider")
|
|
||||||
|
|
||||||
static let centerElements: [CenterElementProtocol.Type] = [
|
|
||||||
CElement0.self,
|
|
||||||
CElement1.self,
|
|
||||||
CElement2.self,
|
|
||||||
CElement3.self,
|
|
||||||
CElement4.self,
|
|
||||||
CElement5.self,
|
|
||||||
CElement6.self,
|
|
||||||
CElement7.self,
|
|
||||||
CElement8.self,
|
|
||||||
CElement9.self,
|
|
||||||
CElement10.self,
|
|
||||||
CElement11.self,
|
|
||||||
CElement12.self,
|
|
||||||
CElement13.self,
|
|
||||||
CElement14.self,
|
|
||||||
CElement15.self,
|
|
||||||
CElement16.self,
|
|
||||||
CElement17.self
|
|
||||||
]
|
|
||||||
|
|
||||||
static func get(inFrame frame: CGRect, withId id: Int) -> CenterElementProtocol {
|
|
||||||
os_log("Getting new predifined center element from provider", log: LOG, type: .info)
|
|
||||||
|
|
||||||
return centerElements[id].init(frame: frame)
|
// Generate bases structure
|
||||||
|
os_log("Get player one base", log: LOG, type: .info)
|
||||||
|
let basePlayerOne = Base(
|
||||||
|
position: CGPoint(x: self.size.width * 0.07, y: self.size.height / 2),
|
||||||
|
player: (GameCenterManager.sharedInstance.isServer) ? GKLocalPlayer.local : GameCenterManager.sharedInstance.myMatch?.players[0],
|
||||||
|
team: .team1
|
||||||
|
)
|
||||||
|
|
||||||
|
os_log("Get player one's startbases", log: LOG, type: .info)
|
||||||
|
var p1StartBases = [String: Base]()
|
||||||
|
var ways = [Way]()
|
||||||
|
|
||||||
|
if (mapModel.numBasesP1 == 1) {
|
||||||
|
p1StartBases["mid"] = Base(position: CGPoint(x: self.size.width * 0.2, y: self.size.height * 0.5))
|
||||||
|
ways.append(Way(fromBase: basePlayerOne, toBase: p1StartBases["mid"]!))
|
||||||
|
} else if (mapModel.numBasesP1 == 2) {
|
||||||
|
p1StartBases["top"] = Base(position: CGPoint(x: self.size.width * 0.2, y: self.size.height * 0.333))
|
||||||
|
p1StartBases["bot"] = Base(position: CGPoint(x: self.size.width * 0.2, y: self.size.height * 0.666))
|
||||||
|
ways.append(Way(fromBase: basePlayerOne, toBase: p1StartBases["top"]!))
|
||||||
|
ways.append(Way(fromBase: basePlayerOne, toBase: p1StartBases["bot"]!))
|
||||||
|
} else {
|
||||||
|
p1StartBases["top"] = Base(position: CGPoint(x: self.size.width * 0.2, y: self.size.height * 0.25))
|
||||||
|
p1StartBases["mid"] = Base(position: CGPoint(x: self.size.width * 0.2, y: self.size.height * 0.5))
|
||||||
|
p1StartBases["bot"] = Base(position: CGPoint(x: self.size.width * 0.2, y: self.size.height * 0.75))
|
||||||
|
ways.append(Way(fromBase: basePlayerOne, toBase: p1StartBases["top"]!))
|
||||||
|
ways.append(Way(fromBase: basePlayerOne, toBase: p1StartBases["mid"]!))
|
||||||
|
ways.append(Way(fromBase: basePlayerOne, toBase: p1StartBases["bot"]!))
|
||||||
|
}
|
||||||
|
|
||||||
|
os_log("Generate Map center", log: LOG, type: .info)
|
||||||
|
let gridCellWidth = self.size.width * 0.2
|
||||||
|
let gridCellHeight = self.size.height * 0.4
|
||||||
|
let cellInsetX = CGFloat(self.size.width * 0.05)
|
||||||
|
let cellInsetY = CGFloat(self.size.height * 0.07)
|
||||||
|
|
||||||
|
let gridTopLeft = CGRect(
|
||||||
|
x: self.size.width * 0.3,
|
||||||
|
y: self.size.height * 0.1,
|
||||||
|
width: gridCellWidth,
|
||||||
|
height: gridCellHeight
|
||||||
|
).insetBy(dx: cellInsetX, dy: cellInsetY)
|
||||||
|
|
||||||
|
let gridTopRight = CGRect(
|
||||||
|
x: self.size.width * 0.5,
|
||||||
|
y: self.size.height * 0.1,
|
||||||
|
width: gridCellWidth,
|
||||||
|
height: gridCellHeight
|
||||||
|
).insetBy(dx: cellInsetX, dy: cellInsetY)
|
||||||
|
|
||||||
|
let gridBottomLeft = CGRect(
|
||||||
|
x: self.size.width * 0.3,
|
||||||
|
y: self.size.height * 0.5,
|
||||||
|
width: gridCellWidth,
|
||||||
|
height: gridCellHeight
|
||||||
|
).insetBy(dx: cellInsetX, dy: cellInsetY)
|
||||||
|
|
||||||
|
let gridBottomRight = CGRect(
|
||||||
|
x: self.size.width * 0.5,
|
||||||
|
y: self.size.height * 0.5,
|
||||||
|
width: gridCellWidth,
|
||||||
|
height: gridCellHeight
|
||||||
|
).insetBy(dx: cellInsetX, dy: cellInsetY)
|
||||||
|
|
||||||
|
let topLeft = CenterElementProvider.get(inFrame: gridTopLeft, withId: mapModel.topLeftId)
|
||||||
|
let topRight = CenterElementProvider.get(inFrame: gridTopRight, withId: mapModel.topRightId)
|
||||||
|
let bottomLeft = CenterElementProvider.get(inFrame: gridBottomLeft, withId: mapModel.bottomLeftId)
|
||||||
|
let bottomRight = CenterElementProvider.get(inFrame: gridBottomRight, withId: mapModel.bottomRightId)
|
||||||
|
|
||||||
|
ways.append(contentsOf: topLeft.getInternalWays())
|
||||||
|
ways.append(contentsOf: topRight.getInternalWays())
|
||||||
|
ways.append(contentsOf: bottomLeft.getInternalWays())
|
||||||
|
ways.append(contentsOf: bottomRight.getInternalWays())
|
||||||
|
|
||||||
|
os_log("Get player two base", log: LOG, type: .info)
|
||||||
|
let basePlayerTwo = Base(
|
||||||
|
position: CGPoint(x: self.size.width * 0.93, y: self.size.height / 2),
|
||||||
|
player: (!GameCenterManager.sharedInstance.isServer) ? GKLocalPlayer.local : GameCenterManager.sharedInstance.myMatch?.players[0],
|
||||||
|
team: .team2
|
||||||
|
)
|
||||||
|
|
||||||
|
os_log("Get player two's startbases", log: LOG, type: .info)
|
||||||
|
var p2StartBases = [String: Base]()
|
||||||
|
|
||||||
|
if (mapModel.numBasesP2 == 1) {
|
||||||
|
p2StartBases["mid"] = Base(position: CGPoint(x: self.size.width * 0.8, y: self.size.height * 0.5))
|
||||||
|
ways.append(Way(fromBase: basePlayerTwo, toBase: p2StartBases["mid"]!))
|
||||||
|
} else if (mapModel.numBasesP2 == 2) {
|
||||||
|
p2StartBases["top"] = Base(position: CGPoint(x: self.size.width * 0.8, y: self.size.height * 0.333))
|
||||||
|
p2StartBases["bot"] = Base(position: CGPoint(x: self.size.width * 0.8, y: self.size.height * 0.666))
|
||||||
|
ways.append(Way(fromBase: basePlayerTwo, toBase: p2StartBases["top"]!))
|
||||||
|
ways.append(Way(fromBase: basePlayerTwo, toBase: p2StartBases["bot"]!))
|
||||||
|
} else {
|
||||||
|
p2StartBases["top"] = Base(position: CGPoint(x: self.size.width * 0.8, y: self.size.height * 0.25))
|
||||||
|
p2StartBases["mid"] = Base(position: CGPoint(x: self.size.width * 0.8, y: self.size.height * 0.5))
|
||||||
|
p2StartBases["bot"] = Base(position: CGPoint(x: self.size.width * 0.8, y: self.size.height * 0.75))
|
||||||
|
ways.append(Way(fromBase: basePlayerTwo, toBase: p2StartBases["top"]!))
|
||||||
|
ways.append(Way(fromBase: basePlayerTwo, toBase: p2StartBases["mid"]!))
|
||||||
|
ways.append(Way(fromBase: basePlayerTwo, toBase: p2StartBases["bot"]!))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create adjacency mapping
|
||||||
|
os_log("Connecting base p1 and start bases", log: LOG, type: .info)
|
||||||
|
basePlayerOne.adjacencyList.append(contentsOf: p1StartBases.values)
|
||||||
|
p1StartBases.values.forEach({base in base.adjacencyList.append(basePlayerOne)})
|
||||||
|
|
||||||
|
if (p1StartBases["top"] != nil && topLeft.getLeftConnection() != nil) {
|
||||||
|
os_log("Connecting p1 startbase top with topLeft segment", log: LOG, type: .info)
|
||||||
|
p1StartBases["top"]!.adjacencyList.append(topLeft.getLeftConnection()!)
|
||||||
|
topLeft.getLeftConnection()!.adjacencyList.append(p1StartBases["top"]!)
|
||||||
|
ways.append(Way(fromBase: p1StartBases["top"]!, toBase: topLeft.getLeftConnection()!))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p1StartBases["mid"] != nil) {
|
||||||
|
if (topLeft.getLeftConnection() != nil) {
|
||||||
|
os_log("Connecting p1 startbase mid with topLeft segment", log: LOG, type: .info)
|
||||||
|
p1StartBases["mid"]!.adjacencyList.append(topLeft.getLeftConnection()!)
|
||||||
|
topLeft.getLeftConnection()!.adjacencyList.append(p1StartBases["mid"]!)
|
||||||
|
ways.append(Way(fromBase: p1StartBases["mid"]!, toBase: topLeft.getLeftConnection()!))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bottomLeft.getLeftConnection() != nil) {
|
||||||
|
os_log("Connecting p1 startbase mid with bottomLeft segment", log: LOG, type: .info)
|
||||||
|
p1StartBases["mid"]!.adjacencyList.append(bottomLeft.getLeftConnection()!)
|
||||||
|
bottomLeft.getLeftConnection()!.adjacencyList.append(p1StartBases["mid"]!)
|
||||||
|
ways.append(Way(fromBase: p1StartBases["mid"]!, toBase: bottomLeft.getLeftConnection()!))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p1StartBases["bot"] != nil && bottomLeft.getLeftConnection() != nil) {
|
||||||
|
os_log("Connecting p1 startbase bot with bottomLeft segment", log: LOG, type: .info)
|
||||||
|
p1StartBases["bot"]!.adjacencyList.append(bottomLeft.getLeftConnection()!)
|
||||||
|
bottomLeft.getLeftConnection()!.adjacencyList.append(p1StartBases["bot"]!)
|
||||||
|
ways.append(Way(fromBase: p1StartBases["bot"]!, toBase: bottomLeft.getLeftConnection()!))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (topLeft.getRightConnection() != nil && topRight.getLeftConnection() != nil) {
|
||||||
|
os_log("Connecting topLeft with topRight segment horizontally", log: LOG, type: .info)
|
||||||
|
topLeft.getRightConnection()!.adjacencyList.append(topRight.getLeftConnection()!)
|
||||||
|
topRight.getLeftConnection()!.adjacencyList.append(topLeft.getRightConnection()!)
|
||||||
|
ways.append(Way(fromBase: topLeft.getRightConnection()!, toBase: topRight.getLeftConnection()!))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bottomLeft.getRightConnection() != nil && bottomRight.getLeftConnection() != nil) {
|
||||||
|
os_log("Connecting bottomLeft with bottomRight segment horizontally", log: LOG, type: .info)
|
||||||
|
bottomLeft.getRightConnection()!.adjacencyList.append(bottomRight.getLeftConnection()!)
|
||||||
|
bottomRight.getLeftConnection()!.adjacencyList.append(bottomLeft.getRightConnection()!)
|
||||||
|
ways.append(Way(fromBase: bottomLeft.getRightConnection()!, toBase: bottomRight.getLeftConnection()!))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (topLeft.getBottomConnection() != nil && bottomLeft.getTopConnection() != nil) {
|
||||||
|
os_log("Connecting topLeft with bottomLeft segment vertically", log: LOG, type: .info)
|
||||||
|
topLeft.getBottomConnection()!.adjacencyList.append(bottomLeft.getTopConnection()!)
|
||||||
|
bottomLeft.getTopConnection()!.adjacencyList.append(topLeft.getBottomConnection()!)
|
||||||
|
ways.append(Way(fromBase: topLeft.getBottomConnection()!, toBase: bottomLeft.getTopConnection()!))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (topRight.getBottomConnection() != nil && bottomRight.getTopConnection() != nil) {
|
||||||
|
os_log("Connecting topRight with bottomRight segment vertically", log: LOG, type: .info)
|
||||||
|
topRight.getBottomConnection()!.adjacencyList.append(bottomRight.getTopConnection()!)
|
||||||
|
bottomRight.getTopConnection()!.adjacencyList.append(topRight.getBottomConnection()!)
|
||||||
|
ways.append(Way(fromBase: topRight.getBottomConnection()!, toBase: bottomRight.getTopConnection()!))
|
||||||
|
}
|
||||||
|
|
||||||
|
os_log("Connecting base p2 and start bases", log: LOG, type: .info)
|
||||||
|
basePlayerTwo.adjacencyList.append(contentsOf: p2StartBases.values)
|
||||||
|
p2StartBases.values.forEach({base in base.adjacencyList.append(basePlayerTwo)})
|
||||||
|
|
||||||
|
if (p2StartBases["top"] != nil && topRight.getRightConnection() != nil) {
|
||||||
|
os_log("Connecting p2 startbase top with topRight segment", log: LOG, type: .info)
|
||||||
|
p2StartBases["top"]!.adjacencyList.append(topRight.getRightConnection()!)
|
||||||
|
topRight.getRightConnection()!.adjacencyList.append(p2StartBases["top"]!)
|
||||||
|
ways.append(Way(fromBase: p2StartBases["top"]!, toBase: topRight.getRightConnection()!))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p2StartBases["mid"] != nil) {
|
||||||
|
if (topRight.getRightConnection() != nil) {
|
||||||
|
os_log("Connecting p2 startbase mid with topRight segment", log: LOG, type: .info)
|
||||||
|
p2StartBases["mid"]!.adjacencyList.append(topRight.getRightConnection()!)
|
||||||
|
topRight.getRightConnection()!.adjacencyList.append(p2StartBases["mid"]!)
|
||||||
|
ways.append(Way(fromBase: topRight.getRightConnection()!, toBase: p2StartBases["mid"]!))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bottomRight.getRightConnection() != nil) {
|
||||||
|
os_log("Connecting p2 startbase mid with bottomRight segment", log: LOG, type: .info)
|
||||||
|
p2StartBases["mid"]!.adjacencyList.append(bottomRight.getRightConnection()!)
|
||||||
|
bottomRight.getRightConnection()!.adjacencyList.append(p2StartBases["mid"]!)
|
||||||
|
ways.append(Way(fromBase: p2StartBases["mid"]!, toBase: bottomRight.getRightConnection()!))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p2StartBases["bot"] != nil && bottomRight.getRightConnection() != nil) {
|
||||||
|
os_log("Connecting p2 startbase bot with bottomRight segment", log: LOG, type: .info)
|
||||||
|
p2StartBases["bot"]!.adjacencyList.append(bottomRight.getRightConnection()!)
|
||||||
|
bottomRight.getRightConnection()!.adjacencyList.append(p2StartBases["bot"]!)
|
||||||
|
ways.append(Way(fromBase: p2StartBases["bot"]!, toBase: bottomRight.getRightConnection()!))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Add all bases to the scene
|
||||||
|
entityManager.add(basePlayerOne)
|
||||||
|
p1StartBases.forEach({(key, base) in entityManager.add(base)})
|
||||||
|
|
||||||
|
topLeft.getAllBases().forEach({base in entityManager.add(base)})
|
||||||
|
topRight.getAllBases().forEach({base in entityManager.add(base)})
|
||||||
|
bottomLeft.getAllBases().forEach({base in entityManager.add(base)})
|
||||||
|
bottomRight.getAllBases().forEach({base in entityManager.add(base)})
|
||||||
|
|
||||||
|
entityManager.add(basePlayerTwo)
|
||||||
|
p2StartBases.forEach({(key, base) in entityManager.add(base)})
|
||||||
|
|
||||||
|
ways.forEach({way in entityManager.add(way)})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
81
GoldWars/GoldWars/Map/MapUtils.swift
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
//
|
||||||
|
// MapUtils.swift
|
||||||
|
// GoldWars
|
||||||
|
//
|
||||||
|
// Created by Marcel Schwarz on 29.05.20.
|
||||||
|
// Copyright © 2020 SP2. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import GameKit
|
||||||
|
import os
|
||||||
|
|
||||||
|
protocol CenterElementProtocol {
|
||||||
|
|
||||||
|
var bases: [Base] {get set}
|
||||||
|
var ways: [Way] {get set}
|
||||||
|
var id: Int { get }
|
||||||
|
|
||||||
|
init(frame: CGRect)
|
||||||
|
|
||||||
|
func getAllBases() -> [Base]
|
||||||
|
func getInternalWays() -> [Way]
|
||||||
|
func getTopConnection() -> Base?
|
||||||
|
func getRightConnection() -> Base?
|
||||||
|
func getBottomConnection() -> Base?
|
||||||
|
func getLeftConnection() -> Base?
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MapGenerationModel: Codable {
|
||||||
|
|
||||||
|
let numBasesP1: Int
|
||||||
|
let numBasesP2: Int
|
||||||
|
let topLeftId: Int
|
||||||
|
let topRightId: Int
|
||||||
|
let bottomLeftId: Int
|
||||||
|
let bottomRightId: Int
|
||||||
|
|
||||||
|
static func new() -> MapGenerationModel {
|
||||||
|
let noOfCElements = CenterElementProvider.centerElements.count - 1
|
||||||
|
|
||||||
|
return MapGenerationModel(
|
||||||
|
numBasesP1: Int.random(in: 1...3),
|
||||||
|
numBasesP2: Int.random(in: 1...3),
|
||||||
|
topLeftId: Int.random(in: 0...noOfCElements),
|
||||||
|
topRightId: Int.random(in: 0...noOfCElements),
|
||||||
|
bottomLeftId: Int.random(in: 0...noOfCElements),
|
||||||
|
bottomRightId: Int.random(in: 0...noOfCElements)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class CenterElementProvider {
|
||||||
|
static let LOG = OSLog.init(subsystem: "MapGenerator", category: "CenterElementProvider")
|
||||||
|
|
||||||
|
static let centerElements: [CenterElementProtocol.Type] = [
|
||||||
|
CElement0.self,
|
||||||
|
CElement1.self,
|
||||||
|
CElement2.self,
|
||||||
|
CElement3.self,
|
||||||
|
CElement4.self,
|
||||||
|
CElement5.self,
|
||||||
|
CElement6.self,
|
||||||
|
CElement7.self,
|
||||||
|
CElement8.self,
|
||||||
|
CElement9.self,
|
||||||
|
CElement10.self,
|
||||||
|
CElement11.self,
|
||||||
|
CElement12.self,
|
||||||
|
CElement13.self,
|
||||||
|
CElement14.self,
|
||||||
|
CElement15.self,
|
||||||
|
CElement16.self,
|
||||||
|
CElement17.self
|
||||||
|
]
|
||||||
|
|
||||||
|
static func get(inFrame frame: CGRect, withId id: Int) -> CenterElementProtocol {
|
||||||
|
os_log("Getting new predifined center element from provider", log: LOG, type: .info)
|
||||||
|
|
||||||
|
return centerElements[id].init(frame: frame)
|
||||||
|
}
|
||||||
|
}
|
@ -11,48 +11,42 @@ import Foundation
|
|||||||
import GameKit
|
import GameKit
|
||||||
|
|
||||||
class MultiplayerNetwork{
|
class MultiplayerNetwork{
|
||||||
static let sharedInstance = MultiplayerNetwork()
|
static let sharedInstance = MultiplayerNetwork()
|
||||||
|
|
||||||
var isSending = false
|
var isSending = false
|
||||||
|
|
||||||
func sendData(data: Data) {
|
func sendData(data: Data) {
|
||||||
let mmHelper = MatchmakingHelper.sharedInstance
|
let mmHelper = GameCenterManager.sharedInstance
|
||||||
if let multiplayerMatch = mmHelper.mpMatch {
|
if let multiplayerMatch = mmHelper.myMatch {
|
||||||
do {
|
do {
|
||||||
try multiplayerMatch.sendData(toAllPlayers: data, with: .reliable)
|
try multiplayerMatch.sendData(toAllPlayers: data, with: .reliable)
|
||||||
} catch {
|
} catch {
|
||||||
//TODO: Add logging
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendDataToHost(data: Data) {
|
func sendDataToHost(data: Data) {
|
||||||
let mmHelper = MatchmakingHelper.sharedInstance
|
|
||||||
let hostGKPlayer = MatchmakingHelper.sharedInstance.mpMatch?.players.filter{ $0.displayName == DataService.sharedInstance.gameHost!.playerName}[0]
|
|
||||||
|
|
||||||
if let multiplayerMatch = mmHelper.mpMatch{
|
if let multiplayerMatch = GameCenterManager.sharedInstance.myMatch{
|
||||||
do {
|
do {
|
||||||
try multiplayerMatch.send(data, to: [hostGKPlayer!], dataMode: .reliable)
|
try multiplayerMatch.send(data, to: [GameCenterManager.sharedInstance.hostingPlayer!], dataMode: .reliable)
|
||||||
} catch {
|
} catch {
|
||||||
//TODO: Add logging
|
//TODO: Add logging
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendPlayerMoves(playerMoves: [PlayerMove]) {
|
func sendPlayerMoves(localRoundData: LocalRoundData) {
|
||||||
if MatchmakingHelper.sharedInstance.isServer == false {
|
if GameCenterManager.sharedInstance.isServer == false {
|
||||||
|
print("I am client")
|
||||||
self.isSending = true
|
self.isSending = true
|
||||||
let encoder = JSONEncoder()
|
let encoder = JSONEncoder()
|
||||||
let encoded = (try? encoder.encode(playerMoves))!
|
let encoded = (try? encoder.encode(localRoundData))!
|
||||||
sendDataToHost(data: encoded)
|
sendDataToHost(data: encoded)
|
||||||
DataService.sharedInstance.localPlayerMoves.removeAll()
|
DataService.sharedInstance.localRoundData.localPlayerMoves.removeAll()
|
||||||
|
DataService.sharedInstance.localRoundData.hasAttackBoost = false
|
||||||
|
DataService.sharedInstance.localRoundData.hasDefenceBoost = false
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func sendHostIdentifier() {
|
|
||||||
let encoder = JSONEncoder()
|
|
||||||
let encoded = (try? encoder.encode(DataService.sharedInstance.gameHost))!
|
|
||||||
sendData(data: encoded)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendSnapshotModelToPlayers() {
|
func sendSnapshotModelToPlayers() {
|
||||||
@ -66,5 +60,5 @@ class MultiplayerNetwork{
|
|||||||
let encoded = (try? encoder.encode(mapModel))!
|
let encoded = (try? encoder.encode(mapModel))!
|
||||||
sendData(data: encoded)
|
sendData(data: encoded)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
BIN
GoldWars/GoldWars/Partikels/Explosion.sks
Normal file
@ -10,34 +10,31 @@ import GameKit
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
class RoundCalculatorService {
|
class RoundCalculatorService {
|
||||||
|
var entityManager = EntityManager.gameEMInstance
|
||||||
static let sharedInstance = RoundCalculatorService()
|
static let sharedInstance = RoundCalculatorService()
|
||||||
static let LOG = OSLog.init(subsystem: "Round Calculator", category: "RoundCalculatorService")
|
static let LOG = OSLog.init(subsystem: "Round Calculator", category: "RoundCalculatorService")
|
||||||
|
|
||||||
var allPlayerMoves: [String: [PlayerMove]] = [:]
|
var allPlayerMoves: [String: [PlayerMove]] = [:]
|
||||||
var baseSpecificMoves: [Int: [String: [PlayerMove]]] = [:]
|
// TODO: Better data structure
|
||||||
|
var boosts: [String: (Bool, Bool)] = [:] // First bool is atk boost, second is def boost
|
||||||
|
|
||||||
|
let ATK_BOOST_MULTIPLICATOR = 1.1
|
||||||
|
let DEF_BOOST_MULTIPLICATOR = 1.1
|
||||||
|
let MAX_ROUNDS = 20
|
||||||
|
var currentRound = 1
|
||||||
var isCalculating = false
|
var isCalculating = false
|
||||||
|
var numberOfAttacks = 0
|
||||||
|
var numberOfOwnUnitMoves = 0
|
||||||
|
|
||||||
func calculateRound() {
|
func calculateRound() {
|
||||||
os_log("Started calculating Round", log: RoundCalculatorService.LOG, type: .info)
|
os_log("Started calculating Round", log: RoundCalculatorService.LOG, type: .info)
|
||||||
isCalculating = true
|
isCalculating = true
|
||||||
let currentSnapshotModel = DataService.sharedInstance.snapshotModel
|
let currentSnapshotModel = DataService.sharedInstance.snapshotModel
|
||||||
|
|
||||||
for playerMove in DataService.sharedInstance.remotePlayerMoves {
|
var baseSpecificMoves = collectBaseSpecificMoves()
|
||||||
addPlayerMove(playerName: playerMove.key, playerMoves: playerMove.value)
|
|
||||||
}
|
|
||||||
addPlayerMove(playerName: GKLocalPlayer.local.displayName, playerMoves: DataService.sharedInstance.localPlayerMoves)
|
|
||||||
|
|
||||||
for playerMove in allPlayerMoves {
|
|
||||||
for move in playerMove.value {
|
|
||||||
mapPlayerMoveToAttackedBase(playerName: playerMove.key, playerMove: move)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Refactor to a less complex way
|
// TODO: Refactor to a less complex way
|
||||||
for (key, value) in baseSpecificMoves {
|
for (baseId, playerMovesByBase) in baseSpecificMoves {
|
||||||
let baseId = key
|
|
||||||
var playerMovesByBase = value
|
|
||||||
let targetBase = currentSnapshotModel?.baseEntites.filter { $0.baseId == baseId }[0]
|
let targetBase = currentSnapshotModel?.baseEntites.filter { $0.baseId == baseId }[0]
|
||||||
let possiblyOwnershipMoves = playerMovesByBase.filter { $0.key == targetBase?.ownership}
|
let possiblyOwnershipMoves = playerMovesByBase.filter { $0.key == targetBase?.ownership}
|
||||||
|
|
||||||
@ -52,10 +49,10 @@ class RoundCalculatorService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
playerMovesByBase.removeValue(forKey: playerName)
|
baseSpecificMoves[baseId]!.removeValue(forKey: playerName)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (_, playerMoves) in playerMovesByBase {
|
for playerMoves in baseSpecificMoves[baseId]!.values {
|
||||||
for playerMove in playerMoves {
|
for playerMove in playerMoves {
|
||||||
for base in currentSnapshotModel!.baseEntites {
|
for base in currentSnapshotModel!.baseEntites {
|
||||||
if base.baseId == playerMove.fromBase {
|
if base.baseId == playerMove.fromBase {
|
||||||
@ -64,21 +61,42 @@ class RoundCalculatorService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (baseId, playerMovesByBase) in baseSpecificMoves {
|
||||||
var combinePotentionalForces: [String: PlayerMove] = [:]
|
var combinePotentionalForces: [String: PlayerMove] = [:]
|
||||||
|
|
||||||
for playerMoves in playerMovesByBase {
|
for playerMoves in playerMovesByBase {
|
||||||
combinePotentionalForces[playerMoves.key] = PlayerMove(fromBase: playerMoves.value[0].fromBase, toBase: playerMoves.value[0].toBase, unitCount: 0)
|
combinePotentionalForces[playerMoves.key] = PlayerMove(
|
||||||
|
fromBase: playerMoves.value[0].fromBase,
|
||||||
|
toBase: playerMoves.value[0].toBase,
|
||||||
|
unitCount: 0
|
||||||
|
)
|
||||||
for move in playerMoves.value {
|
for move in playerMoves.value {
|
||||||
combinePotentionalForces[playerMoves.key]!.unitCount += move.unitCount
|
combinePotentionalForces[playerMoves.key]!.unitCount += move.unitCount
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(combinePotentionalForces.count > 0) {
|
|
||||||
|
if combinePotentionalForces.count > 0 {
|
||||||
let sortedPotentionalCombinedForces = combinePotentionalForces.sorted { $0.1.unitCount > $1.1.unitCount }
|
let sortedPotentionalCombinedForces = combinePotentionalForces.sorted { $0.1.unitCount > $1.1.unitCount }
|
||||||
|
|
||||||
var playerMoveWithMaxUnits = sortedPotentionalCombinedForces[0]
|
var playerMoveWithMaxUnits = sortedPotentionalCombinedForces[0]
|
||||||
|
|
||||||
if playerMovesByBase.count >= 2 {
|
if playerMovesByBase.count >= 2 {
|
||||||
let playerMoveWithSecMaxUnits = sortedPotentionalCombinedForces[1]
|
var playerMoveWithSecMaxUnits = sortedPotentionalCombinedForces[1]
|
||||||
|
if boosts[playerMoveWithMaxUnits.key]!.0 {
|
||||||
|
playerMoveWithMaxUnits.value.unitCount = Int(Double(playerMoveWithMaxUnits.value.unitCount) * ATK_BOOST_MULTIPLICATOR)
|
||||||
|
}
|
||||||
|
if boosts[playerMoveWithSecMaxUnits.key]!.0 {
|
||||||
|
playerMoveWithSecMaxUnits.value.unitCount = Int(Double(playerMoveWithSecMaxUnits.value.unitCount) * ATK_BOOST_MULTIPLICATOR)
|
||||||
|
}
|
||||||
|
|
||||||
|
if playerMoveWithMaxUnits.value.unitCount < playerMoveWithSecMaxUnits.value.unitCount {
|
||||||
|
let temp = playerMoveWithMaxUnits
|
||||||
|
playerMoveWithMaxUnits = playerMoveWithSecMaxUnits
|
||||||
|
playerMoveWithSecMaxUnits = temp
|
||||||
|
}
|
||||||
|
|
||||||
playerMoveWithMaxUnits.value.unitCount -= playerMoveWithSecMaxUnits.value.unitCount
|
playerMoveWithMaxUnits.value.unitCount -= playerMoveWithSecMaxUnits.value.unitCount
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,17 +104,17 @@ class RoundCalculatorService {
|
|||||||
if base.baseId == playerMoveWithMaxUnits.value.toBase {
|
if base.baseId == playerMoveWithMaxUnits.value.toBase {
|
||||||
if base.ownership == nil {
|
if base.ownership == nil {
|
||||||
base.unitCount += playerMoveWithMaxUnits.value.unitCount
|
base.unitCount += playerMoveWithMaxUnits.value.unitCount
|
||||||
if playerMoveWithMaxUnits.value.unitCount == 0 {
|
base.ownership = playerMoveWithMaxUnits.value.unitCount == 0 ? nil : playerMoveWithMaxUnits.key
|
||||||
base.ownership = nil
|
|
||||||
} else {
|
|
||||||
base.ownership = playerMoveWithMaxUnits.key
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
|
if boosts[base.ownership!]!.1 {
|
||||||
|
base.unitCount = Int(Double(base.unitCount) * DEF_BOOST_MULTIPLICATOR)
|
||||||
|
}
|
||||||
if base.unitCount < playerMoveWithMaxUnits.value.unitCount {
|
if base.unitCount < playerMoveWithMaxUnits.value.unitCount {
|
||||||
base.unitCount = playerMoveWithMaxUnits.value.unitCount - base.unitCount
|
base.unitCount = playerMoveWithMaxUnits.value.unitCount - base.unitCount
|
||||||
base.ownership = playerMoveWithMaxUnits.key
|
base.ownership = playerMoveWithMaxUnits.key
|
||||||
} else if (base.unitCount == playerMoveWithMaxUnits.value.unitCount) {
|
} else if (base.unitCount == playerMoveWithMaxUnits.value.unitCount) {
|
||||||
base.ownership = nil
|
base.ownership = nil
|
||||||
|
base.unitCount = 0
|
||||||
} else {
|
} else {
|
||||||
base.unitCount -= playerMoveWithMaxUnits.value.unitCount
|
base.unitCount -= playerMoveWithMaxUnits.value.unitCount
|
||||||
}
|
}
|
||||||
@ -106,34 +124,131 @@ class RoundCalculatorService {
|
|||||||
}
|
}
|
||||||
baseSpecificMoves.removeValue(forKey: baseId)
|
baseSpecificMoves.removeValue(forKey: baseId)
|
||||||
}
|
}
|
||||||
|
var player1BaseCount = 0;
|
||||||
|
var player2BaseCount = 0;
|
||||||
|
let player1 = GameCenterManager.sharedInstance.hostingPlayer?.displayName
|
||||||
|
let player2 = GameCenterManager.sharedInstance.peerPlayer?.displayName
|
||||||
|
for baseEntry in currentSnapshotModel!.baseEntites {
|
||||||
|
if baseEntry.ownership == player1 {
|
||||||
|
player1BaseCount += 1
|
||||||
|
} else if baseEntry.ownership == player2 {
|
||||||
|
player2BaseCount += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currentSnapshotModel?.baseEntites = currentSnapshotModel!.baseEntites.map { (BaseEntityModel) -> BaseEntityModel in
|
||||||
|
if BaseEntityModel.ownership == player1 {
|
||||||
|
BaseEntityModel.unitCount += player1BaseCount
|
||||||
|
} else if BaseEntityModel.ownership == player2 {
|
||||||
|
BaseEntityModel.unitCount += player2BaseCount
|
||||||
|
}
|
||||||
|
return BaseEntityModel
|
||||||
|
}
|
||||||
allPlayerMoves.removeAll()
|
allPlayerMoves.removeAll()
|
||||||
DataService.sharedInstance.localPlayerMoves.removeAll()
|
DataService.sharedInstance.localRoundData.localPlayerMoves.removeAll()
|
||||||
|
DataService.sharedInstance.localRoundData.hasAttackBoost = false
|
||||||
|
DataService.sharedInstance.localRoundData.hasDefenceBoost = false
|
||||||
|
|
||||||
|
if isGameOver() {
|
||||||
|
let winner: String?
|
||||||
|
if MAX_ROUNDS == currentRound {
|
||||||
|
os_log("Game is over by rounds", log: RoundCalculatorService.LOG, type: .info)
|
||||||
|
winner = determineWinner(by: "rounds")
|
||||||
|
} else {
|
||||||
|
os_log("Game is over by capture", log: RoundCalculatorService.LOG, type: .info)
|
||||||
|
winner = determineWinner(by: "capture")
|
||||||
|
}
|
||||||
|
winner == GameCenterManager.sharedInstance.hostingPlayer?.displayName ? GameCenterManager.sharedInstance.sendStateToPeers(state: State(state: 4)) : GameCenterManager.sharedInstance.sendStateToPeers(state: State(state: 5))
|
||||||
|
//TODO: Trigger Winner/Loser-Scene for Server
|
||||||
|
return
|
||||||
|
}
|
||||||
|
currentRound += 1
|
||||||
|
entityManager.getHUD()?.setCurrentRound(round: currentRound)
|
||||||
|
|
||||||
MultiplayerNetwork.sharedInstance.sendSnapshotModelToPlayers()
|
MultiplayerNetwork.sharedInstance.sendSnapshotModelToPlayers()
|
||||||
DataService.sharedInstance.snapshotModel = currentSnapshotModel
|
DataService.sharedInstance.snapshotModel = currentSnapshotModel
|
||||||
EntityManager.sharedInstance.updateSnapshotModel(snapshotModel: currentSnapshotModel!)
|
entityManager.updateSnapshotModel(snapshotModel: currentSnapshotModel!)
|
||||||
sleep(1)
|
entityManager.getHUD()?.startWithDuration()
|
||||||
EntityManager.sharedInstance.getTimer().startWithDuration(duration: 31)
|
|
||||||
os_log("Finished calculating Round", log: RoundCalculatorService.LOG, type: .info)
|
os_log("Finished calculating Round", log: RoundCalculatorService.LOG, type: .info)
|
||||||
}
|
}
|
||||||
|
|
||||||
func addPlayerMove(playerName: String, playerMoves: [PlayerMove]) {
|
func collectBaseSpecificMoves() -> [Int: [String: [PlayerMove]]] {
|
||||||
self.allPlayerMoves[playerName] = playerMoves
|
for playerMove in DataService.sharedInstance.remotePlayerMoves {
|
||||||
}
|
allPlayerMoves[playerMove.key] = playerMove.value.localPlayerMoves
|
||||||
|
|
||||||
func mapPlayerMoveToAttackedBase(playerName: String, playerMove: PlayerMove) {
|
|
||||||
if self.baseSpecificMoves.keys.contains(playerMove.toBase) {
|
|
||||||
if (self.baseSpecificMoves[playerMove.toBase]?.keys.contains(playerName))!{
|
|
||||||
self.baseSpecificMoves[playerMove.toBase]?[playerName]?.append(playerMove)
|
|
||||||
} else {
|
|
||||||
self.baseSpecificMoves[playerMove.toBase]?.merge([playerName: [playerMove]]){(current, _) in current}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
self.baseSpecificMoves[playerMove.toBase] = [playerName: [playerMove]]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boosts[GameCenterManager.sharedInstance.hostingPlayer!.displayName] = (
|
||||||
|
DataService.sharedInstance.localRoundData.hasAttackBoost,
|
||||||
|
DataService.sharedInstance.localRoundData.hasDefenceBoost
|
||||||
|
)
|
||||||
|
boosts[GameCenterManager.sharedInstance.peerPlayer!.displayName] = (
|
||||||
|
DataService.sharedInstance.remotePlayerMoves[GameCenterManager.sharedInstance.peerPlayer!.displayName]?.hasAttackBoost ?? false,
|
||||||
|
DataService.sharedInstance.remotePlayerMoves[GameCenterManager.sharedInstance.peerPlayer!.displayName]?.hasDefenceBoost ?? false
|
||||||
|
)
|
||||||
|
|
||||||
|
allPlayerMoves[GKLocalPlayer.local.displayName] = DataService.sharedInstance.localRoundData.localPlayerMoves
|
||||||
|
|
||||||
|
var baseSpecificMoves: [Int: [String: [PlayerMove]]] = [:]
|
||||||
|
|
||||||
|
for playerMove in allPlayerMoves {
|
||||||
|
for move in playerMove.value {
|
||||||
|
if baseSpecificMoves.keys.contains(move.toBase) {
|
||||||
|
if (baseSpecificMoves[move.toBase]?.keys.contains(playerMove.key))! {
|
||||||
|
baseSpecificMoves[move.toBase]?[playerMove.key]?.append(move)
|
||||||
|
} else {
|
||||||
|
baseSpecificMoves[move.toBase]?.merge([playerMove.key: [move]]){(current, _) in current}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
baseSpecificMoves[move.toBase] = [playerMove.key: [move]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DataService.sharedInstance.remotePlayerMoves.removeAll()
|
||||||
|
return baseSpecificMoves
|
||||||
}
|
}
|
||||||
|
|
||||||
func resolvePlayerMove(playerMove: PlayerMove, unitCount: Int, ownership: String?, resolveType: String) {
|
func resolvePlayerMove(playerMove: PlayerMove, unitCount: Int, ownership: String?, resolveType: String) {
|
||||||
//TODO: outsource playermoves
|
//TODO: outsource playermoves
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func resetNumberOfAttacksAndFormats() {
|
||||||
|
self.numberOfAttacks = 0;
|
||||||
|
self.numberOfOwnUnitMoves = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
func increaseMoveCounter(ownBase: Bool!) {
|
||||||
|
if ownBase {
|
||||||
|
self.numberOfOwnUnitMoves += 1
|
||||||
|
} else {
|
||||||
|
self.numberOfAttacks += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func isGameOver() -> Bool {
|
||||||
|
let remoteplayerBasesCount = entityManager.getBasesByPlayer(for: GameCenterManager.sharedInstance.peerPlayer!).count
|
||||||
|
let localplayerBasesCount = entityManager.getBasesByPlayer(for: GameCenterManager.sharedInstance.hostingPlayer!).count
|
||||||
|
let onePlayerLoseAllBases = remoteplayerBasesCount == 0 || localplayerBasesCount == 0
|
||||||
|
let reachMaxRounds = MAX_ROUNDS == currentRound
|
||||||
|
return onePlayerLoseAllBases || reachMaxRounds
|
||||||
|
}
|
||||||
|
|
||||||
|
func determineWinner(by criteria: String) -> String {
|
||||||
|
var winner: String?
|
||||||
|
switch criteria {
|
||||||
|
case "rounds":
|
||||||
|
let peerPlayerBasesCount = entityManager.getBasesByPlayer(for: GameCenterManager.sharedInstance.peerPlayer!).count
|
||||||
|
let hostingPlayerBasesCount = entityManager.getBasesByPlayer(for: GameCenterManager.sharedInstance.hostingPlayer!).count
|
||||||
|
if peerPlayerBasesCount == hostingPlayerBasesCount {
|
||||||
|
let hostingPlayerUnitCount = entityManager.getUnitSum(by: GameCenterManager.sharedInstance.hostingPlayer!)
|
||||||
|
let peerPlayerUnitCount = entityManager.getUnitSum(by: GameCenterManager.sharedInstance.peerPlayer!)
|
||||||
|
winner = hostingPlayerUnitCount > peerPlayerUnitCount ? GameCenterManager.sharedInstance.hostingPlayer?.displayName : GameCenterManager.sharedInstance.peerPlayer?.displayName
|
||||||
|
} else {
|
||||||
|
winner = hostingPlayerBasesCount > peerPlayerBasesCount ? GameCenterManager.sharedInstance.hostingPlayer?.displayName : GameCenterManager.sharedInstance.peerPlayer?.displayName
|
||||||
|
}
|
||||||
|
case "capture":
|
||||||
|
winner = entityManager.getBasesByPlayer(for: GameCenterManager.sharedInstance.hostingPlayer!).count == 0 ? GameCenterManager.sharedInstance.peerPlayer?.displayName : GameCenterManager.sharedInstance.hostingPlayer?.displayName
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return winner!
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
55
GoldWars/GoldWars/RoundTimer.swift
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
//
|
||||||
|
// RoundTimer.swift
|
||||||
|
// GoldWars
|
||||||
|
//
|
||||||
|
// Created by Jakob Haag on 28.05.20.
|
||||||
|
// Copyright © 2020 SP2. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
class RoundTimer: Timer {
|
||||||
|
|
||||||
|
var timer: Timer?
|
||||||
|
var timeLeft: Int = 0
|
||||||
|
var calculate = false
|
||||||
|
var roundEnded = "Syncing"
|
||||||
|
|
||||||
|
func initTimer() {
|
||||||
|
timer = Timer.scheduledTimer(
|
||||||
|
timeInterval: 1.0,
|
||||||
|
target: self,
|
||||||
|
selector: #selector(onTimerFires),
|
||||||
|
userInfo: nil,
|
||||||
|
repeats: true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func startTimer() {
|
||||||
|
timeLeft = 30
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc func onTimerFires()
|
||||||
|
{
|
||||||
|
timeLeft -= 1
|
||||||
|
|
||||||
|
EntityManager.gameEMInstance.updateTime(time: (timeLeft > 0 ? String(timeLeft) : roundEnded))
|
||||||
|
|
||||||
|
if timeLeft == 0 {
|
||||||
|
RoundCalculatorService.sharedInstance.resetNumberOfAttacksAndFormats()
|
||||||
|
if !MultiplayerNetwork.sharedInstance.isSending {
|
||||||
|
MultiplayerNetwork.sharedInstance.sendPlayerMoves(localRoundData: DataService.sharedInstance.localRoundData)
|
||||||
|
}
|
||||||
|
calculate = true
|
||||||
|
}
|
||||||
|
if timeLeft <= 0 {
|
||||||
|
if calculate
|
||||||
|
&& !RoundCalculatorService.sharedInstance.isCalculating
|
||||||
|
&& DataService.sharedInstance.didReceiveAllData()
|
||||||
|
&& GameCenterManager.sharedInstance.isServer {
|
||||||
|
RoundCalculatorService.sharedInstance.calculateRound()
|
||||||
|
calculate = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -12,26 +12,20 @@ import GameKit
|
|||||||
|
|
||||||
class GameScene: SKScene{
|
class GameScene: SKScene{
|
||||||
|
|
||||||
|
var entityManager = EntityManager.gameEMInstance
|
||||||
|
|
||||||
var isMoveTouch = false
|
var isMoveTouch = false
|
||||||
var currentDraggedBase : Base?
|
var currentDraggedBase : Base?
|
||||||
static var sendUnits: CGFloat = 0
|
static var sendUnits: CGFloat = 0
|
||||||
var collisionBase: Base?
|
var collisionBase: Base?
|
||||||
|
|
||||||
override func sceneDidLoad() {
|
override func sceneDidLoad() {
|
||||||
EntityManager.sharedInstance.setScene(scene: self)
|
entityManager.setScene(scene: self)
|
||||||
EntityManager.sharedInstance.add(HUD(size: self.size))
|
entityManager.add(HUD(size: self.size))
|
||||||
EntityManager.sharedInstance.add(Background(size: self.size))
|
entityManager.add(Background(size: self.size))
|
||||||
initMap()
|
|
||||||
}
|
|
||||||
|
|
||||||
func initMap() {
|
|
||||||
if (DataService.sharedInstance.gameHost?.playerName == GKLocalPlayer.local.displayName) {
|
|
||||||
let mapModel = MapFactory(scene: self, entityManager: EntityManager.sharedInstance).loadMap()
|
|
||||||
MultiplayerNetwork.sharedInstance.sendMapModelToPlayers(mapModel: mapModel)
|
|
||||||
DataService.sharedInstance.setSnapshotModel(snapshotModel: EntityManager.sharedInstance.getSnapshotModel())
|
|
||||||
}
|
|
||||||
if CommandLine.arguments.contains("--no-matchmaking") {
|
if CommandLine.arguments.contains("--no-matchmaking") {
|
||||||
MapFactory(scene: self, entityManager: EntityManager.sharedInstance).loadMap()
|
_ = MapFactory(scene: self, entityManager: entityManager).load()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,22 +36,23 @@ class GameScene: SKScene{
|
|||||||
|
|
||||||
let touchLocation = touch.location(in: self)
|
let touchLocation = touch.location(in: self)
|
||||||
|
|
||||||
if isMoveTouch{
|
if isMoveTouch {
|
||||||
isMoveTouch = false
|
isMoveTouch = false
|
||||||
currentDraggedBase!.component(ofType: DefaultBaseComponent.self)?.spriteNode.position = currentDraggedBase!.position
|
moveFireAndBase(base: currentDraggedBase!, touchLocation: currentDraggedBase!.position)
|
||||||
currentDraggedBase!.component(ofType: TeamComponent.self)?.fire.position = currentDraggedBase!.position
|
|
||||||
currentDraggedBase!.component(ofType: DefaultBaseComponent.self)?.labelNode?.position = CGPoint(x: currentDraggedBase!.position.x + 30, y: currentDraggedBase!.position.y - 50)
|
|
||||||
addAttackDetails(touchLocation: touchLocation)
|
addAttackDetails(touchLocation: touchLocation)
|
||||||
|
|
||||||
|
entityManager.getBasesByPlayer(for: GKLocalPlayer.local).forEach({base in
|
||||||
|
moveFireAndBase(base: base, touchLocation: base.position)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for entity in EntityManager.sharedInstance.entities {
|
for entity in entityManager.entities {
|
||||||
let spriteNode = entity.component(ofType: DefaultBaseComponent.self)?.spriteNode
|
let spriteNode = entity.component(ofType: DefaultBaseComponent.self)?.spriteNode
|
||||||
|
|
||||||
//FIXME: this is confusing
|
//FIXME: this is confusing
|
||||||
addBaseDetails(touchLocation: touchLocation, spriteNode: spriteNode, touches: touches, event: event, entity: entity)
|
addBaseDetails(touchLocation: touchLocation, spriteNode: spriteNode, touches: touches, event: event, entity: entity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
|
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||||
@ -72,33 +67,24 @@ class GameScene: SKScene{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
checkSlider()
|
checkSlider()
|
||||||
|
let bases = entityManager.getBasesByPlayer(for: GKLocalPlayer.local)
|
||||||
let bases = EntityManager.sharedInstance.getBasesByPlayer(for: GKLocalPlayer.local)
|
|
||||||
|
|
||||||
checkBases(bases: bases, touchLocation: touchLocation)
|
checkBases(bases: bases, touchLocation: touchLocation)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func update(_ currentTime: TimeInterval) {
|
override func update(_ currentTime: TimeInterval) {
|
||||||
EntityManager.sharedInstance.getBackground()?.update(deltaTime: currentTime)
|
entityManager.getBackground()?.update(deltaTime: currentTime)
|
||||||
EntityManager.sharedInstance.getHUD()?.component(ofType: TimerComponent.self)?.update()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func addBaseDetails(touchLocation: CGPoint, spriteNode: SKNode?, touches: Set<UITouch>, event: UIEvent?, entity: GKEntity){
|
func addBaseDetails(touchLocation: CGPoint, spriteNode: SKNode?, touches: Set<UITouch>, event: UIEvent?, entity: GKEntity){
|
||||||
if atPoint(touchLocation) == spriteNode && !EntityManager.sharedInstance.isModal {
|
if atPoint(touchLocation) == spriteNode && !entityManager.isModal {
|
||||||
spriteNode?.touchesBegan(touches, with: event)
|
spriteNode?.touchesBegan(touches, with: event)
|
||||||
if let baseEntity = entity as? Base {
|
if let baseEntity = entity as? Base {
|
||||||
if baseEntity.ownershipPlayer == GKLocalPlayer.local {
|
if baseEntity.ownershipPlayer == GKLocalPlayer.local {
|
||||||
for child in self.children {
|
entityManager.add(Modal(modaltype: .BaseDetails,
|
||||||
if(child.name != "fire"){
|
base: entity as! Base,
|
||||||
child.alpha = 0.3
|
anchorPoint: CGPoint(x: self.size.width / 2 , y: self.size.height / 2),
|
||||||
}
|
gameScene: self,
|
||||||
}
|
currentDraggedBase: currentDraggedBase, touchLocation: touchLocation, collisionBase: collisionBase))
|
||||||
EntityManager.sharedInstance.add(Modal(modaltype: .BaseDetails,
|
|
||||||
base: entity as! Base,
|
|
||||||
anchorPoint: CGPoint(x: self.size.width / 2 , y: self.size.height / 2),
|
|
||||||
gameScene: self,
|
|
||||||
currentDraggedBase: currentDraggedBase, touchLocation: touchLocation, collisionBase: collisionBase))
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -110,10 +96,18 @@ class GameScene: SKScene{
|
|||||||
collisionBase = base
|
collisionBase = base
|
||||||
// TODO: change interaction based on collision instead of touchlocation
|
// TODO: change interaction based on collision instead of touchlocation
|
||||||
if currentDraggedBase!.unitCount > 1 {
|
if currentDraggedBase!.unitCount > 1 {
|
||||||
EntityManager.sharedInstance.add(Modal(modaltype: .BaseAttack,
|
if !checkIfMoveIsAble() {
|
||||||
base: currentDraggedBase!,
|
return
|
||||||
anchorPoint: CGPoint(x: self.size.width / 2 , y: self.size.height / 2),
|
}
|
||||||
gameScene: self, currentDraggedBase: currentDraggedBase, touchLocation: touchLocation, collisionBase: collisionBase))
|
let modaltype = setModalType()
|
||||||
|
entityManager.add(Modal(modaltype: modaltype,
|
||||||
|
base: currentDraggedBase!,
|
||||||
|
anchorPoint: CGPoint(x: self.size.width / 2 , y: self.size.height / 2),
|
||||||
|
gameScene: self,
|
||||||
|
currentDraggedBase: currentDraggedBase,
|
||||||
|
touchLocation: touchLocation,
|
||||||
|
collisionBase: collisionBase)
|
||||||
|
)
|
||||||
GameScene.sendUnits = CGFloat(currentDraggedBase!.unitCount / 2)
|
GameScene.sendUnits = CGFloat(currentDraggedBase!.unitCount / 2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,8 +115,8 @@ class GameScene: SKScene{
|
|||||||
}
|
}
|
||||||
|
|
||||||
func checkSlider(){
|
func checkSlider(){
|
||||||
for e in EntityManager.sharedInstance.entities{
|
for e in entityManager.entities{
|
||||||
if let body = e.component(ofType: ModalContentComponent.self)?.body{
|
if let modal = e as? Modal {
|
||||||
GameScene.sendUnits = ((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
|
//TODO: refactor this quick and dirty fix
|
||||||
@ -131,20 +125,22 @@ class GameScene: SKScene{
|
|||||||
} else if Int(GameScene.sendUnits) == currentDraggedBase?.unitCount {
|
} else if Int(GameScene.sendUnits) == currentDraggedBase?.unitCount {
|
||||||
GameScene.sendUnits -= 1
|
GameScene.sendUnits -= 1
|
||||||
}
|
}
|
||||||
body.text = "Schicke \(GameScene.sendUnits) Einheiten "
|
modal.body.text = "Schicke \(GameScene.sendUnits) Einheiten "
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkBases(bases: Set<Base>, touchLocation: CGPoint){
|
func checkBases(bases: Set<Base>, touchLocation: CGPoint){
|
||||||
for base in bases {
|
for base in bases {
|
||||||
if atPoint(touchLocation) == base.component(ofType: DefaultBaseComponent.self)?.spriteNode{
|
if atPoint(touchLocation) == base.component(ofType: DefaultBaseComponent.self)?.spriteNode {
|
||||||
if !isMoveTouch {
|
if !base.changeOwnership {
|
||||||
currentDraggedBase = base
|
if !isMoveTouch {
|
||||||
|
currentDraggedBase = base
|
||||||
|
}
|
||||||
|
isMoveTouch = true
|
||||||
|
moveFireAndBase(base: base, touchLocation: touchLocation)
|
||||||
|
showNearestBases(base: base)
|
||||||
}
|
}
|
||||||
isMoveTouch = true
|
|
||||||
moveFireAndBase(base: base, touchLocation: touchLocation)
|
|
||||||
showNearestBases(base: base)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -152,7 +148,7 @@ class GameScene: SKScene{
|
|||||||
func moveFireAndBase(base: Base, touchLocation: CGPoint){
|
func moveFireAndBase(base: Base, touchLocation: CGPoint){
|
||||||
base.component(ofType: DefaultBaseComponent.self)?.spriteNode.position = touchLocation
|
base.component(ofType: DefaultBaseComponent.self)?.spriteNode.position = touchLocation
|
||||||
base.component(ofType: TeamComponent.self)?.fire.position = touchLocation
|
base.component(ofType: TeamComponent.self)?.fire.position = touchLocation
|
||||||
base.component(ofType: DefaultBaseComponent.self)?.labelNode?.position = CGPoint(x:touchLocation.x + 30, y: touchLocation.y - 50)
|
base.component(ofType: DefaultBaseComponent.self)?.labelNode.position = CGPoint(x:touchLocation.x + 30, y: touchLocation.y - 50)
|
||||||
}
|
}
|
||||||
|
|
||||||
func showNearestBases(base: Base){
|
func showNearestBases(base: Base){
|
||||||
@ -164,4 +160,24 @@ class GameScene: SKScene{
|
|||||||
]))
|
]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func checkIfMoveIsAble() -> Bool{
|
||||||
|
if isAttackMove() {
|
||||||
|
return RoundCalculatorService.sharedInstance.numberOfAttacks < 2
|
||||||
|
} else {
|
||||||
|
return RoundCalculatorService.sharedInstance.numberOfOwnUnitMoves < 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func setModalType() -> ModalType {
|
||||||
|
if isAttackMove() {
|
||||||
|
return .BaseAttack
|
||||||
|
} else {
|
||||||
|
return .BaseMoveOwnUnits
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func isAttackMove() -> Bool {
|
||||||
|
return collisionBase?.ownershipPlayer != currentDraggedBase?.ownershipPlayer
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,13 +9,16 @@
|
|||||||
import SpriteKit
|
import SpriteKit
|
||||||
import SceneKit
|
import SceneKit
|
||||||
class MenuScene: SKScene {
|
class MenuScene: SKScene {
|
||||||
|
|
||||||
|
var entityManager = EntityManager.menuEMInstance
|
||||||
|
|
||||||
override func sceneDidLoad() {
|
override func sceneDidLoad() {
|
||||||
EntityManager.sharedInstance.setScene(scene: self)
|
GameCenterManager.sharedInstance.menusc = self
|
||||||
|
entityManager.setScene(scene: self)
|
||||||
let midX = self.size.width / 2
|
let midX = self.size.width / 2
|
||||||
let midY = self.size.height / 2
|
let midY = self.size.height / 2
|
||||||
EntityManager.sharedInstance.add(Button(name: "startGameButton",
|
entityManager.add(Button(name: "startGameButton",
|
||||||
iconName: "",
|
textureName: "yellow_button04",
|
||||||
text: "Start Game",
|
text: "Start Game",
|
||||||
position: CGPoint(x: midX, y: midY),
|
position: CGPoint(x: midX, y: midY),
|
||||||
onButtonPress: {
|
onButtonPress: {
|
||||||
@ -23,18 +26,35 @@ class MenuScene: SKScene {
|
|||||||
self.loadScene(scene: GameScene(size: self.size))
|
self.loadScene(scene: GameScene(size: self.size))
|
||||||
SoundManager.sharedInstance.stopMenuMusic()
|
SoundManager.sharedInstance.stopMenuMusic()
|
||||||
} else {
|
} else {
|
||||||
MatchmakingHelper.sharedInstance.presentMatchmaker(scene: self)
|
|
||||||
|
if GameCenterManager.isAuthenticated {
|
||||||
|
GameCenterManager.sharedInstance.presentMatchmaker()
|
||||||
|
}else {
|
||||||
|
GameCenterManager.sharedInstance.authUser()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
EntityManager.sharedInstance.add(Button(name: "settingsButton",
|
entityManager.add(Button(name: "settingsButton",
|
||||||
iconName: "",
|
textureName: "yellow_button04",
|
||||||
text: "Settings",
|
text: "Settings",
|
||||||
position: CGPoint(x: midX, y: midY - 80 ),
|
position: CGPoint(x: midX, y: midY - 80 ),
|
||||||
onButtonPress: {
|
onButtonPress: {
|
||||||
self.loadScene(scene: SettingsScene(size: self.size))
|
let scene = SettingsScene(size: self.size)
|
||||||
|
self.loadScene(scene: scene)
|
||||||
}))
|
}))
|
||||||
EntityManager.sharedInstance.add(Background(size: self.size))
|
entityManager.add(Button(name: "gameCenterButton",
|
||||||
EntityManager.sharedInstance.add(SpinningLogoEntity(position: CGPoint(x: midX, y: midY + 200)))
|
textureName: "yellow_button04",
|
||||||
|
text: "GameCenter",
|
||||||
|
position: CGPoint(x: midX, y: midY - 160),
|
||||||
|
onButtonPress: {
|
||||||
|
if GameCenterManager.isAuthenticated {
|
||||||
|
GameCenterManager.sharedInstance.presentGameCenter()
|
||||||
|
}else {
|
||||||
|
GameCenterManager.sharedInstance.authUser()
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
entityManager.add(Background(size: self.size))
|
||||||
|
entityManager.add(SpinningLogoEntity(position: CGPoint(x: midX, y: midY + 200)))
|
||||||
|
|
||||||
if SoundManager.sharedInstance.isMusicPlaying == false && SoundManager.sharedInstance.isMusicEnabled == true {
|
if SoundManager.sharedInstance.isMusicPlaying == false && SoundManager.sharedInstance.isMusicEnabled == true {
|
||||||
SoundManager.sharedInstance.startMenuMusic()
|
SoundManager.sharedInstance.startMenuMusic()
|
||||||
@ -43,11 +63,19 @@ class MenuScene: SKScene {
|
|||||||
|
|
||||||
func loadScene(scene: SKScene) {
|
func loadScene(scene: SKScene) {
|
||||||
let transition = SKTransition.flipVertical(withDuration: 0.5)
|
let transition = SKTransition.flipVertical(withDuration: 0.5)
|
||||||
|
entityManager.entities.removeAll()
|
||||||
self.view?.presentScene(scene, transition: transition)
|
self.view?.presentScene(scene, transition: transition)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func update(_ currentTime: TimeInterval) {
|
override func update(_ currentTime: TimeInterval) {
|
||||||
EntityManager.sharedInstance.getBackground()!.update(deltaTime: currentTime)
|
if entityManager.entities.count != 0 {
|
||||||
EntityManager.sharedInstance.getButtonByName(buttonName: "startGameButton").component(ofType: ButtonComponent.self)?.buttonNode.isEnabled = GameCenterHelper.isAuthenticated
|
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!)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,20 +10,22 @@ import SpriteKit
|
|||||||
|
|
||||||
class SettingsScene: SKScene {
|
class SettingsScene: SKScene {
|
||||||
|
|
||||||
|
var entityManager = EntityManager.settingsEMInstance
|
||||||
|
|
||||||
override func sceneDidLoad() {
|
override func sceneDidLoad() {
|
||||||
EntityManager.sharedInstance.setScene(scene: self)
|
entityManager.setScene(scene: self)
|
||||||
let positionX = self.size.width * 0.1
|
let positionX = self.size.width * 0.1
|
||||||
let positionY = self.size.height * 0.05
|
let positionY = self.size.height * 0.05
|
||||||
|
entityManager.add(Button(name: "backToMenuScene",
|
||||||
EntityManager.sharedInstance.add(Button(name: "backToMenuScene",
|
textureName: "yellow_button04",
|
||||||
iconName: "",
|
|
||||||
text: "Back",
|
text: "Back",
|
||||||
position: CGPoint(x: positionX, y: positionY),
|
position: CGPoint(x: positionX, y: positionY),
|
||||||
onButtonPress: {
|
onButtonPress: {
|
||||||
self.loadScene(scene: MenuScene(size: self.size))
|
let scene = MenuScene(size: self.size)
|
||||||
|
self.loadScene(scene: scene)
|
||||||
}))
|
}))
|
||||||
EntityManager.sharedInstance.add(Button(name: "StopMenuMusic",
|
entityManager.add(Button(name: "StopMenuMusic",
|
||||||
iconName: "",
|
textureName: "yellow_button04",
|
||||||
text: "ON/OFF",
|
text: "ON/OFF",
|
||||||
position: CGPoint(x: self.size.width * 0.6, y: self.size.height / 2),
|
position: CGPoint(x: self.size.width * 0.6, y: self.size.height / 2),
|
||||||
onButtonPress: {
|
onButtonPress: {
|
||||||
@ -35,8 +37,8 @@ class SettingsScene: SKScene {
|
|||||||
SoundManager.sharedInstance.startMenuMusic()
|
SoundManager.sharedInstance.startMenuMusic()
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
EntityManager.sharedInstance.add(Button(name: "StopMovingBackground",
|
entityManager.add(Button(name: "StopMovingBackground",
|
||||||
iconName: "",
|
textureName: "yellow_button04",
|
||||||
text: "MOVE/STOP",
|
text: "MOVE/STOP",
|
||||||
position: CGPoint(x: self.size.width * 0.6, y: self.size.height / 2 - 100),
|
position: CGPoint(x: self.size.width * 0.6, y: self.size.height / 2 - 100),
|
||||||
onButtonPress: {
|
onButtonPress: {
|
||||||
@ -46,7 +48,7 @@ class SettingsScene: SKScene {
|
|||||||
BackgroundComponent.isMovingBackgroundEnabled = true
|
BackgroundComponent.isMovingBackgroundEnabled = true
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
EntityManager.sharedInstance.add(Label(fontnamed: "Courier-Bold",
|
entityManager.add(Label(fontnamed: "Courier-Bold",
|
||||||
name: "SettingsLabel",
|
name: "SettingsLabel",
|
||||||
text: "Settings",
|
text: "Settings",
|
||||||
fontSize: 200.0,
|
fontSize: 200.0,
|
||||||
@ -57,7 +59,7 @@ class SettingsScene: SKScene {
|
|||||||
isAnimationEnabled: true,
|
isAnimationEnabled: true,
|
||||||
isAnimationInfinite: true)
|
isAnimationInfinite: true)
|
||||||
)
|
)
|
||||||
EntityManager.sharedInstance.add(Label(fontnamed: "Courier-Bold",
|
entityManager.add(Label(fontnamed: "Courier-Bold",
|
||||||
name: "LabelMusic",
|
name: "LabelMusic",
|
||||||
text: "Music", fontSize: 50.0,
|
text: "Music", fontSize: 50.0,
|
||||||
fontColor: .black,
|
fontColor: .black,
|
||||||
@ -67,7 +69,7 @@ class SettingsScene: SKScene {
|
|||||||
isAnimationEnabled: true,
|
isAnimationEnabled: true,
|
||||||
isAnimationInfinite: false)
|
isAnimationInfinite: false)
|
||||||
)
|
)
|
||||||
EntityManager.sharedInstance.add(Label(fontnamed: "Courier-Bold",
|
entityManager.add(Label(fontnamed: "Courier-Bold",
|
||||||
name: "LabelBackground",
|
name: "LabelBackground",
|
||||||
text: "Background",
|
text: "Background",
|
||||||
fontSize: 50.0,
|
fontSize: 50.0,
|
||||||
@ -78,16 +80,19 @@ class SettingsScene: SKScene {
|
|||||||
isAnimationEnabled: true,
|
isAnimationEnabled: true,
|
||||||
isAnimationInfinite: false)
|
isAnimationInfinite: false)
|
||||||
)
|
)
|
||||||
EntityManager.sharedInstance.add(Background(size: self.size))
|
entityManager.add(Background(size: self.size))
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadScene(scene: SKScene) {
|
func loadScene(scene: SKScene) {
|
||||||
let transition = SKTransition.flipVertical(withDuration: 0.5)
|
let transition = SKTransition.flipVertical(withDuration: 0.5)
|
||||||
|
entityManager.entities.removeAll()
|
||||||
self.view?.presentScene(scene, transition: transition)
|
self.view?.presentScene(scene, transition: transition)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func update(_ currentTime: TimeInterval) {
|
override func update(_ currentTime: TimeInterval) {
|
||||||
EntityManager.sharedInstance.getBackground()!.update(deltaTime: currentTime)
|
if entityManager.entities.count != 0 {
|
||||||
|
entityManager.getBackground()!.update(deltaTime: currentTime)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|