314 lines
12 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
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;
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();
}
void Start()
{
cube = transform.Find("Cube");
//获取媒体播放器
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);
}
}
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;
public int GetCurrentFrame()
{
return mediaPlayer.Control.GetCurrentTimeFrames();
}
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();
}
public List<VideoMapModel> getVideoPointList()
{
return videoPointList;
}
}
}