Compare commits

...

111 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
0b2b552d16 Merge branch '102-ueberarbeitung-slider' into 'development'
Resolve "Ueberarbeitung Slider"

Closes #102

See merge request marcel.schwarz/software-projekt-2!128
2020-06-18 21:10:50 +00:00
c8bdc40c12 Set gray overlay for done to invisible for better understanding 2020-06-18 23:07:24 +02:00
Niko Jochim
bddad86674 review changes 2020-06-18 22:53:41 +02:00
Niko Jochim
adf01db4bf FIX Slider performance
* create hidden silderKnob
2020-06-18 22:28:49 +02:00
ba00702e67 Merge branch '91-gold-wars-schriftzug-2' into 'development'
Resolve "Gold Wars Schriftzug"

Closes #91

See merge request marcel.schwarz/software-projekt-2!127
2020-06-18 19:08:16 +00:00
Niko Jochim
fca44f3072 Refine logo and buttons in MainScene 2020-06-18 21:01:22 +02:00
Niko Jochim
5d14a8bd56 create GoldWars lettering
+ add new Gold Button Texture
2020-06-18 21:01:22 +02:00
1039f48859 Merge branch '75-elo-system' into 'development'
Resolve "ELO-System"

Closes #75

See merge request marcel.schwarz/software-projekt-2!122
2020-06-18 18:31:00 +00:00
f852aae859 Implement EloSystem in EloHelper
Calculate new EloData for both sides on serverside
Report scores on both sides
New Data type for sharing EloData
2020-06-18 20:10:08 +02:00
875524d170 Merge branch '66-game-over-scene-2' into 'development'
Resolve "Game-Over Scene"

Closes #66

See merge request marcel.schwarz/software-projekt-2!115
2020-06-18 17:50:35 +00:00
Niko Jochim
3c4ae97b61 fix getBackground to return a optional 2020-06-18 19:48:46 +02:00
Niko Jochim
b22e645163 review changes 2020-06-18 19:30:27 +02:00
Niko Jochim
e76f86b126 clean Code 2020-06-18 17:24:34 +02:00
Niko Jochim
e2c08b51a2 add winner/loser Icons
* remove SpinningLogoComponent
* create SoinningLogoNode
2020-06-18 17:13:44 +02:00
Niko Jochim
8df133f896 setLabel Names 2020-06-18 12:55:37 +02:00
Niko Jochim
f363d30f15 rest RoundCalculatorService 2020-06-18 11:51:56 +02:00
Niko Jochim
48e6247b69 Pfusch von Aldin.D 2020-06-18 11:51:56 +02:00
Niko Jochim
3082297415 create GameEnd Animation 2020-06-18 11:51:56 +02:00
Niko Jochim
b29111cb9e create gameEnd Trigger 2020-06-18 11:51:00 +02:00
dc3ef818df Merge branch '105-basen-disablen-sobald-zug-durch-done-beendet-wurde' into 'development'
Resolve "Basen disablen, sobald Zug durch Done beendet wurde"

Closes #105

See merge request marcel.schwarz/software-projekt-2!126
2020-06-17 22:54:26 +00:00
Jakob Haag
9de3e2cfa5 Add blockWholeScreenPane to disable clicks after Done was clicked 2020-06-18 00:49:53 +02:00
c46849e95d Merge branch '103-info-modal-entfernen' into 'development'
Resolve "Info-Modal entfernen"

Closes #103

See merge request marcel.schwarz/software-projekt-2!125
2020-06-17 22:20:26 +00:00
42446a7d49 Remove Modal when round ends, to prevent sending already dead units 2020-06-18 00:19:30 +02:00
afad3e808e Remove base details modal 2020-06-18 00:03:53 +02:00
0d8a134445 Merge branch '104-teamkomponente-loschen' into 'development'
Resolve "Teamkomponente löschen"

Closes #104

See merge request marcel.schwarz/software-projekt-2!124
2020-06-17 21:35:18 +00:00
Jakob Haag
5aa10e3fc5 review changes 2020-06-17 23:34:48 +02:00
71c01d589c Fix Spy-Skill to show labels again 2020-06-17 23:29:05 +02:00
Jakob Haag
07e630881e Remove fireNode if base has no ownership. Move unitcount Label from BaseComponent to Teamcomponent and remove it if base has no ownership. Remove unused Team-Enum cases. Remove unused team-colors. 2020-06-17 22:19:50 +02:00
f50d00a416 Merge branch '92-bei-angriff-unitcountlabel-anpassen' into 'development'
Resolve "Bei Angriff unitCountLabel anpassen"

Closes #92

See merge request marcel.schwarz/software-projekt-2!119
2020-06-12 13:26:15 +00:00
15fb959315 Hide label with unit counts when attacking a base 2020-06-11 22:43:16 +02:00
e10d57968c Merge branch '84-nachkomma-stellen-entfernen' into 'development'
Resolve "Nachkomma-Stellen entfernen"

Closes #84

See merge request marcel.schwarz/software-projekt-2!110
2020-06-11 20:42:08 +00:00
Chauntalle Schüle
f871bfda1d Units now only shown in slider of modal as Integer 2020-06-11 22:38:55 +02:00
00f8fbc61a Merge branch '49-leaderboard-einbauen' into 'development'
Resolve "Leaderboard einbauen"

Closes #49

See merge request marcel.schwarz/software-projekt-2!117
2020-06-11 20:35:54 +00:00
c517a36adc Add Leaderboard managing methods 2020-06-10 18:48:07 +02:00
1a9c075dce Merge branch '87-vektorisierte-wege' into 'development'
Resolve "Vektorisierte Wege"

Closes #87

See merge request marcel.schwarz/software-projekt-2!113
2020-06-10 13:00:30 +00:00
4e8b42d81c Fix warning while casting entity to base 2020-06-10 14:58:32 +02:00
04e55be394 Remove orphan files 2020-06-10 14:55:04 +02:00
Jakob Haag
502c609d81 remove old unused unnecessary DefaultWayComponent and rename for better understanding 2020-06-10 14:49:29 +02:00
Jakob Haag
ad9e970ef6 fix gap between two crossed curves 2020-06-10 14:49:29 +02:00
Jakob Haag
ed764afc45 remove Ways as Component and add function to generate different types of ways 2020-06-10 14:49:29 +02:00
79781ccdc9 Merge branch '97-music-flag' into 'development'
Resolve "Music Flag"

Closes #97

See merge request marcel.schwarz/software-projekt-2!116
2020-06-09 21:48:08 +00:00
Aldin Duraki
376ed849ae Merge branch '98-appdelegate' into 'development'
Resolve "AppDelegate"

Closes #98

See merge request marcel.schwarz/software-projekt-2!114
2020-06-09 16:07:52 +00:00
2f32943511 Add --no-music flag, Implement NSUserDefaults for music settings 2020-06-08 10:42:05 +02:00
Aldin Duraki
e6d866bc70 For better understanding 2020-06-06 19:20:13 +02:00
Aldin Duraki
a37187bbad Impl. AppDelegates handlings 2020-06-06 18:59:26 +02:00
Aldin Duraki
46fa90bfe3 Merge branch 'sprint_4_delivery' into 'development'
Sprint 4 delivery

See merge request marcel.schwarz/software-projekt-2!108
2020-06-04 16:16:31 +00:00
Aldin Duraki
a26efeb3d1 Update Build Version 2020-06-04 18:15:48 +02:00
103 changed files with 1634 additions and 501 deletions

View File

@ -16,14 +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 */; };
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 */; }; 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 */; };
3EAD889524801B6A0048A10A /* RoundTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EAD889424801B6A0048A10A /* RoundTimer.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 */; };
3F79FFE02486F7CD003F79C3 /* Explosion.sks in Resources */ = {isa = PBXBuildFile; fileRef = 3F79FFDF2486F7CD003F79C3 /* Explosion.sks */; }; 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 */; };
8B9CA5F1249A3C2E00561704 /* SkillButtonNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B9CA5F0249A3C2E00561704 /* SkillButtonNode.swift */; };
8BB6FF402472B8F000162BBD /* SingeClickButtonNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8BB6FF3F2472B8F000162BBD /* SingeClickButtonNode.swift */; }; 8BB6FF402472B8F000162BBD /* SingeClickButtonNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8BB6FF3F2472B8F000162BBD /* SingeClickButtonNode.swift */; };
9E0E459724796262009817A6 /* GameCenterManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E0E459624796262009817A6 /* GameCenterManager.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 */; };
@ -32,6 +34,8 @@
9E174C86245DD91500209FF0 /* ButtonComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E174C85245DD91500209FF0 /* ButtonComponent.swift */; }; 9E174C86245DD91500209FF0 /* ButtonComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E174C85245DD91500209FF0 /* ButtonComponent.swift */; };
9E174C88245DF1FF00209FF0 /* BackgroundComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E174C87245DF1FF00209FF0 /* BackgroundComponent.swift */; }; 9E174C88245DF1FF00209FF0 /* BackgroundComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E174C87245DF1FF00209FF0 /* BackgroundComponent.swift */; };
9E174C8A245E1A0A00209FF0 /* Background.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E174C89245E1A0A00209FF0 /* Background.swift */; }; 9E174C8A245E1A0A00209FF0 /* Background.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E174C89245E1A0A00209FF0 /* Background.swift */; };
9E61EAC4249BAC9100334DDE /* LoserFire.sks in Resources */ = {isa = PBXBuildFile; fileRef = 9E61EAC2249BAC9100334DDE /* LoserFire.sks */; };
9E61EAC7249BB61A00334DDE /* SpinningLogo3DNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E61EAC6249BB61A00334DDE /* SpinningLogo3DNode.swift */; };
9E78ACB6245C9A5300526FF7 /* GameKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E78ACB5245C9A5300526FF7 /* GameKit.framework */; }; 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 */; };
@ -42,10 +46,11 @@
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 */; };
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 */; };
AB21D7D5246C748A00B09CBA /* MapFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB21D7D4246C748A00B09CBA /* MapFactory.swift */; }; AB21D7D5246C748A00B09CBA /* MapFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB21D7D4246C748A00B09CBA /* MapFactory.swift */; };
AB671B252494ECF0003FBE8D /* EloHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB671B242494ECF0003FBE8D /* EloHelper.swift */; };
ABA03DA0244BD54F00A66916 /* Base.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABA03D9F244BD54F00A66916 /* Base.swift */; }; ABA03DA0244BD54F00A66916 /* Base.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABA03D9F244BD54F00A66916 /* Base.swift */; };
ABC0C3732481509300387B8F /* MapUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABC0C3722481509300387B8F /* MapUtils.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 */; }; 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 */; }; C05BB9C4247D890C00411249 /* SliderComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C05BB9C3247D890C00411249 /* SliderComponent.swift */; };
@ -80,14 +85,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>"; };
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>"; }; 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>"; };
3EAD889424801B6A0048A10A /* RoundTimer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoundTimer.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>"; };
3F79FFDF2486F7CD003F79C3 /* Explosion.sks */ = {isa = PBXFileReference; lastKnownFileType = file.sks; path = Explosion.sks; 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>"; };
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>"; }; 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>"; }; 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>"; };
@ -96,6 +103,8 @@
9E174C85245DD91500209FF0 /* ButtonComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonComponent.swift; sourceTree = "<group>"; }; 9E174C85245DD91500209FF0 /* ButtonComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonComponent.swift; sourceTree = "<group>"; };
9E174C87245DF1FF00209FF0 /* BackgroundComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundComponent.swift; sourceTree = "<group>"; }; 9E174C87245DF1FF00209FF0 /* BackgroundComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundComponent.swift; sourceTree = "<group>"; };
9E174C89245E1A0A00209FF0 /* Background.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Background.swift; sourceTree = "<group>"; }; 9E174C89245E1A0A00209FF0 /* Background.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Background.swift; sourceTree = "<group>"; };
9E61EAC2249BAC9100334DDE /* LoserFire.sks */ = {isa = PBXFileReference; lastKnownFileType = file.sks; path = LoserFire.sks; sourceTree = "<group>"; };
9E61EAC6249BB61A00334DDE /* SpinningLogo3DNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpinningLogo3DNode.swift; sourceTree = "<group>"; };
9E78ACB5245C9A5300526FF7 /* GameKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameKit.framework; path = System/Library/Frameworks/GameKit.framework; sourceTree = SDKROOT; }; 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>"; };
@ -107,10 +116,11 @@
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>"; };
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>"; };
AB21D7D4246C748A00B09CBA /* MapFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapFactory.swift; sourceTree = "<group>"; }; AB21D7D4246C748A00B09CBA /* MapFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapFactory.swift; sourceTree = "<group>"; };
AB671B242494ECF0003FBE8D /* EloHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EloHelper.swift; sourceTree = "<group>"; };
ABA03D9F244BD54F00A66916 /* Base.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Base.swift; sourceTree = "<group>"; }; 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>"; }; 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>"; }; 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>"; }; C05BB9C3247D890C00411249 /* SliderComponent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SliderComponent.swift; sourceTree = "<group>"; };
@ -163,6 +173,9 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
C04783ED2468583F004961FB /* intro-music.mp3 */, C04783ED2468583F004961FB /* intro-music.mp3 */,
20F1990624A4FAC1004B7A30 /* attack_base.wav */,
20F1990424A4FAC1004B7A30 /* new_round.wav */,
20F1990524A4FAC1004B7A30 /* use_boost.wav */,
9ECD3699245C91F7008DEEBD /* GoldWars.entitlements */, 9ECD3699245C91F7008DEEBD /* GoldWars.entitlements */,
9E11FF74245CD79100EED3BE /* Partikels */, 9E11FF74245CD79100EED3BE /* Partikels */,
116060F5245C5709004E5A36 /* Entities */, 116060F5245C5709004E5A36 /* Entities */,
@ -182,6 +195,8 @@
9E0E459624796262009817A6 /* GameCenterManager.swift */, 9E0E459624796262009817A6 /* GameCenterManager.swift */,
C04783EF24685995004961FB /* SettingsScene.swift */, C04783EF24685995004961FB /* SettingsScene.swift */,
3EAD889424801B6A0048A10A /* RoundTimer.swift */, 3EAD889424801B6A0048A10A /* RoundTimer.swift */,
AB671B242494ECF0003FBE8D /* EloHelper.swift */,
AE0C8E2E249BCC2A00996360 /* RulesScene.swift */,
); );
path = GoldWars; path = GoldWars;
sourceTree = "<group>"; sourceTree = "<group>";
@ -203,15 +218,15 @@
9E174C85245DD91500209FF0 /* ButtonComponent.swift */, 9E174C85245DD91500209FF0 /* ButtonComponent.swift */,
9E174C81245DD81D00209FF0 /* ButtonNode.swift */, 9E174C81245DD81D00209FF0 /* ButtonNode.swift */,
9EA3ABE8245C6DAA006BC61D /* DefaultBaseComponent.swift */, 9EA3ABE8245C6DAA006BC61D /* DefaultBaseComponent.swift */,
3E6785432472CC27007B9DE4 /* DefaultWayComponent.swift */,
C064E9A9246C114C0022B228 /* LabelComponent.swift */, C064E9A9246C114C0022B228 /* LabelComponent.swift */,
C064E9A7246C0EA50022B228 /* LabelNode.swift */, C064E9A7246C0EA50022B228 /* LabelNode.swift */,
9EC2FBA62476B1EC00ABF11F /* PlayerInfoComponent.swift */, 9EC2FBA62476B1EC00ABF11F /* PlayerInfoComponent.swift */,
8BB6FF3F2472B8F000162BBD /* SingeClickButtonNode.swift */, 8BB6FF3F2472B8F000162BBD /* SingeClickButtonNode.swift */,
8B9CA5F0249A3C2E00561704 /* SkillButtonNode.swift */,
C05BB9C3247D890C00411249 /* SliderComponent.swift */, C05BB9C3247D890C00411249 /* SliderComponent.swift */,
9EC7E48A2461FBF700396BCD /* SliderNode.swift */, 9EC7E48A2461FBF700396BCD /* SliderNode.swift */,
9EEDE02E246FCD800096C735 /* SpinningLogoComponent.swift */,
9E78ACB7245CB75B00526FF7 /* TeamComponent.swift */, 9E78ACB7245CB75B00526FF7 /* TeamComponent.swift */,
9E61EAC6249BB61A00334DDE /* SpinningLogo3DNode.swift */,
); );
path = Components; path = Components;
sourceTree = "<group>"; sourceTree = "<group>";
@ -237,6 +252,7 @@
children = ( children = (
3F79FFDF2486F7CD003F79C3 /* Explosion.sks */, 3F79FFDF2486F7CD003F79C3 /* Explosion.sks */,
9E11FF77245CD81100EED3BE /* Fire.sks */, 9E11FF77245CD81100EED3BE /* Fire.sks */,
9E61EAC2249BAC9100334DDE /* LoserFire.sks */,
); );
path = Partikels; path = Partikels;
sourceTree = "<group>"; sourceTree = "<group>";
@ -253,7 +269,6 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
3EBD242D245D9332003CECE7 /* Team.swift */, 3EBD242D245D9332003CECE7 /* Team.swift */,
3F745DEF246F48FC00CE7375 /* PlayerMoveType.swift */,
); );
path = Enums; path = Enums;
sourceTree = "<group>"; sourceTree = "<group>";
@ -368,9 +383,13 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
110360DE244B101A008610AF /* Main.storyboard in Resources */, 110360DE244B101A008610AF /* Main.storyboard in Resources */,
20F1990924A4FAC1004B7A30 /* attack_base.wav in Resources */,
9E11FF79245CD81100EED3BE /* Fire.sks in Resources */, 9E11FF79245CD81100EED3BE /* Fire.sks in Resources */,
20F1990724A4FAC1004B7A30 /* new_round.wav in Resources */,
110360E0244B101B008610AF /* Assets.xcassets in Resources */, 110360E0244B101B008610AF /* Assets.xcassets in Resources */,
110360E3244B101B008610AF /* LaunchScreen.storyboard in Resources */, 110360E3244B101B008610AF /* LaunchScreen.storyboard in Resources */,
9E61EAC4249BAC9100334DDE /* LoserFire.sks in Resources */,
20F1990824A4FAC1004B7A30 /* use_boost.wav in Resources */,
C04783EE2468583F004961FB /* intro-music.mp3 in Resources */, C04783EE2468583F004961FB /* intro-music.mp3 in Resources */,
3F79FFE02486F7CD003F79C3 /* Explosion.sks in Resources */, 3F79FFE02486F7CD003F79C3 /* Explosion.sks in Resources */,
); );
@ -406,6 +425,7 @@
9EC2FBA72476B1EC00ABF11F /* PlayerInfoComponent.swift in Sources */, 9EC2FBA72476B1EC00ABF11F /* PlayerInfoComponent.swift in Sources */,
9EEDE02D246FCD770096C735 /* SpinningLogoEntity.swift in Sources */, 9EEDE02D246FCD770096C735 /* SpinningLogoEntity.swift in Sources */,
9E174C86245DD91500209FF0 /* ButtonComponent.swift in Sources */, 9E174C86245DD91500209FF0 /* ButtonComponent.swift in Sources */,
AB671B252494ECF0003FBE8D /* EloHelper.swift in Sources */,
11036113244B3E30008610AF /* MenuScene.swift in Sources */, 11036113244B3E30008610AF /* MenuScene.swift in Sources */,
C099579C246C5E5C0016AA22 /* DataService.swift in Sources */, C099579C246C5E5C0016AA22 /* DataService.swift in Sources */,
AB21D7D5246C748A00B09CBA /* MapFactory.swift in Sources */, AB21D7D5246C748A00B09CBA /* MapFactory.swift in Sources */,
@ -413,18 +433,18 @@
9E174C8A245E1A0A00209FF0 /* Background.swift in Sources */, 9E174C8A245E1A0A00209FF0 /* Background.swift in Sources */,
8BB6FF402472B8F000162BBD /* SingeClickButtonNode.swift in Sources */, 8BB6FF402472B8F000162BBD /* SingeClickButtonNode.swift in Sources */,
C064E9A8246C0EA50022B228 /* LabelNode.swift in Sources */, C064E9A8246C0EA50022B228 /* LabelNode.swift in Sources */,
3F745DF0246F48FC00CE7375 /* PlayerMoveType.swift in Sources */, 8B9CA5F1249A3C2E00561704 /* SkillButtonNode.swift in Sources */,
3EAD889524801B6A0048A10A /* RoundTimer.swift in Sources */, 3EAD889524801B6A0048A10A /* RoundTimer.swift in Sources */,
AE0C8E2F249BCC2A00996360 /* RulesScene.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 */, 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 */, 9E61EAC7249BB61A00334DDE /* SpinningLogo3DNode.swift in Sources */,
9E174C84245DD8CE00209FF0 /* Button.swift in Sources */, 9E174C84245DD8CE00209FF0 /* Button.swift in Sources */,
110360DB244B101A008610AF /* GameViewController.swift in Sources */, 110360DB244B101A008610AF /* GameViewController.swift in Sources */,
3E6785442472CC27007B9DE4 /* DefaultWayComponent.swift in Sources */,
C05BB9C4247D890C00411249 /* SliderComponent.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 */,
@ -591,7 +611,7 @@
CODE_SIGN_ENTITLEMENTS = GoldWars/GoldWars.entitlements; CODE_SIGN_ENTITLEMENTS = GoldWars/GoldWars.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 3; CURRENT_PROJECT_VERSION = 4;
DEVELOPMENT_TEAM = DDKFQG46BQ; DEVELOPMENT_TEAM = DDKFQG46BQ;
INFOPLIST_FILE = GoldWars/Info.plist; INFOPLIST_FILE = GoldWars/Info.plist;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
@ -614,7 +634,7 @@
CODE_SIGN_ENTITLEMENTS = GoldWars/GoldWars.entitlements; CODE_SIGN_ENTITLEMENTS = GoldWars/GoldWars.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 3; CURRENT_PROJECT_VERSION = 4;
DEVELOPMENT_TEAM = DDKFQG46BQ; DEVELOPMENT_TEAM = DDKFQG46BQ;
INFOPLIST_FILE = GoldWars/Info.plist; INFOPLIST_FILE = GoldWars/Info.plist;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (

View File

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

Binary file not shown.

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" : [ "images" : [
{ {
"filename" : "Base.png", "filename" : "BaseTexture.png",
"idiom" : "universal", "idiom" : "universal",
"scale" : "1x" "scale" : "1x"
}, },
{ {
"filename" : "Base-1.png", "filename" : "BaseTexture-1.png",
"idiom" : "universal", "idiom" : "universal",
"scale" : "2x" "scale" : "2x"
}, },
{ {
"filename" : "Base-2.png", "filename" : "BaseTexture-2.png",
"idiom" : "universal", "idiom" : "universal",
"scale" : "3x" "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

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 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: 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

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 448 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 448 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 448 KiB

View File

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

View File

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

View File

@ -12,20 +12,11 @@ import GameKit
class DefaultBaseComponent: GKComponent { class DefaultBaseComponent: GKComponent {
var spriteNode: BaseNode var spriteNode: BaseNode
var labelNode : SKLabelNode
init(texture: SKTexture, position: CGPoint) { init(texture: SKTexture, position: CGPoint) {
spriteNode = BaseNode(texture: texture, size: CGSize(width: 100, height: 100)) spriteNode = BaseNode(texture: texture, size: CGSize(width: 100, height: 100))
spriteNode.position = position spriteNode.position = position
spriteNode.zPosition = 2 spriteNode.zPosition = 2
labelNode = SKLabelNode(text: "")
labelNode.fontColor = SKColor.black
labelNode.horizontalAlignmentMode = .left
labelNode.verticalAlignmentMode = .center
labelNode.fontName = "AvenirNext-Bold"
labelNode.fontSize = 15
labelNode.position = CGPoint(x: position.x + 30 , y: position.y - 50 )
labelNode.zPosition = spriteNode.zPosition - 1
super.init() super.init()
} }

View File

@ -1,28 +0,0 @@
//
// DefaultWayComponent.swift
// GoldWars
//
// Created by Jakob Haag on 18.05.20.
// Copyright © 2020 SP2. All rights reserved.
//
import Foundation
import GameplayKit
import SpriteKit
class DefaultWayComponent: GKComponent {
var shapeNode: SKShapeNode
init(pathToDraw: CGMutablePath) {
self.shapeNode = SKShapeNode()
shapeNode.path = pathToDraw
shapeNode.strokeColor = UIColor(red: 0.852, green: 0.649, blue: 0.123, alpha: 1)
shapeNode.lineWidth = 10
shapeNode.zPosition = 0
super.init()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

View File

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

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

View File

@ -10,58 +10,70 @@ import SpriteKit
class SliderNode :SKNode { class SliderNode :SKNode {
var sliderLine :SKShapeNode var sliderLine :SKShapeNode
var sliderKnob :SliderKnob var hiddenKnob :SliderKnob
var width: CGFloat var silderKnob :SKSpriteNode
var width: CGFloat
var getValue: CGFloat{
get{ var getValue: CGFloat{
return ((sliderKnob.position.x.rounded() - sliderKnob.min) / width) get{
} silderKnob.position = hiddenKnob.position
} return ((hiddenKnob.position.x.rounded() - hiddenKnob.min) / width)
}
init(width: CGFloat, position: CGPoint) { }
self.width = width
sliderLine = SKShapeNode(rectOf: CGSize(width: width, height: 8)) init(width: CGFloat, position: CGPoint) {
sliderLine.position = position self.width = width
sliderLine.fillColor = SKColor.white sliderLine = SKShapeNode(rectOf: CGSize(width: width, height: 8))
sliderLine.position = position
sliderLine.fillColor = SKColor.white
sliderLine.zPosition = 4 sliderLine.zPosition = 4
sliderKnob = SliderKnob(circleOfRadius: 20)
sliderKnob.min = position.x - width / 2 hiddenKnob = SliderKnob(circleOfRadius: 58 )
sliderKnob.max = position.x + width / 2 hiddenKnob.min = position.x - width / 2
sliderKnob.fillColor = SKColor.red hiddenKnob.max = position.x + width / 2
sliderKnob.zPosition = sliderLine.zPosition + 1 hiddenKnob.fillColor = SKColor.red
sliderKnob.position = CGPoint(x: sliderLine.position.x, y: sliderLine.position.y + 1) hiddenKnob.alpha = 0.001
super.init() hiddenKnob.zPosition = sliderLine.zPosition + 1
hiddenKnob.position = CGPoint(x: sliderLine.position.x, y: sliderLine.position.y + 1)
}
silderKnob = SKSpriteNode(texture: SKTexture(imageNamed: "yellow_boxTick"))
required init?(coder aDecoder: NSCoder) { silderKnob.position = hiddenKnob.position
fatalError("init(coder:) has not been implemented") silderKnob.zPosition = hiddenKnob.zPosition - 1
} silderKnob.size = CGSize(width: 50, height: 50)
super.init()
self.name = "slider"
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
} }
class SliderKnob: SKShapeNode { class SliderKnob: SKShapeNode {
var min = CGFloat() var min = CGFloat()
var max = CGFloat() var max = CGFloat()
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches { for touch in touches {
let touchLocation = touch.location(in: self.scene!) let touchLocation = touch.location(in: self.scene!)
if self.position.x >= min - 1 && self.position.x <= max + 1{ if self.position.x >= min - 1 && self.position.x <= max + 1{
self.position.x = touchLocation.x self.position.x = touchLocation.x
} }
if(self.position.x <= min){ if(self.position.x <= min){
self.position.x = min self.position.x = min
} }
if(self.position.x >= max){ if(self.position.x >= max){
self.position.x = max self.position.x = max
}
} }
} }
}
} }

View File

@ -0,0 +1,40 @@
//
// SpinningLogo3DNode.swift
// GoldWars
//
// Created by Niko Jochim on 18.06.20.
// Copyright © 2020 SP2. All rights reserved.
//
import Foundation
import SpriteKit
import GameKit
class SpinningLogo3DNode : SK3DNode {
init() {
super.init(viewportSize: CGSize(width: 250, height: 250))
let scnScene: SCNScene = {
let scnScene = SCNScene()
let cylinder = SCNCylinder(radius: 250, height: 50)
let logoMaterial = SCNMaterial()
let colorMaterial = SCNMaterial()
logoMaterial.diffuse.contents = UIImage(named: "logo_no_background")
colorMaterial.diffuse.contents = UIColor(red: 0.852, green: 0.649, blue: 0.123, alpha: 1)
cylinder.materials = [colorMaterial,logoMaterial,logoMaterial]
let cylinderNode = SCNNode(geometry: cylinder)
cylinderNode.eulerAngles = SCNVector3(x: Float(CGFloat.pi / 2), y: 0, z: Float(CGFloat.pi / 2))
let action = SCNAction.rotateBy(x: CGFloat(GLKMathDegreesToRadians(360)), y:0 , z: 0, duration: 8)
let forever = SCNAction.repeatForever(action)
cylinderNode.runAction(forever)
scnScene.rootNode.addChildNode(cylinderNode)
return scnScene
}()
self.scnScene = scnScene
self.position = position
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

View File

@ -1,45 +0,0 @@
//
// SpinningLogoComponent.swift
// GoldWars
//
// Created by Niko Jochim on 15.05.20.
// Copyright © 2020 SP2. All rights reserved.
//
import Foundation
import GameKit
class SpinningLogoComponent: GKComponent{
var node : SK3DNode
init(position: CGPoint) {
let scnScene: SCNScene = {
let scnScene = SCNScene()
let cylinder = SCNCylinder(radius: 250, height: 50)
let logoMaterial = SCNMaterial()
let colorMaterial = SCNMaterial()
logoMaterial.diffuse.contents = UIImage(named: "logo_no_background")
colorMaterial.diffuse.contents = UIColor(red: 0.852, green: 0.649, blue: 0.123, alpha: 1)
cylinder.materials = [colorMaterial,logoMaterial,logoMaterial]
let cylinderNode = SCNNode(geometry: cylinder)
cylinderNode.eulerAngles = SCNVector3(x: Float(CGFloat.pi / 2), y: 0, z: Float(CGFloat.pi / 2))
let action = SCNAction.rotateBy(x: CGFloat(GLKMathDegreesToRadians(360)), y:0 , z: 0, duration: 8)
let forever = SCNAction.repeatForever(action)
cylinderNode.runAction(forever)
scnScene.rootNode.addChildNode(cylinderNode)
return scnScene
}()
self.node = SK3DNode(viewportSize: CGSize(width: 250, height: 250))
node.scnScene = scnScene
node.position = position
super.init()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

@ -8,10 +8,11 @@
import GameplayKit import GameplayKit
enum ModalType: String{ enum ModalType: String {
case BaseDetails
case BaseAttack case BaseAttack
case BaseMoveOwnUnits case BaseMoveOwnUnits
case PauseGame
case QuitGame
} }
class Modal: GKEntity{ class Modal: GKEntity{
@ -24,9 +25,15 @@ class Modal: GKEntity{
var body: SKLabelNode var body: SKLabelNode
var footer: SKLabelNode var footer: SKLabelNode
var overlay: SKSpriteNode 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?) {
unitCount = base.unitCount self.type = modaltype
unitCount = 0
if base != nil {
unitCount = base!.unitCount
}
let texture = SKTexture(imageNamed:"ModalBackground") let texture = SKTexture(imageNamed:"ModalBackground")
background = SKSpriteNode(texture: texture, size: texture.size()) background = SKSpriteNode(texture: texture, size: texture.size())
@ -45,33 +52,38 @@ class Modal: GKEntity{
overlay.zPosition = 3 overlay.zPosition = 3
switch modaltype { switch modaltype {
case .BaseDetails: case .BaseAttack:
header = SKLabelNode(text: "Information") header = SKLabelNode(text: "Angriff")
body = SKLabelNode(text: "Diese Basis enthält \(base.unitCount) Einheiten") body = SKLabelNode(text: "\(unitCount / 2) Einheiten")
footer = SKLabelNode() footer = SKLabelNode()
case .BaseAttack: case .BaseMoveOwnUnits:
header = SKLabelNode(text: "Angriff") header = SKLabelNode(text: "Formation")
body = SKLabelNode(text: "Schicke \(unitCount / 2)\nEinheiten") body = SKLabelNode(text: "\(unitCount / 2) Einheiten")
footer = SKLabelNode() footer = SKLabelNode()
case .BaseMoveOwnUnits: case .PauseGame:
header = SKLabelNode(text: "Formation") header = SKLabelNode(text: "Pause")
body = SKLabelNode(text: "Sende \(unitCount / 2)\nEinheiten") body = SKLabelNode(text: "Warte auf Gegner...")
footer = SKLabelNode() 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) self.header.position = CGPoint(x: anchorPoint.x, y: anchorPoint.y + 90)
self.header.fontName = "HelveticaNeue-Bold" self.header.fontName = "HelveticaNeue-Bold"
self.header.fontSize = 40 self.header.fontSize = 40
self.header.zPosition = 5 self.header.zPosition = 5
self.body.position = CGPoint(x: anchorPoint.x, y: anchorPoint.y - 20) self.body.position = CGPoint(x: anchorPoint.x, y: anchorPoint.y + 15)
self.body.numberOfLines = 2 self.body.numberOfLines = 2
self.body.preferredMaxLayoutWidth = 390 self.body.preferredMaxLayoutWidth = 390
self.body.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.center self.body.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.center
self.body.fontName = "HelveticaNeue-Bold" self.body.fontName = "HelveticaNeue-Bold"
self.body.fontSize = 40 self.body.fontSize = 40
self.body.zPosition = 5 self.body.zPosition = 5
self.footer.position = CGPoint(x: anchorPoint.x, y: anchorPoint.y - 40) self.footer.position = CGPoint(x: anchorPoint.x, y: anchorPoint.y - 40)
self.footer.fontName = "HelveticaNeue-Bold" self.footer.fontName = "HelveticaNeue-Bold"
self.footer.fontSize = 40 self.footer.fontSize = 40
@ -79,19 +91,26 @@ class Modal: GKEntity{
super.init() super.init()
switch modaltype{ switch modaltype {
case .BaseDetails: case .BaseAttack, .BaseMoveOwnUnits:
addComponent(ButtonComponent(textureName: "yellow_button04", text: "Zurück", position: CGPoint(x: anchorPoint.x , y: anchorPoint.y - 105), isEnabled: true, onButtonPress: { let text = (modaltype == .BaseAttack) ? "Angriff" : "Senden"
EntityManager.gameEMInstance.removeModal() 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: {
case .BaseAttack, .BaseMoveOwnUnits: self.sendUnits(currentDraggedBase: currentDraggedBase, touchLocation: touchLocation!, gameScene: gameScene, collisionBase: collisionBase)
let text = (modaltype == .BaseAttack) ? "Angriff" : "Senden" EntityManager.gameEMInstance.removeModal()
addComponent(SliderComponent(width: 300, position: CGPoint(x: anchorPoint.x , y: anchorPoint.y - 50))) }))
addComponent(ButtonComponent(textureName: "yellow_button04", text: text, position: CGPoint(x: anchorPoint.x , y: anchorPoint.y - 105), isEnabled: true, onButtonPress: { case .QuitGame:
self.sendUnits(currentDraggedBase: currentDraggedBase, touchLocation: touchLocation, gameScene: gameScene, collisionBase: collisionBase) addComponent(ButtonComponent(textureName: "yellow_button04", text: "Verlassen", position: CGPoint(x: anchorPoint.x , y: anchorPoint.y - 95), isEnabled: true, onButtonPress: {
EntityManager.gameEMInstance.removeModal() EntityManager.gameEMInstance.removeModal()
})) GameCenterManager.sharedInstance.sendStateToPeers(state: State(state: 6))
GameCenterManager.sharedInstance.opponentQuit = false
GameCenterManager.sharedInstance.quitGame = true
}))
case .PauseGame:
break
} }
} }
required init?(coder: NSCoder) { required init?(coder: NSCoder) {
@ -106,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 { for base in currentDraggedBase!.adjacencyList {
if base == collisionBase { if base == collisionBase {
RoundCalculatorService.sharedInstance.increaseMoveCounter(ownBase: currentDraggedBase?.ownershipPlayer == base.ownershipPlayer) 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 GameScene.sendUnits = 0
} }
} }

View File

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

View File

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

View File

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

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

View File

@ -24,12 +24,13 @@ struct State: Codable {
// 3 Host hat Spiel gestartet // 3 Host hat Spiel gestartet
// 4 Peer hat verloren // 4 Peer hat verloren
// 5 Peer hat gewonnen // 5 Peer hat gewonnen
// 6 Peer hat Spiel verlassen
let state: Int let state: Int
} }
final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate, GKGameCenterControllerDelegate ,GKMatchDelegate,GKLocalPlayerListener{ final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate, GKGameCenterControllerDelegate, GKMatchDelegate, GKLocalPlayerListener{
static let sharedInstance = GameCenterManager() static var sharedInstance = GameCenterManager()
let LOG = OSLog.init(subsystem: "GameCenterManager", category: "GameCenterManager") let LOG = OSLog.init(subsystem: "GameCenterManager", category: "GameCenterManager")
@ -44,7 +45,11 @@ final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate, GKG
var entityManager = EntityManager.gameEMInstance var entityManager = EntityManager.gameEMInstance
var localPlayerRandomNumber: RandomNumber? var localPlayerRandomNumber: RandomNumber?
var initIsFinish = false var initIsFinish = false
var gameEnded = false
var winner: String?
var gameScene: GameScene? var gameScene: GameScene?
var quitGame: Bool = false
var opponentQuit: Bool = false
static var isAuthenticated: Bool { static var isAuthenticated: Bool {
return GKLocalPlayer.local.isAuthenticated return GKLocalPlayer.local.isAuthenticated
} }
@ -56,6 +61,16 @@ final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate, GKG
localPlayerRandomNumber = RandomNumber() localPlayerRandomNumber = RandomNumber()
} }
func reset() {
isMatchStarted = false
isServer = false
localPlayerRandomNumber = RandomNumber()
initIsFinish = false
gameEnded = false
winner = nil
gameScene = nil
}
func authUser() -> Void { func authUser() -> Void {
GKLocalPlayer.local.authenticateHandler = { gcAuthVC, error in GKLocalPlayer.local.authenticateHandler = { gcAuthVC, error in
NotificationCenter.default NotificationCenter.default
@ -88,7 +103,6 @@ final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate, GKG
GKAchievement.loadAchievements { (achievements: [GKAchievement]?, err: Error?) in GKAchievement.loadAchievements { (achievements: [GKAchievement]?, err: Error?) in
var achievementExists: Bool = false var achievementExists: Bool = false
achievements?.forEach({ (achievement: GKAchievement) in achievements?.forEach({ (achievement: GKAchievement) in
print(achievement.identifier)
if achievement.identifier == identifier { if achievement.identifier == identifier {
achievementExists = true achievementExists = true
achievement.percentComplete += increasePercentComplete achievement.percentComplete += increasePercentComplete
@ -108,7 +122,7 @@ final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate, GKG
} }
} }
} }
func match(_ match: GKMatch, didReceive data: Data, fromRemotePlayer player: GKPlayer) { func match(_ match: GKMatch, didReceive data: Data, fromRemotePlayer player: GKPlayer) {
if myMatch != match { return } if myMatch != match { return }
let jsonDecoder = JSONDecoder() let jsonDecoder = JSONDecoder()
@ -154,10 +168,16 @@ final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate, GKG
os_log("Spiel startet", log: LOG, type: .info) os_log("Spiel startet", log: LOG, type: .info)
case 4: case 4:
os_log("State 4 erhalten, Peer hat verloren", log: LOG, type: .info) os_log("State 4 erhalten, Peer hat verloren", log: LOG, type: .info)
// TODO: Trigger Loser Scene winner = hostingPlayer?.displayName
gameEnded = true
case 5: case 5:
os_log("State 5 erhalten, Peer hat gewonnen", log: LOG, type: .info) os_log("State 5 erhalten, Peer hat gewonnen", log: LOG, type: .info)
// TODO: Trigger Winner Scene 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: default:
break break
} }
@ -185,9 +205,35 @@ final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate, GKG
initIsFinish = true initIsFinish = true
os_log("Peer startet Spiel", log: LOG, type: .info) os_log("Peer startet Spiel", log: LOG, type: .info)
} }
if let notification = try? jsonDecoder.decode(NotificationModel.self, from: data) {
os_log("Notification erhalten", log: LOG, type: .info)
NotificationCenter.default.post(name: Notification.Name(rawValue: notification.name), object: nil)
}
if let eloData = try? jsonDecoder.decode(EloDataForPeer.self, from: data) {
print("Recieved elo data: \(eloData.scoreToReport)")
EloHelper.reportScore(score: eloData.scoreToReport)
}
if let heartbeat = try? jsonDecoder.decode(Heartbeat.self, from: data) {
entityManager.getHUD()?.roundTimer.isHeartbeatLocked = false
let df = DateFormatter()
df.dateFormat = "yyyy-MM-dd HH:mm:ss"
let dateString = df.string(from: heartbeat.date)
print("Received last Heartbeat at \(dateString)")
}
MultiplayerNetwork.sharedInstance.isSending = false 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 { func initAndSendMap() -> Void {
self.gameScene = GameScene(size: self.menusc!.size) self.gameScene = GameScene(size: self.menusc!.size)
let mapModel = MapFactory(scene: self.gameScene!, entityManager: entityManager).load() let mapModel = MapFactory(scene: self.gameScene!, entityManager: entityManager).load()
@ -212,6 +258,7 @@ final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate, GKG
} }
return nilGK return nilGK
} }
func sendStateToPeers(state: State){ func sendStateToPeers(state: State){
let encoder = JSONEncoder() let encoder = JSONEncoder()
let encoded = (try? encoder.encode(state))! let encoded = (try? encoder.encode(state))!
@ -230,6 +277,7 @@ final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate, GKG
matchmakerVC!.matchmakerDelegate = self matchmakerVC!.matchmakerDelegate = self
viewController?.present(matchmakerVC!, animated: true, completion: nil) viewController?.present(matchmakerVC!, animated: true, completion: nil)
} }
func matchmakerViewControllerWasCancelled(_ viewController: GKMatchmakerViewController) { func matchmakerViewControllerWasCancelled(_ viewController: GKMatchmakerViewController) {
viewController.dismiss(animated: true, completion: nil) viewController.dismiss(animated: true, completion: nil)
} }

View File

@ -11,7 +11,8 @@ import SpriteKit
import GameplayKit import GameplayKit
class GameViewController: UIViewController { class GameViewController: UIViewController {
var currentScene: SKView?
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
@ -25,9 +26,8 @@ class GameViewController: UIViewController {
view.showsNodeCount = true view.showsNodeCount = true
} }
GameCenterManager.sharedInstance.viewController = self GameCenterManager.sharedInstance.viewController = self
} }
override var shouldAutorotate: Bool { override var shouldAutorotate: Bool {
return true return true
} }
@ -43,4 +43,5 @@ class GameViewController: UIViewController {
override var prefersStatusBarHidden: Bool { override var prefersStatusBarHidden: Bool {
return true return true
} }
} }

View File

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

View File

@ -15,15 +15,15 @@ class MultiplayerNetwork{
var isSending = false var isSending = false
func sendData(data: Data) { func sendData(data: Data) {
let mmHelper = GameCenterManager.sharedInstance let mmHelper = GameCenterManager.sharedInstance
if let multiplayerMatch = mmHelper.myMatch { if let multiplayerMatch = mmHelper.myMatch {
do { do {
try multiplayerMatch.sendData(toAllPlayers: data, with: .reliable) try multiplayerMatch.sendData(toAllPlayers: data, with: .reliable)
} catch { } catch {
} }
} }
} }
func sendDataToHost(data: Data) { func sendDataToHost(data: Data) {
@ -38,7 +38,6 @@ class MultiplayerNetwork{
func sendPlayerMoves(localRoundData: LocalRoundData) { func sendPlayerMoves(localRoundData: LocalRoundData) {
if GameCenterManager.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(localRoundData))! let encoded = (try? encoder.encode(localRoundData))!
@ -61,4 +60,21 @@ class MultiplayerNetwork{
sendData(data: encoded) sendData(data: encoded)
} }
func sendEloData(scoreToReport: GKScore) {
let encoder = JSONEncoder()
let encoded = (try? encoder.encode(EloDataForPeer(scoreToReport: scoreToReport.value)))!
sendData(data: encoded)
}
func sendNotificationToPlayer(name: String) {
let encoder = JSONEncoder()
let encoded = (try? encoder.encode(NotificationModel(name: name)))!
sendData(data: encoded)
}
func sendHeartbeatToPlayer() {
let encoder = JSONEncoder()
let encoded = (try? encoder.encode(Heartbeat(date: Date())))!
sendData(data: encoded)
}
} }

Binary file not shown.

Binary file not shown.

View File

@ -158,7 +158,16 @@ class RoundCalculatorService {
winner = determineWinner(by: "capture") winner = determineWinner(by: "capture")
} }
winner == GameCenterManager.sharedInstance.hostingPlayer?.displayName ? GameCenterManager.sharedInstance.sendStateToPeers(state: State(state: 4)) : GameCenterManager.sharedInstance.sendStateToPeers(state: State(state: 5)) 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 GameCenterManager.sharedInstance.winner = winner
GameCenterManager.sharedInstance.gameEnded = true
// Update EloSystem
if winner == GameCenterManager.sharedInstance.hostingPlayer?.displayName {
EloHelper.updateEloScore(winner: GameCenterManager.sharedInstance.hostingPlayer!, hatDenNikoGemacht: GameCenterManager.sharedInstance.peerPlayer!)
} else {
EloHelper.updateEloScore(winner: GameCenterManager.sharedInstance.peerPlayer!, hatDenNikoGemacht: GameCenterManager.sharedInstance.hostingPlayer!)
}
return return
} }
currentRound += 1 currentRound += 1

View File

@ -12,6 +12,7 @@ class RoundTimer: Timer {
var timer: Timer? var timer: Timer?
var timeLeft: Int = 0 var timeLeft: Int = 0
var isHeartbeatLocked = false
var calculate = false var calculate = false
var roundEnded = "Syncing" var roundEnded = "Syncing"
@ -29,27 +30,49 @@ class RoundTimer: Timer {
timeLeft = 30 timeLeft = 30
} }
func stopTimer() {
guard timer != nil else { return }
timer?.invalidate()
timer = nil
}
func resumeTimer() {
timer = Timer.scheduledTimer(
timeInterval: 1.0,
target: self,
selector: #selector(onTimerFires),
userInfo: nil,
repeats: true
)
}
@objc func onTimerFires() @objc func onTimerFires()
{ {
timeLeft -= 1 timeLeft -= 1
EntityManager.gameEMInstance.updateTime(time: (timeLeft > 0 ? String(timeLeft) : roundEnded)) EntityManager.gameEMInstance.updateTime(time: (timeLeft > 0 ? String(timeLeft) : roundEnded))
if timeLeft == 0 { if timeLeft == 0 {
EntityManager.gameEMInstance.removeModal()
RoundCalculatorService.sharedInstance.resetNumberOfAttacksAndFormats() RoundCalculatorService.sharedInstance.resetNumberOfAttacksAndFormats()
if !MultiplayerNetwork.sharedInstance.isSending { if !MultiplayerNetwork.sharedInstance.isSending {
MultiplayerNetwork.sharedInstance.sendPlayerMoves(localRoundData: DataService.sharedInstance.localRoundData) MultiplayerNetwork.sharedInstance.sendPlayerMoves(localRoundData: DataService.sharedInstance.localRoundData)
} }
calculate = true calculate = true
} }
if timeLeft <= 0 { if timeLeft <= 0 {
if calculate if calculate
&& !RoundCalculatorService.sharedInstance.isCalculating && !RoundCalculatorService.sharedInstance.isCalculating
&& DataService.sharedInstance.didReceiveAllData() && DataService.sharedInstance.didReceiveAllData()
&& GameCenterManager.sharedInstance.isServer { && GameCenterManager.sharedInstance.isServer {
RoundCalculatorService.sharedInstance.calculateRound() RoundCalculatorService.sharedInstance.calculateRound()
calculate = false calculate = false
} }
} }
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

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

View File

@ -17,46 +17,59 @@ class MenuScene: SKScene {
entityManager.setScene(scene: 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.add(Button(name: "startGameButton", entityManager.add(
textureName: "yellow_button04", Button(name: "startGameButton",
text: "Start Game", textureName: "gold_button_3",
position: CGPoint(x: midX, y: midY), text: "Start Game",
onButtonPress: { position: CGPoint(x: midX, y: midY + 90),
if CommandLine.arguments.contains("--no-matchmaking") { onButtonPress: {
self.loadScene(scene: GameScene(size: self.size)) if CommandLine.arguments.contains("--no-matchmaking") {
SoundManager.sharedInstance.stopMenuMusic() self.loadScene(scene: GameScene(size: self.size))
} else { SoundManager.sharedInstance.stopMenuMusic()
} else {
if GameCenterManager.isAuthenticated { if GameCenterManager.isAuthenticated {
GameCenterManager.sharedInstance.presentMatchmaker() GameCenterManager.sharedInstance.presentMatchmaker()
}else { } else {
GameCenterManager.sharedInstance.authUser() GameCenterManager.sharedInstance.authUser()
} }
} }
})) }
entityManager.add(Button(name: "settingsButton", )
textureName: "yellow_button04", )
text: "Settings", entityManager.add(
position: CGPoint(x: midX, y: midY - 80 ), Button(name: "settingsButton",
onButtonPress: { textureName: "gold_button_3",
let scene = SettingsScene(size: self.size) text: "Einstellungen",
self.loadScene(scene: scene) position: CGPoint(x: midX, y: midY ),
})) onButtonPress: { self.loadScene(scene: SettingsScene(size: self.size))}
entityManager.add(Button(name: "gameCenterButton", )
textureName: "yellow_button04", )
text: "GameCenter", entityManager.add(
position: CGPoint(x: midX, y: midY - 160), Button(name: "gameCenterButton",
onButtonPress: { textureName: "gold_button_3",
if GameCenterManager.isAuthenticated { text: "GameCenter",
GameCenterManager.sharedInstance.presentGameCenter() position: CGPoint(x: midX, y: midY - 90),
}else { onButtonPress: {
GameCenterManager.sharedInstance.authUser() if GameCenterManager.isAuthenticated {
} GameCenterManager.sharedInstance.presentGameCenter()
})) } else {
GameCenterManager.sharedInstance.authUser()
}
}
)
)
entityManager.add(
Button(name: "regelwerkButton",
textureName: "questionmark",
text: "",
position: CGPoint(x: self.size.width - 50, y: self.size.height - 50),
onButtonPress: { self.loadScene(scene: RulesScene(size: self.size)) }
)
)
entityManager.add(Background(size: self.size)) entityManager.add(Background(size: self.size))
entityManager.add(SpinningLogoEntity(position: CGPoint(x: midX, y: midY + 200))) entityManager.add(SpinningLogoEntity(sceneSize: self.size))
if SoundManager.sharedInstance.isMusicPlaying == false && SoundManager.sharedInstance.isMusicEnabled == true { if SoundManager.sharedInstance.isMusicPlaying == false && SoundManager.sharedInstance.isMusicEnabled == true && !CommandLine.arguments.contains("--no-music") && !UserDefaults.standard.bool(forKey: "noMusic"){
SoundManager.sharedInstance.startMenuMusic() SoundManager.sharedInstance.startMenuMusic()
} }
} }

View File

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

View File

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

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