using System; using System.Collections.Generic; using System.Threading.Tasks; using Cysharp.Threading.Tasks; using JNGame.Math; using JNGame.Sync.Entity; using JNGame.Sync.Frame.Service; using JNGame.Sync.State.Tile.Entity; using UnityEngine; namespace JNGame.Sync.State.Tile { /// /// 瓦片状态同步 : 用于开放世界类型的游戏 将 世界分多个Tile 不同的Service管理 /// public abstract partial class JNSSTileServerService : JNSStateServerService { /// /// 区块索引组 /// protected abstract int[][] Tiles { get; } /// /// 区块大小 /// protected abstract int TileSize { get; } /// /// 区块ID /// 用于管理当前 Service 负责的区块ID /// public int TID { get; private set; } /// /// 区块最大最小位置 /// public LVector2 MinContains{ get; private set; } public LVector2 MaxContains{ get; private set; } public override void Initialize() { OnInit(); } protected virtual async Task OnInit() { try { //获取权限 this.TID = await FetchTileId(); //更新范围 UpdateContains(); base.Initialize(); } catch (Exception e) { Debug.LogError(e.Message); throw; } } public sealed override JNContexts CreateContexts() { return CreateTileContexts(); } public sealed override JNRandomSystem CreateRandom() { //根据区块设置Id 起始值 var random = base.CreateRandom(); random.SetIdValue(100000000000L * TID); return random; } protected virtual JNTileContexts CreateTileContexts() { return new JNTileContexts(); } public bool IsTileIndex((int X, int Y) xTuple) { if (xTuple.X >= 0 && xTuple.Y >= 0) { return xTuple.Y < Tiles.Length && xTuple.X < Tiles[0].Length; } return false; } /// /// 更新区块范围 /// public void UpdateContains() { MinContains = new LVector2(); MaxContains = new LVector2(); try { //更新区块最大最小位置 (LVector2 max, LVector2 min) = GetTileContains(TID); MinContains = min; MaxContains = max; } catch (Exception e) { // ignored return; } } /// /// 判断位置是否在区块内 /// /// /// public bool IsContains(LVector3 position) { // 假设LVector2是一个包含X和Y属性的结构体或类 // 检查X坐标是否在范围内 if (position.x < MinContains.x || position.x >= MaxContains.x) { return false; // X坐标不在范围内 } // 检查Y坐标是否在范围内 if (position.z < MinContains.y || position.z >= MaxContains.y) { return false; // Y坐标不在范围内 } // 如果X和Y坐标都在范围内,则返回true return true; } /// /// 根据TileId 获取最大最小范围 /// /// public (LVector2 Max,LVector2 Min) GetTileContains(int index) { (int X, int Y) = GetTileIDXY(index); var min = new LVector2(X.ToLFloat() * TileSize,Y.ToLFloat() * TileSize); var max = new LVector2((X + 1).ToLFloat() * TileSize,(Y + 1).ToLFloat() * TileSize); return (max,min); } /// /// 获取TileID X Y /// /// public (int X, int Y) GetTileIDXY(int index) { // 遍历数组 for (int y = 0; y < Tiles.Length; y++) { for (int x = 0; x < Tiles[y].Length; x++) { // 检查当前元素是否非零 if (Tiles[y][x] != 0 && Tiles[y][x] == index) { // 返回找到的坐标 return (x,y); } } } throw new Exception(); } /// /// 获取九宫格Index /// /// public List GetTileGridIndex(int index) { List grid = new List(); (int X, int Y) = GetTileIDXY(index); // 填充九宫格 for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { int tempX = X + i; int tempY = Y + j; // 注意这里j+1+1是因为数组第二维存储的是y坐标 if (IsTileIndex((tempX,tempY))) grid.Add(Tiles[tempY][tempX]); } } return grid; } /// /// 获取 TileId 权限 (返回多少 Service 则管理所属Tile) /// /// protected abstract UniTask FetchTileId(); /// /// 获取当前连接的区块 /// /// public virtual int[] GetLinkTiles() { return Array.Empty(); } } }