骑行界面调整,底层逻辑细化

This commit is contained in:
lishuo 2021-03-30 17:15:16 +08:00
parent d5133ee7b0
commit 9a7830f46a
168 changed files with 19164 additions and 393 deletions

View File

@ -32,7 +32,7 @@
_locationProvider.OnLocationUpdated -= LocationProvider_OnLocationUpdated;
//_map.Initialize(location.LatitudeLongitude, _map.AbsoluteZoom);
var mainController = transform.parent.GetComponent<MainController>();
var mainController = transform.parent.GetComponent<CyclingController>();
if (mainController != null)
{
//初始化map

Binary file not shown.

View File

@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: 80691a320791ff54ca89cd6cdaf7e0d2
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,205 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &1553891496
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 116094885906044059}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: cf37eca46d898384fa2d9e17dfa3e25e, type: 3}
m_Name:
m_EditorClassIdentifier:
character: {fileID: 116094885906044059}
characterAnimator: {fileID: 116094885898626905}
CurrentIndex: 0
--- !u!1 &5773460712156952929
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 4343934065607842291}
- component: {fileID: 6299847091037955312}
- component: {fileID: 6530994641530503712}
- component: {fileID: 3304837852231199275}
m_Layer: 9
m_Name: Sphere
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &4343934065607842291
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5773460712156952929}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 8, y: 8, z: 8}
m_Children: []
m_Father: {fileID: 116094885906139323}
m_RootOrder: 4
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!33 &6299847091037955312
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5773460712156952929}
m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
--- !u!23 &6530994641530503712
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5773460712156952929}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: 03fcf11879198499f9e71b4e087af3c0, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!135 &3304837852231199275
SphereCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5773460712156952929}
m_Material: {fileID: 0}
m_IsTrigger: 0
m_Enabled: 1
serializedVersion: 2
m_Radius: 0.5
m_Center: {x: 0, y: 0, z: 0}
--- !u!1001 &116094885906010681
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications:
- target: {fileID: 100002, guid: 383b41aea1ea4ee43b23a95bb413ebd8, type: 3}
propertyPath: m_Name
value: VirtualPlayer
objectReference: {fileID: 0}
- target: {fileID: 100002, guid: 383b41aea1ea4ee43b23a95bb413ebd8, type: 3}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
- target: {fileID: 400002, guid: 383b41aea1ea4ee43b23a95bb413ebd8, type: 3}
propertyPath: m_RootOrder
value: 0
objectReference: {fileID: 0}
- target: {fileID: 400002, guid: 383b41aea1ea4ee43b23a95bb413ebd8, type: 3}
propertyPath: m_LocalScale.x
value: 2
objectReference: {fileID: 0}
- target: {fileID: 400002, guid: 383b41aea1ea4ee43b23a95bb413ebd8, type: 3}
propertyPath: m_LocalScale.y
value: 2
objectReference: {fileID: 0}
- target: {fileID: 400002, guid: 383b41aea1ea4ee43b23a95bb413ebd8, type: 3}
propertyPath: m_LocalScale.z
value: 2
objectReference: {fileID: 0}
- target: {fileID: 400002, guid: 383b41aea1ea4ee43b23a95bb413ebd8, type: 3}
propertyPath: m_LocalPosition.x
value: 11
objectReference: {fileID: 0}
- target: {fileID: 400002, guid: 383b41aea1ea4ee43b23a95bb413ebd8, type: 3}
propertyPath: m_LocalPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 400002, guid: 383b41aea1ea4ee43b23a95bb413ebd8, type: 3}
propertyPath: m_LocalPosition.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 400002, guid: 383b41aea1ea4ee43b23a95bb413ebd8, type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 400002, guid: 383b41aea1ea4ee43b23a95bb413ebd8, type: 3}
propertyPath: m_LocalRotation.x
value: -0
objectReference: {fileID: 0}
- target: {fileID: 400002, guid: 383b41aea1ea4ee43b23a95bb413ebd8, type: 3}
propertyPath: m_LocalRotation.y
value: -0
objectReference: {fileID: 0}
- target: {fileID: 400002, guid: 383b41aea1ea4ee43b23a95bb413ebd8, type: 3}
propertyPath: m_LocalRotation.z
value: -0
objectReference: {fileID: 0}
- target: {fileID: 400002, guid: 383b41aea1ea4ee43b23a95bb413ebd8, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 400002, guid: 383b41aea1ea4ee43b23a95bb413ebd8, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 400002, guid: 383b41aea1ea4ee43b23a95bb413ebd8, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 9500000, guid: 383b41aea1ea4ee43b23a95bb413ebd8, type: 3}
propertyPath: m_Controller
value:
objectReference: {fileID: 9100000, guid: 14e9d0801d59b004db16bd8b0057c8c9, type: 2}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 383b41aea1ea4ee43b23a95bb413ebd8, type: 3}
--- !u!1 &116094885906044059 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 100002, guid: 383b41aea1ea4ee43b23a95bb413ebd8,
type: 3}
m_PrefabInstance: {fileID: 116094885906010681}
m_PrefabAsset: {fileID: 0}
--- !u!4 &116094885906139323 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 400002, guid: 383b41aea1ea4ee43b23a95bb413ebd8,
type: 3}
m_PrefabInstance: {fileID: 116094885906010681}
m_PrefabAsset: {fileID: 0}
--- !u!95 &116094885898626905 stripped
Animator:
m_CorrespondingSourceObject: {fileID: 9500000, guid: 383b41aea1ea4ee43b23a95bb413ebd8,
type: 3}
m_PrefabInstance: {fileID: 116094885906010681}
m_PrefabAsset: {fileID: 0}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: f46190fc0ed09774fb2d01664232ea2a
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -19,7 +19,7 @@ RenderTexture:
m_MipCount: -1
m_DepthFormat: 2
m_ColorFormat: 8
m_MipMap: 0
m_MipMap: 1
m_GenerateMips: 1
m_SRGB: 0
m_UseDynamicScale: 1
@ -27,11 +27,11 @@ RenderTexture:
m_EnableCompatibleFormat: 1
m_TextureSettings:
serializedVersion: 2
m_FilterMode: 1
m_FilterMode: 0
m_Aniso: 0
m_MipBias: 0
m_WrapU: 1
m_WrapV: 1
m_WrapW: 1
m_WrapV: 2
m_WrapW: 3
m_Dimension: 2
m_VolumeDepth: 1

File diff suppressed because it is too large Load Diff

View File

@ -7,15 +7,18 @@ using System.Collections.Generic;
using UnityEngine;
using XCharts;
using UnityEngine.Networking;
using Assets.Scenes.Ride.Scripts.Model;
public class MainController : MonoBehaviour
public class CyclingController : MonoBehaviour
{
private MapDataModel mapData;//当前路书数据
private double[] coordiantes;//当前地图中心
private int currentUserId;//当前选中的用户id
private bool isStart;//当前游戏是否开始
private string gameType;//当前骑行模式
private DateTime startTime;//开始时间
private bool initComplete;
private CyclingModel cyclingModel;//当前骑行模式
public int RouteId;
public MapDataModel GetMapData()
{
@ -29,28 +32,37 @@ public class MainController : MonoBehaviour
// Start is called before the first frame update
void Awake()
{
initComplete = false;
cyclingModel = CyclingModel.Single;
//获取当前用户信息 TODO
//获取路书信息
//MapApi mapApi = new MapApi();
//var result = mapApi.GetData(5942);
RouteId = 5942;
var result = GetTestData();
//StartCoroutine(requset());
//获取UDP信息 TODO
//获取蓝牙设备信息 TODO
if (result != null && result.List.Count > 0)
{
mapData = result;
coordiantes = result.List[0].Point;
initComplete = true;
}
else
{
throw new System.Exception("fail to get route data");
}
//TODO:
//获取当前用户信息
//获取当前udp信息
//获取蓝牙设备信息
}
private void Update()
{
//发送UDP
}
IEnumerator requset() {
string url = @"http://192.168.0.97:5081/Map/GetData?routeid=5492&m=20";
UnityWebRequest request = UnityWebRequest.Get(url);
@ -95,5 +107,4 @@ public class MainController : MonoBehaviour
}
return dist.ToArray();
}
}

View File

@ -1,23 +1,49 @@
using System;
using Assets.Scenes.Ride.Scripts.Model;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
namespace Assets.Scenes.Ride.Scripts
{
public class Helper
{
public static string GetDataDire(string dirName = "")
public static string GetDataDire(string pathName)
{
//var parentPath = System.IO.Directory.GetParent(Environment.CurrentDirectory).FullName;
var parentPath = " ";//TODO
var path = Path.Combine(parentPath, "PowerFunData", dirName);
if (!System.IO.Directory.Exists(path))
return @"D:\unityproject\Test\"+ pathName;
}
public static double AveragePower(IList<TargetData> list)
{
return Math.Floor(list.Where(p => p._Power > -1).Average(a => a._Power));
}
/// <summary>
/// 优化功率
/// </summary>
/// <param name="list"></param>
/// <returns></returns>
public static double GetNP(List<TargetData> list)
{
var _npinterval = new List<double>();
var count = list.Count / 28;
for (int i = 0; i < count; i++)
{
Directory.CreateDirectory(path);
var list1 = list.Skip(i * 28).Take(28);
double avgpower = Math.Pow((int)list1.Where(d => d._Power > -1).Average(a => a._Power), 4);
_npinterval.Add(avgpower);
}
return path;
double n = 0.25;
if (_npinterval.Count == 0) return 0;
return Math.Pow((_npinterval.Sum() / _npinterval.Count), n);
}
/// <summary>
/// TODO:获取Ftp
/// </summary>
/// <returns></returns>
public static int GetFtp()
{
return 200;
}
public static string FormatTicks(int seconds)

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: cdcb8176fafcd62448e8c70ed9d43074
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0e8389fe2e69de14ba5b9b48f580dd81
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,108 @@
using Assets.Scripts.Apis.Models;
using GeoJSON.Net.Geometry;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assets.Scenes.Ride.Scripts.Model.CyclingModels
{
public abstract class BaseCycling
{
public CyclingModel Mode { get; private set; }
/// <summary>
/// 是否记录数据
/// </summary>
internal bool IsRecord { get; set; }
/// <summary>
/// 骑行数据记录器
/// </summary>
public RecorderDataModel recorderData { get; protected set; }
public List<BaseRider> riders { get; protected set; }
/// <summary>
/// 骑行的路线
/// </summary>
public Route route;
/// <summary>
/// 计时器
/// </summary>
public int Ticks = 0;
/// <summary>
/// 当前骑行的距离
/// </summary>
protected double currentDistance { get; set; }
public virtual bool CanPause => true;
protected TurfHelper _turfHelper;
protected double Zoom { get; private set; }
protected string Bounds { get; private set; }
protected List<OutUser> realRiders;
protected GeographicPosition CenterPoint { get; private set; }
/// <summary>
/// 结束的时间
/// </summary>
protected DateTime? EndTime { get; set; }
public BaseCycling(Route route, CyclingModel cyclingModel)
{
this.route = route;
this.Mode = cyclingModel;
_turfHelper = new TurfHelper(route.JsonData.List.Select(d => d.Point));
}
/// <summary>
/// 骑行函数(如果此方法不满足,可以在子类中重写此方法)
/// </summary>
/// <param name="data"></param>
protected virtual void Run(TargetData targetData)
{
//将当前用户的位置发送到udf服务
SendUserPositionToServer();
}
/// <summary>
/// =>发送用户的位置信息到服务端
/// </summary>
private void SendUserPositionToServer()
{
try
{
if (recorderData.RiderDatas.Any())
{
var lastData = recorderData.RiderDatas.Last();
var preDistance = recorderData.PreDistance;
var weightKg = Math.Round(lastData._Power / recorderData.CurrentUser.Weight, 2);
MapUDPService.Send(route.RouteInstance.Id, recorderData.BelongUserId,
new double[] { lastData._Lat, lastData._Lon },
recorderData.IsCompleted, false, recorderData.EndDistance,
true, 1, lastData._Speed, false, preDistance, weightKg, competitionId: recorderData.Competitionid, recorderData.Saved);
}
else if (recorderData.EndDistance > 0)//没有骑,但是有初始位置的情况
{
var point = _turfHelper.Along(recorderData.EndDistance);
MapUDPService.Send(route.RouteInstance.Id, recorderData.BelongUserId, new double[] { point.Latitude, point.Longitude }, competitionId: recorderData.Competitionid);
}
else
{
MapUDPService.Send(route.RouteInstance.Id, recorderData.BelongUserId, route.Point.First().Reverse().ToArray(), competitionId: recorderData.Competitionid);
}
}
catch (Exception)
{
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 89d63056e2fd43e41b30635a0036ba33
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,106 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assets.Scenes.Ride.Scripts.Model
{
/// <summary>
/// 骑行模式
/// </summary>
public enum CyclingModel
{
/// <summary>
/// 单人模式
/// </summary>
Single = 0,
/// <summary>
/// 在线模式
/// </summary>
Online = 1,
/// <summary>
/// 多人历史数据回顾模式
/// </summary>
Review = 2,
/// <summary>
/// 比赛模式
/// </summary>
Competition = 3,
/// <summary>
/// 环球骑行
/// </summary>
GlobalCycling = 4
}
/// <summary>
/// 骑手类型
/// </summary>
public enum RiderType
{
//Real,//真实的人
Online,//在线人
Review,//回顾人(历史数据中的人)
Virtual
}
/// <summary>
/// 骑行状态(状态变更示意图Paush=>Cycling=>Stop=>Cycling=>Stop)
/// </summary>
public enum CyclingStateEnum
{
/// <summary>
/// 准备阶段
/// </summary>
Prepare,
/// 骑行中
/// </summary>
Cycling,
/// <summary>
/// 暂停
/// </summary>
Stop
}
/// <summary>
/// 发送数据模式
/// </summary>
public enum SendDataMode
{
/// <summary>
/// 自由骑
/// </summary>
Freedom,
/// <summary>
/// 阻力模式
/// </summary>
Resistance,
/// <summary>
/// 轨道模式
/// </summary>
Track
}
/// <summary>
/// 浏览器窗口
/// </summary>
public enum BrowserWindow
{
/// <summary>
/// 主页面窗口
/// </summary>
Main,
/// <summary>
/// 骑行页面窗口
/// </summary>
Cycling
}
public enum CurrentPage
{
index,
list,
detial,
review,
competition,
cycling
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d3d3dd3c4d6e2694eb9d94bc819a12f6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,536 @@
using GeoJSON.Net.Geometry;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assets.Scenes.Ride.Scripts.Model
{
/// <summary>
/// 排名
/// </summary>
public class CompetitionRankingSortModel
{
public int Index { get; set; }
public string Name { get; set; }
public string Headimage { get; set; }
public double Near { get; set; }
public string KGWeight { get; set; }
public double Speed { get; set; }
public string CountryImg { get; set; }
public int UserId { get; set; }
public bool IsSelf { get; set; }
}
/// <summary>
/// 结果页模型
/// </summary>
public class CompetitionResultModel
{
public int Index { get; set; }
public string Name { get; set; }
//public string Time { get; set; }
public double Power { get; set; }
public double WeightKg { get; set; }
public double Weight { get; set; }
public double BicycleWeight { get; set; }
public double HeartRate { get; set; }
public string DeviceType { get; set; }
public string CreateTime { get; set; }
/// <summary>
/// 骑行时长
/// </summary>
public string TripTime { get; set; }
public string CompleteTime { get; set; }
/// <summary>
/// 与冲线时间的差距
/// </summary>
public string Gap { get; set; }
}
public class RankingDataModel
{
public int UserId { get; set; }
public TargetData data { get; set; }
}
public class RankingSortData
{
public int Index { get; set; }
public int UserId { get; set; }
public string WxHeadImg { get; set; }
public string NickName { get; set; }
/// <summary>
/// 注意这里TotalTime不是时间是距离为了重用前端组件没改名称
/// </summary>
public double TotalTime { get; set; }
public int Ticks { get; set; }
/// <summary>
/// 其他人和我的距离(m)
/// </summary>
public double Near { get; set; }
}
public class CyclingFrameRankingModel
{
public List<RankingDataModel> data { get; set; }
public List<RankingSortData> sort { get; set; }
public int myranking { get; set; }
}
/// <summary>
/// 比赛的排名
/// </summary>
public class CompetitionRankingModel
{
public List<CompetitionRankingSortModel> Sorts { get; set; }
public int Total { get; set; }
public int MyRanking { get; set; }
public List<CompetitionResultModel> Results { get; set; }
}
/// <summary>
/// 骑行中 输出的数据模型
/// </summary>
public class OutModel
{
public double progress { get; set; }
public double? Elevation { get; set; }
public string Seconds { get; set; }
public int? EleIndex { get; set; }
//public long ExcuteTime { get; set; }
//public double? Bearing { get; set; }
/// <summary>
/// 坡度
/// </summary>
public double SlopeGrade { get; set; }
public TargetData targetData { get; set; }
public List<OutUser> baseRiders { get; set; }
public CyclingFrameRankingModel Ranking { get; set; }
public CompetitionRankingModel CompetitionRanking { get; set; }
public bool CanStart { get; set; } = true;
/// <summary>
/// 开始倒计时
/// </summary>
public int StartCountDown { get; set; }
/// <summary>
/// 结束倒计时
/// </summary>
public int EndCountDown { get; set; }
/// <summary>
/// 标识比赛的倒计时是关门时间
/// </summary>
public bool IsClosed { get; set; }
///// <summary>
///// 是否已保存
///// </summary>
//public bool Saved { get; set; }
/// <summary>
/// 比赛模式下,第一名的坐标
/// </summary>
public GeographicPosition FirstPoint { get; set; }
public ChartSymbol ChartSymbol { get; set; }
}
public class OutUser
{
public int UserId { get; set; }
public string InMapId { get; set; }
public double NextDistance { get; set; }
public double PreDistance { get; set; }
//public TargetData targetData { get; set; }//暂时不需要此字段
public List<double[]> NextFrameArray { get; set; }
//private List<object> _nextFrameArray { get; set; }
//public List<object> NextFrameArray
//{
// get
// {
// if (_nextFrameArray != null)
// {
// return _nextFrameArray;
// }
// _nextFrameArray = (List<object>)CefBrowserPool.GetFrame(BrowserWindow.Main).EvaluateScriptAsync($"getFrameArray({PreDistance},{NextDistance})").ConfigureAwait(false).GetAwaiter().GetResult().Result;
// return _nextFrameArray;
// }
//}
public string NickName { get; set; }
public string WxHeadImg { get; set; }
public bool IsSelf
{
get
{
return this.UserId == PubCommData.CurrentUser.Id;
}
}
public GeographicPosition Point { get; set; }
public double Bearing { get; set; }
}
public class ChartSymbol
{
private double _grade = 0;
private double _nextGrade = 0;
public string GradeSymbol
{
get
{
if (_grade > 0)
{
return "+";
}
if (_grade < 0)
{
return "-";
}
return "";
}
}
public string GradeDisplay
{
get
{
if (_grade < 0)
{
return (_grade * -1).ToString("0.#");
}
if (_grade > 0)
{
return _grade.ToString("0.#");
}
return "0";
}
}
public string NextGrade
{
get
{
if (_nextGrade > 0)
{
return "+" + _nextGrade.ToString("0.#");
}
return _nextGrade.ToString("0.#");
}
}
/// <summary>
/// 单位m
/// </summary>
public double Distance { get; set; }
/// <summary>
///
/// </summary>
/// <param name="grade"></param>
/// <param name="nextGrade"></param>
/// <param name="distance">单位m</param>
public ChartSymbol(double grade, double nextGrade, double distance)
{
this._grade = grade;
this._nextGrade = nextGrade;
this.Distance = Math.Round(distance, 1);
}
}
public class NearRiderModel
{
public string Name { get; set; }
public string Headimage { get; set; }
public double Near { get; set; }
public string KGWeight { get; set; }
public double Speed { get; set; }
public string CountryImg { get; set; }
public bool IsSelf { get; set; }
}
public class MsgModel
{
public int RouteId { get; set; }
public int MemberId { get; set; }
public double[] Point { get; set; }
public bool exit { get; set; }
public double Speed { get; set; }
public bool IsCompleted { get; set; }
/// <summary>
/// 需要展示的属性
/// </summary>
//public string Prop { get; set; }
public double EndDistance { get; set; }
///// <summary>
///// 是否展示在线的人
///// </summary>
//public bool ShowVirtual { get; set; }
/// <summary>
/// 命令类型,0命令1消息
/// </summary>
public byte CommandType { get; set; }
//public bool IsVirtual { get; set; }
/// <summary>
/// 功率体重比
/// </summary>
public double WeightKg { get; set; }
public double PreDistance { get; set; }
public int Competitionid { get; set; }
/// <summary>
/// 客户端通过是否有用户保存了数据,来拉取相应的已经被保存的数据。(主要用在比赛)
/// </summary>
public bool Saved { get; set; }
public int V { get; set; }
}
public class ReceiveMsgModel
{
public int RouteId { get; set; }
public int MemberId { get; set; }
public double[] Point { get; set; }
//public bool exit { get; set; }
public double Speed { get; set; }
public bool IsCompleted { get; set; }
/// <summary>
/// 需要展示的属性
/// </summary>
//public string Prop { get; set; }
public double EndDistance { get; set; }
/// <summary>
/// 是否展示在线的人
/// </summary>
//public bool ShowVirtual { get; set; }
/// <summary>
/// 命令类型,0命令1消息
/// </summary>
//public byte CommandType { get; set; }
//public bool IsVirtual { get; set; }
public double PreDistance { get; set; }
/// <summary>
/// 功率体重比
/// </summary>
public double WeightKg { get; set; }
public int Competitionid { get; set; }
public bool Saved { get; set; }
public static ReceiveMsgModel Parse(string str)
{
var list = str.Split(',');
if (list.Length != 10)
{
return null;
}
try
{
return new ReceiveMsgModel
{
RouteId = Convert.ToInt32(list[0]),
MemberId = Convert.ToInt32(list[1]),
Point = new double[] { double.Parse(list[2].Split(':')[0]), double.Parse(list[2].Split(':')[1]) },
IsCompleted = ToBoolean(list[3]),
//exit = ToBoolean(list[4]),
Speed = Convert.ToDouble(list[4]),
PreDistance = Convert.ToDouble(list[5]),
EndDistance = Convert.ToDouble(list[6]),
WeightKg = Convert.ToDouble(list[7]),
Competitionid = Convert.ToInt32(list[8]),
Saved = ToBoolean(list[9])
};
}
catch
{
return null;
}
}
private static bool ToBoolean(string str)
{
return Convert.ToBoolean(int.Parse(str));
}
}
public class OnlineUser
{
/// <summary>
/// 用户Id
/// </summary>
public int Id { get; set; }
/// <summary>
/// 在地图中的ID
/// </summary>
public string InMapId
{
get
{
//if (IsVirtual)
//{
// return "Online-Virtual-" + this.Id;
//}
return "Online-" + this.Id;
}
}
public bool IsVirtual { get; set; }
/// <summary>
/// 虚拟人物名称
/// </summary>
public string Name { get; set; }
public double Weight { get; set; }
/// <summary>
/// 头像地址
/// </summary>
public string HeadImage { get; set; }
/// <summary>
/// 路线Id
/// </summary>
public int RouteId { get; set; }
/// <summary>
/// FTP
/// </summary>
public int FTP { get; set; }
/// <summary>
/// 点位
/// </summary>
public double[] Point { get; set; }
/// <summary>
/// 需要展示的属性
/// </summary>
//public List<KeyPaire> Show { get; set; }
/// <summary>
/// 需要隐藏的属性
/// </summary>
public List<KeyPaire> Hide { get; set; }
/// <summary>
/// 是否骑行完毕
/// </summary>
public bool IsCompleted { get; set; }
public double PreDistance { get; set; }
/// <summary>
/// 最后距离
/// </summary>
public double EndDistance { get; set; }
///// <summary>
///// 是否退出
///// </summary>
//public bool exit { get; set; }
/// <summary>
/// 速度(km/h)
/// </summary>
public double Speed { get; set; }
///// <summary>
///// 圆形头像
///// </summary>
//public string CircHeadImg
//{
// get; set;
//}
public bool IsSelf
{
get
{
return Id == PubCommData.CurrentUser.Id;
}
}
public double WeightKg { get; set; }
public int CompetitionId { get; set; }
/// <summary>
/// 已保存的
/// </summary>
public bool Saved { get; set; }
public DateTime LastActiveTime { get; set; }
public bool IsLost
{
get
{
return (DateTime.Now - LastActiveTime).TotalSeconds > 3;
}
}
}
public class KeyPaire
{
public object Key { get; set; }
public object Value { get; set; }
public KeyPaire(object key, object value)
{
this.Key = key;
this.Value = value;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d5741018b26c4d94dbd42daf26d87f3f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,216 @@
using Assets.Scripts.Apis;
using Assets.Scripts.Apis.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assets.Scenes.Ride.Scripts.Model
{
public class RecorderDataModel
{
//private readonly MapWorkoutService service = new MapWorkoutService();
public t_user CurrentUser { get; set; }
/// <summary>
/// 所属人ID
/// </summary>
public int BelongUserId
{
get
{
return CurrentUser.Id;
}
}
/// <summary>
/// 记录是否完毕
/// </summary>
public bool IsCompleted { get; set; }
/// <summary>
/// 是否需要计算排名
/// </summary>
public bool IsNeedRanking { get; set; }
/// <summary>
/// 骑行记录索引(用于中断骑行,继续骑行)
/// </summary>
public int ContinueIndex { get; set; }
/// <summary>
/// 骑行状态
/// </summary>
public CyclingStateEnum CyclingState { get; set; }
/// <summary>
/// 赛事Id
/// </summary>
public int Competitionid { get; set; }
/// <summary>
/// 当前已经骑行的距离(表示用户现在在的距离,并不是实际骑的距离)
/// </summary>
public double EndDistance { get; set; }
/// <summary>
/// 上次骑行的距离
/// </summary>
public double PreDistance { get; set; }
/// <summary>
/// 继续骑行记录标志
/// </summary>
public string ContinueMark { get; set; }
/// <summary>
/// 厂商Id
/// </summary>
public int ManufacturerId { get; set; }
public int? AntModelId { get; set; }
/// <summary>
/// 骑行数据
/// </summary>
public List<TargetData> RiderDatas = new List<TargetData>();
/// <summary>
/// 当前路线
/// </summary>
public Route CurrentRoute { get; set; }
/// <summary>
/// 骑行记录Id
/// </summary>
//public string RecordId { get; private set; }
/// <summary>
/// 设备号
/// </summary>
public string DeviceNumber { get; set; }
/// <summary>
/// 当前给骑行台发送数据的模式
/// </summary>
public SendDataMode SendDataMode { get; set; }
/// <summary>
/// 临时使用的坡度
/// </summary>
public double SlopeGrade { get; set; }
/// <summary>
/// 临时使用的海拔
/// </summary>
public double Elevation { get; set; }
/// <summary>
/// 当前路书开始的距离
/// </summary>
public double CurrentRouteStartDistance { get; set; }
public DateTime StartTime { get; set; }
/// <summary>
/// 是否已经保存成功
/// </summary>
public bool Saved { get; set; }
public int GlobalCyclingId { get; set; }
/// <summary>
/// 保存数据
/// </summary>
/// <param name="base64Image"></param>
/// <returns></returns>
public JsonResult<AddMapRecordResultModel> SaveData(CyclingModel cyclingModel, SelectParamModel selectParam, DateTime createTime, string base64Image = "")
{
if (RiderDatas.Count <= 0)
{
return new JsonResult<AddMapRecordResultModel> { result = true };
}
string newFileName = Guid.NewGuid().ToString();
int FTP = Helper.GetFtp();
double NP = Helper.GetNP(RiderDatas);
//强度
double IF = NP / FTP;
//训练量
double TSS = (RiderDatas.Count * NP * IF) / (FTP * 3600) * 100;
var averagePower = Helper.AveragePower(RiderDatas);
MapInterruptRecordApi service = new MapInterruptRecordApi();
//AntManufacturer manufacturer = service.GetAntManufacturer(ManufacturerId);
var recordId = Guid.NewGuid().ToString();
var interruptRecord = new MapInterruptRecord
{
Id = recordId,
RouteId = CurrentRoute.RouteInstance.Id,
RouteName = CurrentRoute.RouteInstance.Name,
TotalDistance = CurrentRoute.RouteInstance.Distance,
UserId = BelongUserId,
RecordFileName = newFileName + ".txt",
Ftp = FTP,//FTP设置
IF = Math.Round(IF, 2),
Kj = RiderDatas.Sum(a => a._Power) / 1000,//消耗
Tss = Math.Round(TSS, 2),
EndDistance = EndDistance,
IsCompleted = IsCompleted,
//TrainingTime = TimeHelper.FormatSeconds(RiderDatas.Last().Ticks),//训练时间
NormalizedPower = Math.Floor(NP),//标准化功率
AveragePower = averagePower,//平均功率
MaxPower = RiderDatas.Max(a => a._Power),//最大功率
WeightKg = Math.Round(averagePower / PubCommData.CurrentUser.Weight, 2),
Weight = PubCommData.CurrentUser.Weight,
BicycleWeight = PubCommData.CurrentUser.BicycleWeight,
ContinueMark = ContinueMark,
ContinueIndex = ContinueIndex,
IsDelete = false,
MapCompetitionId = Competitionid,
ManufacturerName = "TODO",//manufacturer == null ? "" : manufacturer.Name,
DeviceNumber = DeviceNumber,
IsRanking = IsNeedRanking,
CurrentRouteStartDistance = CurrentRouteStartDistance,
ManufacturerId = ManufacturerId,
AntModelId = AntModelId,
StartTime = StartTime,
CreateTime = createTime,
Ticks = RiderDatas.Last().Ticks,
Mode = cyclingModel.ToString(),
Param = Newtonsoft.Json.JsonConvert.SerializeObject(selectParam),
GlobalCyclingId = selectParam.GlobalCyclingId
};
//var range = new MapSpeedRange().GetSpeedRange(RiderDatas, CurrentRoute.RouteInstance.Distance);
interruptRecord.SpeedRange = null; //JsonConvert.SerializeObject(range);
double process = Math.Round((EndDistance - interruptRecord.CurrentRouteStartDistance) / CurrentRoute.RouteInstance.Distance, 2);
interruptRecord.Progress = process > 1 ? 1 : process;
var cadences = RiderDatas.Where(a => a._Cadence.HasValue && a._Cadence.Value > 0);
if (cadences.Any())
{
interruptRecord.AverageCadence = Math.Round(cadences.Average(a => a._Cadence.GetValueOrDefault(0)));
}
interruptRecord.MaxCadence = Math.Round(RiderDatas.Max(a => a._Cadence.GetValueOrDefault(0)));
interruptRecord.AverageHeartRate = Math.Round(RiderDatas.Average(a => a._HeartRate.GetValueOrDefault(0)));
interruptRecord.MaxHeartRate = RiderDatas.Max(a => a._HeartRate.GetValueOrDefault(0));
//service.CreateRecordCyclingData(interruptRecord);
var path = Helper.GetDataDire("MapWorkoutRecords");
var fname = path + "/" + newFileName + ".txt";
var files = new List<string>();
using (var fs = new FileInfo(fname).OpenWrite())
{
var stream = new StreamWriter(fs);
stream.BaseStream.Seek(0, SeekOrigin.End);
foreach (var item in RiderDatas)
{
stream.Write(item.Write() + "\r\n");
}
stream.Flush();
stream.Close();
files.Add(fname);
}
//TODO 截图
if (!string.IsNullOrEmpty(base64Image))
{
//var imageName = path + "/" + Guid.NewGuid().ToString() + ".png";
//base64Image = base64Image.Replace("data:image/png;base64,", "").Replace("data:image/jgp;base64,", "").Replace("data:image/jpg;base64,", "").Replace("data:image/jpeg;base64,", ""); ;
//byte[] image = Convert.FromBase64String(base64Image);
//using (MemoryStream ms = new MemoryStream(image))
//using (Image img = Image.FromStream(ms))
//{
// img.Save(imageName, System.Drawing.Imaging.ImageFormat.Png);
// //img.Dispose();
//}
//files.Add(imageName);
}
var result = service.Add(interruptRecord, files);
return new JsonResult<AddMapRecordResultModel> { result = result.result, errMsg = result.errMsg, data = result.data };
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 11c5f863a5d0baa49b7b374090197f99
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: fb74a9f48e6075b4098a071b7c41755b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assets.Scenes.Ride.Scripts.Model
{
public abstract class BaseRider
{
//internal static MapWorkoutService service = new MapWorkoutService();
public abstract RiderType riderType { get; }
/// <summary>
/// 用户Id
/// </summary>
public int UserId { get; set; }
public string InMapId
{
get
{
return this.riderType.ToString() + "-" + UserId;
}
}
/// <summary>
/// 用户姓名
/// </summary>
public string NickName { get; set; }
/// <summary>
/// 微信头像
/// </summary>
public string WxHeadImg { get; set; }
/// <summary>
/// 最后骑行的距离
/// </summary>
public double EndDistance { get; set; }
/// <summary>
/// 是否是当前登陆人
/// </summary>
public bool IsSelf
{
get
{
return this.UserId == PubCommData.CurrentUser.Id;
}
}
/// <summary>
/// 圆形头像
/// </summary>
public string CircHeadImg
{
get
{
return "";
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9a318f90ef1c36742a0ffa27baa04c98
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,60 @@
using GeoJSON.Net.Geometry;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assets.Scenes.Ride.Scripts.Model.RiderModels
{
public class OnlineRiderModel : BaseRider
{
public override RiderType riderType => RiderType.Online;
public double PreDistance { get; set; } = 0;
/// <summary>
///
/// </summary>
public GeographicPosition Point { get; set; }
public OutUser GetOutUser(double preDistance, double currentDistance, TurfHelper turfHelper, CyclingStateEnum cyclingState)
{
if (this.IsSelf)
{
var newRealUser = new OutUser()
{
NickName = this.NickName,
WxHeadImg = this.WxHeadImg,
UserId = this.UserId,
//targetData = targetData,
InMapId = this.InMapId,
PreDistance = preDistance,
NextDistance = currentDistance,
Point = turfHelper.Along(currentDistance),
};
if (cyclingState != CyclingStateEnum.Cycling)
{
newRealUser.NextDistance = preDistance;
}
return newRealUser;
}
else
{
var newRealUser = new OutUser()
{
NickName = this.NickName,
WxHeadImg = this.WxHeadImg,
UserId = this.UserId,
//targetData = targetData,
InMapId = this.InMapId,
PreDistance = this.PreDistance,
NextDistance = this.EndDistance,
Point = this.Point, //turfHelper.Along(this.EndDistance)
};
return newRealUser;
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 83879fd24afab69418f97cb56eaebda7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,55 @@
using GeoJSON.Net.Geometry;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assets.Scenes.Ride.Scripts.Model.RiderModels
{
/// <summary>
/// 骑行伴侣
/// </summary>
public class ReviewRiderModel : BaseRider
{
public override RiderType riderType => RiderType.Review;
public GeographicPosition Point { get; set; }
/// <summary>
/// 骑行记录数据
/// </summary>
public string[] record { get; set; }
public OutUser GetOutUser(int ticks, TurfHelper turfHelper)
{
var reviewer = this;
TargetData revierData = null;
if (ticks >= reviewer.record.Length)
{
revierData = TargetData.Read(reviewer.record[reviewer.record.Length - 1]);
}
else if (ticks > 0)
{
revierData = TargetData.Read(reviewer.record[ticks - 1]);
}
//(Ticks >= reviewer.record.Length ? TargetData.Read(reviewer.record[reviewer.record.Length - 1]) :
//TargetData.Read(reviewer.record[Ticks]));
var reivewPreDistance = ticks == 1 || ticks == 0 ? 0 :
(ticks >= reviewer.record.Length ? TargetData.Read(reviewer.record[reviewer.record.Length - 1])._Distance :
TargetData.Read(reviewer.record[ticks - 2])._Distance);
var result = new OutUser()
{
UserId = this.UserId,
//targetData = revierData,
InMapId = this.InMapId,
PreDistance = reivewPreDistance,
NextDistance = ticks == 0 ? 0 : revierData._Distance,
NickName = this.NickName,
WxHeadImg = this.WxHeadImg
};
result.Point = turfHelper.Along(result.NextDistance);
return result;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8d265479686613e418a745e888533ec5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,369 @@
using Assets.Scripts.Apis.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assets.Scenes.Ride.Scripts.Model
{
public class Route
{
/// <summary>
/// 路线实例
/// </summary>
public MapRoute RouteInstance { get; private set; }
/// <summary>
/// 从服务端获取的Json数据
/// </summary>
public MapDataModel JsonData { get; set; }
/// <summary>
/// 当前路书的排行榜信息
/// </summary>
public List<MapRecordRanking> RecordRankings { get; set; }
private List<double[]> _Point = null;
/// <summary>
/// 点位信息
/// </summary>
public List<double[]> Point
{
get
{
if (_Point == null)
{
_Point = JsonData.List.Select(n => n.Point.Reverse().ToArray()).ToList();
}
return _Point;
}
}
private List<double> _Elevation { get; set; }
/// <summary>
/// 海拔信息
/// </summary>
public List<double> Elevation
{
get
{
if (_Elevation == null)
{
_Elevation = JsonData.List.Select(n => n.Elevation).ToList();
}
return _Elevation;
}
}
private List<double> _SlopeGrade { get; set; }
/// <summary>
/// 坡度信息
/// </summary>
public List<double> SlopeGrade
{
get
{
if (_SlopeGrade == null)
{
//_SlopeGrade = CalPatch();
_SlopeGrade = JsonData.List.Select(d => d.Grade).ToList();
}
return _SlopeGrade;
}
}
private List<double> _StepDistance { get; set; }
/// <summary>
/// 每两点的距离
/// </summary>
public List<double> StepDistance
{
get
{
if (_StepDistance == null)
{
_StepDistance = JsonData.List.Select(n => n.Distance).ToList();
}
return _StepDistance;
}
}
public double? _TotalDistance { get; set; }
public double TotalDistance
{
get
{
if (_TotalDistance == null)
{
_TotalDistance = GetTotalDistance();
}
return (double)_TotalDistance;
}
}
/// <summary>
/// 每一小步到起点的距离
/// </summary>
private List<double> _StepToStartDistance;
public List<double> StepToStartDistance
{
get
{
if (_StepToStartDistance == null)
{
_StepToStartDistance = GetStepToStartDistance();
}
return _StepToStartDistance;
}
}
public Route(MapDataModel data)
{
JsonData = data;
}
public Route(MapDataModel data, MapRoute mapRoute)
{
RouteInstance = mapRoute;
JsonData = data;
}
/// <summary>
/// km
/// </summary>
/// <returns></returns>
public double GetTotalDistance()
{
var total = 0d;
for (int i = 0; i < JsonData.List.Count - 1; i++)
{
var current = JsonData.List[i];
var next = JsonData.List[i + 1];
total += TurfHelper.GetDistances(new double[] { current.Point[1], current.Point[0] }, new double[] { next.Point[1], next.Point[0] });
}
return total / 1000;
}
/// <summary>
/// 根据下标获取海拔
/// </summary>
/// <returns></returns>
public double GetElevationByIndex(int index)
{
if (index > this.Elevation.Count)
{
return this.Elevation.Last();
}
else
{
return this.Elevation[index];
}
}
/// <summary>
/// 根据下标获取距离的小段
/// </summary>
/// <returns></returns>
public double GetDistanceStepByIndex(int index)
{
if (index > this.StepDistance.Count)
{
return this.StepDistance.Last();
}
else
{
return this.StepDistance[index];
}
}
/// <summary>
/// 根据索引获取坡度
/// </summary>
/// <param name="index">索引</param>
/// <param name="average">是否需要平均坡度</param>
/// <returns></returns>
public double GetPatchByIndex(int index, bool average, double endDistance = 0, double cacheDistance = 5)
{
double slop = 0;
if (average)
{
//每一小段的距离
double step = GetDistanceStepByIndex(index);
//每一段到起点的距离
double stepToStart = GetStepToStartDistanceByIndex(index);
//当前骑行距离与前一段的绝对值之差
double absoluteValue = step - (stepToStart - endDistance);
//绝对值之差是否大于多少米,如果大于则返回原始坡度,如果小于则返回平均坡度
if (absoluteValue < cacheDistance && cacheDistance < step)
{
if (index >= this.SlopeGrade.Count - 1)
{
double slope = this.SlopeGrade.Last();
//if (slope > 10)
//{
// slop = 10;
//}
//else if (slope < -10)
//{
// slop = -10;
//}
//else
{
slop = slope / 2;
}
}
else
{
double slope = this.SlopeGrade[index];
//if (slope > 10)
//{
// slop = 10;
//}
//else if (slope < -10)
//{
// slop = -10;
//}
//else
{
slop = slope / 2;
}
}
}
}
else
{
if (index >= this.SlopeGrade.Count - 1)
{
slop = this.SlopeGrade.Last();
}
else
{
slop = this.SlopeGrade[index];
}
}
//if (slop > 10)
//{
// return 10;
//}
//if (slop < -10)
//{
// return -10;
//}
return slop;
}
/// <summary>
/// 根据距离获取点位下标
/// </summary>
/// <returns></returns>
public int GetStepIndex(double distance)
{
distance *= 1000;//将距离转化为米
var totalDistance = 0D;
var index = 0;
foreach (var item in this.StepDistance)
{
totalDistance += item;
if (totalDistance > distance)
{
return index;
}
index++;
}
if (distance > this.StepDistance[this.StepDistance.Count - 1])
{
return this.StepDistance.Count - 1;
}
return 0;
}
/// <summary>
/// 通过索引获取当前到起点的距离(单位m)
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public double GetStepToStartDistanceByIndex(int index)
{
if (index >= this.StepToStartDistance.Count - 1)
{
return this.StepToStartDistance.Last();
}
else
{
return this.StepToStartDistance[index];
}
}
/// <summary>
/// 计算每一段路程的斜率
/// </summary>
private List<double> CalPatch()
{
if (this.Elevation != null)
{
List<double> grade = new List<double>();
for (int i = 0; i < this.Point.Count - 1; i++)
{
var a = this.Elevation[i + 1] - this.Elevation[i];
if (a == 0)
{
grade.Add(0);
continue;
}
//勾股定理
var c = this.StepDistance[i];//如果车停了下来c为0
if (c == 0 && i > 0)
{
grade.Add(grade[grade.Count - 1]);
}
else
{
var b = Math.Sqrt(c * c - a * a);
if (b == 0)//如果b等于这就是垂直的墙壁
{
grade.Add(grade[grade.Count - 1]);
}
else
{
grade.Add(a / b * 100);
}
}
}
//检是否有NaN的值
for (int i = 0; i < grade.Count; i++)
{
if (double.IsNaN(grade[i]) && i != 0)
{
grade[i] = grade[i - 1];
}
else if (double.IsNaN(grade[i]) && i == 0)
{
grade[i] = 0;
}
}
return grade;
}
return null;
}
/// <summary>
/// 获取每一段到起点的距离
/// </summary>
/// <returns></returns>
private List<double> GetStepToStartDistance()
{
if (StepDistance != null)
{
List<double> stepToStartDis = new List<double>();
double start = 0;
for (int i = 0; i < StepDistance.Count; i++)
{
start += StepDistance[i];
stepToStartDis.Add(start);
}
return stepToStartDis;
}
return null;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9b4a6fa5405752242a577299e27df510
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assets.Scenes.Ride.Scripts.Model
{
public class SelectParamModel
{
/// <summary>
/// 在线用户ID跟骑选的用户
/// </summary>
public int OnlineUserId { get; set; }
/// <summary>
/// 继续骑行的标志
/// </summary>
public string ContinueMark { get; set; }
/// <summary>
/// 当前第几次骑行
/// </summary>
public int? ContinueIndex { get; set; }
/// <summary>
/// 路线Id
/// </summary>
public int RouteId { get; set; }
/// <summary>
/// 赛事Id
/// </summary>
public int CompetitionId { get; set; }
/// <summary>
/// 最后一次骑行的距离
/// </summary>
public double EndDistance { get; set; }
/// <summary>
/// 排名信息Id用于骑行回顾多人
/// </summary>
public List<string> RankingsId { get; set; }
///// <summary>
///// 是否为全球骑行的继续骑行
///// </summary>
//public bool GlobalContinue { get; set; }
public int GlobalCyclingId { get; set; }
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fab2eae6e723baa46ad8c972556f38c6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assets.Scenes.Ride.Scripts.Model
{
/// <summary>
/// 指标数据
/// </summary>
public class TargetData
{
public double _Power = 0d;
public double _Speed = 0;
/// <summary>
/// km
/// </summary>
public double _Distance { get; set; } = 0D;
public double? _Cadence = 0;
public int? _HeartRate = 0;
public int Ticks = 0;
/// <summary>
/// 纬度
/// </summary>
public double _Lat { get; set; } = 0d;
/// <summary>
/// 经度
/// </summary>
public double _Lon { get; set; } = 0d;
//public double _Bearing = 0d;
public TargetData Clone()
{
return (TargetData)MemberwiseClone();
}
public override string ToString()
{
return string.Format($"Ticks:{Ticks} Power:{_Power} Speed:{_Speed} Distance:{_Distance} Cadence:{_Cadence} HeartRate:{_HeartRate} Lat:{_Lat} Lon:{_Lon}");
}
public string Write()
{
return string.Format($"{ Ticks },{ _Power.ToString(CultureInfo.InvariantCulture) },{ _Speed.ToString(CultureInfo.InvariantCulture) },{ Math.Round(_Distance, 6).ToString(CultureInfo.InvariantCulture) },{ (_Cadence == null ? "" : _Cadence.Value.ToString(CultureInfo.InvariantCulture)) },{ (_HeartRate == null ? "null" : _HeartRate.Value.ToString(CultureInfo.InvariantCulture)) },{ Math.Round(_Lat, 6).ToString(CultureInfo.InvariantCulture) },{ Math.Round(_Lon, 6).ToString(CultureInfo.InvariantCulture) }");//,{_Bearing}
}
public static TargetData Read(string data)
{
string[] split = data.Split(',');
var target = new TargetData();
target.Ticks = int.Parse(split[0]);
target._Power = double.Parse(split[1]);
target._Speed = double.Parse(split[2]);
target._Distance = double.Parse(split[3]);
target._Cadence = double.Parse(split[4]);
if (!string.IsNullOrWhiteSpace(split[5]) && split[5] != "null")
{
target._HeartRate = int.Parse(split[5]);
}
if (split.Length > 6)
{
target._Lat = double.Parse(split[6]);
target._Lon = double.Parse(split[7]);
//target._Bearing = double.Parse(split[8]);
}
return target;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 79850d6cccee69445927e491750a500b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assets.Scenes.Ride.Scripts.Model
{
public class t_user
{
public int Id { get; set; }
public string Nickname { get; set; }
/// <summary>
/// 用户的性别值为1时是男性值为2时是女性值为0时是未知
/// </summary>
public int Sex { get; set; }
public int Unit { get; set; }
public double Weight { get; set; }
public int FTP { get; set; }
public int WheelDiameter { get; set; }
public string Phone { get; set; }
public string Email { get; set; }
public string Pass { get; set; }
public string OtherPlatforms { get; set; }
public string Country { get; set; }
public string Province { get; set; }
public string City { get; set; }
public string Area { get; set; }
public string WxHeadImg { get; set; }
public DateTime LastLoginTime { get; set; }
/// <summary>
/// 自动暂停
/// </summary>
public bool AutoPause { get; set; }
/// <summary>
/// 最大心率
/// </summary>
public int MaxHeartRate { get; set; }
public bool CanEditRoom { get; set; }
/// <summary>
/// 自行车重
/// </summary>
public double BicycleWeight { get; set; }
public string Contact { get; set; }
public string ContactPhone { get; set; }
public string ContactAddress { get; set; }
/// <summary>
/// 阻力灵敏度
/// </summary>
public int Sensitivity { get; set; }
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0d977fd7941debf4b90f950a8fd3c0a1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f0b6448d57a2ab249a67f66c160c8293
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,18 @@
using Assets.Scenes.Ride.Scripts.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assets.Scenes.Ride.Scripts.Network
{
interface IService
{
void Start(Action<List<ReceiveMsgModel>> action);
void Send(byte[] dgram, int bytes);
void Close();
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 04b976b21b69ff640956ca0574491797
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,367 @@
using Assets.Scenes.Ride.Scripts.Model;
using Assets.Scenes.Ride.Scripts.Network;
using Assets.Scripts;
using Assets.Scripts.Apis;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Assets.Scenes.Ride.Scripts
{
public class MapUDPService
{
private static IService _udpService;
//private static UdpClient udpClient;
//private static IPEndPoint iPEndPoint;
private static bool isExit = false;
//private static Task task = null;
//private static CancellationTokenSource cts { get; set; }
private static CancellationToken ct { get; set; }
//private static List<OnlineUser> onlineUsers { get; set; } = new List<OnlineUser>();
private static System.Timers.Timer heartbeat { get; set; }
public static bool Pause { get; set; } = false;
private static OnlineUserHelper _onlineUserHelper;
private static OnlineUserHelper onlineUserHelper
{
get
{
if (_onlineUserHelper == null)
{
_onlineUserHelper = new OnlineUserHelper();
}
return _onlineUserHelper;
}
}
private static DateTime LastActiveTime = DateTime.Now;
private static List<ReceiveMsgModel> msgs = new List<ReceiveMsgModel>();
/// <summary>
/// 初始化如果UDP服务未启动则会已没5秒一次不断尝试直到连接上为止,前端不需要考虑任何UDP连接的事情
/// </summary>
public static void Init()
{
try
{
//var ddd = new MapWorkoutService().GetRealOnlineUserInfo(new List<int> { 6 });
isExit = false;
Pause = false;
if (_udpService == null)
{
_udpService = new TcpService1();
_udpService.Start(list =>
{
LastActiveTime = DateTime.Now;
//onlineUserHelper.RemoveExceptionData(list);
msgs = list;
onlineUserHelper.SetOnlineUser(msgs);
});
heartbeat = new System.Timers.Timer();
heartbeat.Interval = 1000;
heartbeat.AutoReset = true;
heartbeat.Enabled = true;
heartbeat.Elapsed += Heartbeat_Elapsed;
}
}
catch (Exception e)
{
Trace.WriteLine("UDP:" + e.Message);
}
finally
{
//发送一条心跳包
//SendHeartbeat();
}
}
private static void Heartbeat_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
var now = DateTime.Now;
//超过一秒没有收到消息
if ((now - LastActiveTime).TotalSeconds > 1)
{
onlineUserHelper.SetOnlineUser(new List<ReceiveMsgModel>());
}
if (now.Second % 20 == 0)
{
//LastActiveTime = now;
SendHeartbeat();
}
}
/// <summary>
/// 发送心跳包
/// </summary>
private static void SendHeartbeat()
{
Send(0, PubCommData.CurrentUser.Id, new double[] { 0, 0 }, false, false, 0, true, 0);
}
/// <summary>
/// 发送数据
/// </summary>
/// <param name="RouteId">路书Id</param>
/// <param name="MemberId">用户id</param>
/// <param name="Point">当前点位</param>
/// <param name="prop">属性</param>
/// <param name="IsCompleted">是否完成</param>
/// <param name="exit">是否退出</param>
public static void Send(int RouteId, int MemberId, double[] Point, bool IsCompleted = false, bool exit = false,
double endDistance = 0, bool showVirtual = false, byte commandType = 1, double speed = 0, bool isVirtual = false, double preDistance = 0,
double weightKg = 0, int competitionId = 0, bool saved = false)
{
try
{
var model = new MsgModel
{
RouteId = RouteId,
MemberId = MemberId,
Point = Point,
IsCompleted = IsCompleted,
exit = exit,
EndDistance = endDistance,
//ShowVirtual = showVirtual,
CommandType = commandType,
Speed = speed,
//IsVirtual = isVirtual,
PreDistance = preDistance,
WeightKg = weightKg,
Competitionid = competitionId,
Saved = saved,
V = 1
};
var sendBytes = Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(model));
_udpService.Send(sendBytes, sendBytes.Length);
}
catch (Exception e)
{
Console.WriteLine("发送失败:" + e);
}
}
public static void Dispose()
{
try
{
isExit = true;
if (MapUDPService._udpService == null) return;
for (int i = 0; i < 3; i++)
{
Send(0, PubCommData.CurrentUser.Id, new double[] { 1, 1 }, true, isExit);
}
_udpService.Close();
//task.Dispose();
_udpService = null;
_onlineUserHelper = null;
}
catch (Exception)
{
}
finally
{
//停止计时
if (heartbeat != null)
{
heartbeat.Stop();
heartbeat.Close();
}
}
}
public static OnlineUser GetOnlineUserLastDataById(int userId)
{
//return _onlineUserHelper.GetOnlineUserLastDataById(userId);
//var msg = msgs.Where(m => m.MemberId == userId);
//if (msg == null) return null;
return onlineUserHelper.OnlineUsers.FirstOrDefault(u => u.Id == userId);
}
/// <summary>
/// 根据路书获取在线用户
/// </summary>
/// <param name="routeId"></param>
/// <returns></returns>
public static List<OnlineUser> GetOnlineUsers(params int[] routeId)
{
//return onlineUsers.Where(n => routeId.Contains(n.RouteId)).ToList();
var result = onlineUserHelper.OnlineUsers.Where(u => routeId.Contains(u.RouteId)).ToList();
return result;
}
/// <summary>
/// 获取附近的人(当前在线的所有人)
/// </summary>
/// <returns></returns>
public static object GetNearRiderData(int pageIndex, int pageSize = 5, double[] point = null)
{
if (point == null) return null;
var dict = new List<System.Tuple<double, OnlineUser>>();
var allOnlineUsers = onlineUserHelper.OnlineUsers;
foreach (var item in allOnlineUsers)
{
if (item.Id == PubCommData.CurrentUser.Id)
{
dict.Add(new Tuple<double, OnlineUser>(0, item));
continue;
}
if (item.Point[0] != 0 && item.Point[1] != 0)
{
var distance = Math.Round(TurfHelper.GetDistances(point, item.Point) / 1000, 2);
dict.Add(new Tuple<double, OnlineUser>(distance, item));
}
}
var allList = dict.OrderBy(d => d.Item1);//.Select(d=>d.Item2);
var list = allList.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
var nearData = list.Select(n => new NearRiderModel()
{
Headimage = n.Item2.HeadImage,
Name = n.Item2.Name,
Near = n.Item1, //Math.Round(TurfHelper.GetDistances(point, n.Point) / 1000, 2),
KGWeight = n.Item2.WeightKg.ToString(),
Speed = Math.Round(n.Item2.Speed, 1),
CountryImg = ConfigHelper.Host + $"User/GetCountryImg?userid={n.Item2.Id}",
IsSelf = n.Item2.IsSelf
});
return new
{
NearData = nearData,
PageCount = (int)Math.Ceiling((double)allList.Count() / pageSize)
};
}
private class OnlineUserHelper
{
//public static List<OnlineUser> users { get; private set; }
private static readonly object locker = new object();
private readonly List<OnlineUser> onlineUsers = new List<OnlineUser>();
public List<OnlineUser> OnlineUsers
{
get
{
//if((DateTime.Now - LastActiveTime).TotalSeconds > 1)
//{
// SetOnlineUser(new List<ReceiveMsgModel>());
//}
return onlineUsers.ToList();
}
}
/// <summary>
/// 设置在线的人员
/// </summary>
public void SetOnlineUser(List<ReceiveMsgModel> mes)
{
try
{
var msgs = RemoveExceptionData(mes);
//LastActiveTime = DateTime.Now;
var ids = msgs.Where(m => onlineUsers.All(u => u.Id != m.MemberId)).Select(m => m.MemberId);
if (ids.Any())
{
MapApi api = new MapApi();
var rangeUser = api.GetOnlineUserInfo(ids).data;
onlineUsers.AddRange(rangeUser);
}
foreach (var user in onlineUsers)
{
var item = msgs.FirstOrDefault(u => u.MemberId == user.Id);
if (item != null)
{
user.LastActiveTime = DateTime.Now;
user.RouteId = item.RouteId;
user.Point = item.Point;
user.IsCompleted = item.IsCompleted;
//user.exit = item.exit;
user.EndDistance = item.EndDistance;
user.IsVirtual = item.MemberId < 0;
user.Speed = item.Speed;
user.WeightKg = item.WeightKg;
user.PreDistance = item.PreDistance;
user.CompetitionId = item.Competitionid;
user.Saved = item.Saved;
}
else
{
user.PreDistance = user.EndDistance;
}
}
onlineUsers.RemoveAll(u => u.IsLost);
}
catch (Exception)
{
#if DEBUG
throw;
#endif
//return new List<OnlineUser>();
}
}
/// <summary>
/// 去除重复数据去除坐标为0的数据
/// </summary>
/// <param name="mes"></param>
private List<ReceiveMsgModel> RemoveExceptionData(List<ReceiveMsgModel> mes)
{
var list = mes.ToList();
//去除自己的数据和命令包
//mes.RemoveAll(item => item.MemberId == PubCommData.CurrentUser.Id || item.Point[0] == 0);
list.RemoveAll(item => item.Point[0] == 0 && item.Point[1] == 0);
//去除重复数据
list = list.Distinct(new OlineUserComparer()).ToList();
return list;
}
public class NearUserComparer : IEqualityComparer<NearRiderModel>
{
public bool Equals(NearRiderModel x, NearRiderModel y)
{
if (x == null)
return y == null;
return x.Name == y.Name;
}
public int GetHashCode(NearRiderModel obj)
{
if (obj == null)
return 0;
return obj.Name.GetHashCode();
}
}
public class OlineUserComparer : IEqualityComparer<ReceiveMsgModel>
{
public bool Equals(ReceiveMsgModel x, ReceiveMsgModel y)
{
if (x == null)
return y == null;
return x.MemberId == y.MemberId;
}
public int GetHashCode(ReceiveMsgModel obj)
{
if (obj == null)
return 0;
return obj.MemberId.GetHashCode();
}
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f01b9ae72517c36488f04fdbbb889f71
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,123 @@
using Assets.Scenes.Ride.Scripts.Model;
using Assets.Scripts;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Assets.Scenes.Ride.Scripts.Network
{
public class TcpService1 : IService
{
private bool isExit = false;
private PfTcpClient _tcpClient;
private IPEndPoint iPEndPoint;
//private Action<List<ReceiveMsgModel>> _action;
public void Start(Action<List<ReceiveMsgModel>> action)
{
if (_tcpClient == null)
{
//if (!IPAddress.TryParse(ConfigHelper.ServerIpAdress, out var ipString))
//{
// throw new ArgumentException("IP地址不正确");
//}
//服务端端口
iPEndPoint = ConfigHelper.TcpAddress;
_tcpClient = new PfTcpClient(iPEndPoint.Address.ToString(), 11001, action);
_tcpClient.OptionNoDelay = true;
//_action = action;
_tcpClient.ConnectAsync();
}
}
public void Send(byte[] dgram, int bytes)
{
if (_tcpClient == null) return;
if (_tcpClient.IsConnected == false) return;
//_tcpClient.WriteLine(System.Text.Encoding.ASCII.GetString(dgram));
var txt = System.Text.Encoding.ASCII.GetString(dgram);
//Debug.WriteLine("发送:"+txt);
_tcpClient.Send(txt);
}
public void Close()
{
isExit = true;
_tcpClient.DisconnectAndStop();
_tcpClient = null;
}
class PfTcpClient : NetCoreServer.TcpClient
{
private bool _stop;
Action<List<ReceiveMsgModel>> _action;
public PfTcpClient(string address, int port, Action<List<ReceiveMsgModel>> action) : base(address, port)
{
_action = action;
}
public void DisconnectAndStop()
{
_stop = true;
DisconnectAsync();
while (IsConnected)
{
Thread.Yield();
}
}
protected override void OnConnected()
{
base.OnConnected();
}
protected override void OnDisconnected()
{
//base.OnDisconnected();
Debug.WriteLine("tcp断线3秒后重连");
Thread.Sleep(3000);
if (!_stop)
{
ConnectAsync();
}
}
protected override void OnReceived(byte[] buffer, long offset, long size)
{
//base.OnReceived(buffer, offset, size);
var returnData = Encoding.UTF8.GetString(buffer, (int)offset, (int)size);
//Debug.WriteLine("收到:" + returnData+"\r\n");
//System.IO.File.AppendAllText(System.Environment.CurrentDirectory + "接收到的数据.txt", returnData.Trim().Replace("\0", "")+"\r\n", Encoding.UTF8);
var list = new List<ReceiveMsgModel>();
var itemList = returnData.Split('|');
foreach (var item in itemList)
{
var info = ReceiveMsgModel.Parse(item);
if (info != null)
{
list.Add(info);
}
}
_action(list);
}
protected override void OnError(SocketError error)
{
//base.OnError(error);
Debug.WriteLine(error);
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7d27070ad7cfef3418e8f764a42c08a7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,94 @@
using Assets.Scenes.Ride.Scripts.Model;
using Assets.Scripts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace Assets.Scenes.Ride.Scripts.Network
{
public class UdpService : IService
{
private bool isExit = false;
private UdpClient udpClient;
private IPEndPoint iPEndPoint;
public void Start(Action<List<ReceiveMsgModel>> action)
{
if (udpClient == null)
{
//if (!IPAddress.TryParse(ConfigHelper.ServerIpAdress, out var ipString))
//{
// throw new ArgumentException("IP地址不正确");
//}
//服务端端口
iPEndPoint = ConfigHelper.UdpAddress;
udpClient = new UdpClient();
uint IOC_IN = 0x80000000;
uint IOC_VENDOR = 0x18000000;
uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
udpClient.Client.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null);
udpClient.Client.ReceiveTimeout = 5000;//这里如果不设置超时,会导致整个应用程序阻塞。
udpClient.Client.SendTimeout = 5000;
udpClient.Connect(iPEndPoint);
//heartbeat = new System.Timers.Timer();
//heartbeat.Interval = 1000;//20秒一次心跳包
//heartbeat.AutoReset = true;
//heartbeat.Enabled = true;
//heartbeat.Elapsed += Heartbeat_Elapsed;
Task.Run(async () =>
{
while (isExit == false)
{
try
{
byte[] receiveBytes = udpClient.Receive(ref iPEndPoint);
var returnData = Encoding.ASCII.GetString(receiveBytes);
var list = new List<ReceiveMsgModel>();
var itemList = returnData.Split('|');
foreach (var item in itemList)
{
var info = ReceiveMsgModel.Parse(item);
if (info != null)
{
list.Add(info);
}
}
action(list);
}
catch (SocketException ex)
{
await Task.Delay(6000);
if (isExit == false && udpClient != null)
{
udpClient.Connect(iPEndPoint);
}
}
catch (Exception ex)
{
}
}
});
}
}
public void Send(byte[] dgram, int bytes)
{
udpClient?.Send(dgram, bytes);
}
public void Close()
{
isExit = true;
udpClient?.Close();
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 170d4696cbfb82743a9189608d3a162a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,184 @@
using System.Collections;
using UnityEngine;
using Mapbox.Unity.Map;
using Mapbox.Utils;
using Assets.Scripts.Apis.Models;
using static Assets.Scripts.Apis.Models.MapDataModel;
using System;
using Random = UnityEngine.Random;
using Assets.Scripts.Apis;
using GeoJSON.Net.Geometry;
using TurfCS;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Globalization;
namespace Assets.Scenes.Ride.Scripts
{
public class OtherPlayerController : MonoBehaviour
{
[Header("Character")]
[SerializeField]
GameObject character;
[SerializeField]
Animator characterAnimator;
AbstractMap map;
#region
Vector3 nextPos;
Vector3 prePos;
Vector2d currentlatlong; //当前坐标
Vector2d nextlatlong; //下一个点的坐标
float timer = 1.0f;//计时器
#endregion
#region
bool isStart;
bool isMajor;//是否是主人公
MapDataModel mapData;
int userId;
DateTime startTime;//开始骑行时间
double speed;
double power;
double gradev;
double elevation;
double cadance;
double heartRate;
int ticks;
double totalDistance;
double currentSlope;
double nextSlope;
double nextSlopeDistance;
double distance;
public int UserId { get => userId; }
public bool IsStart { get => isStart; }
public double Speed { get => speed; }
public double Power { get => power; }
public double Cadance { get => cadance; }
public double HeartRate { get => heartRate; }
public int TotalTicks { get => ticks; }
public double TotalDistance { get => totalDistance; }
public double CurrentSlope { get => currentSlope; }
public double NextSlope { get => nextSlope; }
public double NextSlopeDistance { get => nextSlopeDistance; }
public double Gradev { get => gradev; }
public double Elevation { get => elevation; }
#endregion
void Start()
{
characterAnimator = GetComponentInChildren<Animator>();
var mainController = transform.parent.GetComponent<CyclingController>();
map = FindObjectOfType<AbstractMap>();
mapData = mainController.GetMapData();//获取路书信息
isStart = true;
}
void Update()
{
timer -= Time.deltaTime;
if (timer <= 0)//定时器 一秒执行一次
{
Run();
timer = 1.0f;
}
}
#region
//骑行中
void Run()
{
if (IsStart)
{
power = 900;//功率
speed = Helper.CalculateSpeed(elevation, 0, power, 65, 7);
distance = Math.Round(speed / 3600, 6);
totalDistance += distance;
characterAnimator.SetBool("IsRide", false);//初始化动画状态
if (totalDistance <= mapData.TotalDistance)
{
//数据处理
ticks++;
nextlatlong = Along(totalDistance);//下一个坐标
nextPos = map.GeoToWorldPosition(nextlatlong);//下一个点
nextPos.y += 0.3f;
prePos = transform.localPosition;//当前点
//动画控制
if (distance > 0)
{
characterAnimator.SetBool("IsRide", true);//开始移动动画
StartCoroutine(LookAtNextPos());//转向
StartCoroutine(MoveTo());//移动
}
}
else
{
//TODO保存骑行数据
characterAnimator.SetBool("ReachEnd", true);
}
}
else
{
characterAnimator.SetBool("IsRide", false);
}
}
#endregion
#region
public int CurrentIndex;
//根据距离计算坐标
Vector2d Along(double endDistance)
{
if (mapData != null)
{
var list = mapData.List.Select(p => new GeoJSON.Net.Geometry.GeographicPosition(p.Point[0], p.Point[1]));
LineString lineString = new LineString(list);
var pt1 = Turf.Along(lineString, endDistance);
var ll = ((GeographicPosition)((GeoJSON.Net.Geometry.Point)pt1.Geometry).Coordinates);
return new Vector2d(ll.Latitude, ll.Longitude);
}
return nextlatlong;
}
#endregion
#region
IEnumerator LookAtNextPos()
{
Quaternion neededRotation = Quaternion.LookRotation(transform.localPosition - nextPos);
Quaternion thisRotation = character.transform.localRotation;
float t = 0;
while (t < 1.0f)
{
t += Time.deltaTime / 0.25f;
var rotationValue = Quaternion.Slerp(thisRotation, neededRotation, t);
character.transform.rotation = Quaternion.Euler(0, rotationValue.eulerAngles.y, 0);
yield return null;
}
}
//人物移动控制
IEnumerator MoveTo()
{
//让人物移动分点增加动画的流畅度
float t = 0;
while (t < 1)
{
t += Time.deltaTime;
Vector3 v = Vector3.Lerp(prePos, nextPos, t);
transform.localPosition = v;
//控制海拔图的位置
yield return null;
}
}
#endregion
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cf37eca46d898384fa2d9e17dfa3e25e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -13,6 +13,9 @@ using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Globalization;
using Assets.Scenes.Ride.Scripts.Model;
using static CyclingController;
using System.IO;
namespace Assets.Scenes.Ride.Scripts
{
@ -36,8 +39,10 @@ namespace Assets.Scenes.Ride.Scripts
#region
bool isStart;
bool isMajor;//是否是主人公
MapDataModel mapData;
int userId;
int routeId;
DateTime startTime;//开始骑行时间
double speed;
@ -45,7 +50,7 @@ namespace Assets.Scenes.Ride.Scripts
double gradev;
double elevation;
double cadance;
double heartRate;
int heartRate;
int ticks;
double totalDistance;
double currentSlope;
@ -71,10 +76,11 @@ namespace Assets.Scenes.Ride.Scripts
void Start()
{
characterAnimator = GetComponentInChildren<Animator>();
var mainController = transform.parent.GetComponent<MainController>();
var mainController = transform.parent.GetComponent<CyclingController>();
map = FindObjectOfType<AbstractMap>();
mapData = mainController.GetMapData();//获取路书信息
InitializePlayer(mainController.GetCenterCoordinate());//初始人物
routeId = mainController.RouteId;//路数id
Initialize(mainController.GetCenterCoordinate());//初始人物
}
void Update()
@ -87,7 +93,7 @@ namespace Assets.Scenes.Ride.Scripts
}
}
#region
#region
//开始骑行
public void SetStart()
{
@ -103,10 +109,14 @@ namespace Assets.Scenes.Ride.Scripts
public void SetPause()
{
isStart = false;
Complete();
}
#endregion
#region
//初始化玩家距离/朝向
void InitializePlayer(double[] coordinates)
void Initialize(double[] coordinates)
{
ticks = 0;//当前骑行时间
//初始化人物位置
@ -119,7 +129,8 @@ namespace Assets.Scenes.Ride.Scripts
//Quaternion firstRotation = Quaternion.LookRotation(transform.localPosition - secondVect3d);
//character.transform.rotation = Quaternion.Euler(0, firstRotation.eulerAngles.y, 0);
}
StringBuilder sb = new StringBuilder();
public List<TargetData> RiderDatas = new List<TargetData>();
//骑行中
void Run()
{
@ -131,6 +142,7 @@ namespace Assets.Scenes.Ride.Scripts
speed = Helper.CalculateSpeed(elevation, 0, power, 65, 7);
distance = Math.Round(speed / 3600, 6);
totalDistance += distance;
characterAnimator.SetBool("IsRide", false);//初始化动画状态
if (totalDistance <= mapData.TotalDistance)
{
@ -143,7 +155,18 @@ namespace Assets.Scenes.Ride.Scripts
//记录骑行数据
var recordText = string.Format($"{ ticks },{ power.ToString(CultureInfo.InvariantCulture) },{ speed.ToString(CultureInfo.InvariantCulture) },{ Math.Round(totalDistance, 6).ToString(CultureInfo.InvariantCulture) },{ cadance.ToString(CultureInfo.InvariantCulture) },{ heartRate.ToString(CultureInfo.InvariantCulture) },{ Math.Round(nextlatlong.x, 6).ToString(CultureInfo.InvariantCulture) },{ Math.Round(nextlatlong.y, 6).ToString(CultureInfo.InvariantCulture) }");
Debug.Log(recordText);
sb.AppendLine(recordText);
RiderDatas.Add(new TargetData
{
Ticks = ticks,
_Power = power,
_Speed = speed,
_Distance = totalDistance,
_Cadence = cadance,
_HeartRate = heartRate,
_Lat = nextlatlong.x,
_Lon = nextlatlong.y
});
//动画控制
if (distance > 0)
@ -155,7 +178,23 @@ namespace Assets.Scenes.Ride.Scripts
}
else
{
//TODO保存骑行数据
totalDistance = mapData.TotalDistance;
//记录骑行数据
var recordText = string.Format($"{ ticks },{ power.ToString(CultureInfo.InvariantCulture) },{ speed.ToString(CultureInfo.InvariantCulture) },{ Math.Round(totalDistance, 6).ToString(CultureInfo.InvariantCulture) },{ cadance.ToString(CultureInfo.InvariantCulture) },{ heartRate.ToString(CultureInfo.InvariantCulture) },{ Math.Round(nextlatlong.x, 6).ToString(CultureInfo.InvariantCulture) },{ Math.Round(nextlatlong.y, 6).ToString(CultureInfo.InvariantCulture) }");
Debug.Log(recordText);
RiderDatas.Add(new TargetData
{
Ticks = ticks,
_Power = power,
_Speed = speed,
_Distance = totalDistance,
_Cadence = cadance,
_HeartRate = heartRate,
_Lat = nextlatlong.x,
_Lon = nextlatlong.y
});
Complete();
isStart = false;
characterAnimator.SetBool("ReachEnd", true);
}
}
@ -164,64 +203,102 @@ namespace Assets.Scenes.Ride.Scripts
characterAnimator.SetBool("IsRide", false);
}
}
//发送当前用户位置给UDPs
void SendUdp() {
}
//TODO骑行结束
void Finish()
private int weight = 65;
private int bicycleWeight = 7;
private string ContinueMark = "TODO";
private int ContinueIndex=0;
private int Competitionid =0;
private bool IsNeedRanking = true;
private double CurrentRouteStartDistance = 0;
private int ManufacturerId=0;
private int AntModelId =0 ;
private CyclingModel cyclingModel = CyclingModel.Single;
private DateTime EndTime;
void Complete()
{
//上传文件
//var path = FileHelper.GetDataDire("MapWorkoutRecords");
//var fname = path + "/" + newFileName + ".txt";
//var files = new List<string>();
EndTime = startTime.AddSeconds(ticks);
MapInterruptRecordApi api = new MapInterruptRecordApi();
int FTP = 200;
double NP = 0;
string id = Guid.NewGuid().ToString();
string newFileName = Guid.NewGuid().ToString();
int FTP = Helper.GetFtp();
double NP = Helper.GetNP(RiderDatas);
//强度
double IF = NP / FTP;
var mapRecord = new MapInterruptRecord
//训练量
double TSS = (RiderDatas.Count * NP * IF) / (FTP * 3600) * 100;
var recordId = Guid.NewGuid().ToString();
var averagePower = Helper.AveragePower(RiderDatas);
var interruptRecord = new MapInterruptRecord
{
Id = id,
RouteId = 5946,
EndDistance = totalDistance,
RouteImage = "",
RecordFileName = "",
CreateTime = DateTime.Now,//骑行结束时间
IsCompleted = true,
TotalDistance = totalDistance,
Id = recordId,
RouteId = routeId,
RouteName = "",
TotalDistance = mapData.TotalDistance,
UserId = userId,
Ftp = 200,
IF = IF,
Kj = 0,
Tss = 0,
NormalizedPower = Math.Round(NP, 0),
AveragePower = 0,
MaxPower = 0,
Ticks = ticks,
AverageCadence = 0,
MaxCadence = 0,
AverageHeartRate = 0,
MaxHeartRate =0,
Progress = 1,
ContinueMark = "",
ContinueIndex = 0,
RecordFileName = newFileName + ".txt",
Ftp = FTP,//FTP设置
IF = Math.Round(IF, 2),
Kj = RiderDatas.Sum(a => a._Power) / 1000,//消耗
Tss = Math.Round(TSS, 2),
EndDistance = totalDistance,
IsCompleted = totalDistance >= mapData.TotalDistance,
NormalizedPower = Math.Floor(NP),//标准化功率
AveragePower = averagePower,//平均功率
MaxPower = RiderDatas.Max(a => a._Power),//最大功率
WeightKg = Math.Round(averagePower / weight, 2),
Weight = weight,
BicycleWeight = bicycleWeight,
ContinueMark = ContinueMark,
ContinueIndex = ContinueIndex,
IsDelete = false,
MapCompetitionId = 0,
CurrentRouteStartDistance = 0,
StartTime = DateTime.Now,
WeightKg = 0,
Weight = 0,
BicycleWeight = 0,
Mode = "Single",
Param = "",
DeviceNumber = "",
ManufacturerId = 0,
ManufacturerName ="",
MapCompetitionId = Competitionid,
ManufacturerName = "TODO",
DeviceNumber = "TODO",
IsRanking = IsNeedRanking,
CurrentRouteStartDistance = CurrentRouteStartDistance,
ManufacturerId = ManufacturerId,
AntModelId = AntModelId,
StartTime = startTime,
CreateTime = EndTime,
Ticks = RiderDatas.Last().Ticks,
Mode = cyclingModel.ToString(),
//Param = Newtonsoft.Json.JsonConvert.SerializeObject(selectParam),
//GlobalCyclingId = selectParam.GlobalCyclingId
};
interruptRecord.SpeedRange = null;
double process = Math.Round((totalDistance - interruptRecord.CurrentRouteStartDistance) /mapData.TotalDistance, 2);
interruptRecord.Progress = process > 1 ? 1 : process;
api.Add(mapRecord, null);
var cadences = RiderDatas.Where(a => a._Cadence.HasValue && a._Cadence.Value > 0);
if (cadences.Any())
{
interruptRecord.AverageCadence = Math.Round(cadences.Average(a => a._Cadence.GetValueOrDefault(0)));
}
interruptRecord.MaxCadence = Math.Round(RiderDatas.Max(a => a._Cadence.GetValueOrDefault(0)));
interruptRecord.AverageHeartRate = Math.Round(RiderDatas.Average(a => a._HeartRate.GetValueOrDefault(0)));
interruptRecord.MaxHeartRate = RiderDatas.Max(a => a._HeartRate.GetValueOrDefault(0));
var path = Helper.GetDataDire("MapWorkoutRecords");
var fname = path + "/" + newFileName + ".txt";
var files = new List<string>();
using (var fs = new FileInfo(fname).OpenWrite())
{
var stream = new StreamWriter(fs);
stream.BaseStream.Seek(0, SeekOrigin.End);
foreach (var item in RiderDatas)
{
stream.Write(item.Write() + "\r\n");
}
stream.Flush();
stream.Close();
files.Add(fname);
}
var result = api.Add(interruptRecord, files);
}
#endregion

View File

@ -0,0 +1,29 @@
using Assets.Scenes.Ride.Scripts.Model;
public class PubCommData
{
public static t_user CurrentUser;
public static int PlanId;//当前训练id
public static string sp = "";
public static string po = "";
public static string SearchKeyword = "";
/// <summary>
/// lat lng
/// </summary>
public static double[] location;
/// <summary>
/// 当前位置
/// </summary>
public static string Address;
public static double routeDistance;
/// <summary>
/// en,zh-CN
/// </summary>
public static string Lauguage = "";
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e19a9a72e39c8da4489a110f68ff2dc1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -27,7 +27,7 @@ namespace Assets.Scenes.Ride.Scripts
GameObject _directionsGO;
GameObject _mipMapRoute;
MainController mainCotroller;
CyclingController cyclingCotroller;
protected virtual void Awake()
{
@ -42,7 +42,7 @@ namespace Assets.Scenes.Ride.Scripts
public void Start()
{
mainCotroller = transform.parent.GetComponent<MainController>();
cyclingCotroller = transform.parent.GetComponent<CyclingController>();
StartCoroutine(QueryTimer());
//CreateRoute();
}
@ -70,7 +70,7 @@ namespace Assets.Scenes.Ride.Scripts
var meshData = new MeshData();
var dat = new List<Vector3>();
var mapData = mainCotroller.GetMapData();
var mapData = cyclingCotroller.GetMapData();
if (mapData != null)
{
foreach (var mapDataItem in mapData.List)

View File

@ -0,0 +1,230 @@
using GeoJSON.Net.Geometry;
using System;
using System.Collections.Generic;
using System.Linq;
using TurfCS;
namespace Assets.Scenes.Ride.Scripts
{
public class TurfHelper
{
//static TurfHelper()
//{
// string name = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name + ".Resources.turf.min.js";
// System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
//}
private LineString _line;
/// <summary>
///
/// </summary>
/// <param name="points">坐标(lat,lon)</param>
public TurfHelper(IEnumerable<double[]> points)
{
//var list = new GeoJSON.Net.Geometry.GeographicPosition();
var list = points.Select(p => new GeoJSON.Net.Geometry.GeographicPosition(p[0], p[1]));
_line = new LineString(list);
}
/// <summary>
///
/// </summary>
/// <param name="distance">km</param>
public GeographicPosition Along(double distance)
{
var pt1 = Turf.Along(_line, distance);
return ((GeographicPosition)((GeoJSON.Net.Geometry.Point)pt1.Geometry).Coordinates);
}
public double Bearing(double[] p1, double[] p2)
{
var pt1 = Turf.Point(p1);
var pt2 = Turf.Point(p2);
return Turf.Bearing(pt1, pt2);
}
/// <summary>
/// 获取两个点的距离m
/// </summary>
/// <param name="from"></param>
/// <param name="to"></param>
/// <returns></returns>
public static double GetDistances(double[] from, double[] to)
{
var pt1 = Turf.Point(from);
var pt2 = Turf.Point(to);
var value = Turf.Distance(pt1, pt2, "kilometers") * 1000;
return Math.Round(value, 2);
}
/// <summary>
///
/// https://gist.github.com/neilkennedy/9227665
/// </summary>
/// <param name="neLng"></param>
/// <param name="neLat"></param>
/// <param name="swLng"></param>
/// <param name="swLat">SouthWest</param>
/// <param name="point">lon,lat</param>
/// <returns></returns>
public static bool Inside(double neLng, double neLat, double swLng, double swLat, double[] point)
{
var poly = Turf.BboxPolygon(new List<double>() { neLng, neLat, swLng, swLat });
var ptIn = Turf.Point(point);
return Turf.Inside(ptIn, poly);
}
///// <summary>
/////
///// </summary>
///// <param name="bottomLeft">lng, lat</param>
///// <param name="bottomRight"></param>
///// <param name="topRight"></param>
///// <param name="topLeft"></param>
///// <param name="point"></param>
///// <returns></returns>
//public static bool Inside(List<double[]> points, double[] point)
//{
// var script = new StringBuilder("var points = [];");
// foreach (var item in points)
// {
// script.AppendLine($"points.push([{ string.Join(",", item) }]);");
// }
// script.AppendLine($"points.push([{ string.Join(",", points.First()) }]);");
// script.AppendLine("var poly = turf.polygon([points]);");
// script.AppendLine($"turf.booleanPointInPolygon([{ string.Join(",", point) }], poly);");
// var result = (bool)engine.Evaluate(script.ToString());
// return result;
//}
public class location
{
public double lat;
public double lng;
}
/// <summary>
/// 坐标点是否在多边形内判断
/// https://www.cnblogs.com/yushuo/p/9304471.html
/// </summary>
/// <param name="point"></param>
/// <param name="pts"></param>
/// <returns></returns>
public static bool isPointInPolygon(location point, List<location> pts)
{
//检查类型
if (point == null || pts == null)
return false;
var N = pts.Count;
var boundOrVertex = true; //如果点位于多边形的顶点或边上也算做点在多边形内直接返回true
var intersectCount = 0; //cross points count of x
var precision = 2e-10; //浮点类型计算时候与0比较时候的容差
location p1, p2; //neighbour bound vertices
var p = point; //测试点
p1 = pts[0]; //left vertex
for (var i = 1; i <= N; ++i)
{
//check all rays
if (p.lat.Equals(p1.lat) && p.lng.Equals(p1.lng))
{
return boundOrVertex; //p is an vertex
}
p2 = pts[i % N]; //right vertex
if (p.lat < Math.Min(p1.lat, p2.lat) || p.lat > Math.Max(p1.lat, p2.lat))
{
//ray is outside of our interests
p1 = p2;
continue; //next ray left point
}
if (p.lat > Math.Min(p1.lat, p2.lat) && p.lat < Math.Max(p1.lat, p2.lat))
{
//ray is crossing over by the algorithm (common part of)
if (p.lng <= Math.Max(p1.lng, p2.lng))
{
//x is before of ray
if (p1.lat == p2.lat && p.lng >= Math.Min(p1.lng, p2.lng))
{
//overlies on a horizontal ray
return boundOrVertex;
}
if (p1.lng == p2.lng)
{
//ray is vertical
if (p1.lng == p.lng)
{
//overlies on a vertical ray
return boundOrVertex;
}
else
{
//before ray
++intersectCount;
}
}
else
{
//cross point on the left side
var xinters =
(p.lat - p1.lat) * (p2.lng - p1.lng) / (p2.lat - p1.lat) +
p1.lng; //cross point of lng
if (Math.Abs(p.lng - xinters) < precision)
{
//overlies on a ray
return boundOrVertex;
}
if (p.lng < xinters)
{
//before ray
++intersectCount;
}
}
}
}
else
{
//special case when ray is crossing through the vertex
if (p.lat == p2.lat && p.lng <= p2.lng)
{
//p crossing over p2
var p3 = pts[(i + 1) % N]; //next vertex
if (p.lat >= Math.Min(p1.lat, p3.lat) && p.lat <= Math.Max(p1.lat, p3.lat))
{
//p.lat lies between p1.lat & p3.lat
++intersectCount;
}
else
{
intersectCount += 2;
}
}
}
p1 = p2; //next ray left point
}
if (intersectCount % 2 == 0)
{
//偶数在多边形外
return false;
}
else
{
//奇数在多边形内
return true;
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5c9cee88de351ad4da4f2d171a46a533
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -6,41 +6,56 @@ using System.Linq;
using System.Collections;
using Mapbox.Unity.Map;
using DG.Tweening;
using System;
using Assets.Scenes.Ride.Scripts.Model;
namespace Assets.Scenes.Ride.Scripts
{
public class UIManager : MonoBehaviour
{
#region UI control
[SerializeField]
Button startBtn;
Button startBtn;//开始按钮
[SerializeField]
Button simpleBtn;
Button simpleBtn;//进入简约模式按钮
[SerializeField]
Text ditance;//当前骑行距离
[SerializeField]
Text candance;//踏频
[SerializeField]
Text heartRate;//心率
[SerializeField]
GameObject rightPanel;//右边列表
[SerializeField]
GameObject leftPanel;//左边列表
[SerializeField]
Text speedTxt;//当前速度
[SerializeField]
Text powerTxt;//功率
[SerializeField]
Text timerTxt;//计时器
[SerializeField]
Text countDownTxt;//倒计时5s
[SerializeField] LineChart elevationChart;//海拔图
[SerializeField] Image img;//当前用户头像
[SerializeField]
Button StartOrPauseButton;//暂停按钮
[SerializeField]
Button SettingButton;//设置那妞
[SerializeField]
Button DeviceButton;//设备按钮
[SerializeField]
Button ExitButton;//退出按钮
#endregion
[SerializeField]
GameObject rightPanel;
[SerializeField]
GameObject leftPanel;
#region
[SerializeField]
Text speedTxt;
PlayerController playerController;//当前用户
CyclingController mainController;//主控制器
[SerializeField]
Text powerTxt;
#endregion
[SerializeField]
Text timerTxt;
[SerializeField]
Text countDownTxt;
[SerializeField]
LineChart elevationChart;
[SerializeField] Image img;
PlayerController playerController;
MainController mainController;
private float timeRemaining = 1f;
private int count = 0;
@ -48,11 +63,21 @@ namespace Assets.Scenes.Ride.Scripts
{
startBtn.onClick.AddListener(StartRide);
simpleBtn.onClick.AddListener(ClearPanel);
StartOrPauseButton.onClick.AddListener(PauseRide);
SettingButton.onClick.AddListener(ShowSettingPanel);
DeviceButton.onClick.AddListener(ShowDevicePanel);
ExitButton.onClick.AddListener(StopRide);
playerController = FindObjectOfType<PlayerController>();
mainController = FindObjectOfType<MainController>();
mainController = FindObjectOfType<CyclingController>();
}
//根据不同的骑行模式渲染不同的UI界面
void InitUI(CyclingModel cyclingModel)
{
}
// Start is called before the first frame update
void Start()
{
RenderChart();
@ -66,23 +91,49 @@ namespace Assets.Scenes.Ride.Scripts
countDownTxt.gameObject.SetActive(true);
countDownTxt.text = count.ToString();
}
//暂停游戏
private void PauseRide()
{
playerController.SetPause();
startBtn.gameObject.SetActive(true);
}
//结束游戏
private void StopRide()
{
}
//显示设备连接
private void ShowDevicePanel()
{
}
//显示设置
private void ShowSettingPanel()
{
}
int isSimple = 1;
//TODO:简约模式
private void ClearPanel()
{
leftPanel.transform.DOMoveX(leftPanel.transform.position.x+isSimple * 286.1764f, 1);
rightPanel.transform.DOMoveX(rightPanel.transform.position.x - isSimple * 286.1764f, 1);
elevationChart.transform.DOMoveX(elevationChart.transform.position.x + isSimple * 286.1764f, 1);
leftPanel.transform.DOLocalMove(new Vector3(leftPanel.transform.localPosition.x + isSimple * -430f, leftPanel.transform.localPosition.y, leftPanel.transform.localPosition.z), 1);
rightPanel.transform.DOLocalMove(new Vector3(rightPanel.transform.localPosition.x+ isSimple* 330f, rightPanel.transform.localPosition.y, rightPanel.transform.localPosition.z), 1);
//elevationChart.transform.DOMoveX(elevationChart.transform.position.x + isSimple * 286.1764f, 1);
isSimple *= -1;
}
// Update is called once per frame
void Update()
{
//获取当前选中玩家绑定当前UI
if (playerController != null)
{
//绑定UI
speedTxt.text = $"{playerController.Speed}";
powerTxt.text = $"{playerController.Power}";
timerTxt.text = Helper.FormatTicks(playerController.TotalTicks);
ditance.text = $"{Math.Round(playerController.TotalDistance,2)}KM";
heartRate.text = $"{Math.Round(playerController.HeartRate, 0)}";
candance.text = $"{Math.Round(playerController.Cadance, 0)}";
//倒计时
if (count > 0)
{
timeRemaining -= Time.deltaTime;
@ -98,11 +149,11 @@ namespace Assets.Scenes.Ride.Scripts
}
}
countDownTxt.text = count.ToString();
//移动海拔图头像 TODO移动所有人的头像
MoveChartMarkPoint();
}
}
//初始化海拔图
void RenderChart()
{
elevationChart.ClearData();
@ -115,12 +166,10 @@ namespace Assets.Scenes.Ride.Scripts
void MoveChartMarkPoint()
{
var dataPoints = elevationChart.series.list[0].dataPoints;
var dataPoints = elevationChart.series.list[0].dataPoints.OrderBy(c=>c.x).ToList();
if (dataPoints.Count > 0)
{
var pinLoction = dataPoints[playerController.CurrentIndex];
Debug.Log(pinLoction);
Debug.Log(dataPoints[0]);
pinLoction.y += 10;
img.transform.localPosition = pinLoction;
}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9605c5a09befa644fb31e6d59785fa21
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -0,0 +1,104 @@
fileFormatVersion: 2
guid: 9e814bd829485c14885e66788ddddd01
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

View File

@ -0,0 +1,104 @@
fileFormatVersion: 2
guid: 2cd9b5ab531797d4eaa820fcfa982c62
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

View File

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View File

@ -0,0 +1,104 @@
fileFormatVersion: 2
guid: b8196c4e549a22d4f9379de1f208d0ae
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@ -0,0 +1,104 @@
fileFormatVersion: 2
guid: 602a012543e878f49b091385a3bb7d68
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,104 @@
fileFormatVersion: 2
guid: cfebaeb62faae4c4caa69f4a4d49e669
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: 1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

View File

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -0,0 +1,104 @@
fileFormatVersion: 2
guid: fa0429f412b20364382ad3842c9234dd
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View File

@ -0,0 +1,104 @@
fileFormatVersion: 2
guid: cdab9e56a0e02f649babff60cf86d9c3
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,104 @@
fileFormatVersion: 2
guid: f06e0ed7b7049f14fa8d09a08fd524c7
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -514,4 +514,4 @@ namespace Assets.Scripts.Apis
}
}
}
}

View File

@ -1,4 +1,5 @@
using Assets.Scripts.Apis.Models;
using Assets.Scenes.Ride.Scripts.Model;
using Assets.Scripts.Apis.Models;
using System;
using System.Collections.Generic;
using System.Linq;
@ -70,5 +71,21 @@ namespace Assets.Scripts.Apis
return Get<JsonResult<Dictionary<string, string>>>($"Map/GetServiceKey").data;
}
/// <summary>
/// 获取在线用户的数据
/// </summary>
/// <param name="ids"></param>
/// <returns></returns>
public JsonResult<List<OnlineUser>> GetOnlineUserInfo(IEnumerable<int> ids)
{
//var result = PostAsync<JsonResult<List<OnlineUser>>>("Map/GetUserInfoByIds", ids).ConfigureAwait(false).GetAwaiter().GetResult();
var result = Newtonsoft.Json.JsonConvert.DeserializeObject<JsonResult<List<OnlineUser>>>(Post("Map/GetUserInfoByIds", ids));
if (result.result)
{
return result;
}
return null;
}
}
}

View File

@ -3,6 +3,7 @@ using Assets.Scripts.Apis.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
@ -17,5 +18,10 @@ namespace Assets.Scripts
public static UserApi userApi = new UserApi();
public static MapApi mapApi = new MapApi();
public static MapInterruptRecordApi mapInterruptRecordApi = new MapInterruptRecordApi();
public static string AppVersion = "1.0.0";
public static IPEndPoint UdpAddress ;
public static IPEndPoint TcpAddress ;
}
}

8
Assets/TextMesh Pro.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f54d1bd14bd3ca042bd867b519fee8cc
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8e7e8f5a82a3a134e91c54efd2274ea9
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ce51c8e33b734b4db6086586558c53a3
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b63e0053080646b9819789bf3bf9fa17
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5808953df7a24274a851aa6dee52d30e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5bff2544887143f5807c7d5059d07f79
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d6d3a169ad794942a21da6a552d62f6f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7f422cd1388b01047a58cd07c7a23d9d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4f1e85c79acf49968737939ce8b445c7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3ac6db30e75b49b282a3564110579f27
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: db1090641b3241f6995b587eb21637bc
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Some files were not shown because too many files have changed in this diff Show More