2024-08-17 14:27:18 +08:00
|
|
|
|
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
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 瓦片状态同步 : 用于开放世界类型的游戏 将 世界分多个Tile 不同的Service管理
|
|
|
|
|
/// </summary>
|
|
|
|
|
public abstract partial class JNSSTileServerService : JNSStateServerService
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 区块索引组
|
|
|
|
|
/// </summary>
|
|
|
|
|
protected abstract int[][] Tiles { get; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 区块大小
|
|
|
|
|
/// </summary>
|
|
|
|
|
protected abstract int TileSize { get; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 区块ID
|
|
|
|
|
/// 用于管理当前 Service 负责的区块ID
|
|
|
|
|
/// </summary>
|
|
|
|
|
public int TID { get; private set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 区块最大最小位置
|
|
|
|
|
/// </summary>
|
|
|
|
|
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)
|
|
|
|
|
{
|
2024-08-19 11:51:17 +08:00
|
|
|
|
return xTuple.Y < Tiles.Length && xTuple.X < Tiles[0].Length;
|
2024-08-17 14:27:18 +08:00
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 更新区块范围
|
|
|
|
|
/// </summary>
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 判断位置是否在区块内
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="pos"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 根据TileId 获取最大最小范围
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取TileID X Y
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
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();
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取九宫格Index
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public List<int> GetTileGridIndex(int index)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
List<int> grid = new List<int>();
|
|
|
|
|
(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;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取 TileId 权限 (返回多少 Service 则管理所属Tile)
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
protected abstract UniTask<int> FetchTileId();
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取当前连接的区块
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public virtual int[] GetLinkTiles()
|
|
|
|
|
{
|
|
|
|
|
return Array.Empty<int>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|