๐งญ Compass Game Mode (Developer Docs)
The CompassFragment implements the Compass Game Mode in zMantra.
This mode challenges players to physically rotate their device toward a target compass direction (e.g., North, South-East, West).
It integrates Androidโs accelerometer and magnetometer sensors, custom accessibility announcements, and real-time feedback.
๐ Location
com.zendalona.zmantra.presentation.features.game.compass.CompassFragment
๐ Core Responsibilities
- Sensor Management
- Uses
SensorManager
to register the Accelerometer and Magnetometer. - Calculates device orientation with
SensorManager.getRotationMatrix()
. -
Converts orientation to azimuth (0โ360ยฐ).
-
Game Question Flow
- Loads compass questions (
GameQuestion
objects). - Each question specifies a target direction (e.g., "North").
-
Players must rotate the device and hold it in the target direction for 3 seconds.
-
Accessibility & Feedback
- Announces each new question with TalkBack / TTS.
- Periodically announces the current facing direction (every 10 seconds).
-
Provides spoken and visual feedback on correct orientation.
-
Game Result
- Calculates grade based on time taken vs questionโs time limit.
- Shows result dialog, then proceeds to the next question.
โ๏ธ Key Fields
Variable | Type | Purpose |
---|---|---|
sensorManager |
SensorManager |
Access to device sensors. |
magnetometer , accelerometer |
Sensor? |
Required sensors for orientation. |
rotationMatrix , orientation |
FloatArray |
Store orientation math results. |
currentAzimuth |
Float |
Current compass azimuth in degrees. |
targetDirection |
Float |
Target direction in degrees (from question). |
questions |
MutableList<GameQuestion> |
Loaded compass questions. |
holdHandler |
Handler |
Used to check if user holds correct direction for 3s. |
directionAnnounceHandler |
Handler |
Announces direction every 10s for accessibility. |
๐ Lifecycle
- onAttach() โ Initialize
SensorManager
, get sensors. - onCreateView() โ Inflate layout, load compass directions from
strings.xml
. - onViewCreated() โ Announce "Turn to ..." instruction.
- onQuestionsLoaded() โ Populate questions & call
generateNewQuestion()
. - generateNewQuestion() โ
- Set new
targetDirection
. - Announce question.
- Start periodic announcements.
- onSensorChanged() โ
- Collect accelerometer & magnetometer values.
- Compute azimuth.
- Call
updateCompassUI()
. - updateCompassUI() โ Update rotation + check if holding correct direction.
- checkIfHoldingCorrectDirection() โ
- If user holds within ยฑ22.5ยฐ of target for 3s โ trigger success.
๐ Orientation Logic
```kotlin SensorManager.getRotationMatrix(rotationMatrix, null, lastAccelerometer, lastMagnetometer) SensorManager.getOrientation(rotationMatrix, orientation)
val azimuth = Math.toDegrees(orientation[0].toDouble()).toFloat() val azimuthFixed = (azimuth + 360) % 360 ````
azimuth
โ Raw compass heading.azimuthFixed
โ Normalized value (0โ360ยฐ).
๐ง Accessibility
-
Announcements:
-
At question start โ
"Turn to North"
- Every 10s โ
"Currently facing East"
- TalkBack users can still navigate UI, but spoken feedback is automatic.
- This ensures blind learners can orient their device correctly.
๐งช Testing Notes
- Test in environments without strong magnetic interference.
- Validate with both sighted mode (UI compass rotates) and TalkBack mode (spoken feedback only).
-
Edge cases:
-
Missing sensors โ show
"No compass questions found"
and end game. - Holding at borderline angle (22.5ยฐ threshold).