314 lines
12 KiB
C#
Raw Normal View History

2022-03-10 18:32:53 +08:00
using Assets.Scenes.Ride.Scripts;
using Assets.Scenes.Ride.Scripts.Model;
using Assets.Scenes.Ride.Scripts.Model.CyclingModels;
using Assets.Scripts.Apis;
using Assets.Scripts.Apis.Models;
using Assets.Scripts.UI.Prefab.Device;
using GeoJSON.Net.Geometry;
using Mapbox.Utils;
using RenderHeads.Media.AVProVideo;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using TurfCS;
using UnityEngine;
using DG.Tweening;
2022-03-10 18:32:53 +08:00
namespace Assets.Scripts.Scenes.VideoRide
{
public class VideoGameManager : DeviceServiceMonoBase
{
private List<VideoMapModel> videoPointList { get; set; }
private VideoPlayer currentVideoPlayer { get; set; }
private MapDataModel mapData { get; set; }
private MediaPlayer mediaPlayer { get; set; }
private bool isStart { get; set; }
private Route route { get; set; }
private MapRoute mapRoute { get; set; }
public RouteResultParam selectParamModel;
public RouteResult routeResult;
public string recordId { get; set; }
public DateTime startTime { get; set; }
public CyclingModel cyclingModel;
public BaseCycling cyclingController;
public Dictionary<int, int> mockDirection = new Dictionary<int, int>();
private double endDistance { get; set; }
public Dictionary<int, bool> slots = new Dictionary<int, bool>();
Transform cube;
2022-03-10 18:32:53 +08:00
private async void Awake()
{
base.Awake();
//自动登录
if (App.CurrentUser == null)
{
await Login();
}
DeviceCache.Init(PFConstants.DeviceCacheFolder);
//var check = CheckAnt();
recordId = Guid.NewGuid().ToString();
startTime = UIManager.Now.GetDateTime();
MapUDPService.Init();//初始化TCP
MockDirection();
InitSlots();
2022-03-10 18:32:53 +08:00
}
void Start()
{
cube = transform.Find("Cube");
2022-03-10 18:32:53 +08:00
//获取媒体播放器
mediaPlayer = FindObjectOfType<MediaPlayer>();
var mapApi = ConfigHelper.mapApi;
const int routeId = 12353;
mapData = mapApi.GetData(routeId);//获取路书地理数据
mapRoute = mapApi.GetById(routeId).data;
route = new Route(mapData, mapRoute);
if (selectParamModel == null)
{
selectParamModel = new RouteResultParam
{
CompetitionId = 0,
ContinueIndex = 0,
ContinueMark = "",
GlobalContinue = false,
EndDistance = 0,
RankingsId = new List<string>(),
OnlineUserId = 0,
RouteId = routeId
};
}
endDistance = 0;
//倒计时5s开始
SetCyclingModel(CyclingModel.Single);
}
// Update is called once per frame
float timer = 1f;
void Update()
{
timer -= Time.deltaTime;
while (timer <= 0)
{
cyclingController?.Run(null);
var onlineRiders = cyclingController.riders;
timer += 1f;
}
var p = FindObjectOfType<VideoPlayer>();
if (p.distance > 0)
{
preFrame = currentFrame;
currentFrame = GetCurrentFrame();
var dd = (currentFrame - preFrame) / 200f * cube.position.z;
cube.DOMoveZ((float)(cube.position.z - dd), 0f);
2022-03-10 18:32:53 +08:00
}
}
private void InitSlots()
{
slots.Add(2, true);
slots.Add(4, true);
slots.Add(-2, true);
slots.Add(-6, true);
slots.Add(-4, true);
slots.Add(-8, true);
}
public int? GetSlotIndex()
{
foreach (var item in slots)
{
if (item.Value)
{
slots[item.Key] = false;
return item.Key;
}
}
return 0;
}
public async Task ContinueAsync()
{
//继续骑行数据
var r = await ConfigHelper.mapInterruptRecordApi.GetMapInterruptRecord("重庆", 0, 20, "routes");
if (r.result)
{
var first = r.data.FirstOrDefault();
RouteResult routeResult = first.ToObject<RouteResult>();
if (routeResult.ContinueCyclingParam != null)
{
App.RouteIdParam = routeResult.RouteId;
App.routeResult = routeResult;
//骑行结果
if (App.routeResult != null)
{
routeResult = App.routeResult;
selectParamModel = App.routeResult.ContinueCyclingParam;//继续骑行
SetCyclingModel(CyclingModel.Single);
endDistance = routeResult.EndDistance;
var ratio = endDistance / routeResult.TotalDistance;
var frame = Math.Round(ratio * mediaPlayer.Info.GetMaxFrameNumber());
SetCurrentFrame(routeResult.LastFrame ?? 0);
var v = FindObjectOfType<VideoPlayer>();
v.SetEndDistance(endDistance);
}
}
}
}
private void MockDirection()
{
var text = Resources.Load<TextAsset>("UI/direction");
var arr = text.text.Replace("\r\n", ",").Split(',');
foreach (var item in arr)
{
if (string.IsNullOrEmpty(item))
continue;
mockDirection.Add(Convert.ToInt32(item.Split(':')[0]), Convert.ToInt32(item.Split(':')[1]));
}
}
public void SetCyclingModel(CyclingModel mode)
{
this.cyclingModel = mode;
switch (cyclingModel)
{
case CyclingModel.Single:
cyclingController = new SingleModel(route, selectParamModel);
break;
}
}
//模拟登录
private async Task Login()
{
var result = await new UserApi().Login("15261826280", "123456", "");
App.CurrentUser = result.data;
}
//开始游戏
public void StartGame()
{
startTime = UIManager.Now.GetDateTime();
isStart = true;
}
public bool IsStart()
{
return isStart;
}
//按照某种速度播放视频
public void Play(float playbackRate = 1f)
{
if (mediaPlayer != null)
{
mediaPlayer.PlaybackRate = playbackRate;
mediaPlayer.Play();
}
}
//暂停游戏
public void Pause()
{
mediaPlayer?.Pause();
}
public void Quit()
{
mediaPlayer?.Stop();
}
int preFrame = 0;
int currentFrame = 0;
2022-03-10 18:32:53 +08:00
public int GetCurrentFrame()
2022-03-10 18:32:53 +08:00
{
return mediaPlayer.Control.GetCurrentTimeFrames();
2022-03-10 18:32:53 +08:00
}
public void SetCurrentFrame(int seq)
{
mediaPlayer?.Control.SeekToFrame(seq);
}
public void Save(double totalDistance)
{
mediaPlayer?.Pause();//暂停视频
cyclingController.recorderData.EndTime = UIManager.Now.GetDateTime();
isStart = false;
var path = PFConstants.MapWorkoutRecordFolder + "/" + recordId;
Assets.Scenes.Ride.Scripts.Helper.CreateDirectoryIfNotExsit(path);
string imageFileName = path + "/" + Guid.NewGuid().ToString() + ".png";
CaptureCamera(Camera.main, new Rect(Screen.width * 0f, Screen.height * 0f, Screen.width * 0.5f, Screen.height * 0.5f), imageFileName);
cyclingController.recorderData.StartTime = startTime;
cyclingController.recorderData.IsCompleted = totalDistance >= mapData.TotalDistance;
cyclingController.recorderData.EndDistance = totalDistance;
cyclingController.recorderData.AntModelId = AntModelId;
cyclingController.recorderData.ManufacturerId = ManufacturerId;
cyclingController.recorderData.ManufacturerName = ManufacturerName;
cyclingController.recorderData.DeviceNumber = DeviceNumber;
cyclingController.recorderData.LastFrame = GetCurrentFrame();
var RankingId = cyclingController.recorderData.SaveWithLocalRecordAysnc(cyclingModel, selectParamModel, imageFileName, recordId, path);
}
protected void CaptureCamera(Camera camera, Rect rect, string fileName)
{
byte[] bytes = CaptureCameraReturnByte(camera, rect);
//var path = Helper.GetDataDir("MapWorkoutRecords/images");
//string filename = path + "/" + Guid.NewGuid().ToString() + ".png";
System.IO.File.WriteAllBytes(fileName, bytes);
//Debug.Log(string.Format("截屏了一张照片: {0}", filename));
}
private byte[] CaptureCameraReturnByte(Camera camera, Rect rect)
{
// 创建一个RenderTexture对象
RenderTexture rt = new RenderTexture((int)rect.width, (int)rect.height, 0);
// 临时设置相关相机的targetTexture为rt, 并手动渲染相关相机
camera.targetTexture = rt;
camera.Render();
//ps: --- 如果这样加上第二个相机,可以实现只截图某几个指定的相机一起看到的图像。
//ps: camera2.targetTexture = rt;
//ps: camera2.Render();
//ps: -------------------------------------------------------------------
// 激活这个rt, 并从中中读取像素。
RenderTexture.active = rt;
Texture2D screenShot = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.RGB24, false);
screenShot.ReadPixels(rect, 0, 0);// 注这个时候它是从RenderTexture.active中读取像素
screenShot.Apply();
// 重置相关参数以使用camera继续在屏幕上显示
camera.targetTexture = null;
//ps: camera2.targetTexture = null;
RenderTexture.active = null; // JC: added to avoid errors
GameObject.Destroy(rt);
// 最后将这些纹理数据,成一个图片文件
return screenShot.EncodeToJPG();
}
//两个坐标之间的距离
public double Distance(Vector2d from, Vector2d to)
{
var pt1 = Turf.Point(new double[] { from.x, from.y });
var pt2 = Turf.Point(new double[] { to.x, to.y });
return Turf.Distance(pt1, pt2);
}
//根据距离计算下一个点坐标
public 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);
}
else
{
return new Vector2d(0, 0);
}
}
public MapDataModel GetMapData()
{
return mapData;
}
public float GetPlayRatio()
{
return mediaPlayer.Control.GetPlaybackRate();
}
2022-03-10 18:32:53 +08:00
public List<VideoMapModel> getVideoPointList()
{
return videoPointList;
}
}
}