| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289 |
- import 'dart:math';
- import 'package:assets_audio_player/assets_audio_player.dart';
- import 'package:flutter/material.dart';
- import 'package:get/get.dart';
- import 'package:trackoffical_app/generated/assets.dart';
- import 'package:trackoffical_app/global.dart';
- import 'package:trackoffical_app/service/app.dart';
- import 'package:trackoffical_app/utils.dart';
- import '../../model/game_state.dart';
- import '../../model/m_control_point.dart';
- import '../../model/m_position.dart';
- import 'package:sensor/sensor.dart' as sensor;
- import '../../model/map_mode.dart';
- import '../../widget/matrix_gesture_detector.dart';
- import 'package:trackoffical_app/appcore/ffi.dart' as ffi;
- class GameModel{
- DateTime? get startAt {
- final save = gameSrcState.value.pbGameSave;
- return save.hasStartAt()? save.startAt.toModel(): null;
- }
- DateTime? get endAt {
- final save = gameSrcState.value.pbGameSave;
- if(save.hasStopAt()){
- if(save.stopAt.seconds==0){
- return null;
- }
- return save.stopAt.toModel();
- }
- return null;
- }
- final mapTransformMatrix = Matrix4.identity().obs;
- bool get isStarted => startAt != null;
- bool get isFinish => endAt != null;
- final compassDiameter = 160.0.obs;
- final myPositionHistory = <MPosition>[].obs;
- final myPositionHistoryTmp = <MPosition>[];
- final speedMPreS = 0.0.obs;
- final isWalking = false.obs;
- Rx<MPosition?> get myPosition => App.to.position;
- final Rx<Offset?> myPositionOnMap = Rx(null);
- final heartRate = 0.obs;
- final heartRatePercent = 0.0.obs;
- final ei = 0.0.obs;
- final ck = 0.0.obs;
- final kCal = 0.0.obs;
- final exerciseKcal = 0.0.obs;
- final hrMean = 0.obs;
- final hrMax = 0.obs;
- final stepCount = 0.obs;
- /// 指北针弧度,移动时通过GPS判断
- final compassRadiansFused = 0.0.obs;
- final compassRadiansSrc = 0.0.obs;
- final orientation = sensor.Orientation().obs;
- final mapMode = MapMode.compass.obs;
- Offset? mapRotateCenter;
- var isAlwaysShowMyLocation = true;
- var isEnableMyLocation = true;
- /// 用户设置是否锁定旋转中心
- final isLockScreenCenterToMyPosition = false.obs;
- bool get isLockScreenCenterToMyPositionSystem =>
- isLockScreenCenterToMyPosition.value
- && isEnableUserLocation;
- var accelerometerEvent = sensor.Orientation();
- var isMoving = false;
- final Rx<ffi.ZoneType?> zone = Rx(null);
- final _isEnableUserLocation = App.to.userProfile.isEnableUserLocation.val.obs;
- bool get isEnableUserLocation => _isEnableUserLocation.value;
- set isEnableUserLocation(v){
- _isEnableUserLocation.value = v;
- App.to.userProfile.isEnableUserLocation.val =v;
- }
- /// 虚拟点打点有效半径冗余
- static const controlPointEffectiveAreaRadiusKmOffset=0.002;
- /// 虚拟点打点有效半径
- double get controlPointEffectiveAreaRadiusKm =>
- GlobalVar.isGpsTest? 100:
- gameSrcState.value.pbGameData.vcpRadius.toDouble()/1000
- + controlPointEffectiveAreaRadiusKmOffset;
- /// 是否允许在开始点前预览所有点
- bool get isAllowPreviewControlPoint => gameSrcState.value.pbGameData.isPreview;
- /// 是否允许显示地图
- bool get isShowMap => gameSrcState.value.pbGameData.isShowMap;
- /// 是否允许跳点
- bool get isAllowedPassCP => gameSrcState.value.pbGameData.maxPassPoint > 0;
- final trajectoryPoints = <Offset>[].obs;
- /// 用户选项是否显示轨迹
- final isShowTrajectory = true.obs;
- bool get isDrawTrajectory => isShowTrajectory.value && isEnableUserLocation;
- final controlPointWantSequence = <MControlPoint>[].obs;
- final myPositionHistoryLen = 0.meter.obs;
- final gameSrcState = GameState().obs;
- bool get isUseRealNorth => App.to.userProfile.isCompassUseRealNorth.val;
- set isUseRealNorth(v){ App.to.userProfile.isCompassUseRealNorth.val = v; }
- var compassRealNorthOffset = 0.0;
- var deviceSpeed = 0.0;
- Duration get gameQuestionShowDuration => gameSrcState.value.pbGameData.oiShowTime.seconds;
- Distance get myPositionHistoryLenFromLastCP{
- if(checkedPointsHistory.isEmpty){
- return myPositionHistoryLen.value;
- }
- final cp = checkedPointsHistory.last;
- return myPositionHistoryLen.value - cp.checkDistanceAfterStart;
- }
- Duration get startedDuration{
- final b = startAt;
- if(b!= null){
- return App.to.now.difference(b);
- }
- return 0.seconds;
- }
- final paceSecondKm = 0.seconds.obs;
- final paceSecondKmFromLastCP = 0.seconds.obs;
- final checkedPointsHistory = <MControlPoint>[].obs;
- int get checkedCount {
- var i = 0;
- for (var one in gameSrcState.value.pbGameSave.checkedSortedList) {
- if (one.isCheckSuccess) {
- i++;
- }
- }
- return i;
- }
- final Rx<int?> nextPlanPointIndex=Rx(null);
- int get validCPCount{
- var cpChecked = checkedCount;
- if(cpChecked < 0){
- cpChecked = 0;
- }
- return cpChecked;
- }
- // 所有计分点数量
- int get validCPAllNum{
- return controlPointWantSequence.length;
- }
- // 打卡进度
- double get checkProgress {
- if (controlPointWantSequence.isEmpty) {
- return 0;
- }
- return (checkedCount).toDouble() / (controlPointWantSequence.length);
- }
- MControlPoint? getNextWantPoint(int offset){
- final i = checkedCount + offset;
- return controlPointWantSequence.length > i?
- controlPointWantSequence[i] : null;
- }
- MControlPoint? get nextPlanPoint{
- final i = nextPlanPointIndex.value;
- if(i==null){
- return getNextWantPoint(0);
- }
- return controlPointWantSequence.length > i?
- controlPointWantSequence[i] : null;
- }
- set nextPlanPoint(MControlPoint? v){
- if(v==null){
- nextPlanPointIndex.value=null;
- return;
- }
- for(var i=0;i<controlPointWantSequence.length;i++ ){
- if(v.intId==controlPointWantSequence[i].intId){
- if(i < checkedCount){
- return;
- }
- nextPlanPointIndex.value=i;
- AssetsAudioPlayer.newPlayer().open(
- Audio(Assets.soundCpJump),
- autoStart: true,
- showNotification: false
- );
- return;
- }
- }
- }
- bool get isInWantControlPointArea {
- final p = getNextWantPoint(0);
- if(p != null){
- final disKm = nextWantCPDistanceKm;
- if(disKm != null && p.type == MControlPointType.gps){
- return disKm <= controlPointEffectiveAreaRadiusKm.km;
- }
- }
- return false;
- }
- bool get isInPlanControlPointArea {
- final p = nextPlanPoint;
- if(p != null){
- final disKm = nextPlanCPDistanceKm;
- if(disKm != null && p.type == MControlPointType.gps){
- return disKm <= controlPointEffectiveAreaRadiusKm.km;
- }
- }
- return false;
- }
- Distance? get nextWantCPDistanceKm{
- final p1 = myPosition.value;
- final p2 = getNextWantPoint(0)?.position;
- if(p1 != null && p2 != null){
- return p2.distance(p1);
- }
- return null;
- }
- Distance? get nextPlanCPDistanceKm{
- final p1 = myPosition.value;
- final p2 = nextPlanPoint?.position;
- if(p1 != null && p2 != null){
- return p2.distance(p1);
- }
- return null;
- }
- double get compassPlantRadian {
- if(mapMode.value == MapMode.compass){
- return compassRadiansFused.value;
- }
- final ogRm = mapTransformMatrix.value.clone();
- double radian = MatrixGestureDetector.decomposeToValues(ogRm).rotation;
- return radian;
- }
- int get compassShowDegrees{
- var d1 = -( compassPlantRadian - compassRadiansFused.value);
- if(mapMode.value == MapMode.compass){
- d1 = -compassPlantRadian;
- }
- var d = d1 *180~/pi;
- while(d < 0){
- d+=360;
- }
- while(d > 360){
- d-=360;
- }
- return d;
- }
- void setRotateCenterToScreenCenter(){
- final screenCenter =
- Offset(App.to.screenSize.width / 2, App.to.screenSize.height / 2);
- mapRotateCenter = screenCenter;
- }
- void clear(){
- gameSrcState.value = GameState();
- myPositionHistory.clear();
- myPositionHistoryTmp.clear();
- checkedPointsHistory.clear();
- controlPointWantSequence.clear();
- myPositionOnMap.value = null;
- heartRate.value = 0;
- heartRatePercent.value = 0;
- ei.value = 0;
- ck.value = 0;
- myPositionHistoryLen.value = 0.meter;
- nextPlanPointIndex.value=null;
- }
- }
|