Compare commits

..

64 Commits

Author SHA1 Message Date
Aldin Duraki
c7d9d63752 Merge branch '90-ueberarbeitung-einzelner-hud-elemente' into 'development'
Resolve "Ueberarbeitung einzelner HUD Elemente"

Closes #90

See merge request marcel.schwarz/software-projekt-2!142
2020-06-26 01:04:08 +00:00
Niko Jochim
568bc14d03 FIX 2020-06-26 03:03:19 +02:00
Niko Jochim
c7aa992790 FIX pauseGame Modal in GameEnd View 2020-06-26 02:55:02 +02:00
Niko Jochim
67c400a069 review changes 2020-06-26 02:44:09 +02:00
Niko Jochim
f689b54989 review changes 2020-06-26 02:18:57 +02:00
Niko Jochim
88ddf07a05 HUD Layout 2020-06-26 01:57:08 +02:00
Niko Jochim
6607d6739b create new finish Button 2020-06-26 01:02:09 +02:00
Niko Jochim
0cf368fef0 add smaller Base Texture for better performance 2020-06-25 23:57:22 +02:00
Aldin Duraki
742123ea63 Merge branch '112-elo-system-report-score-to-all-leaderboards' into 'development'
Resolve "Elo system report score to all leaderboards"

Closes #112

See merge request marcel.schwarz/software-projekt-2!139
2020-06-25 20:18:34 +00:00
43e474467b Introduce error logging for elo system 2020-06-25 21:41:34 +02:00
2d00bc363a New leaderboard for best elo 2020-06-25 21:41:34 +02:00
890d43edca Report scores to multiple leaderboards 2020-06-25 21:41:34 +02:00
Aldin Duraki
528f32f788 Merge branch '37-disconnect-error-handle-events' into 'development'
Resolve "Disconnect Error Handle Events"

Closes #37

See merge request marcel.schwarz/software-projekt-2!134
2020-06-25 19:39:40 +00:00
Aldin Duraki
da4b5cda63 Impl. Heartbeat and DC check 2020-06-25 21:04:59 +02:00
Aldin Duraki
6cfd91b659 Merge branch '114-adjust-menu-scene-for-smaller-ipads' into 'development'
Resolve "Adjust menu scene for smaller iPads"

Closes #114

See merge request marcel.schwarz/software-projekt-2!141
2020-06-25 19:03:31 +00:00
4a3d22596a Fix size of menu scene text and logo 2020-06-25 20:52:22 +02:00
Aldin Duraki
89dc64db27 Merge branch '89-regelwerk' into 'development'
Resolve "Regelwerk"

Closes #89

See merge request marcel.schwarz/software-projekt-2!112
2020-06-25 17:36:44 +00:00
Chauntalle Schüle
d634727a60 deleted print 2020-06-25 19:34:27 +02:00
Aldin Duraki
207315af30 Merge branch '72-spielabbruch-button' into 'development'
Resolve "Spielabbruch Button"

Closes #72

See merge request marcel.schwarz/software-projekt-2!106
2020-06-25 17:33:15 +00:00
Aldin Duraki
86a16c1d78 ... 2020-06-25 19:32:11 +02:00
Chauntalle Schüle
d5d2270b25 Merge branch 'development' into 89-regelwerk 2020-06-25 19:28:15 +02:00
3e35db1d42 Add Verlassen button with modal and end screen 2020-06-25 19:27:13 +02:00
Chauntalle Schüle
f9a14852f5 update Textures 2020-06-25 19:25:21 +02:00
Aldin Duraki
17332f3f54 Merge branch '113-fix-unitlabel-wenn-bei-aktivem-spy-angegriffen-wird' into 'development'
Resolve "Fix unitlabel wenn bei aktivem Spy angegriffen wird"

Closes #113

See merge request marcel.schwarz/software-projekt-2!140
2020-06-25 16:31:01 +00:00
Aldin Duraki
d925369745 Merge branch '100-soundeffekte' into 'development'
Resolve "Soundeffekte"

Closes #100

See merge request marcel.schwarz/software-projekt-2!138
2020-06-25 16:30:25 +00:00
Jakob Haag
880d2ef7c4 Check if the attacked base is an enemy base or not and update the label according to this 2020-06-25 18:28:13 +02:00
Daniel Steckert
51acc34fb2 Remove unnessary code 2020-06-25 18:25:22 +02:00
Daniel Steckert
6930c83918 Remove unnecessary code 2020-06-25 18:15:17 +02:00
Daniel Steckert
58f6032e06 Add possibility to disable sound effects 2020-06-25 17:47:25 +02:00
Daniel Steckert
9b1ff1d4ae Add and trigger sound effects 2020-06-25 17:39:31 +02:00
Aldin Duraki
d189f799ca Merge branch 'revert-soundeffekte' into 'development'
Revert "Merge branch '100-soundeffekte' into 'development'"

See merge request marcel.schwarz/software-projekt-2!136
2020-06-25 14:56:57 +00:00
dd9d91eab8 Fix missing os import and log init 2020-06-25 16:41:27 +02:00
Aldin Duraki
d6627a4872 Merge branch '111-alles-in-deutsch-ubersetzen' into 'development'
Resolve "Alles in Deutsch übersetzen"

Closes #111

See merge request marcel.schwarz/software-projekt-2!135
2020-06-25 14:40:58 +00:00
Jakob Haag
9ff8bcb6e5 Change all english label to german 2020-06-25 16:35:57 +02:00
5e76c68997 Revert "Merge branch '100-soundeffekte' into 'development'"
This reverts commit 5d89636ebd, reversing
changes made to 2b2c86a4de.
2020-06-25 16:29:50 +02:00
Aldin Duraki
49c6017d8a Merge branch '88-cooldown-fur-skills' into 'development'
Resolve "Cooldown für Skills"

Closes #88

See merge request marcel.schwarz/software-projekt-2!123
2020-06-25 13:20:05 +00:00
Aldin Duraki
9b3ca1060e Alpha value fix for buttons 2020-06-25 15:17:24 +02:00
ff2ffc1164 Add skill cooldowns and new skill button assets 2020-06-25 14:59:45 +02:00
Aldin Duraki
26b3b13459 Merge branch '82-status-eines-jeweiligen-settings-sollte-in-den-settings-erkennbar-sein' into 'development'
Resolve "Status eines jeweiligen Settings sollte in den Settings erkennbar sein"

Closes #82

See merge request marcel.schwarz/software-projekt-2!132
2020-06-25 12:44:52 +00:00
127-Z3R0
77ffe9a815 delete unessecary files 2020-06-25 14:42:23 +02:00
127-Z3R0
bf50703b1c Ignore the last two Commits -> stupidy impact
* Access to ButtonNode via Component
* revert work and implement everything needed
2020-06-25 14:39:31 +02:00
127-Z3R0
6970f27a61 Add new Buttons to SettingsScene
* Due to UserDefaults change label by start
* add logging in SoundManager

finish work
2020-06-25 14:20:16 +02:00
127-Z3R0
2f664712d0 Add designated SettingsButton for ButtonNode-Visibility
* modify EntityManager to add SettingsButton
* implement Method to toggle Status on/off
* in the ButtonNode make Label visible to change text after init
2020-06-25 14:19:24 +02:00
Chauntalle Schüle
2d38373590 Merge branch 'development' into 89-regelwerk 2020-06-25 13:12:05 +02:00
Aldin Duraki
1665e3e6f0 Merge branch '109-minuscount-fehler' into 'development'
Resolve "Minuscount Fehler"

Closes #109

See merge request marcel.schwarz/software-projekt-2!131
2020-06-25 10:40:33 +00:00
Aldin Duraki
c344ff82f4 Fix for #109 & #110 2020-06-25 12:39:53 +02:00
Chauntalle Schüle
3b6647b817 added Credits 2020-06-25 12:38:29 +02:00
Chauntalle Schüle
8758246798 Merge branch 'development' into 89-regelwerk 2020-06-25 00:39:54 +02:00
5d89636ebd Merge branch '100-soundeffekte' into 'development'
Resolve "Soundeffekte"

Closes #100

See merge request marcel.schwarz/software-projekt-2!118
2020-06-24 20:06:44 +00:00
5cbe20e6c8 Delete unused sound-file 2020-06-24 22:00:16 +02:00
Daniel Steckert
7e1a80e33a Add logging and remove local references to files 2020-06-24 21:16:16 +02:00
Daniel Steckert
bd1d29d6ac Change sound files and remove sound effect for timer 2020-06-24 21:16:16 +02:00
Daniel Steckert
e53e3953dc Trigger sound effects 2020-06-24 21:16:16 +02:00
Daniel Steckert
6370d40e25 Add soundfiles 2020-06-24 21:16:16 +02:00
Aldin Duraki
2b2c86a4de Merge branch '108-fix-label-wenn-basis-von-2-basen-angegriffen-werden' into 'development'
Resolve "Fix Label wenn Basis von 2 Basen angegriffen werden"

Closes #108

See merge request marcel.schwarz/software-projekt-2!129
2020-06-24 13:15:53 +00:00
13bc1b46d5 Update base label only when was not empty before 2020-06-23 20:52:55 +02:00
d05364708b Use player move type to update unit count label 2020-06-23 20:52:27 +02:00
9a041c7310 Remove unnecessary complexity, Reformat code 2020-06-23 19:59:28 +02:00
Chauntalle Schüle
a52e4cd8d1 changes after review 2020-06-23 18:55:47 +02:00
Chauntalle Schüle
23cd0ade20 changed questionmark asset 2020-06-21 23:25:58 +02:00
Chauntalle Schüle
29adaf14a7 same functionality just cleaned up code 2020-06-20 01:23:19 +02:00
Chauntalle Schüle
b945f1e236 adding all Rules as Textures 2020-06-20 01:11:19 +02:00
Chauntalle Schüle
0985e02c3d Merge branch 'development' into 89-regelwerk 2020-06-19 13:46:36 +02:00
Chauntalle Schüle
e878016e4f - added new asset questionmark
- added new Scene: RulesScene
- added button to menuScene to load RulesScene
- finished layout of RulesScene
- finished rules of Spielbeschreibung
2020-06-19 02:15:51 +02:00
66 changed files with 896 additions and 347 deletions

View File

@ -16,13 +16,16 @@
110360EE244B101B008610AF /* GoldWarsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110360ED244B101B008610AF /* GoldWarsTests.swift */; };
11036113244B3E30008610AF /* MenuScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11036112244B3E30008610AF /* MenuScene.swift */; };
116060F7245C57D2004E5A36 /* EntityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 116060F6245C57D2004E5A36 /* EntityManager.swift */; };
20F1990724A4FAC1004B7A30 /* new_round.wav in Resources */ = {isa = PBXBuildFile; fileRef = 20F1990424A4FAC1004B7A30 /* new_round.wav */; };
20F1990824A4FAC1004B7A30 /* use_boost.wav in Resources */ = {isa = PBXBuildFile; fileRef = 20F1990524A4FAC1004B7A30 /* use_boost.wav */; };
20F1990924A4FAC1004B7A30 /* attack_base.wav in Resources */ = {isa = PBXBuildFile; fileRef = 20F1990624A4FAC1004B7A30 /* attack_base.wav */; };
3E67854024728368007B9DE4 /* CElements.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E67853F24728368007B9DE4 /* CElements.swift */; };
3E6785422472CBEC007B9DE4 /* Way.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E6785412472CBEC007B9DE4 /* Way.swift */; };
3EAD889524801B6A0048A10A /* RoundTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EAD889424801B6A0048A10A /* RoundTimer.swift */; };
3EBD242E245D9332003CECE7 /* Team.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EBD242D245D9332003CECE7 /* Team.swift */; };
3F745DF0246F48FC00CE7375 /* PlayerMoveType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F745DEF246F48FC00CE7375 /* PlayerMoveType.swift */; };
3F79FFE02486F7CD003F79C3 /* Explosion.sks in Resources */ = {isa = PBXBuildFile; fileRef = 3F79FFDF2486F7CD003F79C3 /* Explosion.sks */; };
3FE19DB5246C7A22004827AB /* RoundCalculatorService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FE19DB4246C7A22004827AB /* RoundCalculatorService.swift */; };
8B9CA5F1249A3C2E00561704 /* SkillButtonNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B9CA5F0249A3C2E00561704 /* SkillButtonNode.swift */; };
8BB6FF402472B8F000162BBD /* SingeClickButtonNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8BB6FF3F2472B8F000162BBD /* SingeClickButtonNode.swift */; };
9E0E459724796262009817A6 /* GameCenterManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E0E459624796262009817A6 /* GameCenterManager.swift */; };
9E11FF79245CD81100EED3BE /* Fire.sks in Resources */ = {isa = PBXBuildFile; fileRef = 9E11FF77245CD81100EED3BE /* Fire.sks */; };
@ -47,16 +50,14 @@
AB671B252494ECF0003FBE8D /* EloHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB671B242494ECF0003FBE8D /* EloHelper.swift */; };
ABA03DA0244BD54F00A66916 /* Base.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABA03D9F244BD54F00A66916 /* Base.swift */; };
ABC0C3732481509300387B8F /* MapUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABC0C3722481509300387B8F /* MapUtils.swift */; };
AE0C8E2F249BCC2A00996360 /* RulesScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE0C8E2E249BCC2A00996360 /* RulesScene.swift */; };
C04783EE2468583F004961FB /* intro-music.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = C04783ED2468583F004961FB /* intro-music.mp3 */; };
C04783F024685995004961FB /* SettingsScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = C04783EF24685995004961FB /* SettingsScene.swift */; };
C04E26D5249BEBB0003B9E51 /* AppUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = C04E26D4249BEBB0003B9E51 /* AppUpdater.swift */; };
C05BB9C4247D890C00411249 /* SliderComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C05BB9C3247D890C00411249 /* SliderComponent.swift */; };
C05FAED62468559D0006AF2E /* SoundManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C05FAED52468559D0006AF2E /* SoundManager.swift */; };
C064E9A8246C0EA50022B228 /* LabelNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = C064E9A7246C0EA50022B228 /* LabelNode.swift */; };
C064E9AA246C114C0022B228 /* LabelComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C064E9A9246C114C0022B228 /* LabelComponent.swift */; };
C064E9AC246C151F0022B228 /* Label.swift in Sources */ = {isa = PBXBuildFile; fileRef = C064E9AB246C151F0022B228 /* Label.swift */; };
C06C71DD249BC74D00B2D63C /* AppUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = C06C71DC249BC74D00B2D63C /* AppUpdater.swift */; };
C06C71DF249BDADF00B2D63C /* UpdatePopUp.swift in Sources */ = {isa = PBXBuildFile; fileRef = C06C71DE249BDADF00B2D63C /* UpdatePopUp.swift */; };
C099579C246C5E5C0016AA22 /* DataService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C099579B246C5E5C0016AA22 /* DataService.swift */; };
/* End PBXBuildFile section */
@ -84,13 +85,16 @@
110360EF244B101B008610AF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
11036112244B3E30008610AF /* MenuScene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuScene.swift; sourceTree = "<group>"; };
116060F6245C57D2004E5A36 /* EntityManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntityManager.swift; sourceTree = "<group>"; };
20F1990424A4FAC1004B7A30 /* new_round.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = new_round.wav; sourceTree = "<group>"; };
20F1990524A4FAC1004B7A30 /* use_boost.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = use_boost.wav; sourceTree = "<group>"; };
20F1990624A4FAC1004B7A30 /* attack_base.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = attack_base.wav; sourceTree = "<group>"; };
3E67853F24728368007B9DE4 /* CElements.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CElements.swift; sourceTree = "<group>"; };
3E6785412472CBEC007B9DE4 /* Way.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Way.swift; sourceTree = "<group>"; };
3EAD889424801B6A0048A10A /* RoundTimer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoundTimer.swift; sourceTree = "<group>"; };
3EBD242D245D9332003CECE7 /* Team.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Team.swift; sourceTree = "<group>"; };
3F745DEF246F48FC00CE7375 /* PlayerMoveType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerMoveType.swift; sourceTree = "<group>"; };
3F79FFDF2486F7CD003F79C3 /* Explosion.sks */ = {isa = PBXFileReference; lastKnownFileType = file.sks; path = Explosion.sks; sourceTree = "<group>"; };
3FE19DB4246C7A22004827AB /* RoundCalculatorService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoundCalculatorService.swift; sourceTree = "<group>"; };
8B9CA5F0249A3C2E00561704 /* SkillButtonNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkillButtonNode.swift; sourceTree = "<group>"; };
8BB6FF3F2472B8F000162BBD /* SingeClickButtonNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingeClickButtonNode.swift; sourceTree = "<group>"; };
9E0E459624796262009817A6 /* GameCenterManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameCenterManager.swift; sourceTree = "<group>"; };
9E11FF77245CD81100EED3BE /* Fire.sks */ = {isa = PBXFileReference; lastKnownFileType = file.sks; path = Fire.sks; sourceTree = "<group>"; };
@ -116,16 +120,14 @@
AB671B242494ECF0003FBE8D /* EloHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EloHelper.swift; sourceTree = "<group>"; };
ABA03D9F244BD54F00A66916 /* Base.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Base.swift; sourceTree = "<group>"; };
ABC0C3722481509300387B8F /* MapUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapUtils.swift; sourceTree = "<group>"; };
AE0C8E2E249BCC2A00996360 /* RulesScene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RulesScene.swift; sourceTree = "<group>"; };
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>"; };
C04E26D4249BEBB0003B9E51 /* AppUpdater.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AppUpdater.swift; path = GoldWars/AppUpdater.swift; sourceTree = SOURCE_ROOT; };
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>"; };
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>"; };
C064E9AB246C151F0022B228 /* Label.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Label.swift; sourceTree = "<group>"; };
C06C71DC249BC74D00B2D63C /* AppUpdater.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppUpdater.swift; sourceTree = "<group>"; };
C06C71DE249BDADF00B2D63C /* UpdatePopUp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdatePopUp.swift; sourceTree = "<group>"; };
C099579B246C5E5C0016AA22 /* DataService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataService.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
@ -155,7 +157,6 @@
110360EC244B101B008610AF /* GoldWarsTests */,
110360D0244B101A008610AF /* Products */,
9E78ACB4245C9A5300526FF7 /* Frameworks */,
C04E26D3249BEB73003B9E51 /* Recovered References */,
);
sourceTree = "<group>";
};
@ -172,6 +173,9 @@
isa = PBXGroup;
children = (
C04783ED2468583F004961FB /* intro-music.mp3 */,
20F1990624A4FAC1004B7A30 /* attack_base.wav */,
20F1990424A4FAC1004B7A30 /* new_round.wav */,
20F1990524A4FAC1004B7A30 /* use_boost.wav */,
9ECD3699245C91F7008DEEBD /* GoldWars.entitlements */,
9E11FF74245CD79100EED3BE /* Partikels */,
116060F5245C5709004E5A36 /* Entities */,
@ -192,7 +196,7 @@
C04783EF24685995004961FB /* SettingsScene.swift */,
3EAD889424801B6A0048A10A /* RoundTimer.swift */,
AB671B242494ECF0003FBE8D /* EloHelper.swift */,
C04E26D4249BEBB0003B9E51 /* AppUpdater.swift */,
AE0C8E2E249BCC2A00996360 /* RulesScene.swift */,
);
path = GoldWars;
sourceTree = "<group>";
@ -218,6 +222,7 @@
C064E9A7246C0EA50022B228 /* LabelNode.swift */,
9EC2FBA62476B1EC00ABF11F /* PlayerInfoComponent.swift */,
8BB6FF3F2472B8F000162BBD /* SingeClickButtonNode.swift */,
8B9CA5F0249A3C2E00561704 /* SkillButtonNode.swift */,
C05BB9C3247D890C00411249 /* SliderComponent.swift */,
9EC7E48A2461FBF700396BCD /* SliderNode.swift */,
9E78ACB7245CB75B00526FF7 /* TeamComponent.swift */,
@ -238,7 +243,6 @@
9EEDE02C246FCD770096C735 /* SpinningLogoEntity.swift */,
3E6785412472CBEC007B9DE4 /* Way.swift */,
C064E9AB246C151F0022B228 /* Label.swift */,
C06C71DE249BDADF00B2D63C /* UpdatePopUp.swift */,
);
path = Entities;
sourceTree = "<group>";
@ -265,7 +269,6 @@
isa = PBXGroup;
children = (
3EBD242D245D9332003CECE7 /* Team.swift */,
3F745DEF246F48FC00CE7375 /* PlayerMoveType.swift */,
);
path = Enums;
sourceTree = "<group>";
@ -298,14 +301,6 @@
path = Map;
sourceTree = "<group>";
};
C04E26D3249BEB73003B9E51 /* Recovered References */ = {
isa = PBXGroup;
children = (
C06C71DC249BC74D00B2D63C /* AppUpdater.swift */,
);
name = "Recovered References";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@ -388,10 +383,13 @@
buildActionMask = 2147483647;
files = (
110360DE244B101A008610AF /* Main.storyboard in Resources */,
20F1990924A4FAC1004B7A30 /* attack_base.wav in Resources */,
9E11FF79245CD81100EED3BE /* Fire.sks in Resources */,
20F1990724A4FAC1004B7A30 /* new_round.wav in Resources */,
110360E0244B101B008610AF /* Assets.xcassets in Resources */,
110360E3244B101B008610AF /* LaunchScreen.storyboard in Resources */,
9E61EAC4249BAC9100334DDE /* LoserFire.sks in Resources */,
20F1990824A4FAC1004B7A30 /* use_boost.wav in Resources */,
C04783EE2468583F004961FB /* intro-music.mp3 in Resources */,
3F79FFE02486F7CD003F79C3 /* Explosion.sks in Resources */,
);
@ -416,7 +414,6 @@
3FE19DB5246C7A22004827AB /* RoundCalculatorService.swift in Sources */,
9EC239E1246878A900952F74 /* MultiplayerNetwork.swift in Sources */,
9EA3ABEB245C6DFA006BC61D /* BaseNode.swift in Sources */,
C04E26D5249BEBB0003B9E51 /* AppUpdater.swift in Sources */,
3E6785422472CBEC007B9DE4 /* Way.swift in Sources */,
110360D9244B101A008610AF /* GameScene.swift in Sources */,
C04783F024685995004961FB /* SettingsScene.swift in Sources */,
@ -436,10 +433,10 @@
9E174C8A245E1A0A00209FF0 /* Background.swift in Sources */,
8BB6FF402472B8F000162BBD /* SingeClickButtonNode.swift in Sources */,
C064E9A8246C0EA50022B228 /* LabelNode.swift in Sources */,
3F745DF0246F48FC00CE7375 /* PlayerMoveType.swift in Sources */,
8B9CA5F1249A3C2E00561704 /* SkillButtonNode.swift in Sources */,
3EAD889524801B6A0048A10A /* RoundTimer.swift in Sources */,
AE0C8E2F249BCC2A00996360 /* RulesScene.swift in Sources */,
3E67854024728368007B9DE4 /* CElements.swift in Sources */,
C06C71DD249BC74D00B2D63C /* AppUpdater.swift in Sources */,
ABA03DA0244BD54F00A66916 /* Base.swift in Sources */,
C064E9AC246C151F0022B228 /* Label.swift in Sources */,
ABC0C3732481509300387B8F /* MapUtils.swift in Sources */,
@ -448,7 +445,6 @@
9E61EAC7249BB61A00334DDE /* SpinningLogo3DNode.swift in Sources */,
9E174C84245DD8CE00209FF0 /* Button.swift in Sources */,
110360DB244B101A008610AF /* GameViewController.swift in Sources */,
C06C71DF249BDADF00B2D63C /* UpdatePopUp.swift in Sources */,
C05BB9C4247D890C00411249 /* SliderComponent.swift in Sources */,
110360D3244B101A008610AF /* AppDelegate.swift in Sources */,
9EC86B9F245C88A300796EF3 /* Modal.swift in Sources */,
@ -615,14 +611,14 @@
CODE_SIGN_ENTITLEMENTS = GoldWars/GoldWars.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
CURRENT_PROJECT_VERSION = 4;
DEVELOPMENT_TEAM = DDKFQG46BQ;
INFOPLIST_FILE = GoldWars/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.1;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = de.hft.stuttgart.ip2.goldwars;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -638,14 +634,14 @@
CODE_SIGN_ENTITLEMENTS = GoldWars/GoldWars.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
CURRENT_PROJECT_VERSION = 4;
DEVELOPMENT_TEAM = DDKFQG46BQ;
INFOPLIST_FILE = GoldWars/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.1;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = de.hft.stuttgart.ip2.goldwars;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";

View File

@ -1,83 +0,0 @@
//
// AppUpdater.swift
// GoldWars
//
// Created by Tim Herbst on 18.06.20.
// Copyright © 2020 SP2. All rights reserved.
//
import GameKit
enum VersionError: Error {
case invalidBundleInfo, invalidResponse
}
class LookupResult: Decodable {
var results: [AppInfo]
}
class AppInfo: Decodable {
var version: String
var trackViewUrl: String
}
class AppUpdater: NSObject {
static var appStoreUrl = ""
static let appUpdaterInstance = AppUpdater()
var entityManager = EntityManager.menuEMInstance
private func getAppInfo(completion: @escaping (AppInfo?, Error?) -> Void) -> URLSessionTask? {
guard let identifier = Bundle.main.infoDictionary!["CFBundleIdentifier"] as? String,
let url = URL(string: "http://itunes.apple.com/lookup?bundleId=\(identifier)") else {
DispatchQueue.main.async {
completion(nil, VersionError.invalidBundleInfo)
}
return nil
}
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
do {
if error != nil { throw error! }
guard let data = data else { throw VersionError.invalidResponse }
print("Data: ", data)
print("response: ", response!)
let result = try JSONDecoder().decode(LookupResult.self, from: data)
let dictionary = try JSONSerialization.jsonObject(with: data, options: .mutableLeaves)
print("dictionary: ", dictionary)
guard let info = result.results.first else { throw VersionError.invalidResponse }
print("result: ", result)
completion(info, nil)
} catch {
completion(nil, error)
}
}
task.resume()
print("task***",task)
return task
}
func checkVersion() -> Bool {
let info = Bundle.main.infoDictionary
let currentVersion = info?["CFBundleShortVersionString"] as? String
var appStoreVersion: AppInfo
var isUpToDate = true
_ = getAppInfo{ (info, error) in
appStoreVersion = info!.version
print("info-version", info?.version)
if let error = error {
print("error: ",error)
}
}
print("currentVersion", currentVersion)
print("appStoreVersion", appStoreVersion)
if !(currentVersion == appStoreVersion) {
isUpToDate = false
}
print("isUptoDate", isUpToDate)
return isUpToDate
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View File

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

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 997 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -1,7 +1,7 @@
{
"images" : [
{
"filename" : "gold_button_3.png",
"filename" : "gold_button_4.png",
"idiom" : "universal",
"scale" : "1x"
},

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

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

View File

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

View File

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

View File

@ -17,18 +17,19 @@ class EloHelper {
static private let LOG = OSLog.init(subsystem: "EloHelper", category: "EloHelper")
static let IDENTIFIER = "de.hft.stuttgart.ip2.goldwars.matchmaking"
static let IDENTIFIER_ALL_ELO = "de.hft.stuttgart.ip2.goldwars.bestelo"
static let IDENTIFIER_ELO = "de.hft.stuttgart.ip2.goldwars.matchmaking"
static func updateEloScore(winner: GKPlayer, hatDenNikoGemacht looser: GKPlayer) {
let leaderboard = GKLeaderboard.init(players: [winner, looser])
leaderboard.identifier = EloHelper.IDENTIFIER
leaderboard.identifier = EloHelper.IDENTIFIER_ELO
leaderboard.loadScores{scores, error in
// Get Scores
let R_looser = scores?.filter { $0.player == looser }.first ?? GKScore(leaderboardIdentifier: EloHelper.IDENTIFIER, player: looser)
let R_winner = scores?.filter { $0.player == winner }.first ?? GKScore(leaderboardIdentifier: EloHelper.IDENTIFIER, player: winner)
let R_looser = scores?.filter { $0.player == looser }.first ?? GKScore(leaderboardIdentifier: EloHelper.IDENTIFIER_ELO, player: looser)
let R_winner = scores?.filter { $0.player == winner }.first ?? GKScore(leaderboardIdentifier: EloHelper.IDENTIFIER_ELO, player: winner)
// Calc ELO
let Q_looser = pow(10.0, Double(R_looser.value) / 400.0)
@ -40,21 +41,30 @@ class EloHelper {
let R_looser_new = Int64(Double(R_looser.value) + 10.0 * (0.0 - E_looser))
// Update Elo on leaderboard
let winner_new = GKScore(leaderboardIdentifier: EloHelper.IDENTIFIER, player: winner)
let winner_new = GKScore(leaderboardIdentifier: EloHelper.IDENTIFIER_ELO, player: winner)
winner_new.value = R_winner_new
let looser_new = GKScore(leaderboardIdentifier: EloHelper.IDENTIFIER, player: looser)
let looser_new = GKScore(leaderboardIdentifier: EloHelper.IDENTIFIER_ELO, player: looser)
looser_new.value = R_looser_new
let scoreForPeer = winner == GameCenterManager.sharedInstance.localPlayer ? looser_new : winner_new
let scoreForHost = winner == GameCenterManager.sharedInstance.localPlayer ? winner_new : looser_new
MultiplayerNetwork.sharedInstance.sendEloData(scoreToReport: scoreForPeer)
GKScore.report([scoreForHost], withCompletionHandler: { error in
os_log("New Scores reported to EloSystem", log: LOG, type: .info)
})
reportScore(score: scoreForHost.value)
}
}
static func reportScore(score: Int64) {
let gkScoreElo = GKScore(leaderboardIdentifier: EloHelper.IDENTIFIER_ELO, player: GKLocalPlayer.local)
gkScoreElo.value = score
let gkScoreAll = GKScore(leaderboardIdentifier: EloHelper.IDENTIFIER_ALL_ELO, player: GKLocalPlayer.local)
gkScoreAll.value = score
GKScore.report([gkScoreAll, gkScoreElo], withCompletionHandler: { error in
if error != nil {
os_log("Could not report %@", log: LOG, type: .error, error!.localizedDescription)
} else {
os_log("New Scores reported to EloSystem", log: self.LOG, type: .info)
}
})
}
}

View File

@ -42,20 +42,24 @@ class Base: GKEntity{
}
}
func doPlayerMoveTypeToBase(base: Base, playerMoveType: PlayerMoveType, units: Int) -> [GKEntity]{
func doPlayerMoveTypeToBase(base: Base, units: Int) -> [GKEntity]{
if base.ownershipPlayer != GKLocalPlayer.local {
base.changeOwnership = true
}
self.unitCount -= units
base.unitCount += units
self.component(ofType: TeamComponent.self)?.unitcountLabel.text = "\(self.unitCount)"
if base.ownershipPlayer == GKLocalPlayer.local {
if base.component(ofType: TeamComponent.self)?.unitcountLabel.text != "" {
if base.ownershipPlayer != self.ownershipPlayer {
base.component(ofType: TeamComponent.self)?.unitcountLabel.text = "\(abs(base.unitCount - units * 2))"
} else {
base.component(ofType: TeamComponent.self)?.unitcountLabel.text = "\(base.unitCount)"
}
base.ownershipPlayer = self.ownershipPlayer
}
DataService.sharedInstance.addMove(playerMove: PlayerMove(fromBase: self.baseID,
toBase: base.baseID,
unitCount: units * playerMoveType.rawValue)
unitCount: units)
)
return [self, base]
}

View File

@ -15,6 +15,7 @@ class EntityManager {
static let gameEMInstance = EntityManager()
static let menuEMInstance = EntityManager()
static let settingsEMInstance = EntityManager()
static let rulesEMInstance = EntityManager()
var entities = Set<GKEntity>()
var scene: SKScene
@ -43,16 +44,12 @@ class EntityManager {
isModal = true
}
if let updateEntity = entity as? UpdatePopUp {
scene.addChild(updateEntity.background)
scene.addChild(updateEntity.message)
}
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.leaveGame)
scene.addChild(hudEntitiy.defSkill)
scene.addChild(hudEntitiy.atkSkill)
scene.addChild(hudEntitiy.spySkill)
@ -137,6 +134,7 @@ class EntityManager {
scene.addChild(spriteNode.unitcountLabel)
scene.addChild(spriteNode.fire)
}
SoundManager.sharedInstance.playSoundEffect(pathToFile: "attack_base",fileExtension: "wav",volumeLevel: -3.0)
}
GameCenterManager.sharedInstance.addAchievementProgress(identifier: "de.hft.stuttgart.ip2.goldwars.capture.fifty.bases", increasePercentComplete: 2)
}
@ -297,6 +295,11 @@ class EntityManager {
return entities.filter{$0 is Button && ($0 as! Button).name == buttonName }[0] as! Button
}
func changeSettingsButtonText(buttonName: String, text: String) {
let button = entities.filter{$0 is Button && ($0 as! Button).name == buttonName }[0] as! Button
button.component(ofType: ButtonComponent.self)?.buttonNode.label.text = text
}
func getHUD() -> HUD? {
return entities.filter{$0 is HUD}.first as? HUD
}
@ -351,18 +354,20 @@ class EntityManager {
button.buttonNode.removeFromParent()
}
self.remove(modal)
for child in scene.children {
if(child.name != "fire"){
child.alpha = 1
}
}
isModal = false
}
})
}
func exitToMenu() {
GameCenterManager.sharedInstance.reset()
EntityManager.gameEMInstance.getTimer()?.stopTimer()
RoundCalculatorService.sharedInstance.currentRound = 1
EntityManager.gameEMInstance.scene.view?.presentScene(EntityManager.menuEMInstance.scene)
EntityManager.gameEMInstance.entities.removeAll()
EntityManager.gameEMInstance.scene.removeFromParent()
}
func getTimer() -> RoundTimer? {
return getHUD()?.roundTimer
}

View File

@ -18,9 +18,11 @@ class HUD: GKEntity {
var peerLabel:SKLabelNode
var peerUnitsLabel:SKLabelNode
var spySkill: SingeClickButtonNode
var defSkill: SingeClickButtonNode
var atkSkill: SingeClickButtonNode
var leaveGame: ButtonNode
var spySkill: SkillButtonNode
var defSkill: SkillButtonNode
var atkSkill: SkillButtonNode
var roundTimerLabel: SKLabelNode
let roundTimer: RoundTimer
@ -50,53 +52,63 @@ class HUD: GKEntity {
self.roundTimer = RoundTimer()
spySkill = SingeClickButtonNode(
textureName: "yellow_circle",
text: "Spy",
finishButton = SingeClickButtonNode(
textureName: "finish_button",
text: "",
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: TeamComponent.self)?.unitcountLabel.text = "\(base.unitCount)"})
GameCenterManager.sharedInstance.addAchievementProgress(identifier: "de.hft.stuttgart.ip2.goldwars.skill.first.time", increasePercentComplete: 100)
GameCenterManager.sharedInstance.addAchievementProgress(identifier: "de.hft.stuttgart.ip2.goldwars.skill.spy.ten", increasePercentComplete: 10)
}
position: CGPoint(
x: EntityManager.gameEMInstance.scene.size.width * 0.95 ,
y: EntityManager.gameEMInstance.scene.size.height * 0.1),
onButtonPress: { }
)
defSkill = SingeClickButtonNode(
textureName: "yellow_circle",
leaveGame = ButtonNode(textureName: "exitButton", text: "" , isEnabled: true, position: CGPoint(x: EntityManager.gameEMInstance.scene.size.width * 0.05, y: EntityManager.gameEMInstance.scene.size.height * 0.11), onButtonPress: {
EntityManager.gameEMInstance.add(Modal(modaltype: .QuitGame, base: nil, anchorPoint: CGPoint(x: EntityManager.gameEMInstance.scene.size.width / 2 , y: EntityManager.gameEMInstance.scene.size.height / 2), gameScene: EntityManager.gameEMInstance.scene, currentDraggedBase: nil, touchLocation: nil, collisionBase: nil))
})
leaveGame.size = CGSize(width: 120, height: 120);
defSkill = SkillButtonNode(
textureName: "def_button",
text: "Def",
isEnabled: true,
position: CGPoint(x: EntityManager.gameEMInstance.scene.size.width * 0.85, y: EntityManager.gameEMInstance.scene.size.height * 0.1),
cooldown: 4,
position: CGPoint(x: finishButton.position.x - 85, y: finishButton.position.y),
onButtonPress: {
DataService.sharedInstance.localRoundData.hasDefenceBoost = true
GameCenterManager.sharedInstance.addAchievementProgress(identifier: "de.hft.stuttgart.ip2.goldwars.skill.first.time", increasePercentComplete: 100)
GameCenterManager.sharedInstance.addAchievementProgress(identifier: "de.hft.stuttgart.ip2.goldwars.skill.def.ten", increasePercentComplete: 10)
SoundManager.sharedInstance.playSoundEffect(pathToFile: "use_boost",fileExtension: "wav",volumeLevel: 0.0)
}
)
atkSkill = SingeClickButtonNode(
textureName: "yellow_circle",
spySkill = SkillButtonNode(
textureName: "spy_button",
text: "Spy",
isEnabled: true,
cooldown: 3,
position: CGPoint(x: defSkill.position.x - 85, y: defSkill.position.y),
onButtonPress: {
EntityManager.gameEMInstance.getOpponentBases(for: EntityManager.gameEMInstance.getTeam()).forEach({base in base.component(ofType: TeamComponent.self)?.unitcountLabel.text = "\(base.unitCount)"})
GameCenterManager.sharedInstance.addAchievementProgress(identifier: "de.hft.stuttgart.ip2.goldwars.skill.first.time", increasePercentComplete: 100)
GameCenterManager.sharedInstance.addAchievementProgress(identifier: "de.hft.stuttgart.ip2.goldwars.skill.spy.ten", increasePercentComplete: 10)
SoundManager.sharedInstance.playSoundEffect(pathToFile: "use_boost",fileExtension: "wav",volumeLevel: 0.0)
}
)
atkSkill = SkillButtonNode(
textureName: "atk_button",
text: "Atk",
isEnabled: true,
position: CGPoint(x: EntityManager.gameEMInstance.scene.size.width * 0.95, y: EntityManager.gameEMInstance.scene.size.height * 0.1),
cooldown: 4,
position: CGPoint(x: spySkill.position.x - 85, y: spySkill.position.y),
onButtonPress: {
DataService.sharedInstance.localRoundData.hasAttackBoost = true
GameCenterManager.sharedInstance.addAchievementProgress(identifier: "de.hft.stuttgart.ip2.goldwars.skill.first.time", increasePercentComplete: 100)
GameCenterManager.sharedInstance.addAchievementProgress(identifier: "de.hft.stuttgart.ip2.goldwars.skill.atk.ten", increasePercentComplete: 10)
SoundManager.sharedInstance.playSoundEffect(pathToFile: "use_boost",fileExtension: "wav",volumeLevel: 0.0)
}
)
finishButton = 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.size = CGSize(width: 100, height: 100)
finishButton.zPosition = 2
backgroundRoundCounter = SKSpriteNode(texture: SKTexture(imageNamed: "roundInfo_texture"))
backgroundRoundCounter = SKSpriteNode(texture: SKTexture(imageNamed: "roundInfoTexture"))
currentRoundLabel = SKLabelNode(fontNamed: "Courier-Bold")
roundsLabel = SKLabelNode(fontNamed: "Courier-Bold")
roundLabel = SKLabelNode(fontNamed: "Courier-Bold")
@ -107,7 +119,6 @@ class HUD: GKEntity {
blockWholeScreenPane.isHidden = true
super.init()
initRoundInfo(size: size)
finishButton.onButtonPress = { [unowned self] in
self.finishRound()
}
@ -119,7 +130,6 @@ class HUD: GKEntity {
hostUnitsLabel.position = CGPoint(x: size.width * 0.05, y: size.height * 0.9)
peerUnitsLabel.position = CGPoint(x: size.width * 0.95, y: size.height * 0.9)
setColor(labelNodes: [hostLabel,hostUnitsLabel,peerLabel,peerUnitsLabel])
roundTimer.initTimer()
startWithDuration()
}
@ -142,7 +152,7 @@ class HUD: GKEntity {
func startWithDuration(){
roundTimer.startTimer()
finishButton.isEnabled = true
self.roundTimer.roundEnded = "Syncing"
self.roundTimer.roundEnded = "Berechnung"
RoundCalculatorService.sharedInstance.isCalculating = false
blockWholeScreenPane.isHidden = true
}
@ -150,29 +160,29 @@ class HUD: GKEntity {
func finishRound() -> () {
self.blockWholeScreenPane.isHidden = false
self.roundTimer.timeLeft = 1;
self.roundTimer.roundEnded = "Waiting for other player..."
self.roundTimer.roundEnded = "Warte auf Gegner..."
}
func initRoundInfo(size: CGSize) -> () {
backgroundRoundCounter.zPosition = 2
backgroundRoundCounter.position = CGPoint(x: Double(size.width) * 0.06, y: Double(size.height) * 0.08)
backgroundRoundCounter.position = CGPoint(x: leaveGame.position.x + 63, y: leaveGame.position.y)
backgroundRoundCounter.size = CGSize(width: 120, height: 120)
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.position = CGPoint(x: backgroundRoundCounter.position.x, y: backgroundRoundCounter.position.y - 4)
currentRoundLabel.zPosition = backgroundRoundCounter.zPosition + 1
roundsLabel.zPosition = backgroundRoundCounter.zPosition + 1
roundsLabel.text = "of \(RoundCalculatorService.sharedInstance.MAX_ROUNDS)"
roundsLabel.text = "von \(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.text = "Runde"
roundLabel.fontColor = SKColor.black
roundLabel.verticalAlignmentMode = .center
roundLabel.fontSize = 12
@ -186,5 +196,13 @@ class HUD: GKEntity {
SKAction.scale(by: 0.5, duration: 1),
])
currentRoundLabel.run(newRoundAction)
SoundManager.sharedInstance.playSoundEffect(pathToFile: "new_round", fileExtension: "wav", volumeLevel: 0.0)
self.decreaseSkillRoundCooldownCounter()
}
func decreaseSkillRoundCooldownCounter() {
self.spySkill.decreaseCooldown()
self.atkSkill.decreaseCooldown()
self.defSkill.decreaseCooldown()
}
}

View File

@ -12,6 +12,7 @@ enum ModalType: String {
case BaseAttack
case BaseMoveOwnUnits
case PauseGame
case QuitGame
}
class Modal: GKEntity{
@ -26,7 +27,7 @@ class Modal: GKEntity{
var overlay: SKSpriteNode
var type: ModalType
init(modaltype: ModalType, base: Base?, anchorPoint: CGPoint, gameScene: GameScene, currentDraggedBase: Base?, touchLocation: CGPoint?, collisionBase: Base?) {
init(modaltype: ModalType, base: Base?, anchorPoint: CGPoint, gameScene: SKScene, currentDraggedBase: Base?, touchLocation: CGPoint?, collisionBase: Base?) {
self.type = modaltype
unitCount = 0
if base != nil {
@ -61,9 +62,13 @@ class Modal: GKEntity{
footer = SKLabelNode()
case .PauseGame:
header = SKLabelNode(text: "Pause")
body = SKLabelNode(text: "Waiting for player to reconnect")
body = SKLabelNode(text: "Warte auf Gegner...")
footer = SKLabelNode()
closeButton.zPosition = -1
case .QuitGame:
header = SKLabelNode(text: "Spiel verlassen")
body = SKLabelNode(text: "Sicher verlassen?")
footer = SKLabelNode()
}
self.header.position = CGPoint(x: anchorPoint.x, y: anchorPoint.y + 90)
@ -86,13 +91,25 @@ class Modal: GKEntity{
super.init()
switch modaltype {
case .BaseAttack, .BaseMoveOwnUnits:
let text = (modaltype == .BaseAttack) ? "Angriff" : "Senden"
addComponent(SliderComponent(width: 300, position: CGPoint(x: anchorPoint.x , y: anchorPoint.y - 15)))
addComponent(ButtonComponent(textureName: "yellow_button04", text: text, position: CGPoint(x: anchorPoint.x , y: anchorPoint.y - 95), isEnabled: true, onButtonPress: {
self.sendUnits(currentDraggedBase: currentDraggedBase, touchLocation: touchLocation!, gameScene: gameScene, collisionBase: collisionBase)
EntityManager.gameEMInstance.removeModal()
}))
case .QuitGame:
addComponent(ButtonComponent(textureName: "yellow_button04", text: "Verlassen", position: CGPoint(x: anchorPoint.x , y: anchorPoint.y - 95), isEnabled: true, onButtonPress: {
EntityManager.gameEMInstance.removeModal()
GameCenterManager.sharedInstance.sendStateToPeers(state: State(state: 6))
GameCenterManager.sharedInstance.opponentQuit = false
GameCenterManager.sharedInstance.quitGame = true
}))
case .PauseGame:
break
}
}
@ -108,11 +125,11 @@ class Modal: GKEntity{
}
}
func sendUnits(currentDraggedBase: Base?, touchLocation: CGPoint, gameScene: GameScene, collisionBase: Base?){
func sendUnits(currentDraggedBase: Base?, touchLocation: CGPoint, gameScene: SKScene, collisionBase: Base?){
for base in currentDraggedBase!.adjacencyList {
if base == collisionBase {
RoundCalculatorService.sharedInstance.increaseMoveCounter(ownBase: currentDraggedBase?.ownershipPlayer == base.ownershipPlayer)
entityManager.update((currentDraggedBase?.doPlayerMoveTypeToBase(base: base, playerMoveType: PlayerMoveType.AtkMove, units: Int(GameScene.sendUnits)))!)
entityManager.update((currentDraggedBase?.doPlayerMoveTypeToBase(base: base, units: Int(GameScene.sendUnits)))!)
GameScene.sendUnits = 0
}
}

View File

@ -9,29 +9,26 @@
import Foundation
import GameplayKit
class SpinningLogoEntity: GKEntity {
class SpinningLogoEntity : GKEntity {
let spinningLogoNode : SpinningLogo3DNode
let goldLetteringNode : SKSpriteNode
let warsLetteringNode : SKSpriteNode
let spinningLogoNode: SpinningLogo3DNode
let goldLetteringNode: SKSpriteNode
let warsLetteringNode: SKSpriteNode
init(sceneSize size: CGSize) {
spinningLogoNode = SpinningLogo3DNode()
let midX = size.width / 2
let midY = size.height / 2
goldLetteringNode = SKSpriteNode(texture: SKTexture(imageNamed: "goldLettering"))
goldLetteringNode.position = CGPoint(x: midX, y: midY);
goldLetteringNode.size = CGSize(width: 675, height: 284)
goldLetteringNode.position = CGPoint(x: midX , y: midY + 280);
goldLetteringNode.size = CGSize(width: 675, height: 284)
goldLetteringNode.position = CGPoint(x: size.width / 2 , y: size.height * 0.83)
goldLetteringNode.size = CGSize(width: size.width / 2.02, height: size.height / 3.6)
warsLetteringNode = SKSpriteNode(texture: SKTexture(imageNamed: "warsLettering"))
warsLetteringNode.position = CGPoint(x: midX, y: midY - 300);
warsLetteringNode.size = CGSize(width: 700, height: 284)
warsLetteringNode.position = CGPoint(x: size.width / 2, y: size.height * 0.17)
warsLetteringNode.size = CGSize(width: size.width / 2.02, height: size.height / 3.6)
spinningLogoNode.viewportSize = CGSize(width: 200, height: 200)
spinningLogoNode = SpinningLogo3DNode()
spinningLogoNode.viewportSize = CGSize(width: size.width / 5.12 * 0.69, height: size.height / 3.84 * 0.69)
spinningLogoNode.zPosition = goldLetteringNode.zPosition - 1
spinningLogoNode.position = CGPoint(x: midX - 65, y: midY + 285);
spinningLogoNode.position = CGPoint(x: size.width * 0.455, y: size.height * 0.83)
super.init()
}

View File

@ -1,44 +0,0 @@
//
// UpdatePopUp.swift
// GoldWars
//
// Created by Tim Herbst on 18.06.20.
// Copyright © 2020 SP2. All rights reserved.
//
import GameplayKit
class UpdatePopUp: GKEntity {
var entityManager = EntityManager.menuEMInstance
var background: SKSpriteNode
var message: SKLabelNode
init(anchorPoint: CGPoint) {
let texture = SKTexture(imageNamed: "ModalBackground")
background = SKSpriteNode(texture: texture, size: texture.size())
background.setScale(2.4)
background.position = anchorPoint
background.zPosition = 4
message = SKLabelNode(text: "Update erforderlich")
self.message.position = CGPoint(x: anchorPoint.x, y: anchorPoint.y + 60)
self.message.fontName = "HelveticaNeue-Bold"
self.message.fontSize = 40
self.message.zPosition = 5
super.init()
addComponent(ButtonComponent(textureName: "yellow_button04", text: "zum Update", position: CGPoint(x: anchorPoint.x, y: anchorPoint.y - 105), isEnabled: true, onButtonPress: {
if let url = URL(string: AppUpdater.appStoreUrl), UIApplication.shared.canOpenURL(url) {
if #available(iOS 13.2, *) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
}
}))
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

View File

@ -1,13 +0,0 @@
//
// PlayerMoveType.swift
// GoldWars
//
// Created by Aldin Duraki on 16.05.20.
// Copyright © 2020 SP2. All rights reserved.
//
enum PlayerMoveType: Int, Codable{
case AtkMove = 1
case TxnMove = -1
}

View File

@ -24,10 +24,11 @@ struct State: Codable {
// 3 Host hat Spiel gestartet
// 4 Peer hat verloren
// 5 Peer hat gewonnen
// 6 Peer hat Spiel verlassen
let state: Int
}
final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate, GKGameCenterControllerDelegate ,GKMatchDelegate,GKLocalPlayerListener{
final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate, GKGameCenterControllerDelegate, GKMatchDelegate, GKLocalPlayerListener{
static var sharedInstance = GameCenterManager()
@ -47,6 +48,8 @@ final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate, GKG
var gameEnded = false
var winner: String?
var gameScene: GameScene?
var quitGame: Bool = false
var opponentQuit: Bool = false
static var isAuthenticated: Bool {
return GKLocalPlayer.local.isAuthenticated
}
@ -100,7 +103,6 @@ final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate, GKG
GKAchievement.loadAchievements { (achievements: [GKAchievement]?, err: Error?) in
var achievementExists: Bool = false
achievements?.forEach({ (achievement: GKAchievement) in
print(achievement.identifier)
if achievement.identifier == identifier {
achievementExists = true
achievement.percentComplete += increasePercentComplete
@ -172,6 +174,10 @@ final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate, GKG
os_log("State 5 erhalten, Peer hat gewonnen", log: LOG, type: .info)
winner = peerPlayer?.displayName
gameEnded = true
case 6:
os_log("State 6 erhalten, Peer hat Spiel verlassen ", log: LOG, type: .info)
opponentQuit = true
quitGame = true
default:
break
}
@ -207,15 +213,27 @@ final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate, GKG
if let eloData = try? jsonDecoder.decode(EloDataForPeer.self, from: data) {
print("Recieved elo data: \(eloData.scoreToReport)")
let score = GKScore(leaderboardIdentifier: EloHelper.IDENTIFIER, player: self.localPlayer)
score.value = eloData.scoreToReport
GKScore.report([score], withCompletionHandler: { error in
os_log("New Scores reported to EloSystem", log: self.LOG, type: .info)
})
EloHelper.reportScore(score: eloData.scoreToReport)
}
if let heartbeat = try? jsonDecoder.decode(Heartbeat.self, from: data) {
entityManager.getHUD()?.roundTimer.isHeartbeatLocked = false
let df = DateFormatter()
df.dateFormat = "yyyy-MM-dd HH:mm:ss"
let dateString = df.string(from: heartbeat.date)
print("Received last Heartbeat at \(dateString)")
}
MultiplayerNetwork.sharedInstance.isSending = false
}
func match(_ match: GKMatch, player: GKPlayer, didChange state: GKPlayerConnectionState) {
if myMatch != match { return }
if state == GKPlayerConnectionState.disconnected {
self.opponentQuit = true;
gameScene?.gameQuit()
}
}
func initAndSendMap() -> Void {
self.gameScene = GameScene(size: self.menusc!.size)
let mapModel = MapFactory(scene: self.gameScene!, entityManager: entityManager).load()
@ -240,6 +258,7 @@ final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate, GKG
}
return nilGK
}
func sendStateToPeers(state: State){
let encoder = JSONEncoder()
let encoded = (try? encoder.encode(state))!
@ -258,6 +277,7 @@ final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate, GKG
matchmakerVC!.matchmakerDelegate = self
viewController?.present(matchmakerVC!, animated: true, completion: nil)
}
func matchmakerViewControllerWasCancelled(_ viewController: GKMatchmakerViewController) {
viewController.dismiss(animated: true, completion: nil)
}

View File

@ -71,4 +71,10 @@ class MultiplayerNetwork{
let encoded = (try? encoder.encode(NotificationModel(name: name)))!
sendData(data: encoded)
}
func sendHeartbeatToPlayer() {
let encoder = JSONEncoder()
let encoded = (try? encoder.encode(Heartbeat(date: Date())))!
sendData(data: encoded)
}
}

View File

@ -12,6 +12,7 @@ class RoundTimer: Timer {
var timer: Timer?
var timeLeft: Int = 0
var isHeartbeatLocked = false
var calculate = false
var roundEnded = "Syncing"
@ -69,6 +70,9 @@ class RoundTimer: Timer {
}
}
if (!isHeartbeatLocked && (timeLeft % 7 == 0)){
MultiplayerNetwork.sharedInstance.sendHeartbeatToPlayer()
isHeartbeatLocked = true;
}
}
}

View File

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

View File

@ -81,8 +81,11 @@ class GameScene: SKScene{
if GameCenterManager.sharedInstance.gameEnded && !gameEndEffects {
gameEnd()
}
if GameCenterManager.sharedInstance.quitGame {
gameQuit()
}
}
func addAttackDetails(touchLocation: CGPoint){
for base in currentDraggedBase!.adjacencyList {
@ -150,10 +153,10 @@ class GameScene: SKScene{
let action = SKAction.afterDelay(2) {
(self.childNode(withName: "hostLabel") as! SKLabelNode).horizontalAlignmentMode = .center
(self.childNode(withName: "peerLabel") as! SKLabelNode).horizontalAlignmentMode = .center
self.childNode(withName: "hostLabel")?.run(SKAction.move(to: CGPoint(x: self.size.width * 0.25, y: self.size.height * 0.3), duration: 1))
self.childNode(withName: "peerLabel")?.run(SKAction.move(to: CGPoint(x: self.size.width * 0.75, y: self.size.height * 0.3), duration: 1))
self.childNode(withName: "hostLabel")?.run(SKAction.move(to: CGPoint(x: self.size.width * 0.25, y: self.size.height * 0.25), duration: 1))
self.childNode(withName: "peerLabel")?.run(SKAction.move(to: CGPoint(x: self.size.width * 0.75, y: self.size.height * 0.25), duration: 1))
self.initGameEndIcons()
let node = ButtonNode(textureName: "yellow_button05", text: "Menu", isEnabled: true, position: CGPoint(x: self.size.width / 2, y: self.size.height / 2 - 300), onButtonPress: {
let node = ButtonNode(textureName: "yellow_button05", text: "Menü", isEnabled: true, position: CGPoint(x: self.size.width / 2, y: self.size.height / 2 - 300), onButtonPress: {
self.backToMenuAction()
})
node.name = "BackButton"
@ -167,6 +170,66 @@ class GameScene: SKScene{
}
}
func gameQuit() {
entityManager.getHUD()?.blockWholeScreenPane.isHidden = true
gameEndEffects = true
GameCenterManager.sharedInstance.quitGame = false
let move = SKAction.move(to: CGPoint(x: self.size.width / 2, y: self.size.height / 2), duration: 1)
let removeParticle = SKAction.removeFromParent()
let sequence = SKAction.sequence([move, removeParticle])
var actionAdded = false
for nodeChild in children {
if nodeChild.name == "peerLabel" || nodeChild.name == "hostLabel"{
nodeChild.removeFromParent()
}
if nodeChild.name == "way" {
nodeChild.run(SKAction.removeFromParent())
continue
}
if nodeChild.name != "clouds"{
nodeChild.run(sequence) {
if !actionAdded {
let explosion = self.getFinalExplosion()
self.addChild(explosion)
let action = SKAction.afterDelay(2) {
let node = ButtonNode(textureName: "yellow_button05", text: "Menü", isEnabled: true, position: CGPoint(x: self.size.width / 2, y: self.size.height / 2 - 300), onButtonPress: {
self.backToMenuAction()
})
node.name = "BackButton"
self.addChild(node)
}
explosion.run(action)
actionAdded = true
}
}
}
}
let disconnectLabel = SKLabelNode.init(fontNamed: "Courier-Bold")
disconnectLabel.position = CGPoint(x: self.size.width/2, y: self.size.height/2)
disconnectLabel.horizontalAlignmentMode = .center
disconnectLabel.fontColor = UIColor.black
disconnectLabel.alpha = 0
disconnectLabel.setScale(0.1)
if GameCenterManager.sharedInstance.opponentQuit {
if GameCenterManager.sharedInstance.localPlayer == GameCenterManager.sharedInstance.hostingPlayer {
disconnectLabel.text = GameCenterManager.sharedInstance.peerPlayer?.displayName
} else {
disconnectLabel.text = GameCenterManager.sharedInstance.hostingPlayer?.displayName
}
disconnectLabel.text?.append(" hat das Spiel verlassen!")
} else {
disconnectLabel.text = "Du hast das Spiel verlassen!"
}
let showUpAnimation = SKAction.sequence([
SKAction.fadeAlpha(by: 1, duration: 2.5),
SKAction.scale(by: 10, duration: 1),
])
disconnectLabel.run(showUpAnimation)
self.addChild(disconnectLabel)
}
func initGameEndIcons() {
let iclonSize = CGSize(width: 400, height: 400)
let winnerIcon = SKSpriteNode(texture: SKTexture(imageNamed: "winner"));
@ -264,10 +327,16 @@ class GameScene: SKScene{
}
func isAttackMove() -> Bool {
return collisionBase?.ownershipPlayer != currentDraggedBase?.ownershipPlayer
if collisionBase?.ownershipPlayer == nil {
return true
}
return collisionBase?.ownershipPlayer != currentDraggedBase?.ownershipPlayer && !(collisionBase?.changeOwnership ?? false)
}
@objc func pauseGame() -> Void {
if !self.gameEndEffects{
entityManager.removeModal()
entityManager.getHUD()?.roundTimer.stopTimer()
entityManager.add(Modal(modaltype: .PauseGame,
@ -279,6 +348,8 @@ class GameScene: SKScene{
collisionBase: nil
))
}
}
@objc func resumeGame() -> Void {
entityManager.removeModal()
entityManager.getHUD()?.roundTimer.resumeTimer()

View File

@ -11,14 +11,14 @@ import SceneKit
class MenuScene: SKScene {
var entityManager = EntityManager.menuEMInstance
var appOutdated = false
override func sceneDidLoad() {
GameCenterManager.sharedInstance.menusc = self
entityManager.setScene(scene: self)
let midX = self.size.width / 2
let midY = self.size.height / 2
entityManager.add(Button(name: "startGameButton",
entityManager.add(
Button(name: "startGameButton",
textureName: "gold_button_3",
text: "Start Game",
position: CGPoint(x: midX, y: midY + 90),
@ -27,33 +27,45 @@ class MenuScene: SKScene {
self.loadScene(scene: GameScene(size: self.size))
SoundManager.sharedInstance.stopMenuMusic()
} else {
if GameCenterManager.isAuthenticated {
GameCenterManager.sharedInstance.presentGameCenter()
}else {
GameCenterManager.sharedInstance.presentMatchmaker()
} else {
GameCenterManager.sharedInstance.authUser()
}
}
}))
entityManager.add(Button(name: "settingsButton",
}
)
)
entityManager.add(
Button(name: "settingsButton",
textureName: "gold_button_3",
text: "Settings",
text: "Einstellungen",
position: CGPoint(x: midX, y: midY ),
onButtonPress: {
let scene = SettingsScene(size: self.size)
self.loadScene(scene: scene)
}))
entityManager.add(Button(name: "gameCenterButton",
onButtonPress: { self.loadScene(scene: SettingsScene(size: self.size))}
)
)
entityManager.add(
Button(name: "gameCenterButton",
textureName: "gold_button_3",
text: "GameCenter",
position: CGPoint(x: midX, y: midY - 90),
onButtonPress: {
if GameCenterManager.isAuthenticated {
GameCenterManager.sharedInstance.presentGameCenter()
}else {
} else {
GameCenterManager.sharedInstance.authUser()
}
}))
}
)
)
entityManager.add(
Button(name: "regelwerkButton",
textureName: "questionmark",
text: "",
position: CGPoint(x: self.size.width - 50, y: self.size.height - 50),
onButtonPress: { self.loadScene(scene: RulesScene(size: self.size)) }
)
)
entityManager.add(Background(size: self.size))
entityManager.add(SpinningLogoEntity(sceneSize: self.size))
@ -71,10 +83,8 @@ class MenuScene: SKScene {
override func update(_ currentTime: TimeInterval) {
if entityManager.entities.count != 0 {
entityManager.getBackground()!.update(deltaTime: currentTime)
if !appOutdated {
entityManager.getButtonByName(buttonName: "startGameButton").component(ofType: ButtonComponent.self)?.buttonNode.isEnabled = GameCenterManager.isAuthenticated
}
}
if GameCenterManager.sharedInstance.initIsFinish {
self.loadScene(scene: GameCenterManager.sharedInstance.gameScene!)

View File

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

View File

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

Binary file not shown.

Binary file not shown.

Binary file not shown.