diff --git a/Dashboard/lib/model/Class.dart b/Dashboard/lib/model/Class.dart index 797ee9d..9b5d914 100644 --- a/Dashboard/lib/model/Class.dart +++ b/Dashboard/lib/model/Class.dart @@ -1,203 +1,226 @@ import 'package:firebase_database/firebase_database.dart'; import 'package:Teacher_Dashboard/model/Group.dart'; import 'package:flutter/widgets.dart'; import 'package:Teacher_Dashboard/model/Group.dart'; import 'package:Teacher_Dashboard/model/activities/activity.Dart'; import 'dart:async'; import 'dart:convert'; Classroom thisClass = new Classroom("1"); class Classroom extends ChangeNotifier { int inactivity; String sessionID = 'SPIA'; String teacherName; int numGroups = 0; List groups = new List(); List groupIDs = new List(); Classroom(this.sessionID); final FirebaseDatabase _database = FirebaseDatabase.instance; StreamSubscription _ongroupAddedSubscription; StreamSubscription _ongroupChangedSubscription; StreamSubscription _onattemptAddedSubscription; StreamSubscription _oninactivityAddedSubscription; StreamSubscription _onrobotpositionAddedSubscription; void toAggregate() {} void desetupDatabse() { _ongroupAddedSubscription.cancel(); _ongroupChangedSubscription.cancel(); _onattemptAddedSubscription.cancel(); notifyListeners(); } void setupDatabse() { _ongroupAddedSubscription = _database .reference() .child(thisClass.sessionID) .child("groups") .onChildAdded .listen(onGroupAdded); _ongroupChangedSubscription = _database .reference() .child(thisClass.sessionID) .child("groups") .onChildChanged .listen(onGroupChanged); _onattemptAddedSubscription = _database .reference() .child(thisClass.sessionID) .child("attempts") .onChildAdded .listen(onAttemptAdded); _oninactivityAddedSubscription = _database .reference() .child(thisClass.sessionID) .child("celluloPosition") .onChildAdded .listen(oncelluloPositionAdded); //Query _todoQuery; } onGroupAdded(Event event) { Group newgroup = new Group(event.snapshot.value['id']); newgroup.member1name = event.snapshot.value['member1name']; newgroup.member2name = event.snapshot.value['member2name']; newgroup.member3name = event.snapshot.value['member3name']; thisClass.groups.add(newgroup); thisClass.groupIDs.add(event.snapshot.value['id']); notifyListeners(); } onGroupChanged(Event event) { //thisClass.groups.add(Group.fromSnapshot(event.snapshot)); int currentGroup = thisClass.groupIDs.indexOf(event.snapshot.key); // print("group" + currentGroup.toString().toString()); thisClass.groups[currentGroup].currentActivity = (event.snapshot.value)['currentActivity'].toString(); thisClass.groups[currentGroup].tabletStatus = (event.snapshot.value)['tabletStatus'].toString(); // setState(() {}); notifyListeners(); //print(thisClass.groups[currentGroup].currentActivity.toString()); } onAttemptAdded(Event event) { // print(jsonDecode(event.snapshot.value)['acID'].toString()); int currentGroup = thisClass.groupIDs.indexOf(jsonDecode(event.snapshot.value)['groupID']); int currentActivity = acList.indexOf(jsonDecode(event.snapshot.value)['acID'].toString()); thisClass.groups[currentGroup].currentActivity = acList[currentActivity]; int currentTurn = (jsonDecode(event.snapshot.value)['currentTurn']); thisClass .groups[currentGroup] .activities[currentActivity] .turns[currentTurn - 1] .numAttempts = jsonDecode(event.snapshot.value)['numAttempts']; thisClass.groups[currentGroup].activities[currentActivity].elapsedTime = jsonDecode(event.snapshot.value)['elpasedTime']; thisClass .groups[currentGroup] .activities[currentActivity] .turns[currentTurn - 1] .elapsedTime = jsonDecode(event.snapshot.value)['elpasedTime']; //print(jsonDecode(event.snapshot.value)['elpasedTime']); var progressmsg = jsonDecode((event.snapshot.value))['progress']; thisClass.groups[currentGroup].activities[currentActivity].progress[0] = progressmsg['turn1']; thisClass.groups[currentGroup].activities[currentActivity].progress[1] = progressmsg['turn2']; thisClass.groups[currentGroup].activities[currentActivity].progress[2] = progressmsg['turn3']; var mistakemsg = jsonDecode(event.snapshot.value)['mistakes']; var mistakemsgturn1 = (mistakemsg['turn1']); var mistakemsgturn2 = (mistakemsg['turn2']); var mistakemsgturn3 = (mistakemsg['turn3']); thisClass.groups[currentGroup].activities[currentActivity].mistakes['slope'] [0] = mistakemsgturn1['slope']; thisClass.groups[currentGroup].activities[currentActivity] .mistakes['initialPoint'][0] = mistakemsgturn1['initialPoint']; thisClass.groups[currentGroup].activities[currentActivity].mistakes['slope'] [1] = mistakemsgturn2['slope']; thisClass.groups[currentGroup].activities[currentActivity] .mistakes['initialPoint'][1] = mistakemsgturn2['initialPoint']; thisClass.groups[currentGroup].activities[currentActivity].mistakes['slope'] [2] = mistakemsgturn3['slope']; thisClass.groups[currentGroup].activities[currentActivity] .mistakes['initialPoint'][2] = mistakemsgturn3['initialPoint']; thisClass.groups[currentGroup].activities[currentActivity].turns[0] .mistakes['slope'] = mistakemsgturn1['slope']; thisClass.groups[currentGroup].activities[currentActivity].turns[0] .mistakes['initialPoint'] = mistakemsgturn1['initialPoint']; thisClass.groups[currentGroup].activities[currentActivity].turns[0] .mistakes['intercept'] = mistakemsgturn1['intercept']; thisClass.groups[currentGroup].activities[currentActivity].turns[1] .mistakes['slope'] = mistakemsgturn2['slope']; thisClass.groups[currentGroup].activities[currentActivity].turns[1] .mistakes['initialPoint'] = mistakemsgturn2['initialPoint']; thisClass.groups[currentGroup].activities[currentActivity].turns[1] .mistakes['intercept'] = mistakemsgturn2['intercept']; thisClass.groups[currentGroup].activities[currentActivity].turns[2] .mistakes['slope'] = mistakemsgturn3['slope']; thisClass.groups[currentGroup].activities[currentActivity].turns[2] .mistakes['initialPoint'] = mistakemsgturn3['initialPoint']; thisClass.groups[currentGroup].activities[currentActivity].turns[2] .mistakes['intercept'] = mistakemsgturn3['intercept']; notifyListeners(); } onInactivityAdded(Event event) { // print(jsonDecode(event.snapshot.value)['acID'].toString()); // int currentGroup = // thisClass.groupIDs.indexOf(jsonDecode(event.snapshot.value)['groupID']); // int currentActivity = // acList.indexOf(jsonDecode(event.snapshot.value)['acID'].toString()); //thisClass.groups[currentGroup].inactivity[currentstepActivation] = // (jsonDecode(event.snapshot.value)['inactivity']); //print(thisClass.groups[currentGroup].inactivity); //currentstepActivation = currentstepActivation + 1; notifyListeners(); } oncelluloPositionAdded(Event event) { int currentGroup = thisClass.groupIDs.indexOf(jsonDecode(event.snapshot.value)['groupID']); int currentActivity = acList.indexOf(jsonDecode(event.snapshot.value)['acID'].toString()); int currentTurn = 0; // print(currentGroup.toString()); if (jsonDecode(event.snapshot.value)['turn'].toString() == '1') currentTurn = 1; if (jsonDecode(event.snapshot.value)['turn'].toString() == '2') currentTurn = 2; if (jsonDecode(event.snapshot.value)['turn'].toString() == '3') currentTurn = 3; // print(currentTurn); // int currentActivity = // acList.indexOf(jsonDecode(event.snapshot.value)['acID'].toString()); // print((jsonDecode(event.snapshot.value)['x'])); if (currentGroup != -1) { + var xlen = thisClass.groups[currentGroup].activities[currentActivity] + .turns[currentTurn - 1].cellulox.x.length; + + double vy = (jsonDecode(event.snapshot.value)['y']) - + thisClass.groups[currentGroup].activities[currentActivity] + .turns[currentTurn - 1].celluloy.y[xlen - 1]; + double vx = (jsonDecode(event.snapshot.value)['x']) - + thisClass.groups[currentGroup].activities[currentActivity] + .turns[currentTurn - 1].cellulox.x[xlen - 1]; thisClass.groups[currentGroup].activities[currentActivity] .turns[currentTurn - 1].cellulox.x .add((jsonDecode(event.snapshot.value)['x'])); // print((jsonDecode(event.snapshot.value)['y'])); thisClass.groups[currentGroup].activities[currentActivity] .turns[currentTurn - 1].celluloy.y .add((jsonDecode(event.snapshot.value)['y'])); + if (vx.abs() < 1) + thisClass.groups[currentGroup].activities[currentActivity] + .turns[currentTurn - 1].cellulox.vx + .add(0); + else { + thisClass.groups[currentGroup].activities[currentActivity] + .turns[currentTurn - 1].cellulox.vx + .add((vy ~/ vx) * 1); + print('vvv' + (vy ~/ vx).toString()); + print('vvvlist' + + (thisClass.groups[currentGroup].activities[currentActivity] + .turns[currentTurn - 1].cellulox.vx) + .toString()); + } } // thisClass.groups[currentGroup].celluloy.y // .add((jsonDecode(event.snapshot.value)['y'] / 40)) // setState(() {}); notifyListeners(); } } diff --git a/Dashboard/lib/model/cellulo.dart b/Dashboard/lib/model/cellulo.dart index 8532051..1ac0bf0 100644 --- a/Dashboard/lib/model/cellulo.dart +++ b/Dashboard/lib/model/cellulo.dart @@ -1,21 +1,22 @@ import 'package:firebase_database/firebase_database.dart'; import 'package:flutter/rendering.dart'; //Activity ac7 = new Activity("Ac7"); //Activity ac8 = new Activity("Ac8"); //List acList = ['Ac7', 'Ac8']; class Cellulo { String id; // String _title; // String _description; int numAttempts = 0; int currentTurn = 1; int elapsedTime = 0; List x = [0.0]; List y = [0.0]; - + List vx = [0]; + List vy = [0.0]; Cellulo(); } diff --git a/Dashboard/lib/screens/Debriefing.dart b/Dashboard/lib/screens/Debriefing.dart index 2b10621..ed6cd20 100644 --- a/Dashboard/lib/screens/Debriefing.dart +++ b/Dashboard/lib/screens/Debriefing.dart @@ -1,271 +1,273 @@ import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:Teacher_Dashboard/widgets/custom_app_bar.dart'; import 'dart:convert'; import 'package:Teacher_Dashboard/config/palette.dart'; import 'package:Teacher_Dashboard/config/styles.dart'; import 'dart:async'; import './screens.dart'; import 'package:Teacher_Dashboard/model/Class.dart'; import 'package:Teacher_Dashboard/model/Group.dart'; import 'package:firebase_database/firebase_database.dart'; import 'package:Teacher_Dashboard/model/activities/activity.Dart'; import 'package:step_progress_indicator/step_progress_indicator.dart'; import 'package:Teacher_Dashboard/widgets/hexagonPainter.Dart'; import 'package:Teacher_Dashboard/widgets/celluloMap.Dart'; import 'package:provider/provider.dart'; //import 'package:Teacher_Dashboard/model/core/models/productModel.dart'; //import 'package:Teacher_Dashboard/model/core/viewmodels/CRUDModel.dart'; //import 'package:provider/provider.dart'; class Debriefing extends StatefulWidget { @override DebriefingState createState() => DebriefingState(); } class DebriefingState extends State { bool mistakesSwitch = false; bool rankingSwitch = false; bool robotPatternSwitch = true; int numofgroups = thisClass.groups.length; int currentstepActivation = 0; String pauseButtonText = 'Pause All'; final FirebaseDatabase _database = FirebaseDatabase.instance; @override void initState() { super.initState(); } @override void dispose() { super.dispose(); } @override Widget build(BuildContext context) { // final productProvider = Provider.of(context); return Scaffold( backgroundColor: Colors.white, appBar: CustomAppBar(), body: Column(children: [ SizedBox( height: 800, child: Consumer( builder: (context, model, child) => Container( child: ListView.builder( itemCount: thisClass.groups.length, itemBuilder: (context, int position) { return Card( child: ListTile( onLongPress: () { Navigator.push( context, MaterialPageRoute( builder: (context) => GroupDashboard(currentgroupID: position))); }, title: Column(children: [ Row(children: [ SizedBox(width: 17), Stack(children: [ CircularStepProgressIndicator( totalSteps: 3, // currentStep: // thisClass.groups[position].activities[0].progress, width: 100, customColor: (index) => thisClass .groups[position] .activities[acList.indexOf(thisClass .groups[position] .currentActivity)] .progress[index] > -2 ? (thisClass .groups[position] .activities[acList.indexOf( thisClass.groups[position] .currentActivity)] .progress[index] > -1 ? (thisClass .groups[position] .activities[acList.indexOf(thisClass.groups[position].currentActivity)] .progress[index] > 0 ? Colors.green : Colors.blue) : Colors.red) : Colors.grey, ), Positioned( bottom: 45, right: 28, child: Center( child: Text( thisClass.groups[position].id, style: TextStyle( fontWeight: FontWeight.bold, fontSize: 13), )), ), ]), SizedBox(width: 25), minituare(position, 1, mistakesSwitch, rankingSwitch, robotPatternSwitch), SizedBox( width: 25, ), minituare(position, 2, mistakesSwitch, rankingSwitch, robotPatternSwitch), SizedBox( width: 25, ), minituare(position, 3, mistakesSwitch, rankingSwitch, robotPatternSwitch), ]), SizedBox(height: 20), ]), trailing: Icon(Icons.more_vert), )); }, )), )), /* Row( // mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( 'Show Students Mistakes', style: TextStyle( fontSize: 15.0, // color: Colors.white, fontWeight: FontWeight.bold), ), SizedBox(width: 5), Checkbox( //title: const Text('Animate Slowly'), value: mistakesSwitch, onChanged: (bool value) { setState(() { mistakesSwitch = value; }); }, // secondary: const Icon(Icons.hourglass_empty), ), SizedBox(width: 300), /* Text( 'Show Students robot pattern', style: TextStyle( fontSize: 15.0, // color: Colors.white, fontWeight: FontWeight.bold), ), SizedBox(width: 5), Checkbox( value: robotPatternSwitch, onChanged: (bool value) { setState(() { robotPatternSwitch = value; }); }, // secondary: const Icon(Icons.hourglass_empty), ), */ ]), */ ])); } } Widget minituare(int position, int turn, bool mistakesSwitch, bool rankingSwitch, bool robotpatternSwitch) { var colors = [Colors.grey, Colors.red, Colors.blue, Colors.green]; + List gColor; List gridAcsPath = [ - "assets/images/GridOnlyPositive.svg", + "assets/images/GridOnlyPositive.svg", "assets/images/Grid.svg", "assets/images/Grid_Ac5_Screen.svg", "assets/images/Grid_Ac6_Screen.svg", "assets/images/Grid_Ac5_Screen.svg", "assets/images/Grid_Ac6_Screen.svg", "assets/images/Grid_Ac7_Screen.svg", "assets/images/Grid_Ac8_Screen.svg", ]; return Container( width: 130, height: 180, decoration: BoxDecoration( border: Border.all( width: 0.5, color: colors[ thisClass.groups[position].activities[0].progress[turn - 1] + 2])), child: Stack(children: [ Positioned( bottom: 65, right: 30, width: 90, height: 90, child: celluloMap( gridAcsPath[ acList.indexOf(thisClass.groups[position].currentActivity)], turn, acList.indexOf(thisClass.groups[position].currentActivity), robotpatternSwitch, thisClass .groups[position] .activities[acList .indexOf(thisClass.groups[position].currentActivity)] .turns[turn - 1] .cellulox .x, thisClass .groups[position] .activities[acList .indexOf(thisClass.groups[position].currentActivity)] .turns[turn - 1] .celluloy .y, 90, - 90)), + 90, + gColor)), Positioned( bottom: 155, right: 27, child: Text( ((turn > 1) ? ((turn > 2) ? 'Third ' : 'Second ') : 'First ') + "Turn ", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14), )), Positioned(bottom: 4, right: 50, child: Text(rankingSwitch ? "" : "")), Positioned( bottom: 25, right: 6, child: Text( mistakesSwitch ? (thisClass.groups[position].activities[0].progress[turn - 1] > -2 ? (thisClass.groups[position].activities[0].mistakes['slope'][turn - 1] == 0 && thisClass.groups[position].activities[0].mistakes['initialPoint'][turn - 1] == 0 ? 'No Mistakes' : (thisClass.groups[position].activities[0].mistakes['slope'][turn - 1] > 0 && thisClass.groups[position].activities[0] .mistakes['initialPoint'][turn - 1] > 0 ? 'Mistakes in finding\n Slope and\n Initial Points' : (thisClass.groups[position].activities[0].mistakes['slope'][turn - 1] > 0 && thisClass.groups[position].activities[0] .mistakes['initialPoint'][turn - 1] == 0 ? 'Mistakes in finding\n slope' : 'Mistakes in finding\n initial points'))) : '') : '', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14), ), ) ])); } diff --git a/Dashboard/lib/screens/groupDashboard.Dart b/Dashboard/lib/screens/groupDashboard.Dart index 553162b..9b1d23a 100644 --- a/Dashboard/lib/screens/groupDashboard.Dart +++ b/Dashboard/lib/screens/groupDashboard.Dart @@ -1,883 +1,889 @@ import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:Teacher_Dashboard/widgets/custom_app_bar.dart'; import 'package:Teacher_Dashboard/widgets/celluloMap.Dart'; import 'dart:convert'; import 'package:Teacher_Dashboard/config/palette.dart'; import 'dart:async'; import 'package:Teacher_Dashboard/model/Class.dart'; import 'package:Teacher_Dashboard/model/Group.dart'; import 'package:Teacher_Dashboard/model/activities/activity.Dart'; import 'package:Teacher_Dashboard/config/palette.dart'; import 'package:firebase_database/firebase_database.dart'; import 'package:step_progress_indicator/step_progress_indicator.dart'; import 'package:Teacher_Dashboard/widgets/mapShapeMaker.dart'; //import 'package:Teacher_Dashboard/model/core/models/productModel.dart'; //import 'package:Teacher_Dashboard/model/core/viewmodels/CRUDModel.dart'; import 'package:provider/provider.dart'; class GroupDashboard extends StatefulWidget { final int currentgroupID; GroupDashboard({Key key, this.currentgroupID}) : super(key: key); @override GroupDashboardState createState() => GroupDashboardState(); } class GroupDashboardState extends State { final TextStyle whiteText = TextStyle(color: Colors.white, fontSize: 20); Timer timer; final FirebaseDatabase _database = FirebaseDatabase.instance; var progress; int groupID = 0; int studentListIndex = 0; int activityID = 0; int activityListIndex = 0; int turnID = 0; + List gColor; static List pointPosition = [ Offset(80, 80), Offset(760, 80), Offset(80, 760), Offset(760, 760) ]; var mapShape = [ [ { 'numCircles': 4, 'originCircles': [ Offset(390, 300), Offset(190, 170), Offset(60, 360), Offset(560, 690) ], 'radiuosCircles': [60.0, 70.0, 60.0, 60.0], 'numRectangles': 2, 'originRectangles': [Offset(300, 30), Offset(300, 560)], 'widthRectangles': [150.0, 100.0], 'heightRectangles': [50.0, 250.0], 'numPolygons': 5, 'sidesofPolygon': [3, 3, 5, 4, 4], 'radiusPolygon': [60.0, 70.0, 70.0, 60.0, 80.0], 'centerPolygon': [ Offset(60, 230), Offset(600, 90), Offset(600, 250), Offset(600, 500), Offset(780, 400) ], 'startCenter': pointPosition[2], 'endCenter': pointPosition[1] }, { 'numCircles': 2, 'originCircles': [ Offset(380, 320), Offset(160, 290), ], 'radiuosCircles': [60.0, 70.0], 'numRectangles': 3, 'originRectangles': [ Offset(100, 500), Offset(700, 560), Offset(500, 360) ], 'widthRectangles': [150.0, 100.0, 80.0], 'heightRectangles': [50.0, 250.0, 230.0], 'numPolygons': 4, 'sidesofPolygon': [3, 5, 4, 4], 'radiusPolygon': [70.0, 80.0, 70.0, 70.0], 'centerPolygon': [ Offset(300, 90), Offset(600, 60), Offset(500, 650), Offset(780, 300) ], 'startCenter': pointPosition[0], 'endCenter': pointPosition[3] }, { 'numCircles': 3, 'originCircles': [ Offset(260, 170), Offset(490, 560), Offset(690, 590), ], 'radiuosCircles': [80.0, 70.0, 70.0], 'numRectangles': 2, 'originRectangles': [Offset(500, 30), Offset(350, 560)], 'widthRectangles': [150.0, 100.0], 'heightRectangles': [80.0, 300.0], 'numPolygons': 3, 'sidesofPolygon': [3, 4, 4], 'radiusPolygon': [70.0, 90.0, 80.0], 'centerPolygon': [ Offset(40, 630), Offset(70, 390), Offset(620, 220), ], 'startCenter': pointPosition[2], 'endCenter': pointPosition[1] }, ], [ { 'numCircles': 0, 'originCircles': [ Offset(390, 300), Offset(160, 70), Offset(60, 360), Offset(560, 690) ], 'radiuosCircles': [60.0, 50.0, 50.0, 40.0], 'numRectangles': 5, 'originRectangles': [ Offset(300, 30), Offset(200, 560), Offset(400, 760), Offset(780, 460), Offset(650, 500) ], 'widthRectangles': [150.0, 100.0, 50.0, 100.0, 100.0], 'heightRectangles': [50.0, 250.0, 300.0, 50.0, 100.0], 'numPolygons': 4, 'sidesofPolygon': [4, 4, 4, 4], 'radiusPolygon': [70.0, 70.0, 50.0, 60.0, 50.0], 'centerPolygon': [ Offset(60, 280), Offset(500, 140), Offset(600, 200), Offset(500, 500), Offset(680, 400) ], 'startCenter': pointPosition[2], 'endCenter': pointPosition[1] }, { 'numCircles': 0, 'originCircles': [ Offset(390, 300), Offset(160, 70), Offset(60, 360), Offset(560, 690) ], 'radiuosCircles': [60.0, 50.0, 50.0, 40.0], 'numRectangles': 4, 'originRectangles': [ Offset(300, 30), Offset(300, 560), Offset(500, 560), Offset(750, 360) ], 'widthRectangles': [ 150.0, 100.0, 50.0, 150.0, ], 'heightRectangles': [50.0, 250.0, 250.0, 300.0], 'numPolygons': 4, 'sidesofPolygon': [4, 4, 4, 4], 'radiusPolygon': [80.0, 60.0, 50.0, 60.0], 'centerPolygon': [ Offset(100, 330), Offset(600, 90), Offset(500, 200), Offset(400, 350), ], 'startCenter': pointPosition[0], 'endCenter': pointPosition[3] }, { 'numCircles': 0, 'originCircles': [ Offset(390, 300), Offset(160, 70), Offset(60, 360), Offset(560, 690) ], 'radiuosCircles': [60.0, 50.0, 50.0, 40.0], 'numRectangles': 3, 'originRectangles': [ Offset(350, 70), Offset(300, 560), Offset(700, 520) ], 'widthRectangles': [350.0, 300.0, 100.0], 'heightRectangles': [50.0, 250.0, 100.0], 'numPolygons': 3, 'sidesofPolygon': [4, 4, 4], 'radiusPolygon': [100.0, 60.0, 70.0], 'centerPolygon': [ Offset(80, 230), Offset(650, 190), Offset(400, 250), ], 'startCenter': pointPosition[2], 'endCenter': pointPosition[1] }, ], [ { 'numCircles': 0, 'originCircles': [Offset(0, 0)], 'radiuosCircles': [0.0], 'numRectangles': 7, 'originRectangles': [ Offset(300, 30), Offset(100, 560), Offset(600, 630), Offset(780, 360), Offset(300, 300), Offset(500, 260), Offset(300, 560) ], 'widthRectangles': [150.0, 100.0, 50.0, 80.0, 150.0, 100.0, 100.0], 'heightRectangles': [70.0, 100.0, 200.0, 300.0, 40.0, 300.0, 200.0], 'numPolygons': 0, 'sidesofPolygon': [0], 'radiusPolygon': [0.0], 'centerPolygon': [Offset(0, 0)], 'startCenter': pointPosition[2], 'endCenter': pointPosition[1] }, { 'numCircles': 0, 'originCircles': [Offset(0, 0)], 'radiuosCircles': [0.0], 'numRectangles': 6, 'originRectangles': [ Offset(690, 430), Offset(500, 560), Offset(430, 130), Offset(300, 760), Offset(100, 230), Offset(100, 460) ], 'widthRectangles': [150.0, 100.0, 200.0, 100.0, 210.0, 210.0], 'heightRectangles': [150.0, 250.0, 50.0, 250.0, 50.0, 300.0], 'numPolygons': 0, 'sidesofPolygon': [3, 3, 5, 4, 4], 'radiusPolygon': [30.0, 40.0, 40.0, 40.0, 50.0], 'centerPolygon': [ Offset(40, 130), Offset(700, 90), Offset(600, 200), Offset(600, 500), Offset(780, 400) ], 'startCenter': pointPosition[0], 'endCenter': pointPosition[3] }, { 'numCircles': 0, 'originCircles': [Offset(0, 0)], 'radiuosCircles': [0.0], 'numRectangles': 7, 'originRectangles': [ Offset(300, 130), Offset(500, 460), Offset(750, 530), Offset(600, 130), Offset(600, 730), Offset(100, 530), Offset(350, 460) ], 'widthRectangles': [160.0, 90.0, 150.0, 100.0, 150.0, 300.0, 50.0], 'heightRectangles': [130.0, 270.0, 150.0, 250.0, 100.0, 70.0, 250.0], 'numPolygons': 0, 'sidesofPolygon': [0], 'radiusPolygon': [0.0], 'centerPolygon': [Offset(0, 0)], 'startCenter': pointPosition[2], 'endCenter': pointPosition[1] }, ] ]; List gridAcsPath = [ "assets/images/GridOnlyPositive.svg", "assets/images/Grid.svg", "assets/images/Grid_Ac5_Screen.svg", "assets/images/Grid_Ac6_Screen.svg", "assets/images/Grid_Ac5_Screen.svg", "assets/images/Grid_Ac6_Screen.svg", "assets/images/Grid_Ac7_Screen.svg", "assets/images/Grid_Ac8_Screen.svg", ]; double _currentSliderValue = 0; String pauseButtonText = 'Pause'; @override void initState() { super.initState(); if (widget.currentgroupID != null) groupID = widget.currentgroupID; } //@override void dispose() { super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, appBar: CustomAppBar(), body: SingleChildScrollView( // padding: const EdgeInsets.all(10.0), child: Row(children: [ Consumer( builder: (context, model, child) => Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( width: 200, decoration: BoxDecoration( color: Palette.primaryColor, border: Border.all(color: Colors.purple), // borderRadius: new BorderRadius.circular(25.0), ), child: Text( 'Groups', style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 18), )), Container( height: 480, width: 200, // margin: const EdgeInsets.all(15.0), // padding: const EdgeInsets.all(10.0), decoration: BoxDecoration( color: Palette.primaryColor, border: Border.all(color: Colors.purple), // borderRadius: new BorderRadius.circular(25.0), ), child: ListView.builder( itemCount: thisClass.groups.length, itemBuilder: (context, int position) { return ListTile( leading: Icon( Icons.person, color: Colors.white, ), onTap: () { setState(() { studentListIndex = position; groupID = position; }); }, title: Text( thisClass.groups[position].id, style: TextStyle( color: (studentListIndex == position) ? Colors.blue : Colors.white, fontWeight: FontWeight.bold, fontSize: 18), ), ); })), Container( width: 200, decoration: BoxDecoration( color: Palette.primaryColor, border: Border.all(color: Colors.purple), // borderRadius: new BorderRadius.circular(25.0), ), child: Text( 'Activities', style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 18), )), Container( height: 330, width: 200, // margin: const EdgeInsets.all(15.0), // padding: const EdgeInsets.all(10.0), decoration: BoxDecoration( color: Palette.primaryColor, border: Border.all(color: Colors.purple), // borderRadius: new BorderRadius.circular(25.0), ), child: ListView.builder( itemCount: acList.length, itemBuilder: (context, int position) { return ListTile( leading: Icon( Icons.description, color: Colors.white, ), onTap: () { setState(() { activityListIndex = position; - print(acList.length); + // print(acList.length); activityID = position; }); }, title: Text( - acList[position], + acListD[position], style: TextStyle( color: (activityListIndex == position) ? Colors.blue : Colors.white, fontWeight: FontWeight.bold, fontSize: 18), ), ); })) ])), SizedBox(width: 20), Consumer( builder: (context, model, child) => Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( height: 1, ), Row( // crossAxisAlignment: CrossAxisAlignment.start, children: [ Stack(children: [ CircularStepProgressIndicator( totalSteps: 3, // currentStep: // thisClass.groups[position].activities[0].progress, width: 100, customColor: (index) => (thisClass.groups.length > 0) ? (thisClass .groups[groupID] .activities[activityID] .progress[index] > -2 ? (thisClass .groups[groupID] .activities[activityID] .progress[index] > -1 ? (thisClass .groups[groupID] .activities[activityID] .progress[index] > 0 ? Colors.green : Colors.blue) : Colors.red) : Colors.grey) : Colors.grey, ), Positioned( bottom: 45, right: 18, child: Text( '', style: TextStyle( fontWeight: FontWeight.bold, fontSize: 15), )), ]), SizedBox(width: 10), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon(Icons.group), Text( (thisClass.groups.length > 0) ? (' ' + thisClass.groups[groupID].id) : '', style: TextStyle( fontSize: 30.0, color: Colors.black, fontWeight: FontWeight.w500), ), ], ), SizedBox(height: 25), Row( // crossAxisAlignment: CrossAxisAlignment.start, children: [ Row(children: [ Icon(Icons.person), Text( (thisClass.groups.length > 0) ? thisClass .groups[groupID].member1name : '', style: TextStyle( fontSize: 20.0, color: Colors.black, fontWeight: FontWeight.w500), ), ]), SizedBox(width: 20), Row(children: [ Icon(Icons.person), Text( (thisClass.groups.length > 0) ? thisClass .groups[groupID].member2name : '', style: TextStyle( fontSize: 20.0, color: Colors.black, fontWeight: FontWeight.w500), ), ]), SizedBox(width: 20), Row(children: [ Icon(Icons.person), Text( (thisClass.groups.length > 0) ? thisClass .groups[groupID].member3name : '', style: TextStyle( fontSize: 20.0, color: Colors.black, fontWeight: FontWeight.w500), ), ]) ]), ]), ]), SizedBox( height: 20, ), Container( width: 500, child: StepProgressIndicator( totalSteps: 50, // currentStep: thisClass.groups[position].inactivity.length, size: 10, padding: 0, customColor: (index) => Palette.primaryColor)), SizedBox( height: 20, ), Row( // mainAxisSize: MainAxisSize.min, children: [ infoTile( (thisClass.groups.length > 0) ? thisClass.groups[groupID].activities[activityID] .turns[turnID].numAttempts .toString() : '0', 'Attempts', Colors.blue), infoTileTime( 'Performing in', (thisClass.groups.length > 0) ? thisClass.groups[groupID].activities[activityID] .turns[turnID].elapsedTime : 0, Colors.blue), ]), SizedBox( height: 20, ), Row( // mainAxisSize: MainAxisSize.min, children: [ Column( // mainAxisSize: MainAxisSize.min, children: [ Container( width: 400, height: 400, child: (activityID > 2) ? celluloMap( gridAcsPath[activityID], turnID + 1, activityID, true, (thisClass.groups.length > 0) ? thisClass .groups[groupID] .activities[activityID] .turns[turnID] .cellulox .x + .sublist( + 0, + (_currentSliderValue * thisClass.groups[groupID].activities[activityID].turns[turnID].cellulox.x.length) + .toInt()) : [0, 0], (thisClass.groups.length > 0) ? thisClass .groups[groupID] .activities[activityID] .turns[turnID] .celluloy .y + .sublist( + 0, + (_currentSliderValue * thisClass.groups[groupID].activities[activityID].turns[turnID].cellulox.x.length) + .toInt()) : [0, 0], 400, - 400) + 400, + (thisClass.groups.length > 0) + ? thisClass + .groups[groupID] + .activities[activityID] + .turns[turnID] + .cellulox + .vx + .sublist( + 0, + (_currentSliderValue * thisClass.groups[groupID].activities[activityID].turns[turnID].cellulox.x.length) + .toInt()) + : [0, 0]) : Container( width: 400, height: 400, child: CustomPaint( //size: Size(200, 200), painter: MapShapeMaker( 400 / 860, 400 / 860, - mapShape[activityID][turnID] - ['numRectangles'], - mapShape[activityID][turnID] - ['originRectangles'], - mapShape[activityID][turnID] - ['widthRectangles'], - mapShape[activityID][turnID] - ['heightRectangles'], - mapShape[activityID][turnID] - ['numCircles'], - mapShape[activityID][turnID] - ['originCircles'], - mapShape[activityID][turnID] - ['radiuosCircles'], - mapShape[activityID][turnID] - ['numPolygons'], - mapShape[activityID][turnID] - ['sidesofPolygon'], - mapShape[activityID][turnID] - ['radiusPolygon'], - mapShape[activityID][turnID] - ['centerPolygon'], - mapShape[activityID][turnID] - ['startCenter'], - mapShape[activityID][turnID] - ['endCenter']))), + mapShape[activityID][turnID]['numRectangles'], + mapShape[activityID][turnID]['originRectangles'], + mapShape[activityID][turnID]['widthRectangles'], + mapShape[activityID][turnID]['heightRectangles'], + mapShape[activityID][turnID]['numCircles'], + mapShape[activityID][turnID]['originCircles'], + mapShape[activityID][turnID]['radiuosCircles'], + mapShape[activityID][turnID]['numPolygons'], + mapShape[activityID][turnID]['sidesofPolygon'], + mapShape[activityID][turnID]['radiusPolygon'], + mapShape[activityID][turnID]['centerPolygon'], + mapShape[activityID][turnID]['startCenter'], + mapShape[activityID][turnID]['endCenter']))), ), Text( ((turnID + 1 > 1) ? ((turnID + 1 > 2) ? 'Third ' : 'Second ') : 'First ') + "Turn ", style: TextStyle( fontWeight: FontWeight.bold, fontSize: 20), ), - /* Slider( activeColor: Colors.purple, value: _currentSliderValue, min: 0, - max: 200, + max: 1, // divisions: 5, // label: _currentSliderValue.round().toString(), onChanged: (double value) { setState(() { _currentSliderValue = value; }); }), - */ ]), /* Column( // mainAxisSize: MainAxisSize.min, children: [ infoTile( (thisClass.groups.length > 0) ? thisClass .groups[groupID] .activities[activityID] .turns[turnID] .mistakes['slope'] .toString() : '0', 'Mistakes in finding slope', Colors.blue), (activityID == 0) ? infoTile( (thisClass.groups.length > 0) ? thisClass .groups[groupID] .activities[activityID] .turns[turnID] .mistakes['initialPoint'] .toString() : '0', 'Mistakes in finding initial Point', Colors.blue) : infoTile( (thisClass.groups.length > 0) ? thisClass .groups[groupID] .activities[activityID] .turns[turnID] .mistakes['intercept'] .toString() : '0', 'Mistakes in finding intercept', Colors.blue), ]) */ ]), SizedBox(height: 10), Row( // mainAxisSize: MainAxisSize.min, children: [ SizedBox(width: 140), FloatingActionButton( heroTag: "prevButton", tooltip: 'Previous Turn', onPressed: () { if (turnID > 0) { setState(() { turnID = turnID - 1; }); } }, child: Icon(Icons.skip_previous), backgroundColor: Palette.primaryColor, ), SizedBox(width: 10), FloatingActionButton( heroTag: "nextButton", tooltip: 'Next Turn', onPressed: () { - print('turnID' + turnID.toString()); + // print('turnID' + turnID.toString()); if (turnID < 2) { setState(() { turnID = turnID + 1; }); } }, child: Icon(Icons.skip_next), backgroundColor: Palette.primaryColor, ), ]), SizedBox(height: 40), Row( // mainAxisSize: MainAxisSize.min, children: [ SizedBox(width: 325), Container( width: 200, child: MaterialButton( color: Colors.red, elevation: 0, onPressed: () { if (pauseButtonText == 'Pause') { pauseButtonText = 'Resume'; } else { pauseButtonText = 'Pause'; // dbRef.child("1").child("isPaused").set(true); } if (pauseButtonText == 'Pause') _database .reference() .child(thisClass.sessionID) .child('groups') .child(thisClass.groupIDs[groupID]) .child('isPaused') .set(false); if (pauseButtonText == 'Resume') _database .reference() .child(thisClass.sessionID) .child('groups') .child(thisClass.groupIDs[groupID]) .child('isPaused') .set(true); }, child: Container( padding: EdgeInsets.all(15.0), child: Text( pauseButtonText, textAlign: TextAlign.center, style: TextStyle( fontSize: 20.0, color: Colors.white, fontWeight: FontWeight.w500), ), ), ), ), SizedBox(width: 20), ], ) ], ), ) ]), ), ); } Container infoTile(String title, String count, MaterialColor color) { return Container( width: 120, // margin: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(10.0), decoration: BoxDecoration( color: color, borderRadius: BorderRadius.circular(10.0), ), child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: const TextStyle( color: Colors.white, fontSize: 20.0, fontWeight: FontWeight.bold, ), ), Text( count, style: const TextStyle( color: Colors.white, fontSize: 15.0, fontWeight: FontWeight.w600, ), ), ], ), ); } Container infoTileTime(String title, int count, MaterialColor color) { return Container( width: 220, // margin: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(10.0), decoration: BoxDecoration( color: color, // borderRadius: BorderRadius.circular(10.0), ), child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: const TextStyle( color: Colors.white, fontSize: 15.0, fontWeight: FontWeight.bold, ), ), Text( ((count > 60000) ? ((count / 60000).round().toString() + ' miutes') : '') + ' ' + ((count % 60000) / 1000).round().toString() + ' Seconds', style: const TextStyle( color: Colors.white, fontSize: 20.0, fontWeight: FontWeight.w600, ), ), ], ), ); } } diff --git a/Dashboard/lib/widgets/celluloMap.Dart b/Dashboard/lib/widgets/celluloMap.Dart index 08f96cb..63c960b 100644 --- a/Dashboard/lib/widgets/celluloMap.Dart +++ b/Dashboard/lib/widgets/celluloMap.Dart @@ -1,112 +1,113 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:Teacher_Dashboard/widgets/linePainter.Dart'; Widget celluloMap( String gridPath, int turn, int acID, bool robotpatternSwitch, List celluloxPositiontopaint, List celluloyPositiontopaint, double mapSizeScreenWidth, - double mapSizeScreenHeight) { + double mapSizeScreenHeight, + List gColor) { // Activity-Dependent var imagespath = [ [ 'assets/images/Ac7_function1.svg', 'assets/images/Ac7_function2.svg', 'assets/images/Ac7_function3.svg' ], [ 'assets/images/Ac8_function1.svg', 'assets/images/Ac8_function2.svg', 'assets/images/Ac8_function3.svg', // 'assets/images/GridOnlyPositive.svg', ], [ 'assets/images/Ac8_function1.svg', 'assets/images/Ac8_function2.svg', 'assets/images/Ac8_function3.svg', // 'assets/images/GridOnlyPositive.svg', ], [ 'assets/images/Ac8_function1.svg', 'assets/images/Ac8_function2.svg', 'assets/images/Ac8_function3.svg', // 'assets/images/GridOnlyPositive.svg', ], [ 'assets/images/Ac8_function1.svg', 'assets/images/Ac8_function2.svg', 'assets/images/Ac8_function3.svg', // 'assets/images/GridOnlyPositive.svg', ], [ - 'assets/images/Ac8_function1.svg', - 'assets/images/Ac8_function2.svg', - 'assets/images/Ac8_function3.svg', + 'assets/images/Ac6_function1.svg', + 'assets/images/Ac6_function2.svg', + 'assets/images/Ac6_function3.svg', // 'assets/images/GridOnlyPositive.svg', ], [ - 'assets/images/Ac8_function1.svg', - 'assets/images/Ac8_function2.svg', - 'assets/images/Ac8_function3.svg', + 'assets/images/Ac7_function1.svg', + 'assets/images/Ac7_function2.svg', + 'assets/images/Ac7_function3.svg', // 'assets/images/GridOnlyPositive.svg', ], [ 'assets/images/Ac8_function1.svg', 'assets/images/Ac8_function2.svg', 'assets/images/Ac8_function3.svg', // 'assets/images/GridOnlyPositive.svg', ], [ 'assets/images/Ac6_function1.svg', 'assets/images/Ac6_function2.svg', 'assets/images/Ac6_function3.svg', // 'assets/images/GridOnlyPositive.svg', ], [ 'assets/images/Ac7_function1.svg', 'assets/images/Ac7_function2.svg', 'assets/images/Ac7_function3.svg', // 'assets/images/GridOnlyPositive.svg', ], [ 'assets/images/Ac8_function1.svg', 'assets/images/Ac8_function2.svg', 'assets/images/Ac8_function3.svg', // 'assets/images/GridOnlyPositive.svg', ], [ 'assets/images/Ac8_function1.svg', 'assets/images/Ac8_function2.svg', 'assets/images/Ac8_function3.svg', // 'assets/images/GridOnlyPositive.svg', ], ]; // 'assets/images/GridOnlyPositive.svg', final double mapSizeWidth = 860; final double mapSizeHeight = 860; List normalizecellulopath(List path) { List pathnorm = new List(); for (int i = 0; i < path.length; i++) { pathnorm.add(path[i] * mapSizeScreenWidth / mapSizeWidth); } return pathnorm; } return Stack(children: [ SvgPicture.asset(imagespath[acID][turn - 1]), SvgPicture.asset(gridPath), robotpatternSwitch ? CustomPaint( size: Size(mapSizeScreenWidth, mapSizeScreenHeight), painter: LinePainter2(normalizecellulopath(celluloxPositiontopaint), - normalizecellulopath(celluloyPositiontopaint)), + normalizecellulopath(celluloyPositiontopaint), gColor), ) : Text(''), ]); } diff --git a/Dashboard/lib/widgets/linePainter.Dart b/Dashboard/lib/widgets/linePainter.Dart index ec6abb2..f0ddc2d 100644 --- a/Dashboard/lib/widgets/linePainter.Dart +++ b/Dashboard/lib/widgets/linePainter.Dart @@ -1,37 +1,47 @@ import 'package:flutter/material.dart'; class LinePainter2 extends CustomPainter { Paint _paint; - + List gColor; List x; List y; var path = Path(); //var patendpathh=path(); - LinePainter2(this.x, this.y) { + LinePainter2(this.x, this.y, this.gColor) { _paint = Paint() - ..color = Colors.blue + // ..color = Color.fromRGBO(38, gColor, 38, 0.9) ..strokeWidth = 3.0 ..style = PaintingStyle.stroke; } @override void paint(Canvas canvas, Size size) { // path.moveTo(0, 0); //canvas.restore(); + print(x); // print(x); + int v; for (int i = 3; i < x.length - 3; i++) { - path.moveTo(x[i - 2], y[i - 2]); - path.lineTo(x[i - 1], y[i - 1]); - canvas.drawPath(path, _paint); + if ((x[i - 1] - x[i - 2]) > 0.1) + v = ((y[i - 1] - y[i - 2]) ~/ (x[i - 1] - x[i - 2])) * 30; + else + v = 0; + + //path.moveTo(x[i - 2], y[i - 2]); + // path.lineTo(x[i - 1], y[i - 1]); + canvas.drawLine(Offset(x[i - 2], y[i - 2]), Offset(x[i - 1], y[i - 1]), + _paint..color = Color.fromRGBO(0, v, v, 0.9)); // canvas.save(); + debugPrint('v' + v.toString()); } + // path.moveTo(0, 0); //path.lineTo(20, 20); //canvas.drawPath(path, _paint); } @override bool shouldRepaint(LinePainter2 oldDelegate) { return true; } } diff --git a/student/android/app/src/main/AndroidManifest.xml b/student/android/app/src/main/AndroidManifest.xml index d7326d7..7b819fa 100644 --- a/student/android/app/src/main/AndroidManifest.xml +++ b/student/android/app/src/main/AndroidManifest.xml @@ -1,47 +1,48 @@ + diff --git a/student/assets/images/IMG_0095.mp4 b/student/assets/images/IMG_0095.mp4 new file mode 100644 index 0000000..0ab6c75 Binary files /dev/null and b/student/assets/images/IMG_0095.mp4 differ diff --git a/student/lib/Activities/Ac1.dart b/student/lib/Activities/Ac1.dart index 0e0c046..3efd3ea 100644 --- a/student/lib/Activities/Ac1.dart +++ b/student/lib/Activities/Ac1.dart @@ -1,743 +1,802 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:student/widgets/onlineRobotMap.Dart'; import 'package:student/widgets/celluloMap.Dart'; import 'dart:async'; import 'dart:convert'; import 'package:student/Database.dart'; import 'package:student/model/Group.dart'; import 'package:student/model/Cellulo.dart'; import 'package:student/widgets/showAlertDialog.Dart'; import 'package:student/widgets/membersBar.Dart'; import 'package:student/widgets/inactivityDetector.Dart'; import 'package:flutter_appavailability/flutter_appavailability.dart'; import 'package:flutter_map/flutter_map.dart'; import 'package:latlong/latlong.dart'; import 'package:map_controller/map_controller.dart'; import 'package:student/widgets/mapShapeMaker.dart'; import 'dart:math' as math; -import 'package:audioplayer/audioplayer.dart'; +import 'package:audioplayers/audioplayers.dart'; import 'package:tip_dialog/tip_dialog.dart'; +import 'package:audioplayers/audio_cache.dart'; class Ac1 extends StatefulWidget { Ac1({Key key}) : super(key: key); @override _Ac1State createState() => _Ac1State(); } class _Ac1State extends State { // Activity_Independent AudioPlayer audioPlugin = AudioPlayer(); AudioPlayer advancedPlayer = AudioPlayer(); + static AudioCache cache = AudioCache(); + AudioPlayer player; + + bool isPlaying = false; + bool isPaused = false; + var elapseTimer = new Stopwatch(); Timer timerCelluloPosition; Timer timerCheckCelluloGame; int currentTurn = 1; bool enterBorderX = false; bool enterBorderY = false; bool enterBorderpolygonX = false; bool enterBorderpolygonY = false; bool enterBorderRectX = false; bool enterBorderRectY = false; bool reachendX = false; bool reachendY = false; bool gameoverX = false; bool gameoverY = false; Timer timerCelluloPositiontoserver; // Celulo var celluloxPosition = [0.0, 0.0]; var celluloyPosition = [0.0, 0.0]; var prevcelluloxPosition = [0.0, 0.0]; var prevcelluloyPosition = [0.0, 0.0]; var celluloxVelocity = [0.0, 0.0]; var celluloyVelocity = [0.0, 0.0]; List celluloxPositiontopaint = [0.0, 0.0]; List celluloyPositiontopaint = [0.0, 0.0]; bool addtoprint; AnimationController controllerRobotPath; Animation animationRobotPath; // Learning List mistakesSlope = [0, 0, 0]; List mistakesIntrepet = [0, 0, 0]; List mistakesInitialPosition = [0, 0, 0]; List trapped = [0]; int scoreX = 6; int scoreY = 6; int trappedCircleX; int trappedCircleY; int trappedRectangleX; int trappedRectangleY; int trappedPolygonX; int trappedPolygonY; //Activity Dependent double radiuosStart = 45; String activityTitle = 'Activity 1'; var linesPath = [ 'assets/images/Ac7_function1.svg', 'assets/images/Ac7_function2.svg', 'assets/images/Ac7_function3.svg', 'assets/images/GridOnlyPositive.svg', ]; List progress = [0, -2, -2]; List progressElpasedTime = [0, 0, 0]; int inactivity = 0; int tapCounter = 0; - var startPoint = ['B', 'A', 'B']; - var endPoint = ['C', 'D', 'C']; + var startPoint = ['C', 'A', 'C']; + var endPoint = ['B', 'D', 'B']; var startPointorder = [2, 0, 2]; var endPointorder = [1, 3, 1]; var pointOrder = ['A', 'B', 'C', 'D']; static List pointPosition = [ Offset(80, 80), Offset(760, 80), Offset(80, 760), Offset(760, 760) ]; // map-related final double mapSizeWidth = 860; final double mapSizeHeight = 860; double coeffScreenMapWidth; double coeffScreenMapHeight; final String mapPath = 'assets/images/GridOnlyPositive.svg'; var overlayPolygons = [ Polygon(points: [ LatLng(0.0, 0.0), LatLng(30.0, 0.0), LatLng(30.0, 30.0), LatLng(0.0, 30.0) ], color: Colors.blue) ]; var mapShape = [ { 'numCircles': 4, 'originCircles': [ Offset(390, 300), Offset(190, 170), Offset(60, 360), Offset(560, 690) ], 'radiuosCircles': [60.0, 70.0, 60.0, 60.0], 'numRectangles': 2, - 'originRectangles': [Offset(300, 30), Offset(300, 560)], + 'originRectangles': [Offset(300, 30), Offset(600, 430)], 'widthRectangles': [150.0, 100.0], 'heightRectangles': [50.0, 250.0], 'numPolygons': 2, 'sidesofPolygon': [3, 3, 5, 4, 4], 'radiusPolygon': [60.0, 70.0, 70.0, 60.0, 80.0], 'centerPolygon': [ Offset(60, 230), Offset(600, 90), Offset(600, 250), Offset(600, 500), Offset(780, 400) ], 'startCenter': pointPosition[2], 'endCenter': pointPosition[1] }, { 'numCircles': 2, 'originCircles': [ Offset(380, 320), - Offset(160, 290), + Offset(460, 690), ], 'radiuosCircles': [60.0, 70.0], 'numRectangles': 3, 'originRectangles': [ Offset(100, 500), Offset(700, 560), Offset(500, 360) ], 'widthRectangles': [150.0, 100.0, 80.0], 'heightRectangles': [50.0, 250.0, 230.0], 'numPolygons': 2, 'sidesofPolygon': [3, 5, 4, 4], 'radiusPolygon': [70.0, 80.0, 70.0, 70.0], 'centerPolygon': [ Offset(300, 90), Offset(600, 60), Offset(500, 650), Offset(780, 300) ], 'startCenter': pointPosition[0], 'endCenter': pointPosition[3] }, { 'numCircles': 2, 'originCircles': [ Offset(260, 170), - Offset(490, 560), + Offset(690, 360), Offset(690, 590), ], 'radiuosCircles': [80.0, 70.0, 70.0], 'numRectangles': 2, 'originRectangles': [Offset(500, 30), Offset(350, 560)], 'widthRectangles': [150.0, 100.0], 'heightRectangles': [80.0, 300.0], 'numPolygons': 2, 'sidesofPolygon': [3, 4, 4], 'radiusPolygon': [70.0, 90.0, 80.0], 'centerPolygon': [ Offset(40, 630), Offset(70, 390), Offset(620, 220), ], 'startCenter': pointPosition[2], 'endCenter': pointPosition[1] }, ]; + Future loadMusic() async { + advancedPlayer = await AudioCache().loop("music/song3.mp3"); + } @override void initState() { + playHandler(); super.initState(); + loadMusic(); dbRef.child('groups').child(group.id).child('tabletStatus').set("YES"); dbRef.child('groups').child(group.id).child('currentActivity').set("Ac1"); elapseTimer.start(); timerCelluloPosition = new Timer.periodic(new Duration(milliseconds: 100), (time) { if (totalRobots() > 1) { // print(cellulox.getrobotKidnapped().toString()); // print(celluloy.getrobotKidnapped().toString()); cellulox.getrobotx().then((val) => setState(() { if (val != null) { celluloxPosition[0] = val; // print(celluloxPosition[0]); if (addtoprint == true) celluloxPositiontopaint.add(val); } // print(addtoprint.toString()); })); cellulox.getroboty().then((val) => setState(() { if (val != null) { celluloxPosition[1] = val; } })); celluloy.getrobotx().then((val) => setState(() { if (val != null) { celluloyPosition[0] = val; } })); celluloy.getroboty().then((val) => setState(() { if (val != null) { celluloyPosition[1] = val; if (addtoprint == true) celluloyPositiontopaint.add(val); } })); if (celluloxPosition[0] > 800 || celluloyPosition[1] > 800) { cellulox.setVelocity(0, 0); celluloy.setVelocity(0, 0); } } }); /* timerCelluloPositiontoserver = new Timer.periodic(new Duration(milliseconds: 800), (time) { dbRef.child("celluloPosition").push().set(json.encode({ "x": celluloxPosition[0], "y": celluloyPosition[1], "acID": "Ac1", "turn": currentTurn, "groupID": group.id, })); }); */ timerCheckCelluloGame = new Timer.periodic(new Duration(milliseconds: 500), (time) { setState(() { checkCelluloGame( mapShape[currentTurn - 1], Offset((celluloxPosition[0]), (celluloxPosition[1])), Offset(celluloxPosition[0], celluloxPosition[1]), Offset(celluloyPosition[0], celluloyPosition[1]), 0); checkCelluloGame( mapShape[currentTurn - 1], Offset((celluloyPosition[0]), (celluloyPosition[1])), Offset(celluloxPosition[0], celluloxPosition[1]), Offset(celluloyPosition[0], celluloyPosition[1]), 1); }); }); onDataSend(); } void colorRobots() { for (int i = 0; i < 6; i++) { cellulox.setColor(0, 0, 0, 0, 0); } for (int i = 0; i < scoreX; i++) { cellulox.setColor(0, 255, 0, 1, i); } for (int i = 0; i < 6; i++) { celluloy.setColor(0, 0, 0, 0, 0); } for (int i = 0; i < scoreY; i++) { celluloy.setColor(0, 0, 255, 1, i); } } void onDataSend() { dbRef.child('attempts').push().set(json.encode({ "numAttempts": tapCounter, "groupID": group.id, "acID": "Ac1", "elpasedTime": elapseTimer.elapsedMilliseconds - progressElpasedTime[currentTurn - 1], "progress": { "turn1": progress[0], "turn2": progress[1], "turn3": progress[2] }, "progressElpasedTime": { "turn1": progressElpasedTime[0], "turn2": progressElpasedTime[1], "turn3": progressElpasedTime[2], }, "currentTurn": currentTurn, "inactivity": inactivity, "mistakes": { "turn1": { "slope": mistakesSlope[0], "initialPoint": mistakesInitialPosition[0] }, "turn2": { "slope": mistakesSlope[1], "initialPoint": mistakesInitialPosition[1] }, "turn3": { "slope": mistakesSlope[2], "initialPoint": mistakesInitialPosition[2] }, } })); } + void playHandler() async { + if (isPlaying) { + player.stop(); + } else { + player = await cache.play('images/smb_breakblock.mp3'); + // print('ffffffffffffffffffffffffffffff'); + } + + setState(() { + if (isPaused) { + isPlaying = false; + isPaused = false; + } else { + isPlaying = !isPlaying; + } + }); + } + + void pauseHandler() { + if (isPaused && isPlaying) { + player.resume(); + } else { + player.pause(); + } + setState(() { + isPaused = !isPaused; + }); + } + void checkCelluloGame(var mapShape, Offset celluloTargetPosition, Offset celluloXPosition, Offset celluloYPosition, int id) { var insideBorder = false; var insideShape = false; final double coeffHaptic = 10; double radiuosBorder = 40; bool enterShape = false; var XVelocityCelluloX; var YVelocityCelluloX; var XVelocityCelluloY; var YVelocityCelluloY; double celluloXYdistances = math.sqrt( math.pow((celluloXPosition.dx - celluloYPosition.dx), 2) + math.pow((celluloXPosition.dy - celluloYPosition.dy), 2)); double distanceThreshold = 120; //print(score.toString()); //print(enterBorder.toString()); if (celluloXYdistances < distanceThreshold) { cellulox.robotVibrate(10, 10, 0, 100, 100); celluloy.robotVibrate(10, 10, 0, 100, 100); // cellulox.setVelocity(-celluloxVelocity[0], -celluloxVelocity[1]); // celluloy.setVelocity(-celluloyVelocity[0], -celluloyVelocity[1]); } var distancePointCenter = math.sqrt(math.pow( (celluloTargetPosition.dx - mapShape['startCenter'].dx), 2) + math.pow((celluloTargetPosition.dy - mapShape['startCenter'].dy), 2)); if (distancePointCenter <= radiuosStart) { if (id == 0) { scoreX = 6; reachendX = false; gameoverX = false; // onDataSend(); } if (id == 1) { scoreY = 6; reachendY = false; gameoverY = false; // onDataSend(); } } if (scoreX <= 0 && gameoverX == false) { tapCounter = tapCounter + 1; gameoverX = true; onDataSend(); showAlertDialog(context, 'Red Robot Does not have energy', 'Tell your friend with Red Robot to go start point'); } if (scoreY <= 0 && gameoverY == false) { tapCounter = tapCounter + 1; onDataSend(); gameoverY = true; showAlertDialog(context, 'BLue Robot Does not have energy', 'Tell your friend with Blue Robot to go start point'); } var distancePointEnd = math.sqrt( math.pow((celluloTargetPosition.dx - mapShape['endCenter'].dx), 2) + math.pow((celluloTargetPosition.dy - mapShape['endCenter'].dy), 2)); if (distancePointEnd <= radiuosStart) { if (id == 0 && reachendX == false) { // scoreX = -1; showAlertDialog(context, 'Red Robot reached the goal point', 'Tell your friend to start again or when both robots reached the end, you can go to next turn.'); onDataSend(); reachendX = true; } if (id == 1 && reachendY == false) { showAlertDialog(context, 'Blue Robot reached the goal point', 'Tell your friend to start again or when both robots reached the end, you can go to next turn.'); onDataSend(); reachendY = true; } } print('enterX' + enterBorderX.toString()); for (int i = 0; i < mapShape['numCircles']; i++) { var distancePointCenter = math.sqrt(math.pow( (celluloTargetPosition.dx - mapShape['originCircles'][i].dx), 2) + math.pow( (celluloTargetPosition.dy - mapShape['originCircles'][i].dy), 2)); if (distancePointCenter <= mapShape['radiuosCircles'][i] + radiuosBorder) { insideBorder = true; XVelocityCelluloX = coeffHaptic * (celluloXPosition.dx - mapShape['originCircles'][i].dx); YVelocityCelluloX = coeffHaptic * (celluloXPosition.dy - mapShape['originCircles'][i].dy); XVelocityCelluloY = coeffHaptic * (celluloYPosition.dx - mapShape['originCircles'][i].dx); YVelocityCelluloY = coeffHaptic * (celluloYPosition.dy - mapShape['originCircles'][i].dy); if (id == 0) cellulox.setVelocity(XVelocityCelluloX, YVelocityCelluloX); if (id == 1) celluloy.setVelocity(XVelocityCelluloY, YVelocityCelluloY); if (id == 0) { if (enterBorderX == false) { scoreX = scoreX - 1; enterBorderX = true; } trappedCircleX = i; } if (id == 1) { if (enterBorderY == false) { scoreY = scoreY - 1; enterBorderY = true; } trappedCircleY = i; } break; } else if (id == 0 && i == trappedCircleX) { enterBorderX = false; } else if (id == 1 && i == trappedCircleY) { enterBorderY = false; } /* insideBorder = false; if (distancePointCenter <= mapShape['radiuosCircles'][i]) { insideShape = true; } else { insideShape = false; enterShape = false; } if (insideShape == true) { if (enterShape == false) { score = score - 1; enterShape = true; } } */ } for (int i = 0; i < mapShape['numRectangles']; i++) { if ((Rect.fromCenter( center: Offset(mapShape['originRectangles'][i].dx, mapShape['originRectangles'][i].dy), width: mapShape['widthRectangles'][i], height: mapShape['heightRectangles'][i]) .contains(celluloTargetPosition) == true)) { insideBorder = true; XVelocityCelluloX = coeffHaptic * (celluloXPosition.dx - mapShape['originRectangles'][i].dx); YVelocityCelluloX = coeffHaptic * (celluloXPosition.dy - mapShape['originRectangles'][i].dy); XVelocityCelluloY = coeffHaptic * (celluloYPosition.dx - mapShape['originRectangles'][i].dx); YVelocityCelluloY = coeffHaptic * (celluloYPosition.dy - mapShape['originRectangles'][i].dy); if (id == 0) cellulox.setVelocity(XVelocityCelluloX, YVelocityCelluloX); if (id == 1) celluloy.setVelocity(XVelocityCelluloY, YVelocityCelluloY); if (id == 0) { if (enterBorderRectX == false) { scoreX = scoreX - 1; enterBorderRectX = true; } trappedRectangleX = i; } if (id == 1) { if (enterBorderRectY == false) { scoreY = scoreY - 1; enterBorderRectY = true; } trappedRectangleY = i; } break; } else if (id == 0 && i == trappedRectangleX) { enterBorderRectX = false; } else if (id == 1 && i == trappedRectangleY) { enterBorderRectY = false; } // if (id == 0) cellulox.clearrobot(); //if (id == 1) celluloy.clearrobot(); } for (int i = 0; i < mapShape['numPolygons']; i++) { var distancePointCenter = math.sqrt(math.pow( (celluloTargetPosition.dx - mapShape['centerPolygon'][i].dx), 2) + math.pow( (celluloTargetPosition.dy - mapShape['centerPolygon'][i].dy), 2)); if (distancePointCenter <= mapShape['radiusPolygon'][i] + radiuosBorder) { insideBorder = true; XVelocityCelluloX = coeffHaptic * (celluloXPosition.dx - mapShape['centerPolygon'][i].dx); YVelocityCelluloX = coeffHaptic * (celluloXPosition.dy - mapShape['centerPolygon'][i].dy); XVelocityCelluloY = coeffHaptic * (celluloYPosition.dx - mapShape['centerPolygon'][i].dx); YVelocityCelluloY = coeffHaptic * (celluloYPosition.dy - mapShape['centerPolygon'][i].dy); if (id == 0) cellulox.setVelocity(XVelocityCelluloX, YVelocityCelluloX); if (id == 1) celluloy.setVelocity(XVelocityCelluloY, YVelocityCelluloY); if (id == 0) { if (enterBorderpolygonX == false) { scoreX = scoreX - 1; enterBorderpolygonX = true; } trappedPolygonX = i; } if (id == 1) { if (enterBorderpolygonY == false) { scoreY = scoreY - 1; enterBorderpolygonY = true; } trappedPolygonY = i; } break; } else if (id == 0 && i == trappedPolygonX) { enterBorderpolygonX = false; } else if (id == 1 && i == trappedPolygonY) { enterBorderpolygonY = false; } } if (enterBorderX == false && enterBorderRectX == false && enterBorderpolygonX == false && id == 0) cellulox.clearrobot(); if (enterBorderY == false && enterBorderRectY == false && enterBorderpolygonY == false && id == 1) celluloy.clearrobot(); colorRobots(); /* /* /* insideBorder = false; if (distancePointCenter <= mapShape['radiuosCircles'][i]) { insideShape = true; } else { insideShape = false; enterShape = false; } if (insideShape == true) { if (enterShape == false) { score = score - 1; enterShape = true; } } */ if (id == 0) cellulox.clearrobot(); if (id == 1) celluloy.clearrobot(); } */ } */ } void calcVelocity() { celluloxVelocity[0] = celluloxPosition[0] - prevcelluloxPosition[0]; celluloxVelocity[1] = celluloxPosition[1] - prevcelluloxPosition[1]; celluloyVelocity[0] = celluloyPosition[0] - prevcelluloyPosition[0]; celluloyVelocity[1] = celluloyPosition[1] - prevcelluloyPosition[1]; prevcelluloxPosition = celluloxPosition; prevcelluloyPosition = celluloyPosition; } @override void dispose() { + advancedPlayer = null; cellulox.resetrobot(); celluloy.resetrobot(); timerCelluloPosition.cancel(); timerCheckCelluloGame.cancel(); elapseTimer.stop(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Avoid the hidden obstacles'), + actions: [ + Padding( + padding: EdgeInsets.only(right: 20.0), + child: GestureDetector( + onTap: () { + group.currentActivity = 'Ac61'; + group.navigatorKeygame.currentState + .pushReplacementNamed(group.currentActivity); + print('ff'); + }, + child: Icon(Icons.help), + )), + ], ), backgroundColor: Colors.white, body: SingleChildScrollView( child: Column(children: [ Row(mainAxisAlignment: MainAxisAlignment.center, children: [ Container( height: 100, width: 600, child: Stack(children: [ Card( child: ListTile( title: Text('Guide your friedns to go from ' + startPoint[currentTurn - 1].toString() + ' to ' + endPoint[currentTurn - 1].toString()), ), ) ])), SizedBox(width: 20), Container( decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(100)), color: Colors.blue), child: FlatButton( child: Text( "Next Turn", style: TextStyle( color: Colors.white, fontWeight: FontWeight.w700, fontSize: 18), ), onPressed: () => { + playHandler(), tapCounter = 0, if (currentTurn <= 2) { setState(() { currentTurn = currentTurn + 1; }), progress[currentTurn - 2] = 1, // controller.reset(), progress[currentTurn - 1] = 0, onDataSend(), } else { progress[2] = 1, onDataSend(), showAlertDialog( context, 'Wait for teacher', 'Game has finished! '), }, }, )), ]), SizedBox( height: 50, ), Container( width: MediaQuery.of(context).size.width * 0.9, height: MediaQuery.of(context).size.height * 0.65, decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(100)), // color: Colors.blue ), child: Stack( children: [ Container( width: MediaQuery.of(context).size.width * 0.9, height: MediaQuery.of(context).size.height * 0.65, child: CustomPaint( //size: Size(200, 200), painter: //LinePainter2(celluloxPositiontopaint, celluloyPositiontopaint), MapShapeMaker( + pointPosition, MediaQuery.of(context).size.width * 0.9 / mapSizeWidth, MediaQuery.of(context).size.height * 0.65 / mapSizeHeight, mapShape[currentTurn - 1]['numRectangles'], mapShape[currentTurn - 1]['originRectangles'], mapShape[currentTurn - 1]['widthRectangles'], mapShape[currentTurn - 1]['heightRectangles'], mapShape[currentTurn - 1]['numCircles'], mapShape[currentTurn - 1]['originCircles'], mapShape[currentTurn - 1]['radiuosCircles'], mapShape[currentTurn - 1]['numPolygons'], mapShape[currentTurn - 1]['sidesofPolygon'], mapShape[currentTurn - 1]['radiusPolygon'], mapShape[currentTurn - 1]['centerPolygon'], mapShape[currentTurn - 1]['startCenter'], mapShape[currentTurn - 1]['endCenter']), ), ), Container( width: MediaQuery.of(context).size.width * 0.9, height: MediaQuery.of(context).size.height * 0.65, child: Align( alignment: Alignment( 2 * ((celluloxPosition[0]) / mapSizeWidth) - 1, 2 * ((celluloxPosition[1]) / mapSizeHeight) - 1), child: Card( child: SvgPicture.asset("assets/images/celluloRed.svg", height: 60, width: 60), ), ), ), Container( width: MediaQuery.of(context).size.width * 0.9, height: MediaQuery.of(context).size.height * 0.65, child: Align( alignment: Alignment( 2 * ((celluloyPosition[0]) / mapSizeWidth) - 1, 2 * ((celluloyPosition[1]) / mapSizeHeight) - 1), child: Card( child: SvgPicture.asset("assets/images/celluloBlue.svg", height: 60, width: 60), ), ), ), ], )), SizedBox( height: 45, ), - MembersBar(), + MembersBar( + curTurn: currentTurn, + ), ]))); } } diff --git a/student/lib/Activities/Ac2.dart b/student/lib/Activities/Ac2.dart index 5c45b94..c052734 100644 --- a/student/lib/Activities/Ac2.dart +++ b/student/lib/Activities/Ac2.dart @@ -1,640 +1,656 @@ import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:student/widgets/mapShapeMaker.dart'; import 'package:student/widgets/onlineRobotMap.Dart'; import 'package:student/widgets/celluloMap.Dart'; import 'dart:async'; import 'dart:convert'; import 'package:student/Database.dart'; import 'package:student/model/Group.dart'; import 'package:student/model/Cellulo.dart'; import 'package:student/widgets/showAlertDialog.Dart'; import 'package:student/widgets/membersBar.Dart'; import 'package:student/widgets/inactivityDetector.Dart'; import 'package:flutter_appavailability/flutter_appavailability.dart'; import 'package:student/widgets/ShapePainter.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:student/widgets/checkCelluloGame.dart'; -import 'package:audioplayer/audioplayer.dart'; +import 'package:audioplayers/audioplayers.dart'; import 'package:tip_dialog/tip_dialog.dart'; import 'dart:math' as math; class Ac2 extends StatefulWidget { Ac2({Key key}) : super(key: key); @override _Ac2State createState() => _Ac2State(); } class _Ac2State extends State { // Activity_Independent var elapseTimer = new Stopwatch(); Timer timerCelluloPosition; Timer timerCelluloPositiontoserver; Timer timerCheckCelluloGame; int currentTurn = 1; int inactivity = 0; int tapCounter = 0; List progress = [0, -2, -2]; List progressElpasedTime = [0, 0, 0]; // Celulo var celluloxPosition = [0.0, 0.0]; var celluloyPosition = [0.0, 0.0]; List celluloxPositiontopaint = [0.0, 0.0]; List celluloyPositiontopaint = [0.0, 0.0]; bool addtoprint; Animation animationRobotPath; // Learning List gameScore = [0, 0, 0]; List celluloEnergy = [6, 6, 6]; List mistakesSlope = [0, 0, 0]; List mistakesIntrepet = [0, 0, 0]; List mistakesInitialPosition = [0, 0, 0]; int score = 6; //Activity Dependent bool enterBorderX = false; bool enterBorderY = false; bool enterBorderpolygonX = false; bool enterBorderpolygonY = false; bool enterBorderRectX = false; bool enterBorderRectY = false; int scoreX = 6; int scoreY = 6; int trappedCircleX; int trappedCircleY; int trappedRectangleX; int trappedRectangleY; int trappedPolygonX; int trappedPolygonY; bool reachendY = false; bool gameoverY = false; String activityTitle = 'Activity 2'; var linesPath = [ 'assets/images/Ac7_function1.svg', 'assets/images/Ac7_function2.svg', 'assets/images/Ac7_function3.svg', 'assets/images/GridOnlyPositive.svg', ]; - var startPoint = ['B', 'A', 'B']; - var endPoint = ['C', 'D', 'C']; + var startPoint = ['C', 'A', 'C']; + var endPoint = ['B', 'D', 'B']; var startPointorder = [2, 0, 2]; var endPointorder = [1, 3, 1]; var pointOrder = ['A', 'B', 'C', 'D']; static List pointPosition = [ Offset(80, 80), Offset(760, 80), Offset(80, 760), Offset(760, 760) ]; // map-related double radiuosStart = 45; //final Offset startPoint = new Offset(0.0, 0.0); //inal Offset endPoint = new Offset(0.0, 0.0); final double mapSizeWidth = 860; final double mapSizeHeight = 860; final String mapPath = 'assets/images/GridOnlyPositive.svg'; double coeffScreenMapWidth; double coeffScreenMapHeight; var mapShape = [ { 'numCircles': 0, 'originCircles': [ Offset(390, 300), Offset(160, 70), Offset(60, 360), Offset(560, 690) ], 'radiuosCircles': [60.0, 50.0, 50.0, 40.0], 'numRectangles': 3, 'originRectangles': [ Offset(300, 30), Offset(200, 560), Offset(400, 760), Offset(780, 460), Offset(650, 500) ], 'widthRectangles': [150.0, 100.0, 50.0, 100.0, 100.0], 'heightRectangles': [50.0, 250.0, 300.0, 50.0, 100.0], 'numPolygons': 2, 'sidesofPolygon': [4, 4, 4, 4], 'radiusPolygon': [70.0, 70.0, 50.0, 60.0, 50.0], 'centerPolygon': [ Offset(60, 280), Offset(500, 140), Offset(600, 200), Offset(500, 500), Offset(680, 400) ], 'startCenter': pointPosition[2], 'endCenter': pointPosition[1] }, { 'numCircles': 0, 'originCircles': [ Offset(390, 300), Offset(160, 70), Offset(60, 360), Offset(560, 690) ], 'radiuosCircles': [60.0, 50.0, 50.0, 40.0], 'numRectangles': 2, 'originRectangles': [ Offset(300, 30), Offset(300, 560), Offset(500, 560), Offset(750, 360) ], 'widthRectangles': [ 150.0, 100.0, 50.0, 150.0, ], 'heightRectangles': [50.0, 250.0, 250.0, 300.0], 'numPolygons': 2, 'sidesofPolygon': [4, 4, 4, 4], 'radiusPolygon': [80.0, 60.0, 50.0, 60.0], 'centerPolygon': [ Offset(100, 330), Offset(600, 90), Offset(500, 200), Offset(400, 350), ], 'startCenter': pointPosition[0], 'endCenter': pointPosition[3] }, { 'numCircles': 0, 'originCircles': [ Offset(390, 300), Offset(160, 70), Offset(60, 360), Offset(560, 690) ], 'radiuosCircles': [60.0, 50.0, 50.0, 40.0], 'numRectangles': 3, 'originRectangles': [Offset(350, 70), Offset(300, 560), Offset(700, 520)], 'widthRectangles': [350.0, 300.0, 100.0], 'heightRectangles': [50.0, 250.0, 100.0], 'numPolygons': 3, 'sidesofPolygon': [4, 4, 4], 'radiusPolygon': [100.0, 60.0, 70.0], 'centerPolygon': [ Offset(80, 230), Offset(650, 190), Offset(400, 250), ], 'startCenter': pointPosition[2], 'endCenter': pointPosition[1] }, ]; @override void initState() { super.initState(); dbRef.child('groups').child(group.id).child('tabletStatus').set("YES"); dbRef.child('groups').child(group.id).child('currentActivity').set("Ac2"); elapseTimer.start(); // coeffScreenMapHeight = // MediaQuery.of(context).size.width * 0.9 / mapSizeWidth; // coeffScreenMapHeight = // MediaQuery.of(context).size.height * 0.9 / mapSizeHeight; timerCelluloPosition = new Timer.periodic(new Duration(milliseconds: 500), (time) { if (totalRobots() > 1) { cellulox.getrobotx().then((val) => setState(() { if (val != null) { celluloxPosition[0] = val; print(celluloxPosition[0]); if (addtoprint == true) celluloxPositiontopaint.add(val); } // print(addtoprint.toString()); })); cellulox.getroboty().then((val) => setState(() { if (val != null) { celluloxPosition[1] = val; } })); celluloy.getrobotx().then((val) => setState(() { if (val != null) { celluloyPosition[0] = val; } })); celluloy.getroboty().then((val) => setState(() { if (val != null) { celluloyPosition[1] = val; if (addtoprint == true) celluloyPositiontopaint.add(val); } })); if (celluloxPosition[0] > 800 || celluloyPosition[1] > 800) { cellulox.setVelocity(0, 0); celluloy.setVelocity(0, 0); } } }); timerCelluloPositiontoserver = new Timer.periodic(new Duration(milliseconds: 2800), (time) { dbRef.child("celluloPosition").push().set(json.encode({ "x": celluloxPosition[0], "y": celluloyPosition[1], "acID": "Ac2", "turn": currentTurn, "groupID": group.id, })); }); timerCheckCelluloGame = new Timer.periodic(new Duration(milliseconds: 500), (time) { checkCelluloGame( mapShape[currentTurn - 1], Offset((celluloxPosition[0] + celluloyPosition[0]) / 2, (celluloxPosition[1] + celluloyPosition[1]) / 2), Offset(celluloxPosition[0], celluloxPosition[1]), Offset(celluloyPosition[0], celluloyPosition[1]), 1); }); } void checkCelluloGame(var mapShape, Offset celluloTargetPosition, Offset celluloXPosition, Offset celluloYPosition, int id) { var insideBorder = false; var insideShape = false; final double coeffHaptic = 10; double radiuosBorder = 40; bool enterShape = false; var XVelocityCelluloX; var YVelocityCelluloX; var XVelocityCelluloY; var YVelocityCelluloY; double celluloXYdistances = math.sqrt( math.pow((celluloXPosition.dx - celluloYPosition.dx), 2) + math.pow((celluloXPosition.dy - celluloYPosition.dy), 2)); double distanceThreshold = 120; //print(score.toString()); //print(enterBorder.toString()); if (celluloXYdistances < distanceThreshold) { cellulox.robotVibrate(10, 10, 0, 100, 100); celluloy.robotVibrate(10, 10, 0, 100, 100); // cellulox.setVelocity(-celluloxVelocity[0], -celluloxVelocity[1]); // celluloy.setVelocity(-celluloyVelocity[0], -celluloyVelocity[1]); } var distancePointCenter = math.sqrt(math.pow( (celluloTargetPosition.dx - mapShape['startCenter'].dx), 2) + math.pow((celluloTargetPosition.dy - mapShape['startCenter'].dy), 2)); if (distancePointCenter <= radiuosStart) { scoreX = 6; scoreY = 6; } if (scoreY <= 0 && gameoverY == false) { tapCounter = tapCounter + 1; onDataSend(); gameoverY = true; showAlertDialog(context, 'BLue Robot Does not have energy', 'Tell your friend with Blue Robot to go start point'); } var distancePointEnd = math.sqrt( math.pow((celluloTargetPosition.dx - mapShape['endCenter'].dx), 2) + math.pow((celluloTargetPosition.dy - mapShape['endCenter'].dy), 2)); if (distancePointEnd <= radiuosStart) { tapCounter = tapCounter + 1; onDataSend(); showAlertDialog(context, 'Blue Robot reached the goal point', 'Tell your friend to start again or when both robots reached the end, you can go to next turn.'); } for (int i = 0; i < mapShape['numRectangles']; i++) { if ((Rect.fromCenter( center: Offset(mapShape['originRectangles'][i].dx, mapShape['originRectangles'][i].dy), width: mapShape['widthRectangles'][i], height: mapShape['heightRectangles'][i]) .contains(celluloTargetPosition) == true)) { insideBorder = true; XVelocityCelluloX = coeffHaptic * (celluloTargetPosition.dx - mapShape['originRectangles'][i].dx); YVelocityCelluloX = coeffHaptic * (celluloTargetPosition.dy - mapShape['originRectangles'][i].dy); XVelocityCelluloY = coeffHaptic * (celluloTargetPosition.dx - mapShape['originRectangles'][i].dx); YVelocityCelluloY = coeffHaptic * (celluloTargetPosition.dy - mapShape['originRectangles'][i].dy); cellulox.setVelocity(XVelocityCelluloX, YVelocityCelluloX); celluloy.setVelocity(XVelocityCelluloY, YVelocityCelluloY); if (enterBorderRectY == false) { scoreY = scoreY - 1; scoreX = scoreX - 1; enterBorderRectY = true; } trappedRectangleY = i; break; } else if (i == trappedRectangleY) { enterBorderRectY = false; } // if (id == 0) cellulox.clearrobot(); //if (id == 1) celluloy.clearrobot(); } for (int i = 0; i < mapShape['numPolygons']; i++) { var distancePointCenter = math.sqrt(math.pow( (celluloTargetPosition.dx - mapShape['centerPolygon'][i].dx), 2) + math.pow( (celluloTargetPosition.dy - mapShape['centerPolygon'][i].dy), 2)); if (distancePointCenter <= mapShape['radiusPolygon'][i] + radiuosBorder) { insideBorder = true; XVelocityCelluloX = coeffHaptic * (celluloTargetPosition.dx - mapShape['centerPolygon'][i].dx); YVelocityCelluloX = coeffHaptic * (celluloTargetPosition.dy - mapShape['centerPolygon'][i].dy); XVelocityCelluloY = coeffHaptic * (celluloTargetPosition.dx - mapShape['centerPolygon'][i].dx); YVelocityCelluloY = coeffHaptic * (celluloTargetPosition.dy - mapShape['centerPolygon'][i].dy); cellulox.setVelocity(XVelocityCelluloX, YVelocityCelluloX); celluloy.setVelocity(XVelocityCelluloY, YVelocityCelluloY); if (enterBorderpolygonY == false) { scoreY = scoreY - 1; scoreX = scoreX - 1; enterBorderpolygonY = true; } trappedPolygonY = i; break; } else if (i == trappedPolygonY) { enterBorderpolygonY = false; } } if (enterBorderY == false && enterBorderRectY == false && enterBorderpolygonY == false && id == 1) { cellulox.clearrobot(); celluloy.clearrobot(); } colorRobots(); /* /* /* insideBorder = false; if (distancePointCenter <= mapShape['radiuosCircles'][i]) { insideShape = true; } else { insideShape = false; enterShape = false; } if (insideShape == true) { if (enterShape == false) { score = score - 1; enterShape = true; } } */ if (id == 0) cellulox.clearrobot(); if (id == 1) celluloy.clearrobot(); } */ } */ } void colorRobots() { for (int i = 0; i < 6; i++) { cellulox.setColor(0, 0, 0, 0, 0); } for (int i = 0; i < scoreX; i++) { cellulox.setColor(0, 255, 0, 1, i); } for (int i = 0; i < 6; i++) { celluloy.setColor(0, 0, 0, 0, 0); } for (int i = 0; i < scoreY; i++) { celluloy.setColor(0, 0, 255, 1, i); } } @override void dispose() { timerCelluloPosition.cancel(); timerCheckCelluloGame.cancel(); elapseTimer.stop(); super.dispose(); } void onDataSend() { dbRef.child('attempts').push().set(json.encode({ "numAttempts": tapCounter, "groupID": group.id, "acID": "Ac2", "elpasedTime": elapseTimer.elapsedMilliseconds - progressElpasedTime[currentTurn - 1], "progress": { "turn1": progress[0], "turn2": progress[1], "turn3": progress[2] }, "progressElpasedTime": { "turn1": progressElpasedTime[0], "turn2": progressElpasedTime[1], "turn3": progressElpasedTime[2], }, "currentTurn": currentTurn, "inactivity": inactivity, "mistakes": { "turn1": { "slope": mistakesSlope[0], "initialPoint": mistakesInitialPosition[0] }, "turn2": { "slope": mistakesSlope[1], "initialPoint": mistakesInitialPosition[1] }, "turn3": { "slope": mistakesSlope[2], "initialPoint": mistakesInitialPosition[2] }, } })); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Avoid the hidden obstacles'), + actions: [ + Padding( + padding: EdgeInsets.only(right: 20.0), + child: GestureDetector( + onTap: () { + group.currentActivity = 'Ac61'; + group.navigatorKeygame.currentState + .pushReplacementNamed(group.currentActivity); + // print('ff'); + }, + child: Icon(Icons.help), + )), + ], ), backgroundColor: Colors.white, body: SingleChildScrollView( child: Column(children: [ Row(mainAxisAlignment: MainAxisAlignment.center, children: [ Container( height: 100, width: 600, child: Stack(children: [ Card( child: ListTile( title: Text('Guide your friedns to go from ' + startPoint[currentTurn - 1].toString() + ' to ' + endPoint[currentTurn - 1].toString()), ), ) ])), SizedBox(width: 20), Container( decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(100)), color: Colors.blue), child: FlatButton( child: Text( "Next Turn", style: TextStyle( color: Colors.white, fontWeight: FontWeight.w700, fontSize: 18), ), onPressed: () => { tapCounter = 0, if (currentTurn <= 2) { setState(() { currentTurn = currentTurn + 1; }), progress[currentTurn - 2] = 1, // controller.reset(), progress[currentTurn - 1] = 0, onDataSend(), } else { progress[2] = 1, onDataSend(), showAlertDialog( context, 'Wait for teacher', 'Game has finished! '), }, }, )), ]), SizedBox( height: 50, ), Container( width: MediaQuery.of(context).size.width * 0.9, height: MediaQuery.of(context).size.height * 0.65, decoration: BoxDecoration( // borderRadius: BorderRadius.all(Radius.circular(100)), // color: Colors.blue ), child: Stack( children: [ CustomPaint( //size: Size(200, 200), painter: //LinePainter2(celluloxPositiontopaint, celluloyPositiontopaint), MapShapeMaker( + pointPosition, MediaQuery.of(context).size.width * 0.9 / mapSizeWidth, MediaQuery.of(context).size.height * 0.65 / mapSizeHeight, mapShape[currentTurn - 1]['numRectangles'], mapShape[currentTurn - 1]['originRectangles'], mapShape[currentTurn - 1]['widthRectangles'], mapShape[currentTurn - 1]['heightRectangles'], mapShape[currentTurn - 1]['numCircles'], mapShape[currentTurn - 1]['originCircles'], mapShape[currentTurn - 1]['radiuosCircles'], mapShape[currentTurn - 1]['numPolygons'], mapShape[currentTurn - 1]['sidesofPolygon'], mapShape[currentTurn - 1]['radiusPolygon'], mapShape[currentTurn - 1]['centerPolygon'], mapShape[currentTurn - 1]['startCenter'], mapShape[currentTurn - 1]['endCenter']), ), Container( width: MediaQuery.of(context).size.width * 0.9, height: MediaQuery.of(context).size.height * 0.65, child: Align( alignment: Alignment( 2 * ((celluloxPosition[0] + celluloyPosition[0]) / 2 / mapSizeWidth) - 1, 2 * ((celluloxPosition[1] + celluloyPosition[1]) / 2 / mapSizeHeight) - 1), child: Card( child: SvgPicture.asset( "assets/images/celluloPurple.svg", height: 60, width: 60), ), ), ), Container( width: MediaQuery.of(context).size.width * 0.9, height: MediaQuery.of(context).size.height * 0.65, child: Align( alignment: Alignment( 2 * ((celluloxPosition[0]) / mapSizeWidth) - 1, 2 * ((celluloxPosition[1]) / mapSizeHeight) - 1), child: Card( child: SvgPicture.asset("assets/images/celluloRed.svg", height: 60, width: 60), ), ), ), Container( width: MediaQuery.of(context).size.width * 0.9, height: MediaQuery.of(context).size.height * 0.65, child: Align( alignment: Alignment( 2 * ((celluloyPosition[0]) / mapSizeWidth) - 1, 2 * ((celluloyPosition[1]) / mapSizeHeight) - 1), child: Card( child: SvgPicture.asset("assets/images/celluloBlue.svg", height: 60, width: 60), ), ), ), ], )), SizedBox( height: 75, ), - MembersBar(), + MembersBar( + curTurn: currentTurn, + ), ]))); } } diff --git a/student/lib/Activities/Ac3.dart b/student/lib/Activities/Ac3.dart index 8c023b5..3a5acd8 100644 --- a/student/lib/Activities/Ac3.dart +++ b/student/lib/Activities/Ac3.dart @@ -1,568 +1,584 @@ import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:student/widgets/onlineRobotMap.Dart'; import 'dart:async'; import 'dart:convert'; import 'package:student/Database.dart'; import 'package:student/model/Group.dart'; import 'package:student/model/Cellulo.dart'; import 'package:student/widgets/showAlertDialog.Dart'; import 'package:student/widgets/membersBar.Dart'; import 'package:student/widgets/inactivityDetector.Dart'; import 'package:flutter_appavailability/flutter_appavailability.dart'; import 'package:student/widgets/mapShapeMaker.dart'; -import 'package:audioplayer/audioplayer.dart'; +import 'package:audioplayers/audioplayers.dart'; import 'package:tip_dialog/tip_dialog.dart'; import 'dart:math' as math; class Ac3 extends StatefulWidget { Ac3({Key key}) : super(key: key); @override _Ac3State createState() => _Ac3State(); } class _Ac3State extends State { // Activity_Independent int currentTurn = 1; var elapseTimer = new Stopwatch(); AnimationController controllerRobotPath; Animation animationRobotPath; Timer timerCelluloPosition; Timer timerCheckCelluloGame; Timer timerCelluloPositiontoserver; // Celulo var celluloxPosition = [0.0, 0.0]; var celluloyPosition = [0.0, 0.0]; // Learning List progress = [0, -2, -2]; int tapCounter = 0; List progressElpasedTime = [0, 0, 0]; int inactivity = 0; List mistakesSlope = [0, 0, 0]; List mistakesIntrepet = [0, 0, 0]; List mistakesInitialPosition = [0, 0, 0]; // ACTIVITY Dependent bool enterBorderX = false; bool enterBorderY = false; bool enterBorderpolygonX = false; bool enterBorderpolygonY = false; bool enterBorderRectX = false; bool enterBorderRectY = false; int scoreX = 6; int scoreY = 6; int trappedCircleX; int trappedCircleY; int trappedRectangleX; int trappedRectangleY; int trappedPolygonX; int trappedPolygonY; bool reachendY = false; bool gameoverY = false; final double mapSizeWidth = 860; final double mapSizeHeight = 860; double coeffScreenMapWidth; double coeffScreenMapHeight; - var startPoint = ['B', 'A', 'B']; - var endPoint = ['C', 'D', 'C']; + var startPoint = ['C', 'A', 'C']; + var endPoint = ['B', 'D', 'B']; var startPointorder = [2, 0, 2]; var endPointorder = [1, 3, 1]; double radiuosStart = 45; var pointOrder = ['A', 'B', 'C', 'D']; static List pointPosition = [ Offset(80, 80), Offset(760, 80), Offset(80, 760), Offset(760, 760) ]; var mapShape = [ { 'numCircles': 0, 'originCircles': [Offset(0, 0)], 'radiuosCircles': [0.0], 'numRectangles': 7, 'originRectangles': [ Offset(300, 30), Offset(100, 560), Offset(600, 630), Offset(780, 360), Offset(300, 300), Offset(500, 260), Offset(300, 560) ], 'widthRectangles': [150.0, 100.0, 50.0, 80.0, 150.0, 100.0, 100.0], 'heightRectangles': [70.0, 100.0, 200.0, 300.0, 40.0, 300.0, 200.0], 'numPolygons': 0, 'sidesofPolygon': [0], 'radiusPolygon': [0.0], 'centerPolygon': [Offset(0, 0)], 'startCenter': pointPosition[2], 'endCenter': pointPosition[1] }, { 'numCircles': 0, 'originCircles': [Offset(0, 0)], 'radiuosCircles': [0.0], 'numRectangles': 6, 'originRectangles': [ Offset(690, 430), Offset(500, 560), Offset(430, 130), Offset(300, 760), Offset(100, 230), Offset(100, 460) ], 'widthRectangles': [150.0, 100.0, 200.0, 100.0, 210.0, 210.0], 'heightRectangles': [150.0, 250.0, 50.0, 250.0, 50.0, 300.0], 'numPolygons': 0, 'sidesofPolygon': [3, 3, 5, 4, 4], 'radiusPolygon': [30.0, 40.0, 40.0, 40.0, 50.0], 'centerPolygon': [ Offset(40, 130), Offset(700, 90), Offset(600, 200), Offset(600, 500), Offset(780, 400) ], 'startCenter': pointPosition[0], 'endCenter': pointPosition[3] }, { 'numCircles': 0, 'originCircles': [Offset(0, 0)], 'radiuosCircles': [0.0], 'numRectangles': 7, 'originRectangles': [ Offset(300, 130), Offset(500, 460), Offset(750, 530), Offset(600, 130), Offset(600, 730), Offset(100, 530), Offset(350, 460) ], 'widthRectangles': [160.0, 90.0, 150.0, 100.0, 150.0, 300.0, 50.0], 'heightRectangles': [130.0, 270.0, 150.0, 250.0, 100.0, 70.0, 250.0], 'numPolygons': 0, 'sidesofPolygon': [0], 'radiusPolygon': [0.0], 'centerPolygon': [Offset(0, 0)], 'startCenter': pointPosition[2], 'endCenter': pointPosition[1] }, ]; var mapShapeScreen; @override void initState() { super.initState(); dbRef.child('groups').child(group.id).child('tabletStatus').set("YES"); dbRef.child('groups').child(group.id).child('currentActivity').set("Ac3"); elapseTimer.start(); timerCelluloPositiontoserver = new Timer.periodic(new Duration(milliseconds: 2800), (time) { dbRef.child("celluloPosition").push().set(json.encode({ "x": celluloxPosition[0], "y": celluloyPosition[1], "acID": "Ac3", "turn": currentTurn, "groupID": group.id, })); }); timerCelluloPosition = new Timer.periodic(new Duration(milliseconds: 500), (time) { if (totalRobots() > 1) { cellulox.getrobotx().then((val) => setState(() { if (val != null) { celluloxPosition[0] = val; print(celluloxPosition[0]); // if (addtoprint == true) celluloxPositiontopaint.add(val); } // print(addtoprint.toString()); })); cellulox.getroboty().then((val) => setState(() { if (val != null) { celluloxPosition[1] = val; } })); celluloy.getrobotx().then((val) => setState(() { if (val != null) { celluloyPosition[0] = val; } })); celluloy.getroboty().then((val) => setState(() { if (val != null) { celluloyPosition[1] = val; // if (addtoprint == true) celluloyPositiontopaint.add(val); } })); if (celluloxPosition[0] > 800 || celluloyPosition[1] > 800) { cellulox.setVelocity(0, 0); celluloy.setVelocity(0, 0); } } }); timerCheckCelluloGame = new Timer.periodic(new Duration(milliseconds: 500), (time) { checkCelluloGame( mapShape[currentTurn - 1], Offset((celluloxPosition[0] + celluloyPosition[0]) / 2, (celluloxPosition[1] + celluloyPosition[1]) / 2), Offset(celluloxPosition[0], celluloxPosition[1]), Offset(celluloyPosition[0], celluloyPosition[1]), 1); }); } void checkCelluloGame(var mapShape, Offset celluloTargetPosition, Offset celluloXPosition, Offset celluloYPosition, int id) { var insideBorder = false; var insideShape = false; final double coeffHaptic = 10; double radiuosBorder = 40; bool enterShape = false; var XVelocityCelluloX; var YVelocityCelluloX; var XVelocityCelluloY; var YVelocityCelluloY; double celluloXYdistances = math.sqrt( math.pow((celluloXPosition.dx - celluloYPosition.dx), 2) + math.pow((celluloXPosition.dy - celluloYPosition.dy), 2)); double distanceThreshold = 120; //print(score.toString()); //print(enterBorder.toString()); if (celluloXYdistances < distanceThreshold) { cellulox.robotVibrate(10, 10, 0, 100, 100); celluloy.robotVibrate(10, 10, 0, 100, 100); // cellulox.setVelocity(-celluloxVelocity[0], -celluloxVelocity[1]); // celluloy.setVelocity(-celluloyVelocity[0], -celluloyVelocity[1]); } var distancePointCenter = math.sqrt(math.pow( (celluloTargetPosition.dx - mapShape['startCenter'].dx), 2) + math.pow((celluloTargetPosition.dy - mapShape['startCenter'].dy), 2)); if (distancePointCenter <= radiuosStart) { scoreY = 6; scoreX = 6; gameoverY = false; reachendY = false; } if (scoreY <= 0 && gameoverY == false) { tapCounter = tapCounter + 1; onDataSend(); gameoverY = true; showAlertDialog(context, 'BLue Robot Does not have energy', 'Tell your friend with Blue Robot to go start point'); } var distancePointEnd = math.sqrt( math.pow((celluloTargetPosition.dx - mapShape['endCenter'].dx), 2) + math.pow((celluloTargetPosition.dy - mapShape['endCenter'].dy), 2)); if (distancePointEnd <= radiuosStart && reachendY == false) { // scoreX = -1; reachendY = true; tapCounter = tapCounter + 1; onDataSend(); showAlertDialog(context, 'Your Robot reached the goal point', 'Tell your friend to start again or you can go to next turn.'); } for (int i = 0; i < mapShape['numRectangles']; i++) { if ((Rect.fromCenter( center: Offset(mapShape['originRectangles'][i].dx, mapShape['originRectangles'][i].dy), width: mapShape['widthRectangles'][i], height: mapShape['heightRectangles'][i]) .contains(celluloTargetPosition) == true)) { insideBorder = true; XVelocityCelluloX = coeffHaptic * (celluloXPosition.dx - mapShape['originRectangles'][i].dx); YVelocityCelluloX = coeffHaptic * (celluloXPosition.dy - mapShape['originRectangles'][i].dy); XVelocityCelluloY = coeffHaptic * (celluloYPosition.dx - mapShape['originRectangles'][i].dx); YVelocityCelluloY = coeffHaptic * (celluloYPosition.dy - mapShape['originRectangles'][i].dy); cellulox.setVelocity(XVelocityCelluloX, 0); celluloy.setVelocity(0, YVelocityCelluloY); if (enterBorderRectY == false) { scoreY = scoreY - 1; scoreX = scoreX - 1; enterBorderRectY = true; } trappedRectangleY = i; break; } else if (id == 1 && i == trappedRectangleY) { enterBorderRectY = false; } // if (id == 0) cellulox.clearrobot(); //if (id == 1) celluloy.clearrobot(); } if (enterBorderY == false && enterBorderRectY == false && enterBorderpolygonY == false) { cellulox.clearrobot(); celluloy.clearrobot(); } colorRobots(); /* /* /* insideBorder = false; if (distancePointCenter <= mapShape['radiuosCircles'][i]) { insideShape = true; } else { insideShape = false; enterShape = false; } if (insideShape == true) { if (enterShape == false) { score = score - 1; enterShape = true; } } */ if (id == 0) cellulox.clearrobot(); if (id == 1) celluloy.clearrobot(); } */ } */ } void colorRobots() { for (int i = 0; i < 6; i++) { cellulox.setColor(0, 0, 0, 0, 0); } for (int i = 0; i < scoreX; i++) { cellulox.setColor(0, 255, 0, 1, i); } for (int i = 0; i < 6; i++) { celluloy.setColor(0, 0, 0, 0, 0); } for (int i = 0; i < scoreY; i++) { celluloy.setColor(0, 0, 255, 1, i); } } @override void dispose() { elapseTimer.stop(); super.dispose(); timerCelluloPosition.cancel(); // // timerCheckCelluloGame.cancel(); } void onDataSend() { dbRef.child('attempts').push().set(json.encode({ "numAttempts": tapCounter, "groupID": group.id, "acID": "Ac3", "elpasedTime": elapseTimer.elapsedMilliseconds - progressElpasedTime[currentTurn - 1], "progress": { "turn1": progress[0], "turn2": progress[1], "turn3": progress[2] }, "progressElpasedTime": { "turn1": progressElpasedTime[0], "turn2": progressElpasedTime[1], "turn3": progressElpasedTime[2], }, "currentTurn": currentTurn, "inactivity": inactivity, "mistakes": { "turn1": { "slope": mistakesSlope[0], "initialPoint": mistakesInitialPosition[0] }, "turn2": { "slope": mistakesSlope[1], "initialPoint": mistakesInitialPosition[1] }, "turn3": { "slope": mistakesSlope[2], "initialPoint": mistakesInitialPosition[2] }, } })); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Avoid the hidden obstacles'), + actions: [ + Padding( + padding: EdgeInsets.only(right: 20.0), + child: GestureDetector( + onTap: () { + group.currentActivity = 'Ac61'; + group.navigatorKeygame.currentState + .pushReplacementNamed(group.currentActivity); + // print('ff'); + }, + child: Icon(Icons.help), + )), + ], ), backgroundColor: Colors.white, body: SingleChildScrollView( child: Column(children: [ Row(mainAxisAlignment: MainAxisAlignment.center, children: [ Container( height: 100, width: 600, child: Stack(children: [ Card( child: ListTile( title: Text('Guide your friedns to go from ' + startPoint[currentTurn - 1].toString() + ' to ' + endPoint[currentTurn - 1].toString()), ), ), ])), SizedBox( width: 15, ), SizedBox(width: 20), Container( decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(100)), color: Colors.blue), child: FlatButton( child: Text( "Next Turn", style: TextStyle( color: Colors.white, fontWeight: FontWeight.w700, fontSize: 18), ), onPressed: () => { tapCounter = 0, if (currentTurn <= 2) { setState(() { currentTurn = currentTurn + 1; }), progress[currentTurn - 2] = 1, // controller.reset(), progress[currentTurn - 1] = 0, onDataSend(), } else { progress[2] = 1, onDataSend(), showAlertDialog( context, 'Wait for teacher', 'Game has finished! '), }, }, ), ) ]), Container( width: MediaQuery.of(context).size.width * 0.9, height: MediaQuery.of(context).size.height * 0.65, decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(100)), // color: Colors.blue ), child: Stack( children: [ CustomPaint( //size: Size(200, 200), painter: //LinePainter2(celluloxPositiontopaint, celluloyPositiontopaint), MapShapeMaker( + pointPosition, MediaQuery.of(context).size.width * 0.9 / mapSizeWidth, MediaQuery.of(context).size.height * 0.65 / mapSizeHeight, mapShape[currentTurn - 1]['numRectangles'], mapShape[currentTurn - 1]['originRectangles'], mapShape[currentTurn - 1]['widthRectangles'], mapShape[currentTurn - 1]['heightRectangles'], mapShape[currentTurn - 1]['numCircles'], mapShape[currentTurn - 1]['originCircles'], mapShape[currentTurn - 1]['radiuosCircles'], mapShape[currentTurn - 1]['numPolygons'], mapShape[currentTurn - 1]['sidesofPolygon'], mapShape[currentTurn - 1]['radiusPolygon'], mapShape[currentTurn - 1]['centerPolygon'], mapShape[currentTurn - 1]['startCenter'], mapShape[currentTurn - 1]['endCenter']), ), Container( width: MediaQuery.of(context).size.width * 0.9, height: MediaQuery.of(context).size.height * 0.65, child: Align( alignment: Alignment( 2 * ((celluloxPosition[0] + celluloyPosition[0]) / 2 / mapSizeWidth) - 1, 2 * ((celluloxPosition[1] + celluloyPosition[1]) / 2 / mapSizeHeight) - 1), child: Card( child: SvgPicture.asset( "assets/images/celluloPurple.svg", height: 60, width: 60), ), ), ), Container( width: MediaQuery.of(context).size.width * 0.9, height: MediaQuery.of(context).size.height * 0.65, child: Align( alignment: Alignment( 2 * ((celluloxPosition[0]) / mapSizeWidth) - 1, 2 * ((celluloxPosition[1]) / mapSizeHeight) - 1), child: Card( child: SvgPicture.asset("assets/images/celluloRed.svg", height: 60, width: 60), ), ), ), Container( width: MediaQuery.of(context).size.width * 0.9, height: MediaQuery.of(context).size.height * 0.65, child: Align( alignment: Alignment( 2 * ((celluloyPosition[0]) / mapSizeWidth) - 1, 2 * ((celluloyPosition[1]) / mapSizeHeight) - 1), child: Card( child: SvgPicture.asset("assets/images/celluloBlue.svg", height: 60, width: 60), ), ), ) ], )), SizedBox( height: 55, ), - MembersBar(), + MembersBar( + curTurn: currentTurn, + ), ]))); } } diff --git a/student/lib/Activities/Ac4.dart b/student/lib/Activities/Ac4.dart index 4d4f76b..39949e8 100644 --- a/student/lib/Activities/Ac4.dart +++ b/student/lib/Activities/Ac4.dart @@ -1,530 +1,574 @@ import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:student/widgets/onlineRobotMap.Dart'; import 'dart:async'; import 'dart:convert'; +import 'package:student/widgets/arrow.dart'; import 'package:student/Database.dart'; import 'package:student/model/Group.dart'; import 'package:student/model/Cellulo.dart'; import 'package:student/widgets/showAlertDialog.Dart'; import 'package:student/widgets/membersBar.Dart'; import 'package:student/widgets/inactivityDetector.Dart'; import 'package:flutter_appavailability/flutter_appavailability.dart'; import 'package:student/widgets/bezierCurvePainter.dart'; import 'package:bezier/bezier.dart'; import 'package:student/widgets/mapShapeMaker.dart'; import 'package:bezier/bezier.dart'; import "dart:math" as math; import "package:vector_math/vector_math.dart" as vector; class Ac4 extends StatefulWidget { Ac4({Key key}) : super(key: key); @override _Ac4State createState() => _Ac4State(); } class _Ac4State extends State { // Activity_Independent int currentTurn = 1; var elapseTimer = new Stopwatch(); + var timeOutofBorder; AnimationController controllerRobotPath; Animation animationRobotPath; Timer timerCelluloPosition; + Timer timerCelluloPositionPainttoserver; // Celulo var celluloxPosition = [0.0, 0.0]; var celluloyPosition = [0.0, 0.0]; var xHaptic; var yHaptic; + var xyHapticG = [0.0, 0.0]; // Learning bool gameover = false; int score = 6; bool outofborder = false; bool reachend = false; double radiuosStart = 45; List mistakesSlope = [0, 0, 0]; List mistakesIntrepet = [0, 0, 0]; List mistakesInitialPosition = [0, 0, 0]; int tapCounter = 0; List progress = [0, -2, -2]; List progressElpasedTime = [0, 0, 0]; //Activity Dependent final double mapSizeWidth = 860; final double mapSizeHeight = 860; static List pointPosition = [ Offset(80, 80), Offset(760, 80), Offset(80, 760), Offset(760, 760) ]; var midddlePoint1 = [ Offset(291.1, 176.2), Offset(110.2, 632.8), Offset(610.2, 732.8) ]; var midddlePoint2 = [ Offset(410.2, 532.8), Offset(356, 357), Offset(110.2, 232.8) ]; + var startPoint = ['C', 'A', 'C']; + var endPoint = ['B', 'D', 'B']; var mapShape = [ { 'numCircles': 0, 'originCircles': [Offset(0, 0)], 'radiuosCircles': [0.0], 'numRectangles': 0, 'originRectangles': [ Offset(300, 30), Offset(100, 560), Offset(600, 630), Offset(780, 360), Offset(300, 300), Offset(500, 260), Offset(300, 560) ], 'widthRectangles': [150.0, 100.0, 50.0, 80.0, 150.0, 100.0, 100.0], 'heightRectangles': [70.0, 100.0, 200.0, 300.0, 40.0, 300.0, 200.0], 'numPolygons': 0, 'sidesofPolygon': [0], 'radiusPolygon': [0.0], 'centerPolygon': [Offset(0, 0)], 'startCenter': pointPosition[2], 'endCenter': pointPosition[1] }, { 'numCircles': 0, 'originCircles': [Offset(0, 0)], 'radiuosCircles': [0.0], 'numRectangles': 0, 'originRectangles': [ Offset(690, 430), Offset(500, 560), Offset(430, 130), Offset(300, 760), Offset(100, 230), Offset(100, 460) ], 'widthRectangles': [150.0, 100.0, 200.0, 100.0, 210.0, 210.0], 'heightRectangles': [150.0, 250.0, 50.0, 250.0, 50.0, 300.0], 'numPolygons': 0, 'sidesofPolygon': [3, 3, 5, 4, 4], 'radiusPolygon': [30.0, 40.0, 40.0, 40.0, 50.0], 'centerPolygon': [ Offset(40, 130), Offset(700, 90), Offset(600, 200), Offset(600, 500), Offset(780, 400) ], 'startCenter': pointPosition[0], 'endCenter': pointPosition[3] }, { 'numCircles': 0, 'originCircles': [Offset(0, 0)], 'radiuosCircles': [0.0], 'numRectangles': 0, 'originRectangles': [ Offset(300, 130), Offset(500, 460), Offset(750, 530), Offset(600, 130), Offset(600, 730), Offset(100, 530), Offset(350, 460) ], 'widthRectangles': [160.0, 90.0, 150.0, 100.0, 150.0, 300.0, 50.0], 'heightRectangles': [130.0, 270.0, 150.0, 250.0, 100.0, 70.0, 250.0], 'numPolygons': 0, 'sidesofPolygon': [0], 'radiusPolygon': [0.0], 'centerPolygon': [Offset(0, 0)], 'startCenter': pointPosition[2], 'endCenter': pointPosition[1] }, ]; void onDataSend() { dbRef.child('attempts').push().set(json.encode({ "numAttempts": tapCounter, "groupID": group.id, "acID": "Ac4", "elpasedTime": elapseTimer.elapsedMilliseconds - progressElpasedTime[currentTurn - 1], "progress": { "turn1": progress[0], "turn2": progress[1], "turn3": progress[2] }, "progressElpasedTime": { "turn1": progressElpasedTime[0], "turn2": progressElpasedTime[1], "turn3": progressElpasedTime[2], }, "currentTurn": currentTurn, // "inactivity": inactivity, "mistakes": { "turn1": { "slope": mistakesSlope[0], "initialPoint": mistakesInitialPosition[0] }, "turn2": { "slope": mistakesSlope[1], "initialPoint": mistakesInitialPosition[1] }, "turn3": { "slope": mistakesSlope[2], "initialPoint": mistakesInitialPosition[2] }, } })); } void calcHaptic() { Offset beginpath = mapShape[currentTurn - 1]['startCenter']; Offset endpath = mapShape[currentTurn - 1]['endCenter']; final curve = new CubicBezier([ new vector.Vector2(beginpath.dx, beginpath.dy), new vector.Vector2( midddlePoint1[currentTurn - 1].dx, midddlePoint1[currentTurn - 1].dy), new vector.Vector2( midddlePoint2[currentTurn - 1].dx, midddlePoint2[currentTurn - 1].dy), new vector.Vector2(endpath.dx, endpath.dy) ]); var tHaptic = curve.nearestTValue(new vector.Vector2( (celluloxPosition[0] + celluloyPosition[0]) / 2, (celluloxPosition[1] + celluloyPosition[1]) / 2)); var xyHaptic = curve.pointAt(tHaptic); - print('thaptic' + tHaptic.toString()); + xyHapticG[0] = xyHaptic[0].toDouble(); + xyHapticG[1] = xyHaptic[1].toDouble(); + //print('thaptic' + tHaptic.toString()); - print('xyhaptic' + xyHaptic.toString()); + // print('xyhaptic' + xyHaptic.toString()); cellulox.setGoalPosition(2 * xyHaptic[0].toDouble() - celluloyPosition[0], celluloxPosition[1], 150); celluloy.setGoalPosition(celluloyPosition[0], 2 * xyHaptic[1].toDouble() - celluloxPosition[1], 150); - var distancePointCurve = math.sqrt(math.pow( - ((celluloxPosition[0] + celluloyPosition[0]) / 2 - beginpath.dx), + ((celluloxPosition[0] + celluloyPosition[0]) / 2 - xyHaptic[0]), 2) + math.pow( - ((celluloxPosition[1] + celluloyPosition[1]) / 2 - beginpath.dy), + ((celluloxPosition[1] + celluloyPosition[1]) / 2 - xyHaptic[1]), 2)); -/* - if (scoret> 50 && outofborder==false) {outofborder=true; - timeStart = new Date().getTime(); - // console.log(timeStart) - } - var timeNow = new Date().getTime(); + if (distancePointCurve > 50 && outofborder == false) { + outofborder = true; + timeOutofBorder = elapseTimer.elapsedMilliseconds; + // console.log(timeStart) + } + var timeNow = elapseTimer.elapsedMilliseconds; + + //console.log( timeNow- timeStart) + if (outofborder == true && + timeNow - timeOutofBorder < 3000 && + distancePointCurve < 10) { + outofborder = false; + // console.log("outofbordrfalse") + } - //console.log( timeNow- timeStart) - if (outofborder==true && timeNow- timeStart < 3000 && scoret < 10 ) - { - outofborder=false; - // console.log("outofbordrfalse") - } + if (outofborder == true && timeNow - timeOutofBorder > 3000) { + outofborder = false; + score = score - 1; - if (outofborder==true && timeNow- timeStart > 3000 ) { -outofborder=false; - score=score-1; - //console.log("battey reduced") - } -*/ + } } @override void initState() { super.initState(); cellulox.setColor(0, 255, 0, 0, 0); celluloy.setColor(0, 0, 255, 0, 0); + Offset beginpath = mapShape[currentTurn - 1]['startCenter']; + cellulox.setGoalPosition(beginpath.dx, beginpath.dy, 150); + celluloy.setGoalPosition(beginpath.dx + 100, beginpath.dy, 150); dbRef.child('groups').child(group.id).child('tabletStatus').set("YES"); dbRef.child('groups').child(group.id).child('currentActivity').set("Ac4"); + + timerCelluloPositionPainttoserver = + new Timer.periodic(new Duration(milliseconds: 1800), (time) { + if (true) { + dbRef.child("celluloPosition").push().set(json.encode({ + "x": celluloxPosition[0], + "y": celluloyPosition[1], + "acID": "Ac4", + "turn": currentTurn, + "groupID": group.id, + })); + } + }); + timerCelluloPosition = new Timer.periodic(new Duration(milliseconds: 200), (time) { if (totalRobots() > 1) { cellulox.getrobotx().then((val) => setState(() { if (val != null) { celluloxPosition[0] = val; - print('dddd' + celluloxPosition[0].toString()); + + /// print('dddd' + celluloxPosition[0].toString()); // if (addtoprint == true) celluloxPositiontopaint.add(val); } // print(addtoprint.toString()); })); cellulox.getroboty().then((val) => setState(() { if (val != null) { celluloxPosition[1] = val; } })); celluloy.getrobotx().then((val) => setState(() { if (val != null) { celluloyPosition[0] = val; } })); celluloy.getroboty().then((val) => setState(() { if (val != null) { celluloyPosition[1] = val; // if (addtoprint == true) celluloyPositiontopaint.add(val); } })); - if (celluloxPosition[0] > 800 || celluloyPosition[1] > 800) { cellulox.setVelocity(0, 0); celluloy.setVelocity(0, 0); } } //if (runHaptic == true) { calcHaptic(); checkCelluloGame(); }); - elapseTimer.start(); onDataSend(); } void checkCelluloGame() { Offset beginpath = mapShape[currentTurn - 1]['startCenter']; Offset endpath = mapShape[currentTurn - 1]['endCenter']; - double celluloXYdistances = math.sqrt( math.pow((celluloxPosition[0] - celluloyPosition[0]), 2) + math.pow((celluloxPosition[1] - celluloyPosition[1]), 2)); double distanceThreshold = 120; //print(score.toString()); //print(enterBorder.toString()); - if (celluloXYdistances < distanceThreshold) { cellulox.robotVibrate(10, 10, 0, 100, 100); celluloy.robotVibrate(10, 10, 0, 100, 100); // cellulox.setVelocity(-celluloxVelocity[0], -celluloxVelocity[1]); // celluloy.setVelocity(-celluloyVelocity[0], -celluloyVelocity[1]); } var distancePointCenter = math.sqrt(math.pow( ((celluloxPosition[0] + celluloyPosition[0]) / 2 - beginpath.dx), 2) + math.pow( ((celluloxPosition[1] + celluloyPosition[1]) / 2 - beginpath.dy), 2)); if (distancePointCenter <= radiuosStart) { score = 6; gameover = false; reachend = false; } if (score <= 0 && gameover == false) { tapCounter = tapCounter + 1; onDataSend(); gameover = true; - showAlertDialog(context, 'Your Robot Does not have energy', + showAlertDialog(context, 'Your Robot does not have energy', 'Tell your friend to go start point to get energy'); } var distancePointEnd = math.sqrt(math.pow( ((celluloxPosition[0] + celluloyPosition[0]) / 2 - endpath.dx), 2) + math.pow( ((celluloxPosition[1] + celluloyPosition[1]) / 2 - endpath.dy), 2)); if (distancePointEnd <= radiuosStart && reachend == false) { // scoreX = -1; reachend = true; tapCounter = tapCounter + 1; onDataSend(); showAlertDialog(context, 'Your Robot reached the goal point', 'Tell your friend to start again or you can go to next turn.'); } colorRobots(); } void colorRobots() { for (int i = 0; i < 6; i++) { cellulox.setColor(0, 0, 0, 0, 0); } for (int i = 0; i < score; i++) { cellulox.setColor(0, 255, 0, 1, i); } for (int i = 0; i < 6; i++) { celluloy.setColor(0, 0, 0, 0, 0); } for (int i = 0; i < score; i++) { celluloy.setColor(0, 0, 255, 1, i); } } @override void dispose() { elapseTimer.stop(); timerCelluloPosition.cancel(); // + timerCelluloPositionPainttoserver.cancel(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: const Text('Follow the Line'), + title: const Text('Follow the Line Together'), ), backgroundColor: Colors.white, body: SingleChildScrollView( child: Column(children: [ Row(mainAxisAlignment: MainAxisAlignment.center, children: [ Container( height: 100, width: 600, child: Stack(children: [ Card( child: ListTile( - title: Text('Try to follow the curve. '), + title: Text('Follow the curve from ' + + startPoint[currentTurn - 1].toString() + + ' to ' + + endPoint[currentTurn - 1].toString()), ), ), ])), SizedBox( width: 15, ), SizedBox(width: 20), Container( decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(100)), color: Colors.blue), child: FlatButton( child: Text( "Next Turn", style: TextStyle( color: Colors.white, fontWeight: FontWeight.w700, fontSize: 18), ), onPressed: () => { tapCounter = 0, if (currentTurn <= 2) { setState(() { currentTurn = currentTurn + 1; }), progress[currentTurn - 2] = 1, // controller.reset(), progress[currentTurn - 1] = 0, onDataSend(), } else { progress[2] = 1, onDataSend(), showAlertDialog( context, 'Wait for teacher', 'Game has finished! '), }, }, ), ) ]), Container( width: MediaQuery.of(context).size.width * 0.9, height: MediaQuery.of(context).size.height * 0.65, decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(100)), // color: Colors.blue ), child: Stack( children: [ CustomPaint( //size: Size(200, 200), painter: //LinePainter2(celluloxPositiontopaint, celluloyPositiontopaint), MapShapeMaker( + pointPosition, MediaQuery.of(context).size.width * 0.9 / mapSizeWidth, MediaQuery.of(context).size.height * 0.65 / mapSizeHeight, mapShape[currentTurn - 1]['numRectangles'], mapShape[currentTurn - 1]['originRectangles'], mapShape[currentTurn - 1]['widthRectangles'], mapShape[currentTurn - 1]['heightRectangles'], mapShape[currentTurn - 1]['numCircles'], mapShape[currentTurn - 1]['originCircles'], mapShape[currentTurn - 1]['radiuosCircles'], mapShape[currentTurn - 1]['numPolygons'], mapShape[currentTurn - 1]['sidesofPolygon'], mapShape[currentTurn - 1]['radiusPolygon'], mapShape[currentTurn - 1]['centerPolygon'], mapShape[currentTurn - 1]['startCenter'], mapShape[currentTurn - 1]['endCenter']), ), Container( width: MediaQuery.of(context).size.width * 0.9, height: MediaQuery.of(context).size.height * 0.65, child: Align( alignment: Alignment( 2 * ((celluloxPosition[0] + celluloyPosition[0]) / 2 / mapSizeWidth) - 1, 2 * ((celluloxPosition[1] + celluloyPosition[1]) / 2 / mapSizeHeight) - 1), child: Card( child: SvgPicture.asset( "assets/images/celluloPurple.svg", height: 60, width: 60), ), ), ), Container( width: MediaQuery.of(context).size.width * 0.9, height: MediaQuery.of(context).size.height * 0.65, child: Align( alignment: Alignment( 2 * ((celluloxPosition[0]) / mapSizeWidth) - 1, 2 * ((celluloxPosition[1]) / mapSizeHeight) - 1), child: Card( child: SvgPicture.asset("assets/images/celluloRed.svg", height: 60, width: 60), ), ), ), Container( width: MediaQuery.of(context).size.width * 0.9, height: MediaQuery.of(context).size.height * 0.65, child: Align( alignment: Alignment( 2 * ((celluloyPosition[0]) / mapSizeWidth) - 1, 2 * ((celluloyPosition[1]) / mapSizeHeight) - 1), child: Card( child: SvgPicture.asset("assets/images/celluloBlue.svg", height: 60, width: 60), ), ), ), CustomPaint( //size: Size(200, 200), painter: BezierCurvePainter( mapShape[currentTurn - 1]['startCenter'], mapShape[currentTurn - 1]['endCenter'], MediaQuery.of(context).size.width * 0.9 / mapSizeWidth, MediaQuery.of(context).size.height * 0.65 / mapSizeHeight, currentTurn) //LinePainter2(celluloxPositiontopaint, celluloyPositiontopaint), ), + CustomPaint( + //size: Size(200, 200), + painter: + //LinePainter2(celluloxPositiontopaint, celluloyPositiontopaint), + Arrow( + celluloxPosition, + celluloyPosition, + MediaQuery.of(context).size.width * + 0.9 / + mapSizeWidth, + MediaQuery.of(context).size.height * + 0.65 / + mapSizeHeight, + (xyHapticG[0] - celluloxPosition[0]), + xyHapticG[1] - celluloyPosition[1]), + ), ], )), SizedBox( - height: 15, + height: 35, + ), + MembersBar( + curTurn: currentTurn, ), - MembersBar(), ]))); } } diff --git a/student/lib/Activities/Ac5.dart b/student/lib/Activities/Ac5.dart index bb53972..cac51a4 100644 --- a/student/lib/Activities/Ac5.dart +++ b/student/lib/Activities/Ac5.dart @@ -1,473 +1,672 @@ import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:student/widgets/onlineRobotMap.Dart'; import 'dart:async'; import 'dart:convert'; import 'package:student/Database.dart'; import 'package:student/model/Group.dart'; import 'package:student/model/Cellulo.dart'; import 'package:student/widgets/showAlertDialog.Dart'; import 'package:student/widgets/membersBar.Dart'; import 'package:student/widgets/inactivityDetector.Dart'; import 'package:flutter_appavailability/flutter_appavailability.dart'; import 'package:student/widgets/bezierCurvePainter.dart'; import 'package:bezier/bezier.dart'; import 'package:student/widgets/mapShapeMaker.dart'; import 'package:bezier/bezier.dart'; -import "dart:math"; +import "dart:math" as math; import "package:vector_math/vector_math.dart" as vector; import 'package:student/widgets/guidegrid.dart'; +import 'package:student/widgets/stopdrawer.dart'; class Ac5 extends StatefulWidget { Ac5({Key key}) : super(key: key); @override _Ac5State createState() => _Ac5State(); } class _Ac5State extends State { // Activity_Independent int currentTurn = 1; var elapseTimer = new Stopwatch(); + var timeOutofBorder; AnimationController controllerRobotPath; Animation animationRobotPath; Timer timerCelluloPosition; + Timer timerCelluloPositionPainttoserver; // Celulo var celluloxPosition = [0.0, 0.0]; var celluloyPosition = [0.0, 0.0]; var xHaptic; var yHaptic; final String mapPath = 'assets/images/Grid_Ac6_Screen.svg'; // Learning - + bool gameover = false; + int score = 6; + bool outofborder = false; + bool reachend = false; + bool stopend = false; + double radiuosStart = 45; List mistakesSlope = [0, 0, 0]; List mistakesIntrepet = [0, 0, 0]; List mistakesInitialPosition = [0, 0, 0]; int tapCounter = 0; List progress = [0, -2, -2]; List progressElpasedTime = [0, 0, 0]; //Activity Dependent final double mapSizeWidth = 860; final double mapSizeHeight = 860; + final List initialpointList = ['0', '1', '2', '3', '4', '5', '6']; + String initialPointXvalue; + String initialPointYvalue; static List pointPosition = [ - Offset(80, 80), - Offset(760, 80), - Offset(80, 760), - Offset(760, 760) + Offset(610, 132), + Offset(125, 435), ]; var midddlePoint1 = [ Offset(291.1, 176.2), Offset(110.2, 632.8), Offset(610.2, 732.8) ]; var midddlePoint2 = [ Offset(410.2, 532.8), Offset(356, 357), Offset(110.2, 232.8) ]; + var startPoint = ['C', 'A', 'C']; + var endPoint = ['B', 'D', 'B']; + List stopBoxCenter = [ + Offset(450, 330), + Offset(400, 460), + Offset(425, 200) + ]; + Offset origin = new Offset(106, 572.0); // should be calibrated for a new map + var step = 75.0; var mapShape = [ { 'numCircles': 0, 'originCircles': [Offset(0, 0)], 'radiuosCircles': [0.0], 'numRectangles': 0, 'originRectangles': [ Offset(300, 30), Offset(100, 560), Offset(600, 630), Offset(780, 360), Offset(300, 300), Offset(500, 260), Offset(300, 560) ], 'widthRectangles': [150.0, 100.0, 50.0, 80.0, 150.0, 100.0, 100.0], 'heightRectangles': [70.0, 100.0, 200.0, 300.0, 40.0, 300.0, 200.0], 'numPolygons': 0, 'sidesofPolygon': [0], 'radiusPolygon': [0.0], 'centerPolygon': [Offset(0, 0)], - 'startCenter': pointPosition[2], - 'endCenter': pointPosition[1] + 'startCenter': pointPosition[1], + 'endCenter': pointPosition[0] }, { 'numCircles': 0, 'originCircles': [Offset(0, 0)], 'radiuosCircles': [0.0], 'numRectangles': 0, 'originRectangles': [ Offset(690, 430), Offset(500, 560), Offset(430, 130), Offset(300, 760), Offset(100, 230), Offset(100, 460) ], 'widthRectangles': [150.0, 100.0, 200.0, 100.0, 210.0, 210.0], 'heightRectangles': [150.0, 250.0, 50.0, 250.0, 50.0, 300.0], 'numPolygons': 0, 'sidesofPolygon': [3, 3, 5, 4, 4], 'radiusPolygon': [30.0, 40.0, 40.0, 40.0, 50.0], 'centerPolygon': [ Offset(40, 130), Offset(700, 90), Offset(600, 200), Offset(600, 500), Offset(780, 400) ], - 'startCenter': pointPosition[0], - 'endCenter': pointPosition[3] + 'startCenter': pointPosition[1], + 'endCenter': pointPosition[0] }, { 'numCircles': 0, 'originCircles': [Offset(0, 0)], 'radiuosCircles': [0.0], 'numRectangles': 0, 'originRectangles': [ Offset(300, 130), Offset(500, 460), Offset(750, 530), Offset(600, 130), Offset(600, 730), Offset(100, 530), Offset(350, 460) ], 'widthRectangles': [160.0, 90.0, 150.0, 100.0, 150.0, 300.0, 50.0], 'heightRectangles': [130.0, 270.0, 150.0, 250.0, 100.0, 70.0, 250.0], 'numPolygons': 0, 'sidesofPolygon': [0], 'radiusPolygon': [0.0], 'centerPolygon': [Offset(0, 0)], - 'startCenter': pointPosition[2], - 'endCenter': pointPosition[1] + 'startCenter': pointPosition[1], + 'endCenter': pointPosition[0] }, ]; void onDataSend() { dbRef.child('attempts').push().set(json.encode({ "numAttempts": tapCounter, "groupID": group.id, "acID": "Ac5", "elpasedTime": elapseTimer.elapsedMilliseconds - progressElpasedTime[currentTurn - 1], "progress": { "turn1": progress[0], "turn2": progress[1], "turn3": progress[2] }, "progressElpasedTime": { "turn1": progressElpasedTime[0], "turn2": progressElpasedTime[1], "turn3": progressElpasedTime[2], }, "currentTurn": currentTurn, // "inactivity": inactivity, "mistakes": { "turn1": { "slope": mistakesSlope[0], "initialPoint": mistakesInitialPosition[0] }, "turn2": { "slope": mistakesSlope[1], "initialPoint": mistakesInitialPosition[1] }, "turn3": { "slope": mistakesSlope[2], "initialPoint": mistakesInitialPosition[2] }, } })); } + void checkCelluloGame() { + Offset beginpath = mapShape[currentTurn - 1]['startCenter']; + Offset endpath = mapShape[currentTurn - 1]['endCenter']; + double celluloXYdistances = math.sqrt( + math.pow((celluloxPosition[0] - celluloyPosition[0]), 2) + + math.pow((celluloxPosition[1] - celluloyPosition[1]), 2)); + double distanceThreshold = 120; + //print(score.toString()); + //print(enterBorder.toString()); + if (celluloXYdistances < distanceThreshold) { + cellulox.robotVibrate(10, 10, 0, 100, 100); + celluloy.robotVibrate(10, 10, 0, 100, 100); + // cellulox.setVelocity(-celluloxVelocity[0], -celluloxVelocity[1]); + // celluloy.setVelocity(-celluloyVelocity[0], -celluloyVelocity[1]); + } + var distancePointCenter = math.sqrt(math.pow( + ((celluloxPosition[0] + celluloxPosition[0]) / 2 - beginpath.dx), + 2) + + math.pow( + ((celluloyPosition[1] + celluloyPosition[1]) / 2 - beginpath.dy), + 2)); + if (distancePointCenter <= radiuosStart) { + score = 6; + gameover = false; + reachend = false; + } + + if (score <= 0 && gameover == false) { + tapCounter = tapCounter + 1; + onDataSend(); + gameover = true; + showAlertDialog(context, 'Your Robot does not have energy', + 'Tell your friend to go start point to get energy'); + } + + var distancePointEnd = math.sqrt(math.pow( + ((celluloxPosition[0] + celluloxPosition[0]) / 2 - endpath.dx), 2) + + math.pow( + ((celluloyPosition[1] + celluloyPosition[1]) / 2 - endpath.dy), 2)); + if (distancePointEnd <= radiuosStart && reachend == false) { + // scoreX = -1; + reachend = true; + tapCounter = tapCounter + 1; + onDataSend(); + showAlertDialog(context, 'Your Robot reached the goal point', + 'Tell your friend to start again or you can go to next turn.'); + } + + var distancePointStop = math.sqrt(math.pow( + ((celluloxPosition[0] + celluloxPosition[0]) / 2 - + stopBoxCenter[currentTurn - 1].dx), + 2) + + math.pow( + ((celluloyPosition[1] + celluloyPosition[1]) / 2 - + stopBoxCenter[currentTurn - 1].dy), + 2)); + if (distancePointStop <= radiuosStart && stopend == false) { + // scoreX = -1; + stopend = true; + tapCounter = tapCounter + 1; + onDataSend(); + showAlertDialog(context, 'Your Robot reached the middle stop point', + 'Put where should red and blue robot should go in continue.'); + } + colorRobots(); + } + + void colorRobots() { + for (int i = 0; i < 6; i++) { + cellulox.setColor(0, 0, 0, 0, 0); + } + for (int i = 0; i < score; i++) { + cellulox.setColor(0, 255, 0, 1, i); + } + + for (int i = 0; i < 6; i++) { + celluloy.setColor(0, 0, 0, 0, 0); + } + for (int i = 0; i < score; i++) { + celluloy.setColor(0, 0, 255, 1, i); + } + } + void calcHaptic() { Offset beginpath = mapShape[currentTurn - 1]['startCenter']; Offset endpath = mapShape[currentTurn - 1]['endCenter']; final curve = new CubicBezier([ new vector.Vector2(beginpath.dx, beginpath.dy), new vector.Vector2( midddlePoint1[currentTurn - 1].dx, midddlePoint1[currentTurn - 1].dy), new vector.Vector2( midddlePoint2[currentTurn - 1].dx, midddlePoint2[currentTurn - 1].dy), new vector.Vector2(endpath.dx, endpath.dy) ]); var tHaptic = curve.nearestTValue(new vector.Vector2( - (celluloxPosition[0] + celluloyPosition[0]) / 2, - (celluloxPosition[1] + celluloyPosition[1]) / 2)); + (celluloxPosition[0] + celluloxPosition[0]) / 2, + (celluloyPosition[1] + celluloyPosition[1]) / 2)); var xyHaptic = curve.pointAt(tHaptic); - print('thaptic' + tHaptic.toString()); + // print('thaptic' + tHaptic.toString()); - print('xyhaptic' + xyHaptic.toString()); + //print('xyhaptic' + xyHaptic.toString()); - cellulox.setGoalPosition(2 * xyHaptic[0].toDouble() - celluloyPosition[0], - celluloxPosition[1], 150); - celluloy.setGoalPosition(celluloyPosition[0], - 2 * xyHaptic[1].toDouble() - celluloxPosition[1], 150); - /* - var slopeHaptic = -1 / linesSlope[currentTurn - 1]; - var initialHaptic = (originCoordinates[1] - celluloyPosition[1]) / 100 - - slopeHaptic * (celluloxPosition[0] - originCoordinates[0]) / 100; - // print('initialhaptic' + initialHaptic.toString()); - setState(() { - xHaptic = (initialHaptic - initialPoint[currentTurn - 1]) / - (linesSlope[currentTurn - 1] - slopeHaptic); - yHaptic = ((linesSlope[currentTurn - 1]) * xHaptic + - initialPoint[currentTurn - 1]); - }); - // print('xcelluloy' + xcelluloy.toDouble().toString()); -// print('yhaptic' + yHaptic.toString()); - // print('xhaptic' + xHaptic.toString()); - cellulox.setGoalPosition( - xHaptic * 100 + originCoordinates[0], xcelluloy.toDouble(), 150); - celluloy.setGoalPosition( - ycellulox.toDouble(), originCoordinates[1] - (100 * yHaptic), 150); - */ + cellulox.setGoalPosition(xyHaptic[0].toDouble(), 800, 150); + celluloy.setGoalPosition(60, xyHaptic[1].toDouble(), 150); + + var distancePointCurve = math.sqrt(math.pow( + ((celluloxPosition[0] + celluloyPosition[0]) / 2 - xyHaptic[0]), + 2) + + math.pow( + ((celluloxPosition[1] + celluloyPosition[1]) / 2 - xyHaptic[1]), + 2)); + + if (distancePointCurve > 50 && outofborder == false) { + outofborder = true; + timeOutofBorder = elapseTimer.elapsedMilliseconds; + // console.log(timeStart) + } + var timeNow = elapseTimer.elapsedMilliseconds; + + //console.log( timeNow- timeStart) + if (outofborder == true && + timeNow - timeOutofBorder < 3000 && + distancePointCurve < 10) { + outofborder = false; + // console.log("outofbordrfalse") + } + + if (outofborder == true && timeNow - timeOutofBorder > 3000) { + outofborder = false; + score = score - 1; + +//console.log("battey reduced") + } } @override void initState() { super.initState(); cellulox.setColor(0, 255, 0, 0, 0); + timerCelluloPositionPainttoserver = + new Timer.periodic(new Duration(milliseconds: 1800), (time) { + if (true) { + dbRef.child("celluloPosition").push().set(json.encode({ + "x": celluloxPosition[0], + "y": celluloyPosition[1], + "acID": "Ac5", + "turn": currentTurn, + "groupID": group.id, + })); + } + }); + celluloy.setColor(0, 0, 255, 0, 0); dbRef.child('groups').child(group.id).child('tabletStatus').set("YES"); dbRef.child('groups').child(group.id).child('currentActivity').set("Ac5"); timerCelluloPosition = new Timer.periodic(new Duration(milliseconds: 500), (time) { if (totalRobots() > 1) { cellulox.getrobotx().then((val) => setState(() { if (val != null) { celluloxPosition[0] = val; - print('dddd' + celluloxPosition[0].toString()); + // print('dddd' + celluloxPosition[0].toString()); // if (addtoprint == true) celluloxPositiontopaint.add(val); } // print(addtoprint.toString()); })); cellulox.getroboty().then((val) => setState(() { if (val != null) { celluloxPosition[1] = val; } })); celluloy.getrobotx().then((val) => setState(() { if (val != null) { celluloyPosition[0] = val; } })); celluloy.getroboty().then((val) => setState(() { if (val != null) { celluloyPosition[1] = val; // if (addtoprint == true) celluloyPositiontopaint.add(val); } })); if (celluloxPosition[0] > 800 || celluloyPosition[1] > 800) { cellulox.setVelocity(0, 0); celluloy.setVelocity(0, 0); } } //if (runHaptic == true) { calcHaptic(); + checkCelluloGame(); }); elapseTimer.start(); onDataSend(); } @override void dispose() { elapseTimer.stop(); timerCelluloPosition.cancel(); // super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Follow the Line'), ), backgroundColor: Colors.white, body: SingleChildScrollView( child: Column(children: [ Row(mainAxisAlignment: MainAxisAlignment.center, children: [ Container( height: 100, width: 600, child: Stack(children: [ Card( child: ListTile( - title: Text('Try to follow the curve. '), + title: Text('Follow the curve from ' + + startPoint[currentTurn - 1].toString() + + ' to ' + + endPoint[currentTurn - 1].toString()), ), ), ])), SizedBox( width: 15, ), SizedBox(width: 20), Container( decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(100)), color: Colors.blue), child: FlatButton( child: Text( "Next Turn", style: TextStyle( color: Colors.white, fontWeight: FontWeight.w700, fontSize: 18), ), onPressed: () => { tapCounter = 0, if (currentTurn <= 2) { setState(() { currentTurn = currentTurn + 1; }), progress[currentTurn - 2] = 1, // controller.reset(), progress[currentTurn - 1] = 0, onDataSend(), } else { progress[2] = 1, onDataSend(), showAlertDialog( context, 'Wait for teacher', 'Game has finished! '), }, }, ), ) ]), + (stopend) + ? Row( + // crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + width: 250, + child: ListTile( + title: Text('Where the robot should go:'), + )), + Container( + width: 200, + child: DropdownButton( + hint: Text('RED robot goes to: '), + value: initialPointXvalue, + icon: Icon(Icons.arrow_downward), + iconSize: 24, + elevation: 16, + style: TextStyle(color: Colors.deepPurple), + onChanged: (String newValue) { + setState(() { + initialPointXvalue = newValue; + }); + }, + items: initialpointList + .map>((String value) { + return DropdownMenuItem( + value: value, + child: Text(value), + ); + }).toList(), + )), + SizedBox(width: 38), + Container( + width: 200, + child: DropdownButton( + hint: Text('BLUE robot goes to: '), + value: initialPointYvalue, + icon: Icon(Icons.arrow_downward), + iconSize: 24, + elevation: 16, + style: TextStyle(color: Colors.deepPurple), + onChanged: (String newValue) { + setState(() { + initialPointYvalue = newValue; + }); + }, + items: initialpointList + .map>((String value) { + return DropdownMenuItem( + value: value, + child: Text(value), + ); + }).toList(), + )), + ]) + : SizedBox( + height: 1, + ), + SizedBox( + height: 10, + ), Container( width: MediaQuery.of(context).size.width * 0.9, height: MediaQuery.of(context).size.height * 0.65, decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(100)), // color: Colors.blue ), child: Stack( children: [ CustomPaint( //size: Size(200, 200), painter: //LinePainter2(celluloxPositiontopaint, celluloyPositiontopaint), MapShapeMaker( + pointPosition, MediaQuery.of(context).size.width * 0.9 / mapSizeWidth, MediaQuery.of(context).size.height * 0.65 / mapSizeHeight, mapShape[currentTurn - 1]['numRectangles'], mapShape[currentTurn - 1]['originRectangles'], mapShape[currentTurn - 1]['widthRectangles'], mapShape[currentTurn - 1]['heightRectangles'], mapShape[currentTurn - 1]['numCircles'], mapShape[currentTurn - 1]['originCircles'], mapShape[currentTurn - 1]['radiuosCircles'], mapShape[currentTurn - 1]['numPolygons'], mapShape[currentTurn - 1]['sidesofPolygon'], mapShape[currentTurn - 1]['radiusPolygon'], mapShape[currentTurn - 1]['centerPolygon'], mapShape[currentTurn - 1]['startCenter'], mapShape[currentTurn - 1]['endCenter']), ), Container( width: MediaQuery.of(context).size.width * 0.9, height: MediaQuery.of(context).size.height * 0.65, child: Align( alignment: Alignment( 2 * - ((celluloxPosition[0] + celluloyPosition[0]) / + ((celluloxPosition[0] + celluloxPosition[0]) / 2 / mapSizeWidth) - 1, 2 * - ((celluloxPosition[1] + celluloyPosition[1]) / + ((celluloyPosition[1] + celluloyPosition[1]) / 2 / mapSizeHeight) - 1), child: Card( child: SvgPicture.asset( "assets/images/celluloPurple.svg", height: 60, width: 60), ), ), ), Container( width: MediaQuery.of(context).size.width * 0.9, height: MediaQuery.of(context).size.height * 0.65, child: SvgPicture.asset( mapPath, ), ), + CustomPaint( + //size: Size(200, 200), + painter: GuideGrid( + origin, + step, + MediaQuery.of(context).size.width * 0.9 / mapSizeWidth, + MediaQuery.of(context).size.height * 0.65 / mapSizeHeight, + celluloxPosition, + celluloyPosition, + ) + //LinePainter2(celluloxPositiontopaint, celluloyPositiontopaint), + + ), + CustomPaint( + //size: Size(200, 200), + painter: StopDrawer( + MediaQuery.of(context).size.width * 0.9 / mapSizeWidth, + MediaQuery.of(context).size.height * 0.65 / mapSizeHeight, + stopBoxCenter[currentTurn - 1], + ) + //LinePainter2(celluloxPositiontopaint, celluloyPositiontopaint), + + ), Container( width: MediaQuery.of(context).size.width * 0.9, height: MediaQuery.of(context).size.height * 0.65, child: Align( alignment: Alignment( 2 * ((celluloxPosition[0]) / mapSizeWidth) - 1, 2 * ((celluloxPosition[1]) / mapSizeHeight) - 1), child: Card( child: SvgPicture.asset("assets/images/celluloRed.svg", height: 60, width: 60), ), ), ), Container( width: MediaQuery.of(context).size.width * 0.9, height: MediaQuery.of(context).size.height * 0.65, child: Align( alignment: Alignment( 2 * ((celluloyPosition[0]) / mapSizeWidth) - 1, 2 * ((celluloyPosition[1]) / mapSizeHeight) - 1), child: Card( child: SvgPicture.asset("assets/images/celluloBlue.svg", height: 60, width: 60), ), ), ), CustomPaint( //size: Size(200, 200), painter: BezierCurvePainter( mapShape[currentTurn - 1]['startCenter'], mapShape[currentTurn - 1]['endCenter'], MediaQuery.of(context).size.width * 0.9 / mapSizeWidth, MediaQuery.of(context).size.height * 0.65 / mapSizeHeight, currentTurn) //LinePainter2(celluloxPositiontopaint, celluloyPositiontopaint), - ), - CustomPaint( - //size: Size(200, 200), - painter: GuideGrid( - Offset(celluloxPosition[0], celluloyPosition[1]), - 100, - 700, - MediaQuery.of(context).size.width * - 0.9 / - mapSizeWidth, - MediaQuery.of(context).size.height * - 0.65 / - mapSizeHeight) - //LinePainter2(celluloxPositiontopaint, celluloyPositiontopaint), - ), ], )), SizedBox( height: 15, ), - MembersBar(), + MembersBar( + curTurn: currentTurn, + ), ]))); } } diff --git a/student/lib/Activities/Ac6.dart b/student/lib/Activities/Ac6.dart index 7e8c7bd..af65811 100644 --- a/student/lib/Activities/Ac6.dart +++ b/student/lib/Activities/Ac6.dart @@ -1,656 +1,656 @@ import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart'; import 'package:student/widgets/celluloMap.Dart'; import 'dart:async'; import 'dart:convert'; import 'package:student/Database.dart'; import 'package:student/model/Group.dart'; import 'package:student/model/Cellulo.dart'; import 'package:student/widgets/showAlertDialog.Dart'; import 'package:student/widgets/membersBar.Dart'; import 'package:student/widgets/inactivityDetector.Dart'; import 'package:flutter_appavailability/flutter_appavailability.dart'; import 'dart:math' as math; class Ac6 extends StatefulWidget { Ac6({Key key}) : super(key: key); @override _Ac6State createState() => _Ac6State(); } class _Ac6State extends State with SingleTickerProviderStateMixin, WidgetsBindingObserver { // Timers Timer timerCelluloPosition; Timer timerslopedetection; Timer timercleartracking; Timer timerCelluloPositionPaint; Timer timerInactivityDetector; Timer timerCelluloPositionPainttoserver; final acID = 6; final maxLiitCellulo = 800; // UI parameters bool celluloxSwitch1 = true; bool celluloySwitch1 = false; bool celluloxSwitch2 = true; bool celluloySwitch2 = false; var onStop = false; bool mode = false; int wrongcounts = 0; double _progress = 0.0; final celluloSize = 60; final ScrollController _scrollController = ScrollController(); final functionFormulas = ['X ⟼ Y', 'X+1 ⟼ Y', 'X+2 ⟼ Y', '2*X ⟼ Y', '-X ⟼ Y']; Offset beginpath = Offset(0, 0); Offset endpath = Offset(10, 100); AnimationController controllerTrial; AnimationController controllerTurn; Animation animation; Animation animationNextTurn; TextEditingController controllerinitialX = TextEditingController(); TextEditingController controllerinitialY = TextEditingController(); TextEditingController controllerXslope = TextEditingController(); TextEditingController controllerYslope = TextEditingController(); var counterfunctionImage = 0; //Activity Dependent var linesPath = [ 'assets/images/Ac6_function1.svg', 'assets/images/Ac6_function2.svg', 'assets/images/Ac6_function3.svg', 'assets/images/Grid_Ac6_Screen.svg', ]; var lineallow = [false, false, false]; var linesSlope = [1, 2, -1]; var initialPoint = [0, 0, 6]; // map-related final double mapSizeWidth = 860; final double mapSizeHeight = 860; final double screenSizeWidth = 500; final double screenSizeHeight = 500; final String mapPath = 'assets/images/Grid_Ac6_Screen.svg'; final String celluloxpath = 'assets/images/celluloRed.svg'; final String celluloypath = 'assets/images/celluloBlue.svg'; var onTap = [false, false, false, false, false]; // var onTap=[false,false,false,false,false]; final names = [group.member1name, group.member2name, group.member3name]; var currentTurn = 1; var currentTap = 0; var tapCounter = 0; int simulationVelCoeff = 1; // Learning List progress = [0, -2, -2]; // zero: undergoing, -1: not accomplished, 1: accomplished bool waitforanimation = false; List mistakesSlope = [0, 0, 0]; List mistakesIntrepet = [0, 0, 0]; List mistakesInitialPosition = [0, 0, 0]; List progressElpasedTime = [0, 0, 0]; var inactivity = 0; bool checkend = true; var prevcelluloxPositionSlope = 0.0; var prevcelluloyPositionSlope = 0.0; // robot related var elapseTimer = new Stopwatch(); bool allowPaint = false; var celluloxPosition = [0.0, 0.0]; var celluloyPosition = [0.0, 0.0]; var xHaptic; var yHaptic; bool runHaptic = false; var xcelluloy = 820; var ycellulox = 45; var celluloTargetPosition = [0.0, 0.0]; List> celluloxPositiontopaint = new List.generate(3, (int index) => [0.0, 0.0], growable: true); List> celluloyPositiontopaint = new List.generate(3, (int index) => [0.0, 0.0], growable: true); var xlabelposition = [1.0, 1.0]; var ylabelposition = [-0.6, -1.0]; var prevcelluloxPosition = [0.0, 0.0]; var prevcelluloyPosition = [0.0, 0.0]; // screen-related var originCoordinates = [123.5, 736.5]; var correctAnswer = [ {"initialPointX": 1, "initialPointY": 1, "slope": 1}, {"initialPointX": 0, "initialPointY": 0, "slope": 2}, {"initialPointX": 0, "initialPointY": 6, "slope": -1} ]; void calcHaptic() { var slopeHaptic = -1 / linesSlope[currentTurn - 1]; var initialHaptic = (originCoordinates[1] - celluloyPosition[1]) / 100 - slopeHaptic * (celluloxPosition[0] - originCoordinates[0]) / 100; // print('initialhaptic' + initialHaptic.toString()); setState(() { xHaptic = (initialHaptic - initialPoint[currentTurn - 1]) / (linesSlope[currentTurn - 1] - slopeHaptic); yHaptic = ((linesSlope[currentTurn - 1]) * xHaptic + initialPoint[currentTurn - 1]); }); // print('xcelluloy' + xcelluloy.toDouble().toString()); // print('yhaptic' + yHaptic.toString()); // print('xhaptic' + xHaptic.toString()); cellulox.setGoalPosition( xHaptic * 100 + originCoordinates[0], xcelluloy.toDouble(), 150); celluloy.setGoalPosition( ycellulox.toDouble(), originCoordinates[1] - (100 * yHaptic), 150); } @override void initState() { cellulox.setColor(0, 255, 0, 0, 0); celluloy.setColor(0, 0, 255, 0, 0); cellulox.clearrobot(); celluloy.clearrobot(); WidgetsBinding.instance.addObserver(this); dbRef.child('groups').child(group.id).child('tabletStatus').set("YES"); dbRef.child('groups').child(group.id).child('currentActivity').set("Ac6"); elapseTimer.start(); onDataSend(); controllerTrial = AnimationController( duration: Duration(milliseconds: 30000), vsync: this); animation = Tween(begin: 0.0, end: 1.0).animate(controllerTrial) ..addListener(() { _progress = animation.value; if (_progress < 0.2) { //print('uuh'); cellulox.setGoalPosition(originCoordinates[0], 700, 150); celluloy.setGoalPosition(80, originCoordinates[1], 150); } if (_progress > 0.22) { setState(() { allowPaint = true; }); // } //if (celluloxPosition[0] > 700 || // celluloyPosition[1] < 100) { // cellulox.resetrobot(); // celluloy.resetrobot(); // calcHaptic(); // cellulox.setGoalPosition(xHaptic, 0); // celluloy.setGoalPosition(0, yHaptic); } if (_progress == 1.0) { // cellulox.setGoalPosition(770, 600); // celluloy.setGoalPosition(100, 80); setState(() { allowPaint = false; }); // cellulox.setVelocity(0, 0); // celluloy.setVelocity(0, 0); } if (celluloxPosition[0] > 800 || celluloyPosition[1] < 50 || celluloyPosition[1] > 800) { cellulox.setVelocity(0, 0); celluloy.setVelocity(0, 0); } }); super.initState(); // cellulox.resetrobot(); // celluloy.resetrobot(); timerCelluloPosition = new Timer.periodic(new Duration(milliseconds: 100), (time) { if (totalRobots() > 1) { cellulox.getrobotx().then((val) => setState(() { celluloxPosition[0] = val; // print(celluloxPosition[0]); // if (allowPaint == true) // celluloxPositiontopaint.add(val * 500 / mapSizeWidth); // print(allowPaint.toString()); })); cellulox.getroboty().then((val) => setState(() { celluloxPosition[1] = val; //if (allowPaint == true) prevcelluloxPosition[1] = celluloxPosition[1]; })); celluloy.getrobotx().then((val) => setState(() { celluloyPosition[0] = val; // if (allowPaint == true) prevcelluloyPosition[0] = celluloyPosition[0]; })); celluloy.getroboty().then((val) => setState(() { celluloyPosition[1] = val; // if (allowPaint == true) // celluloyPositiontopaint.add(val * 500 / mapSizeHeight); })); if (checkend == true) { if (celluloxPosition[0] > 800 || celluloyPosition[1] > 800 || celluloxPosition[0] < 50 || celluloyPosition[1] < 50) { cellulox.clearrobot(); celluloy.clearrobot(); - runHaptic = false; - showAlertDialog(context, '', 'Make sure robots are on the map'); - checkend = false; + // runHaptic = false; + // showAlertDialog(context, '', 'Make sure robots are on the map'); + // checkend = false; } } if (checkend == false) { if (celluloxPosition[0] < 800 && celluloyPosition[1] < 800 && celluloxPosition[0] > 50 && celluloyPosition[1] > 50) { - // cellulox.clearrobot(); - // celluloy.clearrobot(); + cellulox.clearrobot(); + celluloy.clearrobot(); // runHaptic = false; // showAlertDialog(context, '', 'Make sure robots are on the map'); - checkend = true; - runHaptic = true; + // checkend = true; + // runHaptic = true; } } } if (true) { var distancePointStartX = math.sqrt( math.pow((celluloxPosition[0] - originCoordinates[0]), 2) + math.pow((celluloxPosition[1] - xcelluloy), 2)); var distancePointStartY = math.sqrt( math.pow((celluloyPosition[0] - ycellulox), 2) + math.pow((celluloyPosition[1] - originCoordinates[1]), 2)); if (distancePointStartY < 10 && distancePointStartX < 10) { celluloy.clearrobot(); cellulox.clearrobot(); setState(() { allowPaint = true; runHaptic = true; }); } } if (runHaptic == true) { calcHaptic(); } }); timerCelluloPositionPainttoserver = - new Timer.periodic(new Duration(milliseconds: 1800), (time) { + new Timer.periodic(new Duration(milliseconds: 500), (time) { if (allowPaint == true) { dbRef.child("celluloPosition").push().set(json.encode({ "x": celluloxPosition[0], "y": celluloyPosition[1], "acID": "Ac6", "turn": currentTurn, "groupID": group.id, })); } }); timerCelluloPositionPaint = new Timer.periodic(new Duration(seconds: 1), (time) { setState(() { if (allowPaint == true) { celluloxPositiontopaint[tapCounter - 1] .add(celluloxPosition[0] * screenSizeWidth / mapSizeWidth); celluloyPositiontopaint[tapCounter - 1] .add(celluloyPosition[1] * screenSizeHeight / mapSizeHeight); } }); }); timerInactivityDetector = new Timer.periodic(new Duration(seconds: 60), (time) { onInactivityTimer(); }); /// /// Ask to be notified when messages related to the game /// are sent by the server /// } void onDataSend() { dbRef.child('attempts').push().set(json.encode({ "numAttempts": tapCounter, "groupID": group.id, "acID": "Ac6", "elpasedTime": elapseTimer.elapsedMilliseconds - progressElpasedTime[currentTurn - 1], "progress": { "turn1": progress[0], "turn2": progress[1], "turn3": progress[2] }, "progressElpasedTime": { "turn1": progressElpasedTime[0], "turn2": progressElpasedTime[1], "turn3": progressElpasedTime[2], }, "currentTurn": currentTurn, "inactivity": inactivity, "mistakes": { "turn1": { "slope": mistakesSlope[0], "initialPoint": mistakesInitialPosition[0] }, "turn2": { "slope": mistakesSlope[1], "initialPoint": mistakesInitialPosition[1] }, "turn3": { "slope": mistakesSlope[2], "initialPoint": mistakesInitialPosition[2] }, } })); } void slopeDtectionTimer() { timerslopedetection = new Timer.periodic(new Duration(seconds: 1), (time) { print("prev" + (((celluloxPosition[0] - prevcelluloxPositionSlope).roundToDouble() > 0) .toString())); // print("currwnt" + celluloxPosition[0].toString()); controllerXslope.text = 1.0.toString(); if ((celluloxPosition[0] - prevcelluloxPositionSlope).abs() < 10) { controllerYslope.text = "You sould move the RED robot faster"; } else { controllerYslope.text = (((prevcelluloyPositionSlope - celluloyPosition[1])) / (celluloxPosition[0] - prevcelluloxPositionSlope)) .roundToDouble() .toString(); } prevcelluloxPositionSlope = celluloxPosition[0]; prevcelluloyPositionSlope = celluloyPosition[1]; // print(int.parse(controllerXslope.text) > 0); print("cur" + (((celluloxPosition[0] - prevcelluloxPositionSlope).roundToDouble() > 0) .toString())); if ((celluloxPosition[0] - prevcelluloxPositionSlope).roundToDouble() > 1) { setState(() { celluloxSwitch2 = true; print(celluloxSwitch2); }); } if (((celluloxPosition[0] - prevcelluloxPositionSlope) / 100) .roundToDouble() < -1) { setState(() { celluloxSwitch2 = false; print(celluloxSwitch2); }); } if (celluloyPosition[1] - prevcelluloyPositionSlope > 0) { setState(() { celluloySwitch2 = true; print(celluloySwitch2); }); } if (celluloyPosition[1] - prevcelluloyPositionSlope < 1.0) { setState(() { celluloySwitch2 = false; print(celluloySwitch2); }); } }); } void onInactivityTimer() { group.inactivity = group.inactivity + 1; } @override void dispose() { cellulox.clearrobot(); celluloy.clearrobot(); timer.cancel(); timerCelluloPosition.cancel(); timerCelluloPositionPaint.cancel(); timerCelluloPositionPainttoserver.cancel(); controllerTrial.dispose(); super.dispose(); } AppLifecycleState _notification; @override void didChangeAppLifecycleState(AppLifecycleState state) { if (state == AppLifecycleState.resumed) { dbRef.child('groups').child(group.id).child('tabletStatus').set("YES"); } else { dbRef.child('groups').child(group.id).child('tabletStatus').set("NO"); } setState(() { _notification = state; }); } void nextPLayer() { setState(() { currentTurn = currentTurn + 1; // celluloyPositiontopaint = [0.0, 0.0]; // celluloxPositiontopaint = [0.0, 0.0]; }); } void animationRunner(progress) {} @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: const Text('Move your robots'), + title: const Text('Follow the line with tour hands'), ), backgroundColor: Colors.white, body: SingleChildScrollView( child: Column(children: [ Container( // margin: const EdgeInsets.all(15.0), padding: const EdgeInsets.all(5.0), decoration: BoxDecoration(), height: 290.0, child: Column(children: [ Card( color: Colors.blue, child: ListTile( title: Text( ' Each of you take one robot in each hand and try to follow the orange line', style: new TextStyle( color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold, ), ), ), ), SizedBox( height: 10, ), Row( //mainAxisAlignment: MainAxisAlignment.center, children: [ Container( width: 470, child: Card( color: Colors.blue, child: ListTile( title: Text( (tapCounter == 0) ? names[0] + 'Start the game' : 'When you tried, start again with a next member', style: new TextStyle( color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold, ), ), ), )), SizedBox(width: 40), Container( decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(100)), color: Colors.green), child: FlatButton( child: Text( (tapCounter == 0) ? "Start" : "Start Again", style: TextStyle( color: Colors.white, fontWeight: FontWeight.w700, fontSize: 18), ), // tooltip: 'Run the Robots', onPressed: () => { // avgActivation= if (checkend == true) { if (tapCounter < 3) { setState(() { checkend = true; allowPaint = false; runHaptic = false; lineallow[tapCounter] = true; tapCounter = tapCounter + 1; }), cellulox.setGoalPosition( originCoordinates[0], xcelluloy.toDouble(), 150), celluloy.setGoalPosition( ycellulox.toDouble(), originCoordinates[1], 150), onDataSend(), // onDataSend(), } else { showAlertDialog( context, 'Lets go to next turn', 'Lets try a new line'), }, } // controllerTrial.reset(), // controllerTrial.forward(), }, )), SizedBox(width: 15), ]), Row( //mainAxisAlignment: MainAxisAlignment.center, children: [ Container( width: 470, child: Card( color: Colors.blue, child: ListTile( title: Text( ' When you all tried, go to next turn.', style: new TextStyle( color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold, ), ), ), )), SizedBox(width: 25), SizedBox(width: 15), Container( decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(100)), color: Colors.blue), child: FlatButton( child: Text( "Next Line", style: TextStyle( color: Colors.white, fontWeight: FontWeight.w700, fontSize: 18), ), onPressed: () => { if (currentTurn < 3) { setState(() { currentTurn = currentTurn + 1; lineallow = [false, false, false]; runHaptic = false; if (currentTurn == 2) { progressElpasedTime[0] = elapseTimer.elapsedMilliseconds; } else { progressElpasedTime[currentTurn - 2] = elapseTimer.elapsedMilliseconds - progressElpasedTime[ currentTurn - 3]; } celluloxPositiontopaint[0] = [0, 0]; celluloyPositiontopaint[0] = [0, 0]; celluloxPositiontopaint[1] = [0, 0]; celluloyPositiontopaint[1] = [0, 0]; celluloxPositiontopaint[2] = [0, 0]; celluloyPositiontopaint[2] = [0, 0]; }), // if (progress[currentTurn - 2] == 0) progress[currentTurn - 2] = 1, progress[currentTurn - 1] = 0, onDataSend(), setState(() { allowPaint = false; tapCounter = 0; }), } else { progress[currentTurn - 1] = 1, onDataSend(), showAlertDialog(context, 'Wait for teacher', 'Game has finished! '), }, }, )), ]), ])), SizedBox( height: 70, ), celluloMap( context, celluloxPositiontopaint, celluloyPositiontopaint, celluloxPosition, celluloyPosition, mapPath, linesPath[currentTurn - 1], celluloxpath, celluloypath, mapSizeWidth, mapSizeHeight, 'Right Hand', 'Left Hand', xlabelposition, ylabelposition, lineallow), SizedBox( height: 125, ), MembersBar( curTurn: currentTurn, ), ]))); } } diff --git a/student/lib/Activities/Ac6.dart b/student/lib/Activities/Ac6_1.dart similarity index 86% copy from student/lib/Activities/Ac6.dart copy to student/lib/Activities/Ac6_1.dart index 7e8c7bd..7b1eeff 100644 --- a/student/lib/Activities/Ac6.dart +++ b/student/lib/Activities/Ac6_1.dart @@ -1,656 +1,637 @@ import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart'; import 'package:student/widgets/celluloMap.Dart'; import 'dart:async'; import 'dart:convert'; import 'package:student/Database.dart'; import 'package:student/model/Group.dart'; import 'package:student/model/Cellulo.dart'; import 'package:student/widgets/showAlertDialog.Dart'; import 'package:student/widgets/membersBar.Dart'; import 'package:student/widgets/inactivityDetector.Dart'; import 'package:flutter_appavailability/flutter_appavailability.dart'; - +import 'package:video_player/video_player.dart'; import 'dart:math' as math; -class Ac6 extends StatefulWidget { - Ac6({Key key}) : super(key: key); +class Ac61 extends StatefulWidget { + Ac61({Key key}) : super(key: key); @override - _Ac6State createState() => _Ac6State(); + _Ac61State createState() => _Ac61State(); } -class _Ac6State extends State +class _Ac61State extends State with SingleTickerProviderStateMixin, WidgetsBindingObserver { // Timers Timer timerCelluloPosition; Timer timerslopedetection; Timer timercleartracking; Timer timerCelluloPositionPaint; Timer timerInactivityDetector; Timer timerCelluloPositionPainttoserver; final acID = 6; final maxLiitCellulo = 800; // UI parameters bool celluloxSwitch1 = true; bool celluloySwitch1 = false; bool celluloxSwitch2 = true; bool celluloySwitch2 = false; var onStop = false; bool mode = false; int wrongcounts = 0; double _progress = 0.0; final celluloSize = 60; final ScrollController _scrollController = ScrollController(); final functionFormulas = ['X ⟼ Y', 'X+1 ⟼ Y', 'X+2 ⟼ Y', '2*X ⟼ Y', '-X ⟼ Y']; Offset beginpath = Offset(0, 0); Offset endpath = Offset(10, 100); AnimationController controllerTrial; AnimationController controllerTurn; Animation animation; Animation animationNextTurn; TextEditingController controllerinitialX = TextEditingController(); TextEditingController controllerinitialY = TextEditingController(); TextEditingController controllerXslope = TextEditingController(); TextEditingController controllerYslope = TextEditingController(); var counterfunctionImage = 0; //Activity Dependent var linesPath = [ - 'assets/images/Ac6_function1.svg', - 'assets/images/Ac6_function2.svg', - 'assets/images/Ac6_function3.svg', - 'assets/images/Grid_Ac6_Screen.svg', + 'assets/images/Ac61_function1.svg', + 'assets/images/Ac61_function2.svg', + 'assets/images/Ac61_function3.svg', + 'assets/images/Grid_Ac61_Screen.svg', ]; var lineallow = [false, false, false]; var linesSlope = [1, 2, -1]; var initialPoint = [0, 0, 6]; // map-related final double mapSizeWidth = 860; final double mapSizeHeight = 860; final double screenSizeWidth = 500; final double screenSizeHeight = 500; - final String mapPath = 'assets/images/Grid_Ac6_Screen.svg'; + final String mapPath = 'assets/images/Grid_Ac61_Screen.svg'; final String celluloxpath = 'assets/images/celluloRed.svg'; final String celluloypath = 'assets/images/celluloBlue.svg'; var onTap = [false, false, false, false, false]; // var onTap=[false,false,false,false,false]; final names = [group.member1name, group.member2name, group.member3name]; var currentTurn = 1; var currentTap = 0; var tapCounter = 0; int simulationVelCoeff = 1; // Learning List progress = [0, -2, -2]; // zero: undergoing, -1: not accomplished, 1: accomplished bool waitforanimation = false; List mistakesSlope = [0, 0, 0]; List mistakesIntrepet = [0, 0, 0]; List mistakesInitialPosition = [0, 0, 0]; List progressElpasedTime = [0, 0, 0]; var inactivity = 0; bool checkend = true; var prevcelluloxPositionSlope = 0.0; var prevcelluloyPositionSlope = 0.0; // robot related var elapseTimer = new Stopwatch(); bool allowPaint = false; var celluloxPosition = [0.0, 0.0]; var celluloyPosition = [0.0, 0.0]; var xHaptic; var yHaptic; bool runHaptic = false; var xcelluloy = 820; var ycellulox = 45; var celluloTargetPosition = [0.0, 0.0]; List> celluloxPositiontopaint = new List.generate(3, (int index) => [0.0, 0.0], growable: true); List> celluloyPositiontopaint = new List.generate(3, (int index) => [0.0, 0.0], growable: true); var xlabelposition = [1.0, 1.0]; var ylabelposition = [-0.6, -1.0]; var prevcelluloxPosition = [0.0, 0.0]; var prevcelluloyPosition = [0.0, 0.0]; // screen-related var originCoordinates = [123.5, 736.5]; var correctAnswer = [ {"initialPointX": 1, "initialPointY": 1, "slope": 1}, {"initialPointX": 0, "initialPointY": 0, "slope": 2}, {"initialPointX": 0, "initialPointY": 6, "slope": -1} ]; void calcHaptic() { var slopeHaptic = -1 / linesSlope[currentTurn - 1]; var initialHaptic = (originCoordinates[1] - celluloyPosition[1]) / 100 - slopeHaptic * (celluloxPosition[0] - originCoordinates[0]) / 100; // print('initialhaptic' + initialHaptic.toString()); setState(() { xHaptic = (initialHaptic - initialPoint[currentTurn - 1]) / (linesSlope[currentTurn - 1] - slopeHaptic); yHaptic = ((linesSlope[currentTurn - 1]) * xHaptic + initialPoint[currentTurn - 1]); }); // print('xcelluloy' + xcelluloy.toDouble().toString()); // print('yhaptic' + yHaptic.toString()); // print('xhaptic' + xHaptic.toString()); cellulox.setGoalPosition( xHaptic * 100 + originCoordinates[0], xcelluloy.toDouble(), 150); celluloy.setGoalPosition( ycellulox.toDouble(), originCoordinates[1] - (100 * yHaptic), 150); } + static VideoPlayerController _controller; + static Future _initializeVideoPlayerFuture; @override void initState() { cellulox.setColor(0, 255, 0, 0, 0); celluloy.setColor(0, 0, 255, 0, 0); cellulox.clearrobot(); celluloy.clearrobot(); WidgetsBinding.instance.addObserver(this); dbRef.child('groups').child(group.id).child('tabletStatus').set("YES"); - dbRef.child('groups').child(group.id).child('currentActivity').set("Ac6"); + dbRef.child('groups').child(group.id).child('currentActivity').set("Ac61"); elapseTimer.start(); onDataSend(); controllerTrial = AnimationController( duration: Duration(milliseconds: 30000), vsync: this); animation = Tween(begin: 0.0, end: 1.0).animate(controllerTrial) ..addListener(() { _progress = animation.value; if (_progress < 0.2) { //print('uuh'); cellulox.setGoalPosition(originCoordinates[0], 700, 150); celluloy.setGoalPosition(80, originCoordinates[1], 150); } if (_progress > 0.22) { setState(() { allowPaint = true; }); // } //if (celluloxPosition[0] > 700 || // celluloyPosition[1] < 100) { // cellulox.resetrobot(); // celluloy.resetrobot(); // calcHaptic(); // cellulox.setGoalPosition(xHaptic, 0); // celluloy.setGoalPosition(0, yHaptic); } if (_progress == 1.0) { // cellulox.setGoalPosition(770, 600); // celluloy.setGoalPosition(100, 80); setState(() { allowPaint = false; }); // cellulox.setVelocity(0, 0); // celluloy.setVelocity(0, 0); } if (celluloxPosition[0] > 800 || celluloyPosition[1] < 50 || celluloyPosition[1] > 800) { cellulox.setVelocity(0, 0); celluloy.setVelocity(0, 0); } }); super.initState(); // cellulox.resetrobot(); // celluloy.resetrobot(); + timerCelluloPosition = new Timer.periodic(new Duration(milliseconds: 100), (time) { if (totalRobots() > 1) { cellulox.getrobotx().then((val) => setState(() { celluloxPosition[0] = val; // print(celluloxPosition[0]); // if (allowPaint == true) // celluloxPositiontopaint.add(val * 500 / mapSizeWidth); // print(allowPaint.toString()); })); cellulox.getroboty().then((val) => setState(() { celluloxPosition[1] = val; //if (allowPaint == true) prevcelluloxPosition[1] = celluloxPosition[1]; })); celluloy.getrobotx().then((val) => setState(() { celluloyPosition[0] = val; // if (allowPaint == true) prevcelluloyPosition[0] = celluloyPosition[0]; })); celluloy.getroboty().then((val) => setState(() { celluloyPosition[1] = val; // if (allowPaint == true) // celluloyPositiontopaint.add(val * 500 / mapSizeHeight); })); if (checkend == true) { if (celluloxPosition[0] > 800 || celluloyPosition[1] > 800 || celluloxPosition[0] < 50 || celluloyPosition[1] < 50) { cellulox.clearrobot(); celluloy.clearrobot(); - runHaptic = false; - showAlertDialog(context, '', 'Make sure robots are on the map'); - checkend = false; + // runHaptic = false; + // showAlertDialog(context, '', 'Make sure robots are on the map'); + /// checkend = false; } } if (checkend == false) { if (celluloxPosition[0] < 800 && celluloyPosition[1] < 800 && celluloxPosition[0] > 50 && celluloyPosition[1] > 50) { // cellulox.clearrobot(); // celluloy.clearrobot(); // runHaptic = false; // showAlertDialog(context, '', 'Make sure robots are on the map'); checkend = true; runHaptic = true; } } } if (true) { var distancePointStartX = math.sqrt( math.pow((celluloxPosition[0] - originCoordinates[0]), 2) + math.pow((celluloxPosition[1] - xcelluloy), 2)); var distancePointStartY = math.sqrt( math.pow((celluloyPosition[0] - ycellulox), 2) + math.pow((celluloyPosition[1] - originCoordinates[1]), 2)); if (distancePointStartY < 10 && distancePointStartX < 10) { celluloy.clearrobot(); cellulox.clearrobot(); setState(() { allowPaint = true; runHaptic = true; }); } } if (runHaptic == true) { calcHaptic(); } }); timerCelluloPositionPainttoserver = new Timer.periodic(new Duration(milliseconds: 1800), (time) { if (allowPaint == true) { dbRef.child("celluloPosition").push().set(json.encode({ "x": celluloxPosition[0], "y": celluloyPosition[1], - "acID": "Ac6", + "acID": "Ac61", "turn": currentTurn, "groupID": group.id, })); } }); timerCelluloPositionPaint = new Timer.periodic(new Duration(seconds: 1), (time) { setState(() { if (allowPaint == true) { celluloxPositiontopaint[tapCounter - 1] .add(celluloxPosition[0] * screenSizeWidth / mapSizeWidth); celluloyPositiontopaint[tapCounter - 1] .add(celluloyPosition[1] * screenSizeHeight / mapSizeHeight); } }); }); timerInactivityDetector = new Timer.periodic(new Duration(seconds: 60), (time) { onInactivityTimer(); }); /// /// Ask to be notified when messages related to the game /// are sent by the server /// + _controller = VideoPlayerController.asset('assets/images/IMG_0095.mp4'); + + _initializeVideoPlayerFuture = _controller.initialize(); } void onDataSend() { dbRef.child('attempts').push().set(json.encode({ "numAttempts": tapCounter, "groupID": group.id, - "acID": "Ac6", + "acID": "Ac61", "elpasedTime": elapseTimer.elapsedMilliseconds - progressElpasedTime[currentTurn - 1], "progress": { "turn1": progress[0], "turn2": progress[1], "turn3": progress[2] }, "progressElpasedTime": { "turn1": progressElpasedTime[0], "turn2": progressElpasedTime[1], "turn3": progressElpasedTime[2], }, "currentTurn": currentTurn, "inactivity": inactivity, "mistakes": { "turn1": { "slope": mistakesSlope[0], "initialPoint": mistakesInitialPosition[0] }, "turn2": { "slope": mistakesSlope[1], "initialPoint": mistakesInitialPosition[1] }, "turn3": { "slope": mistakesSlope[2], "initialPoint": mistakesInitialPosition[2] }, } })); } void slopeDtectionTimer() { timerslopedetection = new Timer.periodic(new Duration(seconds: 1), (time) { print("prev" + (((celluloxPosition[0] - prevcelluloxPositionSlope).roundToDouble() > 0) .toString())); // print("currwnt" + celluloxPosition[0].toString()); controllerXslope.text = 1.0.toString(); if ((celluloxPosition[0] - prevcelluloxPositionSlope).abs() < 10) { controllerYslope.text = "You sould move the RED robot faster"; } else { controllerYslope.text = (((prevcelluloyPositionSlope - celluloyPosition[1])) / (celluloxPosition[0] - prevcelluloxPositionSlope)) .roundToDouble() .toString(); } prevcelluloxPositionSlope = celluloxPosition[0]; prevcelluloyPositionSlope = celluloyPosition[1]; // print(int.parse(controllerXslope.text) > 0); print("cur" + (((celluloxPosition[0] - prevcelluloxPositionSlope).roundToDouble() > 0) .toString())); if ((celluloxPosition[0] - prevcelluloxPositionSlope).roundToDouble() > 1) { setState(() { celluloxSwitch2 = true; print(celluloxSwitch2); }); } if (((celluloxPosition[0] - prevcelluloxPositionSlope) / 100) .roundToDouble() < -1) { setState(() { celluloxSwitch2 = false; print(celluloxSwitch2); }); } if (celluloyPosition[1] - prevcelluloyPositionSlope > 0) { setState(() { celluloySwitch2 = true; print(celluloySwitch2); }); } if (celluloyPosition[1] - prevcelluloyPositionSlope < 1.0) { setState(() { celluloySwitch2 = false; print(celluloySwitch2); }); } }); } void onInactivityTimer() { group.inactivity = group.inactivity + 1; } @override void dispose() { cellulox.clearrobot(); celluloy.clearrobot(); timer.cancel(); timerCelluloPosition.cancel(); timerCelluloPositionPaint.cancel(); timerCelluloPositionPainttoserver.cancel(); controllerTrial.dispose(); + _controller.dispose(); super.dispose(); } AppLifecycleState _notification; @override void didChangeAppLifecycleState(AppLifecycleState state) { if (state == AppLifecycleState.resumed) { dbRef.child('groups').child(group.id).child('tabletStatus').set("YES"); } else { dbRef.child('groups').child(group.id).child('tabletStatus').set("NO"); } setState(() { _notification = state; }); } void nextPLayer() { setState(() { currentTurn = currentTurn + 1; // celluloyPositiontopaint = [0.0, 0.0]; // celluloxPositiontopaint = [0.0, 0.0]; }); } void animationRunner(progress) {} @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Move your robots'), ), backgroundColor: Colors.white, body: SingleChildScrollView( child: Column(children: [ Container( // margin: const EdgeInsets.all(15.0), padding: const EdgeInsets.all(5.0), decoration: BoxDecoration(), height: 290.0, child: Column(children: [ Card( color: Colors.blue, child: ListTile( title: Text( ' Each of you take one robot in each hand and try to follow the orange line', style: new TextStyle( color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold, ), ), ), ), SizedBox( height: 10, ), Row( //mainAxisAlignment: MainAxisAlignment.center, children: [ Container( width: 470, child: Card( color: Colors.blue, child: ListTile( title: Text( (tapCounter == 0) ? names[0] + 'Start the game' : 'When you tried, start again with a next member', style: new TextStyle( color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold, ), ), ), )), SizedBox(width: 40), Container( decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(100)), color: Colors.green), child: FlatButton( child: Text( (tapCounter == 0) ? "Start" : "Start Again", style: TextStyle( color: Colors.white, fontWeight: FontWeight.w700, fontSize: 18), ), // tooltip: 'Run the Robots', onPressed: () => { // avgActivation= if (checkend == true) { if (tapCounter < 3) { setState(() { checkend = true; allowPaint = false; runHaptic = false; lineallow[tapCounter] = true; tapCounter = tapCounter + 1; }), cellulox.setGoalPosition( originCoordinates[0], xcelluloy.toDouble(), 150), celluloy.setGoalPosition( ycellulox.toDouble(), originCoordinates[1], 150), onDataSend(), // onDataSend(), } else { showAlertDialog( context, 'Lets go to next turn', 'Lets try a new line'), }, } // controllerTrial.reset(), // controllerTrial.forward(), }, )), SizedBox(width: 15), ]), Row( //mainAxisAlignment: MainAxisAlignment.center, children: [ Container( width: 470, child: Card( color: Colors.blue, child: ListTile( title: Text( ' When you all tried, go to next turn.', style: new TextStyle( color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold, ), ), ), )), SizedBox(width: 25), SizedBox(width: 15), Container( decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(100)), color: Colors.blue), child: FlatButton( child: Text( - "Next Line", + "Play & Pause", style: TextStyle( color: Colors.white, fontWeight: FontWeight.w700, fontSize: 18), ), onPressed: () => { - if (currentTurn < 3) - { - setState(() { - currentTurn = currentTurn + 1; - lineallow = [false, false, false]; - runHaptic = false; - if (currentTurn == 2) { - progressElpasedTime[0] = - elapseTimer.elapsedMilliseconds; - } else { - progressElpasedTime[currentTurn - 2] = - elapseTimer.elapsedMilliseconds - - progressElpasedTime[ - currentTurn - 3]; - } - celluloxPositiontopaint[0] = [0, 0]; - celluloyPositiontopaint[0] = [0, 0]; - celluloxPositiontopaint[1] = [0, 0]; - celluloyPositiontopaint[1] = [0, 0]; - celluloxPositiontopaint[2] = [0, 0]; - celluloyPositiontopaint[2] = [0, 0]; - }), - // if (progress[currentTurn - 2] == 0) - progress[currentTurn - 2] = 1, - progress[currentTurn - 1] = 0, - onDataSend(), - setState(() { - allowPaint = false; - tapCounter = 0; - }), + setState(() { + // If the video is playing, pause it. + if (_controller.value.isPlaying) { + _controller.pause(); + } else { + // If the video is paused, play it. + _controller.play(); } - else - { - progress[currentTurn - 1] = 1, - onDataSend(), - showAlertDialog(context, 'Wait for teacher', - 'Game has finished! '), - }, + }), }, )), ]), ])), SizedBox( height: 70, ), - celluloMap( - context, - celluloxPositiontopaint, - celluloyPositiontopaint, - celluloxPosition, - celluloyPosition, - mapPath, - linesPath[currentTurn - 1], - celluloxpath, - celluloypath, - mapSizeWidth, - mapSizeHeight, - 'Right Hand', - 'Left Hand', - xlabelposition, - ylabelposition, - lineallow), + Container( + height: 700, + child: FutureBuilder( + future: _initializeVideoPlayerFuture, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done) { + // If the VideoPlayerController has finished initialization, use + // the data it provides to limit the aspect ratio of the VideoPlayer. + return AspectRatio( + aspectRatio: _controller.value.aspectRatio, + // Use the VideoPlayer widget to display the video. + child: VideoPlayer(_controller), + ); + } else { + // If the VideoPlayerController is still initializing, show a + // loading spinner. + return Center(child: CircularProgressIndicator()); + } + }, + )), SizedBox( height: 125, ), MembersBar( curTurn: currentTurn, ), ]))); } } diff --git a/student/lib/Activities/Ac7.Dart b/student/lib/Activities/Ac7.Dart index 79e21a9..6c718e3 100644 --- a/student/lib/Activities/Ac7.Dart +++ b/student/lib/Activities/Ac7.Dart @@ -1,785 +1,798 @@ import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart'; import 'package:student/widgets/celluloMap.Dart'; import 'dart:async'; import 'dart:convert'; import 'package:student/Database.dart'; import 'package:student/model/Group.dart'; import 'package:student/model/Cellulo.dart'; import 'package:student/widgets/showAlertDialog.Dart'; import 'package:student/widgets/membersBar.Dart'; import 'package:student/widgets/inactivityDetector.Dart'; import 'package:flutter_appavailability/flutter_appavailability.dart'; import 'dart:math' as math; class Ac7 extends StatefulWidget { Ac7({Key key}) : super(key: key); @override _Ac7State createState() => _Ac7State(); } class _Ac7State extends State with SingleTickerProviderStateMixin, WidgetsBindingObserver { // Timers Timer timerCelluloPosition; Timer timerslopedetection; Timer timerCelluloPositionPaint; Timer timercleartracking; Timer timerprevCelluloPosition; Timer timerInactivityDetector; Timer timerprevCelluloPositiontoserver; final acID = 7; final maxLiitCellulo = 800; // UI parameters bool celluloxSwitch1 = true; bool celluloySwitch1 = false; bool celluloxSwitch2 = true; bool celluloySwitch2 = false; var onStop = false; bool mode = false; int wrongcounts = 0; double _progress = 0.0; final celluloSize = 60; final ScrollController _scrollController = ScrollController(); Offset beginpath = Offset(0, 0); Offset endpath = Offset(10, 100); AnimationController controllerTrial; AnimationController controllerTurn; Animation animation; Animation animationNextTurn; TextEditingController controllerinitialX = TextEditingController(); TextEditingController controllerinitialY = TextEditingController(); TextEditingController controllerXslope = TextEditingController(); TextEditingController controllerYslope = TextEditingController(); var counterfunctionImage = 0; //Activity Dependent var linesPath = [ 'assets/images/Ac7_function1.svg', 'assets/images/Ac7_function2.svg', 'assets/images/Ac7_function3.svg', 'assets/images/Grid_Ac7_Screen.svg', ]; // map-related final double mapSizeWidth = 860; final double mapSizeHeight = 860; final double screenSizeWidth = 500; final double screenSizeHeight = 500; final String mapPath = 'assets/images/Grid_Ac7_Screen.svg'; final String celluloxpath = 'assets/images/celluloRed.svg'; final String celluloypath = 'assets/images/celluloBlue.svg'; final List initialpointList = ['0', '1', '2', '3', '4', '5', '6']; final List slopeList = ['0', '1', '2', '3', '4']; String initialPointXvalue; String initialPointYvalue; String slopeYvalue; var onTap = [false, false, false, false, false]; // var onTap=[false,false,false,false,false]; bool checkorigin; var currentTurn = 1; var currentTap = 0; var tapCounter = 0; int simulationVelCoeff = 1; // Learning List progress = [0, -2, -2]; List progressElpasedTime = [0, 0, 0]; var inactivity = 0; // zero: undergoing, -1: not accomplished, 1: accomplished bool waitforanimation = false; List mistakesSlope = [0, 0, 0]; List mistakesIntrepet = [0, 0, 0]; List mistakesInitialPosition = [0, 0, 0]; var prevcelluloxPositionSlope = 0.0; var prevcelluloyPositionSlope = 0.0; // robot related var elapseTimer = new Stopwatch(); bool allowPaint = false; var celluloxPosition = [0.0, 0.0]; var celluloyPosition = [0.0, 0.0]; List> celluloxPositiontopaint = new List.generate(3, (int index) => [0.0, 0.0], growable: true); List> celluloyPositiontopaint = new List.generate(3, (int index) => [0.0, 0.0], growable: true); var prevcelluloxPosition = [0.0, 0.0]; var prevcelluloyPosition = [0.0, 0.0]; var xlabelposition = [1.0, 0.7]; var ylabelposition = [-1.0, -1.0]; var lineallow = [true, false, false]; bool sendtoend = false; bool checkend = true; // screen-related static var originCoordinates = [225.5, 633.5]; List beginpathlist = [ Offset(originCoordinates[0] - 300, originCoordinates[1] + 300), Offset(originCoordinates[0] - 300, originCoordinates[1] + 200), Offset(originCoordinates[0] - 300, originCoordinates[1] + 100), Offset(originCoordinates[0] - 200, originCoordinates[1] + 400), Offset(originCoordinates[0] - 300, originCoordinates[1] - 300), ]; List endpathlist = [ Offset(originCoordinates[0] + 600, originCoordinates[1] - 400), Offset(originCoordinates[0] + 400, originCoordinates[1] - 600), Offset(originCoordinates[0] + 200, originCoordinates[1] - 400), Offset(originCoordinates[0] + 200, originCoordinates[1] - 400), Offset(originCoordinates[0] + 300, originCoordinates[1] + 300), ]; var xcelluloy = 760; var ycellulox = 45; var correctAnswer = [ {"initialPointX": 2, "initialPointY": 0, "slope": 1}, {"initialPointX": 0, "initialPointY": 2, "slope": 1}, {"initialPointX": 0, "initialPointY": 5, "slope": 1} ]; @override void initState() { cellulox.setColor(0, 255, 0, 0, 0); celluloy.setColor(0, 0, 255, 0, 0); cellulox.clearrobot(); celluloy.clearrobot(); WidgetsBinding.instance.addObserver(this); dbRef.child('groups').child(group.id).child('tabletStatus').set("YES"); dbRef.child('groups').child(group.id).child('currentActivity').set("Ac7"); elapseTimer.start(); onDataSend(); controllerTrial = AnimationController( duration: Duration(milliseconds: 30000), vsync: this); animation = Tween(begin: 0.0, end: 1.0).animate(controllerTrial) ..addListener(() { _progress = animation.value; if (_progress < 0.2) { //print('uuh'); cellulox.setGoalPosition( originCoordinates[0] + 100 * int.parse(initialPointXvalue), 600, 150); celluloy.setGoalPosition(100, originCoordinates[1] - 100 * int.parse(initialPointYvalue), 150); } if (_progress > 0.22) { setState(() { allowPaint = true; }); // cellulox.setGoalPosition(770, 600); // celluloy.setGoalPosition(100, 80); if (celluloxPosition[0] > 700 || celluloyPosition[1] < 100 || celluloyPosition[1] > 700) {} // } //if (celluloxPosition[0] > 700 || // celluloyPosition[1] < 100) { // cellulox.resetrobot(); // celluloy.resetrobot(); } if (_progress == 1.0) { // cellulox.setGoalPosition(770, 600); // celluloy.setGoalPosition(100, 80); cellulox.setVelocity(0, 0); celluloy.setVelocity(0, 0); } }); super.initState(); // cellulox.resetrobot(); //celluloy.resetrobot(); timerCelluloPosition = new Timer.periodic(new Duration(milliseconds: 100), (time) { if (totalRobots() > 1) { cellulox.getrobotx().then((val) => setState(() { celluloxPosition[0] = val; - print(celluloxPosition[0]); + // print(celluloxPosition[0]); // if (allowPaint == true) celluloxPositiontopaint.add(val * 500 / 860); // print(allowPaint.toString()); })); cellulox.getroboty().then((val) => setState(() { celluloxPosition[1] = val; if (allowPaint == true) prevcelluloxPosition[1] = celluloxPosition[1]; })); celluloy.getrobotx().then((val) => setState(() { celluloyPosition[0] = val; if (allowPaint == true) prevcelluloyPosition[0] = celluloyPosition[0]; })); celluloy.getroboty().then((val) => setState(() { celluloyPosition[1] = val; // if (allowPaint == true) celluloyPositiontopaint.add(val * 500 / 860); })); } if (checkend) { if (celluloxPosition[0] > 800 || celluloyPosition[1] > 800 || celluloyPosition[1] < 100) { cellulox.clearrobot(); celluloy.clearrobot(); - showAlertDialog(context, '', 'Make sure robots are on the map'); - checkend = false; + // showAlertDialog(context, '', 'Make sure robots are on the map'); + // checkend = false; } } if (checkorigin) { var distancePointStartX = math.sqrt(math.pow( (celluloxPosition[0] - (originCoordinates[0] + 100 * int.parse(initialPointXvalue))), 2) + math.pow((celluloxPosition[1] - xcelluloy), 2)); var distancePointStartY = math.sqrt( math.pow((celluloyPosition[0] - ycellulox), 2) + math.pow( (celluloyPosition[1] - (originCoordinates[1] - 100 * int.parse(initialPointYvalue))), 2)); if (distancePointStartX < 10 && distancePointStartY < 10) { cellulox.clearrobot(); celluloy.clearrobot(); setState(() { allowPaint = true; checkorigin = false; sendToEnd(); //runHaptic = true; }); } } }); timerCelluloPositionPaint = new Timer.periodic(new Duration(seconds: 1), (time) { setState(() { if (allowPaint == true) { celluloxPositiontopaint[0] .add(celluloxPosition[0] * screenSizeWidth / mapSizeWidth); celluloyPositiontopaint[0] .add(celluloyPosition[1] * screenSizeHeight / mapSizeHeight); } }); }); timerprevCelluloPositiontoserver = new Timer.periodic(new Duration(milliseconds: 1700), (time) { if (allowPaint == true) { dbRef.child("celluloPosition").push().set(json.encode({ "x": celluloxPosition[0], "y": celluloyPosition[1], "acID": "Ac7", "turn": currentTurn, "groupID": group.id, })); } }); // timerprevCelluloPositiontoserver.cancel(); timerprevCelluloPosition = new Timer.periodic(new Duration(seconds: 40), (time) { setState(() { if (allowPaint == true) { prevcelluloxPosition[0] = celluloxPosition[0]; prevcelluloxPosition[1] = celluloxPosition[1]; prevcelluloyPosition[0] = celluloyPosition[0]; prevcelluloyPosition[1] = celluloyPosition[1]; } }); }); timerInactivityDetector = new Timer.periodic(new Duration(seconds: 60), (time) { onInactivityTimer(); }); /// /// Ask to be notified when messages related to the game /// are sent by the server /// } void sendToEnd() { setState(() { checkend = true; }); cellulox.setVelocity(50.0 * simulationVelCoeff, 0); if (celluloySwitch1 == false) celluloy.setVelocity( 0, -50.0 * simulationVelCoeff * int.parse(slopeYvalue)); if (celluloySwitch1 == true) celluloy.setVelocity( 0, 50.0 * simulationVelCoeff * int.parse(slopeYvalue)); } void onDataSend() { dbRef.child('attempts').push().set(json.encode({ "numAttempts": tapCounter, "groupID": group.id, "acID": "Ac7", "elpasedTime": elapseTimer.elapsedMilliseconds - progressElpasedTime[currentTurn - 1], "progress": { "turn1": progress[0], "turn2": progress[1], "turn3": progress[2] }, "progressElpasedTime": { "turn1": progressElpasedTime[0], "turn2": progressElpasedTime[1], "turn3": progressElpasedTime[2], }, "currentTurn": currentTurn, "inactivity": inactivity, "mistakes": { "turn1": { "slope": mistakesSlope[0], "initialPoint": mistakesInitialPosition[0] }, "turn2": { "slope": mistakesSlope[1], "initialPoint": mistakesInitialPosition[1] }, "turn3": { "slope": mistakesSlope[2], "initialPoint": mistakesInitialPosition[2] }, } })); } void slopeDtectionTimer() { timerslopedetection = new Timer.periodic(new Duration(seconds: 1), (time) { print("prev" + (((celluloxPosition[0] - prevcelluloxPositionSlope).roundToDouble() > 0) .toString())); // print("currwnt" + celluloxPosition[0].toString()); controllerXslope.text = 1.0.toString(); if ((celluloxPosition[0] - prevcelluloxPositionSlope).abs() < 10) { slopeYvalue = "You sould move the RED robot faster"; } else { slopeYvalue = (((prevcelluloyPositionSlope - celluloyPosition[1])) / (celluloxPosition[0] - prevcelluloxPositionSlope)) .roundToDouble() .toString(); } prevcelluloxPositionSlope = celluloxPosition[0]; prevcelluloyPositionSlope = celluloyPosition[1]; // print(int.parse(controllerXslope.text) > 0); print("cur" + (((celluloxPosition[0] - prevcelluloxPositionSlope).roundToDouble() > 0) .toString())); if ((celluloxPosition[0] - prevcelluloxPositionSlope).roundToDouble() > 1) { setState(() { celluloxSwitch2 = true; - print(celluloxSwitch2); + // print(celluloxSwitch2); }); } if (((celluloxPosition[0] - prevcelluloxPositionSlope) / 100) .roundToDouble() < -1) { setState(() { celluloxSwitch2 = false; - print(celluloxSwitch2); + // print(celluloxSwitch2); }); } if (celluloyPosition[1] - prevcelluloyPositionSlope > 0) { setState(() { celluloySwitch2 = true; - print(celluloySwitch2); + // print(celluloySwitch2); }); } if (celluloyPosition[1] - prevcelluloyPositionSlope < 1.0) { setState(() { celluloySwitch2 = false; - print(celluloySwitch2); + // print(celluloySwitch2); }); } }); } void onInactivityTimer() { group.inactivity = group.inactivity + 1; } @override void dispose() { cellulox.clearrobot(); celluloy.clearrobot(); timer.cancel(); timerCelluloPosition.cancel(); timerprevCelluloPositiontoserver.cancel(); controllerTrial.dispose(); super.dispose(); } AppLifecycleState _notification; @override void didChangeAppLifecycleState(AppLifecycleState state) { if (state == AppLifecycleState.resumed) { dbRef.child('groups').child(group.id).child('tabletStatus').set("YES"); } else { dbRef.child('groups').child(group.id).child('tabletStatus').set("NO"); } setState(() { _notification = state; }); } void nextPLayer() { setState(() { currentTurn = currentTurn + 1; // celluloyPositiontopaint = [0.0, 0.0]; // celluloxPositiontopaint = [0.0, 0.0]; }); } void animationRunner(progress) {} @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Colors.lightBlue, - title: const Text('Control your robots'), + title: const Text('Guess the Line'), + actions: [ + Padding( + padding: EdgeInsets.only(right: 20.0), + child: GestureDetector( + onTap: () { + group.currentActivity = 'Ac61'; + group.navigatorKeygame.currentState + .pushReplacementNamed(group.currentActivity); + // print('ff'); + }, + child: Icon(Icons.help), + )), + ], ), backgroundColor: Colors.white, body: SingleChildScrollView( child: Column(children: [ Container( // margin: const EdgeInsets.all(15.0), padding: const EdgeInsets.all(5.0), decoration: BoxDecoration(), height: 420.0, child: Column(children: [ Card( color: Colors.lightBlue, child: ListTile( title: Text( 'Choose the two points that your robots start from: ', style: new TextStyle( color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold, ), ), ), ), SizedBox( height: 20, ), Row( // crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ Container( width: 250, child: DropdownButton( hint: Text('RED robot starts at this position: '), value: initialPointXvalue, icon: Icon(Icons.arrow_downward), iconSize: 24, elevation: 16, style: TextStyle(color: Colors.deepPurple), onChanged: (String newValue) { setState(() { initialPointXvalue = newValue; }); }, - items: ['0', '1'] + items: initialpointList .map>((String value) { return DropdownMenuItem( value: value, child: Text(value), ); }).toList(), )), SizedBox(width: 38), Container( width: 250, child: DropdownButton( hint: Text('BLUE robot starts at this position: '), value: initialPointYvalue, icon: Icon(Icons.arrow_downward), iconSize: 24, elevation: 16, style: TextStyle(color: Colors.deepPurple), onChanged: (String newValue) { setState(() { initialPointYvalue = newValue; }); }, items: initialpointList .map>((String value) { return DropdownMenuItem( value: value, child: Text(value), ); }).toList(), )), ]), SizedBox( height: 20, ), Card( color: Colors.lightBlue, child: ListTile( title: Text( ' Choose how much the blue robot should move when the red robot has moved by one.', style: new TextStyle( color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold, ), ), ), ), SizedBox( height: 20, ), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Container( width: 250, child: DropdownButton( hint: Text('then Blue robot should move by: '), value: slopeYvalue, icon: Icon(Icons.arrow_downward), iconSize: 24, elevation: 16, style: TextStyle(color: Colors.deepPurple), onChanged: (String newValue) { setState(() { slopeYvalue = newValue; }); }, items: slopeList .map>((String value) { return DropdownMenuItem( value: value, child: Text(value), ); }).toList(), )), SizedBox(width: 25), Column(children: [ RotatedBox( quarterTurns: 1, child: Switch( value: celluloySwitch1, onChanged: (value) { setState(() { celluloySwitch1 = value; }); }, activeTrackColor: Colors.lightGreenAccent, activeColor: Colors.green, inactiveTrackColor: Colors.lightGreenAccent, inactiveThumbColor: Colors.green, )), Text(celluloySwitch1 ? 'Down' : 'Up') ]), ]), SizedBox( height: 5, ), Row( //mainAxisAlignment: MainAxisAlignment.center, children: [ Container( width: 470, child: Card( color: Colors.lightBlue, child: ListTile( title: Text( 'Run the Robots to see if your answer matches the orange Line.', style: new TextStyle( color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold, ), ), ), )), SizedBox(width: 25), Container( decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(100)), color: Colors.green), child: FlatButton( child: Text( "Run Robots", style: TextStyle( color: Colors.white, fontWeight: FontWeight.w700, fontSize: 18), ), // tooltip: 'Run the Robots', onPressed: () => { print(initialPointXvalue), if (initialPointXvalue != '' && initialPointYvalue != '' && slopeYvalue != '') { celluloxPositiontopaint[0] = [0, 0], celluloyPositiontopaint[0] = [0, 0], cellulox.setGoalPosition( originCoordinates[0] + 100 * int.parse(initialPointXvalue), xcelluloy.toDouble(), 150), celluloy.setGoalPosition( ycellulox.toDouble(), originCoordinates[1] - 100 * int.parse(initialPointYvalue), 150), setState(() { tapCounter = tapCounter + 1; checkorigin = true; checkend = false; }), } else { showAlertDialog(context, 'Robots cant move', 'Dont forget to fill all fileds please!'), }, // avgActivation= if (initialPointXvalue != correctAnswer[currentTurn - 1] ['initialPointX'] .toString() || initialPointYvalue != correctAnswer[currentTurn - 1] ['initialPointY'] .toString()) { mistakesInitialPosition[currentTurn - 1] = mistakesInitialPosition[currentTurn - 1] + 1, }, if (slopeYvalue != correctAnswer[currentTurn - 1]['slope'] .toString()) { mistakesSlope[currentTurn - 1] = mistakesSlope[currentTurn - 1] + 1, }, if (initialPointXvalue == correctAnswer[currentTurn - 1] ['initialPointX'] .toString() && initialPointYvalue == correctAnswer[currentTurn - 1] ['initialPointY'] .toString() && slopeYvalue == correctAnswer[currentTurn - 1]['slope'] .toString()) { progress[currentTurn - 1] = 1, }, onDataSend(), // controllerTrial.reset(), // controllerTrial.forward(), }, )), SizedBox(width: 15), Container( decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(100)), color: Colors.blue), child: FlatButton( child: Text( "Next Turn", style: TextStyle( color: Colors.white, fontWeight: FontWeight.w700, fontSize: 18), ), onPressed: () => { if (currentTurn < 4) { setState(() { tapCounter = 0; currentTurn = currentTurn + 1; if (currentTurn == 2) { progressElpasedTime[0] = elapseTimer.elapsedMilliseconds; } else { progressElpasedTime[currentTurn - 2] = elapseTimer.elapsedMilliseconds - progressElpasedTime[ currentTurn - 3]; } celluloxPositiontopaint[0] = [0, 0]; celluloyPositiontopaint[0] = [0, 0]; }), if (progress[currentTurn - 2] == 0) progress[currentTurn - 2] = -1, // controller.reset(), allowPaint = false, progress[currentTurn - 1] = 0, onDataSend(), } else { showAlertDialog(context, 'Wait for teacher', 'Game has finished! '), }, }, )), ]), ])), SizedBox( height: 5, ), celluloMap( context, celluloxPositiontopaint, celluloyPositiontopaint, celluloxPosition, celluloyPosition, mapPath, linesPath[currentTurn - 1], celluloxpath, celluloypath, mapSizeWidth, mapSizeHeight, group.member1name, group.member2name, xlabelposition, ylabelposition, lineallow), SizedBox( height: 15, ), MembersBar( curTurn: currentTurn, ), ]))); } } diff --git a/student/lib/Activities/Ac9.Dart b/student/lib/Activities/Ac9.Dart index afde4d0..9302de9 100644 --- a/student/lib/Activities/Ac9.Dart +++ b/student/lib/Activities/Ac9.Dart @@ -1,104 +1,228 @@ import 'package:flutter/material.dart'; import 'package:intro_views_flutter/Models/page_view_model.dart'; import 'package:intro_views_flutter/intro_views_flutter.dart'; import 'package:student/model/Group.dart'; +import 'package:video_player/video_player.dart'; /// App widget class -class Ac9 extends StatelessWidget { +class Ac9 extends StatefulWidget { + Ac9({Key key}) : super(key: key); + + @override + _Ac9State createState() => _Ac9State(); +} + +class _ControlsOverlay extends StatelessWidget { + const _ControlsOverlay({Key key, this.controller}) : super(key: key); + + static const _examplePlaybackRates = [ + 0.25, + 0.5, + 1.0, + 1.5, + 2.0, + 3.0, + 5.0, + 10.0, + ]; + + final VideoPlayerController controller; + + @override + Widget build(BuildContext context) { + return Stack( + children: [ + AnimatedSwitcher( + duration: Duration(milliseconds: 50), + reverseDuration: Duration(milliseconds: 200), + child: controller.value.isPlaying + ? SizedBox.shrink() + : Container( + color: Colors.black26, + child: Center( + child: Icon( + Icons.play_arrow, + color: Colors.white, + size: 100.0, + ), + ), + ), + ), + GestureDetector( + onTap: () { + controller.value.isPlaying ? controller.pause() : controller.play(); + }, + ), + Align( + alignment: Alignment.topRight, + child: PopupMenuButton( + initialValue: controller.value.playbackSpeed, + tooltip: 'Playback speed', + onSelected: (speed) { + controller.setPlaybackSpeed(speed); + }, + itemBuilder: (context) { + return [ + for (final speed in _examplePlaybackRates) + PopupMenuItem( + value: speed, + child: Text('${speed}x'), + ) + ]; + }, + child: Padding( + padding: const EdgeInsets.symmetric( + // Using less vertical padding as the text is also longer + // horizontally, so it feels like it would need more spacing + // horizontally (matching the aspect ratio of the video). + vertical: 12, + horizontal: 16, + ), + child: Text('${controller.value.playbackSpeed}x'), + ), + ), + ), + ], + ); + } +} + +class _Ac9State extends State { + static VideoPlayerController _controller; + static Future _initializeVideoPlayerFuture; + + @override + void initState() { + super.initState(); + _controller = VideoPlayerController.network( + 'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4', + ); + + _initializeVideoPlayerFuture = _controller.initialize(); + } + + @override + void dispose() { + //elapseTimer.stop(); + _controller.dispose(); + super.dispose(); + // timerCelluloPosition.cancel(); // +// timerCheckCelluloGame.cancel(); + } + + // static final VideoPlayerController _controller = + // VideoPlayerController.asset('assets/Butterfly-209.mp4'); //making list of pages needed to pass in IntroViewsFlutter constructor. final pages = [ PageViewModel( pageColor: const Color(0xFF03A9F4), // iconImageAssetPath: 'assets/air-hostess.png', - bubble: Image.asset('assets/air-hostess.png'), + bubble: FutureBuilder( + future: _initializeVideoPlayerFuture, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done) { + // If the VideoPlayerController has finished initialization, use + // the data it provides to limit the aspect ratio of the VideoPlayer. + return AspectRatio( + aspectRatio: _controller.value.aspectRatio, + // Use the VideoPlayer widget to display the video. + child: VideoPlayer(_controller), + ); + } else { + // If the VideoPlayerController is still initializing, show a + // loading spinner. + return Center(child: CircularProgressIndicator()); + } + }, + ), body: Text( 'Haselfree booking of flight tickets with full refund on cancelation', ), title: Text( 'Flights', ), titleTextStyle: TextStyle(fontFamily: 'MyFont', color: Colors.white), bodyTextStyle: TextStyle(fontFamily: 'MyFont', color: Colors.white), mainImage: Image.asset( 'assets/airplane.png', height: 285.0, width: 285.0, alignment: Alignment.center, )), PageViewModel( pageColor: const Color(0xFF8BC34A), iconImageAssetPath: 'assets/waiter.png', body: Text( 'We work for the comfort , enjoy your stay at our beautiful hotels', ), title: Text('Hotels'), mainImage: Image.asset( 'assets/hotel.png', height: 285.0, width: 285.0, alignment: Alignment.center, ), titleTextStyle: TextStyle(fontFamily: 'MyFont', color: Colors.white), bodyTextStyle: TextStyle(fontFamily: 'MyFont', color: Colors.white), ), PageViewModel( pageColor: const Color(0xFF607D8B), iconImageAssetPath: 'assets/taxi-driver.png', body: Text( 'Easy cab booking at your doorstep with cashless payment system', ), title: Text('Cabs'), mainImage: Image.asset( 'assets/taxi.png', height: 285.0, width: 285.0, alignment: Alignment.center, ), titleTextStyle: TextStyle(fontFamily: 'MyFont', color: Colors.white), bodyTextStyle: TextStyle(fontFamily: 'MyFont', color: Colors.white), ), ]; @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, title: 'IntroViews Flutter', //title of app theme: ThemeData( primarySwatch: Colors.blue, ), //ThemeData home: Builder( builder: (context) => IntroViewsFlutter( pages, showNextButton: true, showBackButton: true, onTapDoneButton: () { group.navigatorKeygame.currentState .pushReplacementNamed(group.currentActivity); }, pageButtonTextStyles: TextStyle( color: Colors.white, fontSize: 18.0, ), ), //IntroViewsFlutter ), //Builder ); //Material App } } /// Home Page of our example app. class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Home'), ), //Appbar body: Center( child: Text("This is the home page of the app"), ), //Center ); //Scaffold } } diff --git a/student/lib/loginpage_names.dart b/student/lib/loginpage_names.dart index 7e0fb31..9e71372 100644 --- a/student/lib/loginpage_names.dart +++ b/student/lib/loginpage_names.dart @@ -1,176 +1,185 @@ import 'package:flutter/material.dart'; import 'package:student/loginpage_robots.dart'; import 'dart:convert'; import 'package:student/Data/data.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:student/Database.dart'; import 'package:student/model/Group.dart'; import 'package:student/model/Cellulo.dart'; import 'package:student/Game.dart'; import 'package:student/Database.dart'; +import 'package:student/widgets/showAlertDialog.Dart'; import 'package:firebase_database/firebase_database.dart'; class LoginPage extends StatefulWidget { LoginPage({Key key}) : super(key: key); @override _LoginPageState createState() => _LoginPageState(); } class _LoginPageState extends State { TextEditingController controller1 = TextEditingController(); TextEditingController controller2 = TextEditingController(); TextEditingController controller3 = TextEditingController(); TextEditingController controller4 = TextEditingController(); TextEditingController controllersessionID = TextEditingController(); final teamname = "1"; @override void initState() { cellulox.setColor(0, 255, 0, 0, 0); celluloy.setColor(0, 0, 255, 0, 0); cellulox.clearrobot(); celluloy.clearrobot(); super.initState(); } @override void dispose() { super.dispose(); } Widget nextButton() { return InkWell( onTap: () { - group.sessionID = controllersessionID.text; - //print(controller4.text); - group.member1name = controller1.text; - group.member2name = controller2.text; - group.member3name = controller3.text; - group.id = controller4.text; - group.currentActivity = 'Ac5'; - final dbRef = - FirebaseDatabase.instance.reference().child(group.sessionID); + if (controllersessionID.text != null && + controller4.text != null && + controllersessionID.text != '' && + controller4.text != '') { + group.sessionID = controllersessionID.text; + //print(controller4.text); + group.member1name = controller1.text; + group.member2name = controller2.text; + group.member3name = controller3.text; + group.id = controller4.text; + group.currentActivity = 'Ac5'; + final dbRef = + FirebaseDatabase.instance.reference().child(group.sessionID); - dbRef.child('groups').child(controller4.text).set(group.toJson()); - group.setupDatabse(); - group.cellulox = cellulox; - group.celluloy = celluloy; - cellulox.setup(); //setting up the robots - Navigator.push( - context, MaterialPageRoute(builder: (context) => Game())); + dbRef.child('groups').child(controller4.text).set(group.toJson()); + group.setupDatabse(); + group.cellulox = cellulox; + group.celluloy = celluloy; + cellulox.setup(); //setting up the robots + + Navigator.push( + context, MaterialPageRoute(builder: (context) => Game())); + } else + showAlertDialog(context, 'What is your session ID', + 'Fill the session ID and team name'); }, child: Container( width: MediaQuery.of(context).size.width, padding: EdgeInsets.symmetric(vertical: 13), alignment: Alignment.center, decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(5)), boxShadow: [ BoxShadow( color: Color(0xffdf8e33).withAlpha(100), offset: Offset(2, 4), blurRadius: 8, spreadRadius: 2) ], color: Colors.white), child: Text( 'Lets go', style: TextStyle(fontSize: 20, color: Color(0xfff7892b)), ), ), ); } Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Login'), ), backgroundColor: Colors.white, body: SingleChildScrollView( child: Padding( padding: EdgeInsets.all(30.0), child: Column(children: [ Container( padding: EdgeInsets.all(8.0), decoration: BoxDecoration( border: Border( bottom: BorderSide(color: Colors.grey[100]))), child: TextField( controller: controller1, decoration: InputDecoration( border: InputBorder.none, hintText: "Member 1: Enter your name", hintStyle: TextStyle(color: Colors.grey[400])), ), ), SizedBox( height: 100, ), Container( padding: EdgeInsets.all(8.0), decoration: BoxDecoration( border: Border( bottom: BorderSide(color: Colors.grey[100]))), child: TextField( controller: controller2, decoration: InputDecoration( border: InputBorder.none, hintText: "Member 2: Enter your name", hintStyle: TextStyle(color: Colors.grey[400])), ), ), SizedBox( height: 100, ), Container( padding: EdgeInsets.all(8.0), decoration: BoxDecoration( border: Border( bottom: BorderSide(color: Colors.grey[100]))), child: TextField( controller: controller3, decoration: InputDecoration( border: InputBorder.none, hintText: "Member 3: Enter your name", hintStyle: TextStyle(color: Colors.grey[400])), ), ), SizedBox( height: 100, ), Container( padding: EdgeInsets.all(8.0), decoration: BoxDecoration( border: Border( bottom: BorderSide(color: Colors.grey[100]))), child: TextField( controller: controller4, decoration: InputDecoration( border: InputBorder.none, hintText: "Enter your group name", hintStyle: TextStyle(color: Colors.grey[400])), ), ), SizedBox( height: 50, ), Container( padding: EdgeInsets.all(8.0), decoration: BoxDecoration( border: Border( bottom: BorderSide(color: Colors.grey[100]))), child: TextField( controller: controllersessionID, decoration: InputDecoration( border: InputBorder.none, hintText: "Enter session ID", hintStyle: TextStyle(color: Colors.grey[400])), ), ), nextButton() ])))); } } diff --git a/student/lib/ui/router.dart b/student/lib/ui/router.dart index d29cbe9..235a3b6 100644 --- a/student/lib/ui/router.dart +++ b/student/lib/ui/router.dart @@ -1,48 +1,51 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:student/ui/router.dart'; import 'package:student/Activities/Ac7.Dart'; import 'package:student/Activities/Ac8.Dart'; import 'package:student/Activities/Ac9.Dart'; import 'package:student/Activities/Ac6.dart'; +import 'package:student/Activities/Ac6_1.dart'; import 'package:student/Activities/Ac5.dart'; import 'package:student/Activities/Ac4.dart'; import 'package:student/Activities/Ac3.dart'; import 'package:student/Activities/Ac2.dart'; import 'package:student/Activities/Ac1.dart'; import 'package:student/model/Group.dart'; //import 'package:Teacher_Dashboard/screens/bottom_nav_screen.dart'; class Router { static Route generateRoute(RouteSettings settings) { switch (group.currentActivity) { case 'Ac7': return MaterialPageRoute(builder: (_) => Ac7()); case 'Ac8': return MaterialPageRoute(builder: (_) => Ac8()); case 'Ac9': return MaterialPageRoute(builder: (_) => Ac9()); case 'Ac6': return MaterialPageRoute(builder: (_) => Ac6()); + case 'Ac61': + return MaterialPageRoute(builder: (_) => Ac61()); case 'Ac5': return MaterialPageRoute(builder: (_) => Ac5()); case 'Ac4': return MaterialPageRoute(builder: (_) => Ac4()); case 'Ac3': return MaterialPageRoute(builder: (_) => Ac3()); case 'Ac2': return MaterialPageRoute(builder: (_) => Ac2()); case 'Ac1': return MaterialPageRoute(builder: (_) => Ac1()); case 'Idle': return MaterialPageRoute(builder: (_) => Ac7()); default: return MaterialPageRoute( builder: (_) => Scaffold( body: Center( child: Text('No route defined for '), ), )); } } } diff --git a/student/lib/widgets/arrow.dart b/student/lib/widgets/arrow.dart new file mode 100644 index 0000000..2a136a2 --- /dev/null +++ b/student/lib/widgets/arrow.dart @@ -0,0 +1,71 @@ +import 'package:flutter/material.dart'; +import 'package:arrow_path/arrow_path.dart'; +import 'package:student/model/Cellulo.dart'; + +class Arrow extends CustomPainter { + // <-- CustomPainter class + + var celluloxPosition; + var celluloyPosition; + var coeffScreenMapWidth; + var coeffScreenMapHeight; + double directionx; + double directiony; + Offset celluloyM; + Offset celluloxM; + Arrow(this.celluloxPosition, this.celluloyPosition, this.coeffScreenMapWidth, + this.coeffScreenMapHeight, this.directionx, this.directiony) { + celluloxM = Offset(celluloxPosition[0] * coeffScreenMapWidth, + celluloxPosition[1] * coeffScreenMapHeight); + celluloyM = Offset(celluloyPosition[0] * coeffScreenMapWidth, + celluloyPosition[1] * coeffScreenMapHeight); + if (directionx < -40) + directionx = -1; + else if (directionx > 40) + directionx = 1; + else { + directionx = 0; + } + if (directiony < -40) + directiony = -1; + else if (directiony > 40) + directiony = 1; + else { + directiony = 0; + } + } + + @override + void paint(Canvas canvas, Size size) { + Path path; + Paint paintblue = Paint() + ..color = Colors.blue + ..style = PaintingStyle.stroke + ..strokeCap = StrokeCap.round + ..strokeJoin = StrokeJoin.round + ..strokeWidth = 3.0; + Paint paintRed = Paint() + ..color = Colors.red + ..style = PaintingStyle.stroke + ..strokeCap = StrokeCap.round + ..strokeJoin = StrokeJoin.round + ..strokeWidth = 3.0; + path = Path(); + path.moveTo(celluloxM.dx - 20, celluloxM.dy - 20); + path.relativeCubicTo(0, 0, 0, 0, directionx.toDouble() * 40, 0); + path = ArrowPath.make(path: path); + canvas.drawPath(path, paintRed); + + path.moveTo(celluloyM.dx + 30, celluloyM.dy); + path.relativeCubicTo(0, 0, 0, 0, 0, directiony.toDouble() * 40); + path = ArrowPath.make(path: path); + canvas.drawPath(path, paintblue); + + //canvas.drawLine(p1, p2, paint); + } + + @override + bool shouldRepaint(CustomPainter old) { + return false; + } +} diff --git a/student/lib/widgets/bezierCurvePainter.dart b/student/lib/widgets/bezierCurvePainter.dart index b45d33d..29e110c 100644 --- a/student/lib/widgets/bezierCurvePainter.dart +++ b/student/lib/widgets/bezierCurvePainter.dart @@ -1,72 +1,72 @@ import 'package:flutter/material.dart'; class BezierCurvePainter extends CustomPainter { Paint _paint; double _progress; Offset beginpath; Offset endpath; Offset beginpathM; Offset endpathM; int currentTurn; double coeffScreenMapHeight; double coeffScreenMapWidth; var midddlePoint1 = [ Offset(291.1, 176.2), Offset(110.2, 632.8), Offset(610.2, 732.8) ]; var midddlePoint2 = [ Offset(410.2, 532.8), Offset(356, 357), Offset(110.2, 232.8) ]; var midddlePoint1M = [ Offset(291.1, 176.2), Offset(110.2, 232.8), Offset(110.2, 232.8) ]; var midddlePoint2M = [ Offset(291.1, 176.2), Offset(110.2, 232.8), Offset(110.2, 232.8) ]; BezierCurvePainter(this.beginpath, this.endpath, this.coeffScreenMapWidth, this.coeffScreenMapHeight, this.currentTurn) { _paint = Paint() ..style = PaintingStyle.stroke ..strokeJoin = StrokeJoin.round ..strokeCap = StrokeCap.round ..color = Colors.black - ..strokeWidth = 15; + ..strokeWidth = 5; beginpathM = Offset(this.beginpath.dx * coeffScreenMapWidth, beginpath.dy * coeffScreenMapHeight); endpathM = Offset(this.endpath.dx * coeffScreenMapWidth, endpath.dy * coeffScreenMapHeight); for (int i = 0; i < 3; i++) { midddlePoint1M[i] = Offset(midddlePoint1[i].dx * coeffScreenMapWidth, midddlePoint1[i].dy * coeffScreenMapHeight); midddlePoint2M[i] = Offset(midddlePoint2[i].dx * coeffScreenMapWidth, midddlePoint2[i].dy * coeffScreenMapHeight); } } @override void paint(Canvas canvas, Size size) { Path path = Path() ..moveTo(beginpathM.dx, beginpathM.dy) ..cubicTo( midddlePoint1M[currentTurn - 1].dx, midddlePoint1M[currentTurn - 1].dy, midddlePoint2M[currentTurn - 1].dx, midddlePoint2M[currentTurn - 1].dy, endpathM.dx, endpathM.dy); canvas.drawPath(path, _paint); } @override bool shouldRepaint(BezierCurvePainter oldDelegate) { return oldDelegate._progress != _progress; } } diff --git a/student/lib/widgets/guidegrid.dart b/student/lib/widgets/guidegrid.dart index 9002a42..6f5b32b 100644 --- a/student/lib/widgets/guidegrid.dart +++ b/student/lib/widgets/guidegrid.dart @@ -1,38 +1,67 @@ import 'package:flutter/material.dart'; class GuideGrid extends CustomPainter { - Paint _paint; + Paint _paintBlue; + Paint _paintRed; double _progress; Offset beginpath; Offset endpath; - Offset celluloposition; + Offset origin; + var step = 0.0; + List celluloxposition; + List celluloyposition; + double coeffScreenMapHeight; + double coeffScreenMapWidth; + double xaxis = 750; + double yaxis = 80; + int axisX; + int axisY; + var steps = [0.0, 80.0, 157.0, 235.0, 312.0, 389.0, 467.0]; - double axisX; - double axisY; - double scaleX; - double scaleY; + GuideGrid(this.origin, this.step, this.coeffScreenMapWidth, + this.coeffScreenMapHeight, this.celluloxposition, this.celluloyposition) { + _paintBlue = Paint() + ..color = Colors.blue + ..strokeWidth = 1.0 + ..style = PaintingStyle.fill; + _paintRed = Paint() + ..color = Colors.red + ..strokeWidth = 1.0 + ..style = PaintingStyle.fill; - GuideGrid( - this.celluloposition, this.axisX, this.axisY, this.scaleX, this.scaleY) { - _paint = Paint() - ..color = Colors.green - ..strokeWidth = 4.0; + axisX = + ((celluloxposition[0] - origin.dx / coeffScreenMapWidth) ~/ step) - 1; + axisY = + ((origin.dy - celluloyposition[1] / coeffScreenMapHeight) ~/ step) + 1; + if (axisX < 0) axisX = 0; + if (axisY < 0) axisY = 0; + if (axisX > 6) axisX = 6; + if (axisY > 6) axisY = 6; } @override void paint(Canvas canvas, Size size) { + canvas.drawCircle( + Offset(origin.dx + steps[axisX], origin.dy), 11.0, _paintRed); + canvas.drawCircle( + Offset(origin.dx, origin.dy - steps[axisY]), 11.0, _paintBlue); + canvas.drawLine( - Offset(celluloposition.dx * scaleX, celluloposition.dy * scaleY), - Offset(axisX * scaleX, celluloposition.dy * scaleY), - _paint); + Offset(celluloxposition[0] * coeffScreenMapWidth, + celluloyposition[1] * coeffScreenMapHeight), + Offset(celluloxposition[0] * coeffScreenMapWidth, + xaxis * coeffScreenMapHeight), + _paintRed); canvas.drawLine( - Offset(celluloposition.dx * scaleX, celluloposition.dy * scaleY), - Offset(celluloposition.dx * scaleX, axisY * scaleY), - _paint); + Offset(celluloxposition[0] * coeffScreenMapWidth, + celluloyposition[1] * coeffScreenMapHeight), + Offset(yaxis * coeffScreenMapWidth, + celluloyposition[1] * coeffScreenMapHeight), + _paintBlue); } @override bool shouldRepaint(GuideGrid oldDelegate) { return oldDelegate._progress != _progress; } } diff --git a/student/lib/widgets/mapShapeMaker.dart b/student/lib/widgets/mapShapeMaker.dart index c3ad11f..94242bf 100644 --- a/student/lib/widgets/mapShapeMaker.dart +++ b/student/lib/widgets/mapShapeMaker.dart @@ -1,276 +1,238 @@ import 'package:flutter/material.dart'; import 'dart:math' as math; class MapShapeMaker extends CustomPainter { Paint _paint; Paint _paintStartEnd; int numCircles; List originCircles; List radiuosCircles; int numRectangles; List originRectangles; List widthRectangles; List heightRectangles; int numPolygons; List sidesofPolygon; List radiusPolygon; List centerPolygon; List colorHexagon; Offset startCenter; Offset endCenter; double radiuosStart = 45; var pointOrder = ['A', 'B', 'C', 'D']; List pointPosition = [ Offset(80.0, 80.0), Offset(760.0, 80.0), Offset(80.0, 760.0), Offset(760.0, 760.0) ]; List pointPositionM = [ Offset(80.0, 80.0), Offset(760.0, 80.0), Offset(80.0, 760.0), Offset(760.0, 760.0) ]; List originCirclesM; List radiuosCirclesM; List originRectanglesM; List widthRectanglesM; List heightRectanglesM; List radiusPolygonM; List centerPolygonM; Offset startCenterM; Offset endCenterM; double radiuosStartM = 45; final _textPainter = TextPainter(textDirection: TextDirection.ltr); final _textPainter2 = TextPainter(textDirection: TextDirection.ltr); final _textPainter3 = TextPainter(textDirection: TextDirection.ltr); final _textPainter4 = TextPainter(textDirection: TextDirection.ltr); double coeffScreenMapHeight; double coeffScreenMapWidth; MapShapeMaker( + this.pointPosition, coeffScreenMapWidth, this.coeffScreenMapHeight, this.numRectangles, this.originRectangles, this.widthRectangles, this.heightRectangles, this.numCircles, this.originCircles, this.radiuosCircles, this.numPolygons, this.sidesofPolygon, this.radiusPolygon, this.centerPolygon, this.startCenter, this.endCenter) { _paint = Paint() ..color = Colors.blue ..strokeWidth = 10.0 ..style = PaintingStyle.fill; _paintStartEnd = Paint() ..color = Colors.green ..strokeWidth = 10.0 ..style = PaintingStyle.fill; // print(originRectangles[0].dx); // print('coeff' + coeffScreenMapWidth.toString()); originCirclesM = new List(numCircles); radiuosCirclesM = new List(numCircles); for (int i = 0; i < numCircles; i++) { originCirclesM[i] = Offset(originCircles[i].dx * coeffScreenMapWidth, originCircles[i].dy * coeffScreenMapHeight); radiuosCirclesM[i] = radiuosCircles[i] * coeffScreenMapWidth; } originRectanglesM = new List(numRectangles); widthRectanglesM = new List(numRectangles); heightRectanglesM = new List(numRectangles); for (int i = 0; i < numRectangles; i++) { originRectanglesM[i] = Offset( originRectangles[i].dx * coeffScreenMapWidth, originRectangles[i].dy * coeffScreenMapHeight); widthRectanglesM[i] = widthRectangles[i] * coeffScreenMapWidth; heightRectanglesM[i] = heightRectangles[i] * coeffScreenMapHeight; } centerPolygonM = new List(numPolygons); radiusPolygonM = new List(numPolygons); startCenterM = Offset(startCenter.dx * coeffScreenMapWidth, startCenter.dy * coeffScreenMapHeight); endCenterM = Offset(endCenter.dx * coeffScreenMapWidth, endCenter.dy * coeffScreenMapHeight); for (int i = 0; i < numPolygons; i++) { centerPolygonM[i] = Offset(centerPolygon[i].dx * coeffScreenMapWidth, centerPolygon[i].dy * coeffScreenMapHeight); radiusPolygonM[i] = radiusPolygon[i] * coeffScreenMapWidth; } - for (int i = 0; i < 4; i++) { + for (int i = 0; i < pointPosition.length; i++) { pointPositionM[i] = Offset(pointPosition[i].dx * coeffScreenMapWidth, pointPosition[i].dy * coeffScreenMapHeight); } } Path createPolygonPath(int i) { final path = Path(); var angle = (math.pi * 2) / sidesofPolygon[i]; Offset firstPoint = Offset( radiusPolygonM[i] * math.cos(0.0), radiusPolygonM[i] * math.sin(0.0)); path.moveTo(firstPoint.dx + centerPolygonM[i].dx, firstPoint.dy + centerPolygonM[i].dy); for (int j = 1; j <= sidesofPolygon[i]; j++) { double x = radiusPolygonM[i] * math.cos(angle * j) + centerPolygonM[i].dx; double y = radiusPolygonM[i] * math.sin(angle * j) + centerPolygonM[i].dy; path.lineTo(x, y); } path.close(); return path; } Path createStartPath(Offset center, double radius) { final path = Path(); var angle = (math.pi * 2) / 6; Offset firstPoint = Offset(radius * math.cos(0.0), radius * math.sin(0.0)); path.moveTo(firstPoint.dx + center.dx, firstPoint.dy + center.dy); for (int j = 1; j <= 6; j++) { double x = radius * math.cos(angle * j) + center.dx; double y = radius * math.sin(angle * j) + center.dy; path.lineTo(x, y); } path.close(); return path; } @override void paint(Canvas canvas, Size size) { for (int i = 0; i < numCircles; i++) { double x = ((originCirclesM[i].dx)); double y = (originCirclesM[i].dy); canvas.drawCircle(Offset(x, y), radiuosCirclesM[i], _paint); } for (int i = 0; i < numRectangles; i++) { // canvas.translate(0, 90); // canvas.rotate(1.3); canvas.drawRect( Rect.fromCenter( center: Offset(originRectanglesM[i].dx, originRectanglesM[i].dy), width: widthRectanglesM[i], height: heightRectanglesM[i]), _paint); } for (int i = 0; i < numPolygons; i++) { Path path = createPolygonPath(i); canvas.drawPath(path, _paint); } - canvas.drawPath( - createStartPath(pointPositionM[2], radiuosStartM), - Paint() - ..color = Colors.green - ..strokeWidth = 10.0 - ..style = PaintingStyle.fill); - - canvas.drawPath( - createStartPath(pointPositionM[2], radiuosStartM - 10), - Paint() - ..color = Colors.white - ..strokeWidth = 10.0 - ..style = PaintingStyle.fill); - - canvas.drawPath( - createStartPath(pointPositionM[3], radiuosStartM), - Paint() - ..color = Colors.green - ..strokeWidth = 10.0 - ..style = PaintingStyle.fill); - - canvas.drawPath( - createStartPath(pointPositionM[3], radiuosStartM - 10), - Paint() - ..color = Colors.white - ..strokeWidth = 10.0 - ..style = PaintingStyle.fill); - _textPainter2.text = TextSpan( text: pointOrder[1], style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black)); _textPainter2.layout( minWidth: 0, maxWidth: double.maxFinite, ); _textPainter.text = TextSpan( text: pointOrder[0], style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black)); _textPainter.layout( minWidth: 0, maxWidth: double.maxFinite, ); _textPainter3.text = TextSpan( text: pointOrder[2], style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black)); _textPainter3.layout( minWidth: 0, maxWidth: double.maxFinite, ); _textPainter4.text = TextSpan( text: pointOrder[3], style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black)); _textPainter4.layout( minWidth: 0, maxWidth: double.maxFinite, ); - canvas.drawPath( - createStartPath(pointPositionM[0], radiuosStartM), - Paint() - ..color = Colors.green - ..strokeWidth = 10.0 - ..style = PaintingStyle.fill); - canvas.drawPath( - createStartPath(pointPositionM[0], radiuosStartM - 10), - Paint() - ..color = Colors.white - ..strokeWidth = 10.0 - ..style = PaintingStyle.fill); - - canvas.drawPath( - createStartPath(pointPositionM[1], radiuosStartM), - Paint() - ..color = Colors.green - ..strokeWidth = 10.0 - ..style = PaintingStyle.fill); - canvas.drawPath( - createStartPath(pointPositionM[1], radiuosStartM - 10), - Paint() - ..color = Colors.white - ..strokeWidth = 10.0 - ..style = PaintingStyle.fill); - + for (int i = 0; i < pointPosition.length; i++) { + canvas.drawPath( + createStartPath(pointPositionM[i], radiuosStartM), + Paint() + ..color = Colors.green + ..strokeWidth = 10.0 + ..style = PaintingStyle.fill); + + canvas.drawPath( + createStartPath(pointPositionM[i], radiuosStartM - 10), + Paint() + ..color = Colors.white + ..strokeWidth = 10.0 + ..style = PaintingStyle.fill); + } _textPainter.paint( canvas, Offset(pointPositionM[0].dx - 6, pointPositionM[0].dy - 5)); _textPainter2.paint( canvas, Offset(pointPositionM[1].dx - 6, pointPositionM[1].dy - 5)); - _textPainter3.paint( - canvas, Offset(pointPositionM[2].dx - 6, pointPositionM[2].dy - 5)); - _textPainter4.paint( - canvas, Offset(pointPositionM[3].dx - 6, pointPositionM[3].dy - 5)); + // _textPainter3.paint( + /// canvas, Offset(pointPositionM[2].dx - 6, pointPositionM[2].dy - 5)); +// _textPainter4.paint( +// canvas, Offset(pointPositionM[3].dx - 6, pointPositionM[3].dy - 5)); } @override bool shouldRepaint(CustomPainter oldDelegate) { return false; } } diff --git a/student/lib/widgets/onlineRobotMap.Dart b/student/lib/widgets/onlineRobotMap.Dart index bd1bf1f..7fdb9e4 100644 --- a/student/lib/widgets/onlineRobotMap.Dart +++ b/student/lib/widgets/onlineRobotMap.Dart @@ -1,64 +1,66 @@ import 'package:flutter/material.dart'; class LinePainter extends CustomPainter { Paint _paint; Offset beginpath; Offset endpath; var path = Path(); //var patendpathh=path(); LinePainter(this.beginpath, this.endpath) { _paint = Paint() ..color = Colors.blue ..strokeWidth = 8.0 ..style = PaintingStyle.stroke; } @override void paint(Canvas canvas, Size size) { // path.moveTo(0, 0); path.moveTo(beginpath.dx, beginpath.dy); path.lineTo(endpath.dx, endpath.dy); canvas.drawPath(path, _paint); // canvas.saveLayer(bounds, paint); } @override bool shouldRepaint(LinePainter oldDelegate) { return true; } } class LinePainter2 extends CustomPainter { Paint _paint; double _progress; List x; List y; Color linecolor; var path = Path(); //var patendpathh=path(); LinePainter2(this.x, this.y, this.linecolor) { _paint = Paint() ..color = this.linecolor ..strokeWidth = 8.0 ..style = PaintingStyle.stroke; } @override void paint(Canvas canvas, Size size) { // path.moveTo(0, 0); for (int i = 4; i < x.length; i++) { - path.moveTo(x[i - 2], y[i - 2]); - path.lineTo(x[i - 1], y[i - 1]); - canvas.drawPath(path, _paint); + //path.moveTo(x[i - 2], y[i - 2]); + // path.lineTo(x[i - 1], y[i - 1]); + // canvas.drawPath(path, _paint); + canvas.drawLine( + Offset(x[i - 2], y[i - 2]), Offset(x[i - 1], y[i - 1]), _paint); } } @override bool shouldRepaint(LinePainter2 oldDelegate) { return true; } } LinePainter linepainter = new LinePainter(Offset(0, 0), Offset(0, 10)); diff --git a/student/lib/widgets/stopdrawer.dart b/student/lib/widgets/stopdrawer.dart new file mode 100644 index 0000000..f4db073 --- /dev/null +++ b/student/lib/widgets/stopdrawer.dart @@ -0,0 +1,70 @@ +import 'package:flutter/material.dart'; +import "dart:math" as math; + +class StopDrawer extends CustomPainter { + Paint _paintBlue; + Paint _paintRed; + double _progress; + Offset beginpath; + Offset endpath; + Offset origin; + var step = 0.0; + List celluloxposition; + List celluloyposition; + double coeffScreenMapHeight; + double coeffScreenMapWidth; + int axisX; + int axisY; + Offset boxCenter; + Offset boxCenterM; + final _textPainter = TextPainter(textDirection: TextDirection.ltr); + StopDrawer( + this.coeffScreenMapWidth, this.coeffScreenMapHeight, this.boxCenter) { + _paintBlue = Paint() + ..color = Colors.blue + ..strokeWidth = 10.0 + ..style = PaintingStyle.fill; + _paintRed = Paint() + ..color = Colors.red + ..strokeWidth = 10.0 + ..style = PaintingStyle.fill; + boxCenterM = Offset(boxCenter.dx * coeffScreenMapWidth, + boxCenter.dy * coeffScreenMapHeight); + } + + Path createStartPath(Offset center, double radius) { + final path = Path(); + var angle = (math.pi * 2) / 6; + Offset firstPoint = Offset(radius * math.cos(0.0), radius * math.sin(0.0)); + path.moveTo(firstPoint.dx + center.dx, firstPoint.dy + center.dy); + for (int j = 1; j <= 6; j++) { + double x = radius * math.cos(angle * j) + center.dx; + double y = radius * math.sin(angle * j) + center.dy; + path.lineTo(x, y); + } + path.close(); + + return path; + } + + @override + void paint(Canvas canvas, Size size) { + _textPainter.text = TextSpan( + text: 'Stop here', + style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black)); + _textPainter.layout( + minWidth: 0, + maxWidth: double.maxFinite, + ); + +// canvas.drawRect( + // Offset(origin.dx + axisX * step, origin.dy), 11.0, _paintRed); + canvas.drawPath(createStartPath(boxCenterM, 40), _paintBlue); + _textPainter.paint(canvas, Offset(boxCenterM.dx - 27, boxCenterM.dy - 10)); + } + + @override + bool shouldRepaint(StopDrawer oldDelegate) { + return oldDelegate._progress != _progress; + } +} diff --git a/student/pubspec.lock b/student/pubspec.lock index e3e9ddb..d9e55ea 100644 --- a/student/pubspec.lock +++ b/student/pubspec.lock @@ -1,677 +1,705 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: ansicolor: dependency: transitive description: name: ansicolor url: "https://pub.dartlang.org" source: hosted version: "1.0.2" archive: dependency: transitive description: name: archive url: "https://pub.dartlang.org" source: hosted version: "2.0.13" args: dependency: transitive description: name: args url: "https://pub.dartlang.org" source: hosted version: "1.6.0" + arrow_path: + dependency: "direct main" + description: + name: arrow_path + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" async: dependency: transitive description: name: async url: "https://pub.dartlang.org" source: hosted version: "2.4.1" - audioplayer: + audioplayers: dependency: "direct main" description: - name: audioplayer + name: audioplayers url: "https://pub.dartlang.org" source: hosted - version: "0.8.1" + version: "0.16.1" bezier: dependency: "direct main" description: name: bezier url: "https://pub.dartlang.org" source: hosted version: "1.1.5" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted version: "2.0.0" cached_network_image: dependency: transitive description: name: cached_network_image url: "https://pub.dartlang.org" source: hosted version: "2.2.0+1" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted version: "1.1.3" clock: dependency: transitive description: name: clock url: "https://pub.dartlang.org" source: hosted version: "1.0.1" cloud_firestore: dependency: "direct main" description: name: cloud_firestore url: "https://pub.dartlang.org" source: hosted version: "0.13.7" cloud_firestore_platform_interface: dependency: transitive description: name: cloud_firestore_platform_interface url: "https://pub.dartlang.org" source: hosted version: "1.1.2" cloud_firestore_web: dependency: transitive description: name: cloud_firestore_web url: "https://pub.dartlang.org" source: hosted version: "0.1.1+2" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted version: "1.14.12" console_log_handler: dependency: transitive description: name: console_log_handler url: "https://pub.dartlang.org" source: hosted version: "1.1.6" convert: dependency: transitive description: name: convert url: "https://pub.dartlang.org" source: hosted version: "2.1.1" crypto: dependency: transitive description: name: crypto url: "https://pub.dartlang.org" source: hosted version: "2.1.4" cupertino_icons: dependency: "direct main" description: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted version: "0.1.3" extra_pedantic: dependency: transitive description: name: extra_pedantic url: "https://pub.dartlang.org" source: hosted version: "1.2.0" file: dependency: transitive description: name: file url: "https://pub.dartlang.org" source: hosted version: "5.2.1" firebase: dependency: transitive description: name: firebase url: "https://pub.dartlang.org" source: hosted version: "7.3.0" firebase_core: dependency: "direct main" description: name: firebase_core url: "https://pub.dartlang.org" source: hosted version: "0.4.5" firebase_core_platform_interface: dependency: transitive description: name: firebase_core_platform_interface url: "https://pub.dartlang.org" source: hosted version: "1.0.4" firebase_core_web: dependency: transitive description: name: firebase_core_web url: "https://pub.dartlang.org" source: hosted version: "0.1.1+2" firebase_database: dependency: "direct main" description: name: firebase_database url: "https://pub.dartlang.org" source: hosted version: "3.1.6" flutter: dependency: "direct main" description: flutter source: sdk version: "0.0.0" flutter_appavailability: dependency: "direct main" description: name: flutter_appavailability url: "https://pub.dartlang.org" source: hosted version: "0.0.21" flutter_cache_manager: dependency: transitive description: name: flutter_cache_manager url: "https://pub.dartlang.org" source: hosted version: "1.4.1" flutter_image: dependency: transitive description: name: flutter_image url: "https://pub.dartlang.org" source: hosted version: "3.0.0" flutter_launcher_icons: dependency: "direct main" description: name: flutter_launcher_icons url: "https://pub.dartlang.org" source: hosted version: "0.7.5" flutter_map: dependency: "direct main" description: name: flutter_map url: "https://pub.dartlang.org" source: hosted version: "0.9.0" flutter_slidable: dependency: "direct main" description: name: flutter_slidable url: "https://pub.dartlang.org" source: hosted version: "0.5.4" flutter_svg: dependency: "direct main" description: name: flutter_svg url: "https://pub.dartlang.org" source: hosted version: "0.17.4" flutter_test: dependency: "direct dev" description: flutter source: sdk version: "0.0.0" flutter_web_plugins: dependency: transitive description: flutter source: sdk version: "0.0.0" geodesy: dependency: transitive description: name: geodesy url: "https://pub.dartlang.org" source: hosted version: "0.3.2" geojson: dependency: transitive description: name: geojson url: "https://pub.dartlang.org" source: hosted version: "0.9.1" geopoint: dependency: transitive description: name: geopoint url: "https://pub.dartlang.org" source: hosted version: "0.7.1" get_it: dependency: "direct main" description: name: get_it url: "https://pub.dartlang.org" source: hosted version: "4.0.4" google_fonts: dependency: "direct main" description: name: google_fonts url: "https://pub.dartlang.org" source: hosted version: "1.1.0" http: dependency: transitive description: name: http url: "https://pub.dartlang.org" source: hosted version: "0.12.1" http_parser: dependency: transitive description: name: http_parser url: "https://pub.dartlang.org" source: hosted version: "3.1.4" image: dependency: transitive description: name: image url: "https://pub.dartlang.org" source: hosted version: "2.1.12" intl: dependency: "direct main" description: name: intl url: "https://pub.dartlang.org" source: hosted version: "0.16.1" intro_views_flutter: dependency: "direct main" description: name: intro_views_flutter url: "https://pub.dartlang.org" source: hosted version: "2.8.1" iso: dependency: transitive description: name: iso url: "https://pub.dartlang.org" source: hosted version: "0.3.0" js: dependency: transitive description: name: js url: "https://pub.dartlang.org" source: hosted version: "0.6.2" latlong: dependency: transitive description: name: latlong url: "https://pub.dartlang.org" source: hosted version: "0.6.1" lists: dependency: transitive description: name: lists url: "https://pub.dartlang.org" source: hosted version: "0.1.6" loading_view: dependency: transitive description: name: loading_view url: "https://pub.dartlang.org" source: hosted version: "1.0.2" logging: dependency: transitive description: name: logging url: "https://pub.dartlang.org" source: hosted version: "0.11.4" map_controller: dependency: "direct main" description: name: map_controller url: "https://pub.dartlang.org" source: hosted version: "0.8.0" matcher: dependency: transitive description: name: matcher url: "https://pub.dartlang.org" source: hosted version: "0.12.6" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted version: "1.1.8" mgrs_dart: dependency: transitive description: name: mgrs_dart url: "https://pub.dartlang.org" source: hosted version: "1.0.1" nested: dependency: transitive description: name: nested url: "https://pub.dartlang.org" source: hosted version: "0.0.4" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted version: "1.6.4" path_drawing: dependency: transitive description: name: path_drawing url: "https://pub.dartlang.org" source: hosted version: "0.4.1" path_parsing: dependency: transitive description: name: path_parsing url: "https://pub.dartlang.org" source: hosted version: "0.1.4" path_provider: dependency: transitive description: name: path_provider url: "https://pub.dartlang.org" source: hosted version: "1.6.11" path_provider_linux: dependency: transitive description: name: path_provider_linux url: "https://pub.dartlang.org" source: hosted version: "0.0.1+1" path_provider_macos: dependency: transitive description: name: path_provider_macos url: "https://pub.dartlang.org" source: hosted version: "0.0.4+3" path_provider_platform_interface: dependency: transitive description: name: path_provider_platform_interface url: "https://pub.dartlang.org" source: hosted version: "1.0.2" pedantic: dependency: transitive description: name: pedantic url: "https://pub.dartlang.org" source: hosted version: "1.9.0" petitparser: dependency: transitive description: name: petitparser url: "https://pub.dartlang.org" source: hosted version: "2.4.0" platform: dependency: transitive description: name: platform url: "https://pub.dartlang.org" source: hosted version: "2.2.1" plugin_platform_interface: dependency: transitive description: name: plugin_platform_interface url: "https://pub.dartlang.org" source: hosted version: "1.0.2" positioned_tap_detector: dependency: transitive description: name: positioned_tap_detector url: "https://pub.dartlang.org" source: hosted version: "1.0.3" process: dependency: transitive description: name: process url: "https://pub.dartlang.org" source: hosted version: "3.0.13" proj4dart: dependency: transitive description: name: proj4dart url: "https://pub.dartlang.org" source: hosted version: "1.0.5" provider: dependency: "direct main" description: name: provider url: "https://pub.dartlang.org" source: hosted version: "4.3.2" quiver: dependency: transitive description: name: quiver url: "https://pub.dartlang.org" source: hosted version: "2.1.3" rxdart: dependency: transitive description: name: rxdart url: "https://pub.dartlang.org" source: hosted version: "0.24.1" sky_engine: dependency: transitive description: flutter source: sdk version: "0.0.99" slugify2: dependency: transitive description: name: slugify2 url: "https://pub.dartlang.org" source: hosted version: "0.2.1" source_span: dependency: transitive description: name: source_span url: "https://pub.dartlang.org" source: hosted version: "1.7.0" sqflite: dependency: transitive description: name: sqflite url: "https://pub.dartlang.org" source: hosted version: "1.3.1+1" sqflite_common: dependency: transitive description: name: sqflite_common url: "https://pub.dartlang.org" source: hosted version: "1.0.2+1" stack_trace: dependency: transitive description: name: stack_trace url: "https://pub.dartlang.org" source: hosted version: "1.9.3" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.dartlang.org" source: hosted version: "2.0.0" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted version: "1.0.5" synchronized: dependency: transitive description: name: synchronized url: "https://pub.dartlang.org" source: hosted version: "2.2.0+2" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted version: "1.1.0" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted version: "0.2.15" tip_dialog: dependency: "direct main" description: name: tip_dialog url: "https://pub.dartlang.org" source: hosted version: "3.1.0" transparent_image: dependency: transitive description: name: transparent_image url: "https://pub.dartlang.org" source: hosted version: "1.0.0" tuple: dependency: transitive description: name: tuple url: "https://pub.dartlang.org" source: hosted version: "1.0.3" typed_data: dependency: transitive description: name: typed_data url: "https://pub.dartlang.org" source: hosted version: "1.1.6" unicode: dependency: transitive description: name: unicode url: "https://pub.dartlang.org" source: hosted version: "0.2.4" uuid: dependency: transitive description: name: uuid url: "https://pub.dartlang.org" source: hosted version: "2.2.2" validate: dependency: transitive description: name: validate url: "https://pub.dartlang.org" source: hosted version: "1.7.0" vector_math: dependency: transitive description: name: vector_math url: "https://pub.dartlang.org" source: hosted version: "2.0.8" + video_player: + dependency: "direct main" + description: + name: video_player + url: "https://pub.dartlang.org" + source: hosted + version: "0.11.0" + video_player_platform_interface: + dependency: transitive + description: + name: video_player_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.0" + video_player_web: + dependency: transitive + description: + name: video_player_web + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.4" web_socket_channel: dependency: "direct main" description: name: web_socket_channel url: "https://pub.dartlang.org" source: hosted version: "1.1.0" wkt_parser: dependency: transitive description: name: wkt_parser url: "https://pub.dartlang.org" source: hosted version: "1.0.7" xdg_directories: dependency: transitive description: name: xdg_directories url: "https://pub.dartlang.org" source: hosted version: "0.1.0" xml: dependency: transitive description: name: xml url: "https://pub.dartlang.org" source: hosted version: "3.6.1" yaml: dependency: transitive description: name: yaml url: "https://pub.dartlang.org" source: hosted version: "2.2.1" sdks: dart: ">=2.8.0 <3.0.0" flutter: ">=1.17.0 <2.0.0" diff --git a/student/pubspec.yaml b/student/pubspec.yaml index 4abaf6c..fbb1f12 100644 --- a/student/pubspec.yaml +++ b/student/pubspec.yaml @@ -1,89 +1,91 @@ name: student description: A new Flutter project. # The following line prevents the package from being accidentally published to # pub.dev using `pub publish`. This is preferred for private packages. publish_to: "none" # Remove this line if you wish to publish to pub.dev # The following defines the version and build number for your application. # A version number is three numbers separated by dots, like 1.2.43 # followed by an optional build number separated by a +. # Both the version and the builder number may be overridden in flutter # build by specifying --build-name and --build-number, respectively. # In Android, build-name is used as versionName while build-number used as versionCode. # Read more about Android versioning at https://developer.android.com/studio/publish/versioning # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html version: 1.0.0+1 environment: sdk: ">=2.7.0 <3.0.0" dependencies: flutter: sdk: flutter # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^0.1.3 web_socket_channel: "^1.0.8" google_fonts: ^1.1.0 flutter_slidable: ^0.5.4 flutter_svg: ^0.17.1 cloud_firestore: ^0.13.7 firebase_core: ^0.4.4 firebase_database: ^3.1.6 intl: ^0.16.1 flutter_appavailability: ^0.0.21 flutter_launcher_icons: ^0.7.5 provider: ^4.3.2 get_it: ^4.0.4 flutter_map: any map_controller: ^0.8.0 intro_views_flutter: ^2.8.1 - audioplayer: ^0.8.1 + audioplayers: ^0.16.1 tip_dialog: ^3.0.0 bezier: ^1.1.5 + arrow_path: ^1.0.0 + video_player: ^0.11.0 dev_dependencies: flutter_test: sdk: flutter # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec # The following section is specific to Flutter. flutter: # The following line ensures that the Material Icons font is # included with your application, so that you can use the icons in # the material Icons class. uses-material-design: true # To add assets to your application, add an assets section, like this: assets: - assets/images/ # - images/a_dot_burr.jpeg # - images/a_dot_ham.jpeg # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware. # For details regarding adding assets from package dependencies, see # https://flutter.dev/assets-and-images/#from-packages # To add custom fonts to your application, add a fonts section here, # in this "flutter" section. Each entry in this list should have a # "family" key with the font family name, and a "fonts" key with a # list giving the asset and other descriptors for the font. For # example: # fonts: # - family: Schyler # fonts: # - asset: fonts/Schyler-Regular.ttf # - asset: fonts/Schyler-Italic.ttf # style: italic # - family: Trajan Pro # fonts: # - asset: fonts/TrajanPro.ttf # - asset: fonts/TrajanPro_Bold.ttf # weight: 700 # # For details regarding fonts from package dependencies, # see https://flutter.dev/custom-fonts/#from-packages