Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add state management for map markers and circles in GameplayMap #237

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 71 additions & 39 deletions game/lib/gameplay/gameplay_map.dart
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,25 @@ class GameplayMap extends StatefulWidget {
State<GameplayMap> createState() => _GameplayMapState();
}

/// GameplayMap State
///
/// Manages the state and functionality for the GameplayMap widget.
///
/// State Fields:
/// - METERS_TO_DEGREES: Conversion constant for geographic calculations
/// - mapCompleter: Manages async initialization of Google Maps
/// - positionStream: Handles location update subscription
/// - currentLocation: Tracks user's current position
/// - totalHints: Maximum hints allowed
/// - numHintsLeft: Remaining available hints
/// - hintRadius: Current size of hint circle
/// - isExpanded: Image expansion state
/// - isArrivedButtonEnabled: Arrival button interaction state
///
/// @param widget - Reference to the parent GameplayMap widget (with same fields)
///
/// @returns State object managing the GameplayMap's interactive elements and location tracking

class _GameplayMapState extends State<GameplayMap> {
final METERS_TO_DEGREES = 111139;

Expand Down Expand Up @@ -92,12 +111,62 @@ class _GameplayMapState extends State<GameplayMap> {
// Add this to your state variables (After isExapnded)
bool isArrivedButtonEnabled = true;

Set<Marker> _markers = {};
Set<Circle> _circles = {};

@override
void didUpdateWidget(GameplayMap oldWidget) {
super.didUpdateWidget(oldWidget);
// Check if target location changed
if (oldWidget.targetLocation != widget.targetLocation) {
_updateMapMarkers();
}
}

void _updateMapMarkers() {
setState(() {
// Update the target location marker
_markers = {
Marker(
markerId: MarkerId('targetLocation'),
position:
LatLng(widget.targetLocation.lat, widget.targetLocation.long),
icon: BitmapDescriptor.defaultMarker,
),
Marker(
markerId: MarkerId("currentLocation"),
icon: currentLocationIcon,
position: currentLocation == null
? _center
: LatLng(currentLocation!.lat, currentLocation!.long),
anchor: Offset(0.5, 0.5),
rotation: currentLocation == null ? 0 : currentLocation!.heading,
),
};

// Update the hint circle
_circles = {
Circle(
circleId: CircleId('hintCircle'),
center: hintCenter != null
? LatLng(hintCenter!.lat, hintCenter!.long)
: _center,
radius: (hintRadius ?? defaultHintRadius),
strokeColor: Color.fromARGB(80, 30, 41, 143),
strokeWidth: 2,
fillColor: Color.fromARGB(80, 83, 134, 237),
)
};
});
}

@override
void initState() {
setCustomMarkerIcon();
super.initState();
streamStarted = startPositionStream();
setStartingHintCircle();
_updateMapMarkers();
}

@override
Expand Down Expand Up @@ -355,21 +424,6 @@ class _GameplayMapState extends State<GameplayMap> {
body: Stack(
alignment: Alignment.bottomCenter,
children: [
StreamBuilder(
stream: client.clientApi.disconnectedStream,
builder: ((context, snapshot) {
if (client.serverApi == null) {
WidgetsBinding.instance.addPostFrameCallback((_) {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => SplashPageWidget()));
displayToast("Lost connection!", Status.success);
});
}

return Container();
})),
Listener(
onPointerDown: (e) {
cancelRecenterCamera();
Expand All @@ -388,30 +442,8 @@ class _GameplayMapState extends State<GameplayMap> {
: LatLng(currentLocation!.lat, currentLocation!.lat),
zoom: 11,
),
markers: {
Marker(
markerId: const MarkerId("currentLocation"),
icon: currentLocationIcon,
position: currentLocation == null
? _center
: LatLng(currentLocation!.lat, currentLocation!.long),
anchor: Offset(0.5, 0.5),
rotation:
currentLocation == null ? 0 : currentLocation!.heading,
),
},
circles: {
Circle(
circleId: CircleId("hintCircle"),
center: hintCenter != null
? LatLng(hintCenter!.lat, hintCenter!.long)
: _center,
radius: (hintRadius ?? defaultHintRadius),
strokeColor: Color.fromARGB(80, 30, 41, 143),
strokeWidth: 2,
fillColor: Color.fromARGB(80, 83, 134, 237),
)
},
markers: _markers,
circles: _circles,
),
),
Container(
Expand Down
24 changes: 24 additions & 0 deletions game/lib/gameplay/gameplay_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,30 @@ import 'package:game/progress_indicators/circular_progress_indicator.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'dart:async';

/// GameplayPage Widget
///
/// Manages the gameplay experience by combining the map interface with challenge information
/// and progress tracking.
///
/// @remarks
/// This widget serves as the main container for gameplay, coordinating between the interactive
/// map and challenge status displays. It handles location tracking, challenge progress,
/// and provides real-time feedback about the user's distance from targets and points.
/// The widget integrates with various game models to maintain state and track progress.
///
/// The page is structured with:
/// - A header showing challenge information and progress
/// - The main gameplay map for navigation
/// - Interactive elements for hints and location tracking
///
/// @param key - Optional widget key for identification and testing
///
/// @returns A StatefulWidget that provides the complete gameplay interface, including:
/// - Challenge description and location details
/// - Distance tracking and point calculations
/// - Interactive map interface
/// - Navigation controls

class GameplayPage extends StatefulWidget {
const GameplayPage({Key? key}) : super(key: key);

Expand Down
36 changes: 18 additions & 18 deletions game/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -553,10 +553,10 @@ packages:
dependency: "direct main"
description:
name: intl
sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
url: "https://pub.dev"
source: hosted
version: "0.18.1"
version: "0.19.0"
js:
dependency: transitive
description:
Expand Down Expand Up @@ -593,26 +593,26 @@ packages:
dependency: transitive
description:
name: leak_tracker
sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa"
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
url: "https://pub.dev"
source: hosted
version: "10.0.0"
version: "10.0.5"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
url: "https://pub.dev"
source: hosted
version: "2.0.1"
version: "3.0.5"
leak_tracker_testing:
dependency: transitive
description:
name: leak_tracker_testing
sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
url: "https://pub.dev"
source: hosted
version: "2.0.1"
version: "3.0.1"
linkify:
dependency: transitive
description:
Expand Down Expand Up @@ -681,18 +681,18 @@ packages:
dependency: transitive
description:
name: material_color_utilities
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
url: "https://pub.dev"
source: hosted
version: "0.8.0"
version: "0.11.1"
meta:
dependency: transitive
description:
name: meta
sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
url: "https://pub.dev"
source: hosted
version: "1.11.0"
version: "1.15.0"
mgrs_dart:
dependency: transitive
description:
Expand Down Expand Up @@ -1078,10 +1078,10 @@ packages:
dependency: transitive
description:
name: test_api
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
url: "https://pub.dev"
source: hosted
version: "0.6.1"
version: "0.7.2"
tuple:
dependency: "direct main"
description:
Expand Down Expand Up @@ -1214,18 +1214,18 @@ packages:
dependency: "direct main"
description:
name: velocity_x
sha256: "38585b8ed87c17ccb42a5c13d55bdafdc65e7cd3f41dceb61c38714c758fa228"
sha256: "99b910c80cc2010b184ef921f0af6894a8d632e13169cf77e6f6cb5a7f310698"
url: "https://pub.dev"
source: hosted
version: "4.1.2"
version: "4.2.1"
vm_service:
dependency: transitive
description:
name: vm_service
sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
url: "https://pub.dev"
source: hosted
version: "13.0.0"
version: "14.2.5"
vxstate:
dependency: transitive
description:
Expand Down
Loading