README.md (5738B)
1 <div align="center"> 2 <img src="assets/icon/icon.svg" width="300"> 3 4 # Sense the Rhythm 5 > Rhythm game where you have to headbang in the right direction to hit the notes. 6 7 [Source Code](https://source.orangerot.dev/university/sense_the_rhythm) 8 </div> 9 10 ## Idee 11 Das Rhythmusspiel **Sense the Rhythm** ist eine Flutter-App für Android, bei dem 12 der Nutzer durch Neigen des Kopfes im richtigen Moment Noten eines Liedes 13 treffen muss, die ihm in Form von Pfeilen entgegenkommen. 14 15 ## Benutzung 16 17 > Getestet auf einem Oneplus 6 mit Android 13 18 19 Um die App nutzen zu können, werden Simfiles benötigt, welche Lieder, Bilder und 20 Notendaten enthalten. Getestet wurde mit den Dateien, die man über 'Alle 21 herunterladen' von dem [In the Groove Pack](https://drive.google.com/drive/folders/1sIhv4_STnyqXiauMx3BUco0m-a5VEpYy) 22 bekommt. Die ZIP-Datei muss in einen Ordner auf dem Android-Gerät entpackt 23 werden. Generell sind `Beginner Packs`, zum Beispiel von itgpacks.com, zu 24 empfehlen, bei denen wenige Noten hintereinander und keine Noten parallel 25 gespielt werden. 26 27 Sobald sich ein Ordner mit Simfiles auf dem Gerät befindet, kann dieser über 28 den `+`-Knopf ausgewählt werden, woraufhin die Level in der Levelauswahl zu 29 sehen sind. 30 31 Soll das ESense Earable als Eingabe genutzen werden (Pfeiltasten auf der Tastatur 32 als Backup), muss das Bluetooth-Symbol oben rechts berührt werden. Daraufhin 33 erscheint ein Dialog, in welchem der Name des linken Earbuds eingegeben wird. Der 34 Name kann herausgefunden werden, indem der linken Earbud in den 35 Bluetooth-Pairing-Modus gebracht und in den Bluetooth-Einstellungen des 36 Betriebssystems nach den verfügbaren Geräten geschaut wird. Mehr Informationen 37 gibt es in der offiziellen eSense-User-Documentation. Wurde der Name in den 38 Dialog eingegeben, wird auf `Connect` gedrückt und gewartet bis der Text `connected` 39 (nicht nur `connecting...`!) erscheint. Jetzt kann der Dialog mit `Close` 40 geschlossen werden. 41 42 In der Levelauswahl kann nun ein Level ausgewählt werden, worauf das Level 43 startet. Hier kann das Level pausiert und verlassen werden. Um das Level 44 abzuschließen müssen die Noten getroffen werden, indem das ESense in die 45 richtige Richtung geneigt oder die richtige Pfeiltaste in die auf einer 46 Tastatur gedrückt wird. 47 48 Am Ende erscheint eine Statistik wie viele Noten getroffen und verfehlt wurden, 49 sowie die Option das Level zu wiederholen oder zu verlassen. 50 51 ## Code-Qualität 52 53 Der Code ist in eine Ordnerstruktur gegliedert, welche aufgeteilt ist in 54 `/models`, `/utils`, `/screens` und `/widgets`. Alle Imports sind durch absolute 55 Pfade repräsentiert. 56 57 Alle Dateien wurden einheitlich mit dem Code-Formatter des Dart-Language-Servers 58 formatiert. 59 60 ## Dokumentation 61 62 Alle Methoden werden durch dart doc comments `///` beschrieben. Komplizierte 63 Code-Stellen werden durch Kommentare erweitert. Diese `README` dient dem Nutzer 64 als Dokumentation zur Nutzung der App. 65 66 ## Technische Raffinesse 67 68 > Ihre Umsetzung ist nicht trivial (zum Beispiel verarbeiten Sie 69 Sensordaten, Nutzen APIs etc.), Gesamtumfang > 400 Zeilen 70 71 Für die Umsetzung der App wurde ein eigener Parser für 72 [Simfiles](https://github.com/stepmania/stepmania/wiki/sm) geschrieben. Dieser 73 kann Tags, wie Titel, BPM oder Dateinamen zu Banner und Musik einlesen. Außerdem 74 werden die `Charts` mit sämtlichen Noten eingelesen. Diese Daten werden sowohl 75 in den Levels, als auch in der Levelauswahl benutzt. 76 77 Zum Laden des ITG Packs wird das `file-picker` Plugin benutzt und Berechtigungen 78 im Manifest und zur Laufzeit gesetzt (für neue Android-Versionen ist dafür 79 leider kompletter Speicherzugriff nötig). Damit der ausgewählte Ordner beim 80 nächsten Starten der App bestehen bleibt, wird der Pfad mit dem Plugin 81 `shared_preferences` persistent gespeichert. 82 83 Die Musik wird mit dem `audioplayer` Plugin abgespielt. Außerdem werden die 84 Zeitinformationen genutzt, um die Noten als Pfeile zu zeigen, welche sich 85 basierend auf dem Fortschritt des Liedes bewegen. Die Daten des ESense und 86 Tastatur werden in den Zeitabfragen genutzt, um zu prüfen, ob die Note getroffen 87 oder verfehlt wurde und die entsprechende Nachricht anzuzeigen. Für die 88 Nachricht wurde sich mit dem AnimationController befasst. 89 90 Das `esense_flutter` Plugin wird direkt vom GitHub-Repo bezogen, damit es bei 91 aktuellen Flutter-Versionen benutzt werden kann. Der ESense-Input wird als 92 globaler Service implementiert, wodurch er in jedem Widget verfügbar ist, ohne 93 dass man es jedem Widget übergeben müsste. Von dem ESense Earable werden Daten 94 über die Verbindung, den Zustand des Knopfes und Gyroskop-Daten abgefragt. Über 95 den Knopf lässt sich das Level pausieren und weiterspielen. Die Neigung des 96 ESense wird über die Gyroskop-Daten berechnet, indem die Bewegungsänderungen mit 97 dem Standard-Skalierungsfaktor und der Delta-Zeit skaliert und für jede Messung 98 mit der bisherigen Neigung verrechnet wird. Die Neigung wird bei jeder 99 getroffenen Note neu kalibriert. Ob die Note getroffen wurde wird geprüft, indem 100 getestet wird ob sich die Neigung in einem definierten Wertebereich befindet. 101 102 Die Launcher-Icons und Launcher-Name wurden durch die Plugins 103 `flutter_launcher_icons` und `flutter_app_name` automatisch für Größen und 104 gewünschten Plattformen erstellt. 105 106 ## Präsentation 107 108 Siehe `/presentation` 109 110 ## Used Libraries 111 112 - https://github.com/cph-cachet/flutter-plugins.git 113 - https://pub.dev/packages/shared_preferences 114 - https://pub.dev/packages/file_picker 115 - https://pub.dev/packages/audioplayers 116 - https://pub.dev/packages/permission_handler 117 - https://pub.dev/packages/flutter_launcher_icons 118 - https://pub.dev/packages/flutter_app_name 119 120 ## License 121 122 This project is licensed under the GPL-3 License - see the `LICENSE` file for details