Rhythm game where you have to headbang in the right direction to hit the notes.
Go to file
2025-01-13 18:03:02 +01:00
android feat: add launcher name and launcher icon 2025-01-11 17:14:41 +01:00
assets/icon feat: add launcher name and launcher icon 2025-01-11 17:14:41 +01:00
ios feat: add launcher name and launcher icon 2025-01-11 17:14:41 +01:00
lib feat: when selecting level show ESenseNotConnectedDialog if not connected to esense 2025-01-13 18:03:02 +01:00
linux feat: play audio on entering level and pause button 2024-12-23 03:18:39 +01:00
presentation feat: add presentation 2025-01-13 07:16:21 +01:00
test Initial Commit 2024-12-17 09:08:55 +01:00
.gitignore Initial Commit 2024-12-17 09:08:55 +01:00
.metadata Initial Commit 2024-12-17 09:08:55 +01:00
analysis_options.yaml Initial Commit 2024-12-17 09:08:55 +01:00
flutter_launcher_icons.yaml feat: add launcher name and launcher icon 2025-01-11 17:14:41 +01:00
LICENSE feat: add README and LICENSE 2025-01-11 20:31:01 +01:00
pubspec.lock feat: add launcher name and launcher icon 2025-01-11 17:14:41 +01:00
pubspec.yaml feat: add launcher name and launcher icon 2025-01-11 17:14:41 +01:00
README.md feat: add README and LICENSE 2025-01-11 20:31:01 +01:00

Sense the Rhythm

Rhythm game where you have to headbang in the right direction to hit the notes.

Source Code

Idee

Das Rhythmusspiel Sense the Rhythm ist eine Flutter-App für Android, bei dem der Nutzer durch Neigen des Kopfes im richtigen Moment Noten eines Liedes treffen muss, die ihm in Form von Pfeilen entgegenkommen.

Benutzung

Um die App nutzen zu können, werden Simfiles benötigt, welche Lieder, Bilder und Notendaten enthalten. Getestet wurde mit den Dateien, die man über 'Alle herunterladen' von dem In the Groove Pack bekommt. Die ZIP-Datei muss in einen Ordner auf dem Android-Gerät entpackt werden. Generell sind Beginner Packs, zum Beispiel von itgpacks.com, zu empfehlen, bei denen wenige Noten hintereinander und keine Noten parallel gespielt werden.

Sobald sich ein Ordner mit Simfiles auf dem Gerät befindet, kann dieser über den +-Knopf ausgewählt werden, woraufhin die Level in der Levelauswahl zu sehen sind.

Soll das ESense Earable als Eingabe genutzen werden (Pfeiltasten auf der Tastatur als Backup), muss das Bluetooth-Symbol oben rechts berührt werden. Daraufhin erscheint ein Dialog, in welchem der Name des linken Earbuds eingegeben wird. Der Name kann herausgefunden werden, indem der linken Earbud in den Bluetooth-Pairing-Modus gebracht und in den Bluetooth-Einstellungen des Betriebssystems nach den verfügbaren Geräten geschaut wird. Mehr Informationen gibt es in der offiziellen eSense-User-Documentation. Wurde der Name in den Dialog eingegeben, wird auf Connect gedrückt und gewartet bis der Text connected (nicht nur connecting...!) erscheint. Jetzt kann der Dialog mit Close geschlossen werden.

In der Levelauswahl kann nun ein Level ausgewählt werden, worauf das Level startet. Hier kann das Level pausiert und verlassen werden. Um das Level abzuschließen müssen die Noten getroffen werden, indem das ESense in die richtige Richtung geneigt oder die richtige Pfeiltaste in die auf einer Tastatur gedrückt wird.

Am Ende erscheint eine Statistik wie viele Noten getroffen und verfehlt wurden, sowie die Option das Level zu wiederholen oder zu verlassen.

Code-Qualität

Der Code ist in eine Ordnerstruktur gegliedert, welche aufgeteilt ist in /models, /utils, /screens und /widgets. Alle Imports sind durch absolute Pfade repräsentiert.

Alle Dateien wurden einheitlich mit dem Code-Formatter des Dart-Language-Servers formatiert.

Dokumentation

Alle Methoden werden durch dart doc comments /// beschrieben. Komplizierte Code-Stellen werden durch Kommentare erweitert. Diese README dient dem Nutzer als Dokumentation zur Nutzung der App.

Technische Raffinesse

Ihre Umsetzung ist nicht trivial (zum Beispiel verarbeiten Sie Sensordaten, Nutzen APIs etc.), Gesamtumfang > 400 Zeilen

Für die Umsetzung der App wurde ein eigener Parser für Simfiles geschrieben. Dieser kann Tags, wie Titel, BPM oder Dateinamen zu Banner und Musik einlesen. Außerdem werden die Charts mit sämtlichen Noten eingelesen. Diese Daten werden sowohl in den Levels, als auch in der Levelauswahl benutzt.

Zum Laden des ITG Packs wird das file-picker Plugin benutzt und Berechtigungen im Manifest und zur Laufzeit gesetzt (für neue Android-Versionen ist dafür leider kompletter Speicherzugriff nötig). Damit der ausgewählte Ordner beim nächsten Starten der App bestehen bleibt, wird der Pfad mit dem Plugin shared_preferences persistent gespeichert.

Die Musik wird mit dem audioplayer Plugin abgespielt. Außerdem werden die Zeitinformationen genutzt, um die Noten als Pfeile zu zeigen, welche sich basierend auf dem Fortschritt des Liedes bewegen. Die Daten des ESense und Tastatur werden in den Zeitabfragen genutzt, um zu prüfen, ob die Note getroffen oder verfehlt wurde und die entsprechende Nachricht anzuzeigen. Für die Nachricht wurde sich mit dem AnimationController befasst.

Das esense_flutter Plugin wird direkt vom GitHub-Repo bezogen, damit es bei aktuellen Flutter-Versionen benutzt werden kann. Der ESense-Input wird als globaler Service implementiert, wodurch er in jedem Widget verfügbar ist, ohne dass man es jedem Widget übergeben müsste. Von dem ESense Earable werden Daten über die Verbindung, den Zustand des Knopfes und Gyroskop-Daten abgefragt. Über den Knopf lässt sich das Level pausieren und weiterspielen. Die Neigung des ESense wird über die Gyroskop-Daten berechnet, indem die Bewegungsänderungen mit dem Standard-Skalierungsfaktor und der Delta-Zeit skaliert und für jede Messung mit der bisherigen Neigung verrechnet wird. Die Neigung wird bei jeder getroffenen Note neu kalibriert. Ob die Note getroffen wurde wird geprüft, indem getestet wird ob sich die Neigung in einem definierten Wertebereich befindet.

Die Launcher-Icons und Launcher-Name wurden durch die Plugins flutter_launcher_icons und flutter_app_name automatisch für Größen und gewünschten Plattformen erstellt.

Präsentation

Siehe /presentation

Used Libraries

License

This project is licensed under the GPL-3 License - see the LICENSE file for details