255 lines
8.1 KiB
C#
255 lines
8.1 KiB
C#
using UnityEngine;
|
|
using Cinemachine;
|
|
using AibisDream.Kit;
|
|
using AibisDream.Utility;
|
|
using System.Linq;
|
|
using AibisDream.Framework;
|
|
using System;
|
|
|
|
namespace AibisDream
|
|
{
|
|
public class BlockPuzzleSystem : Singleton<BlockPuzzleSystem>
|
|
{
|
|
[Header("物体索引")]
|
|
// 物体索引
|
|
[SerializeField] public BlockPuzzleGrid grid;
|
|
[SerializeField] private Transform shapeRoot;
|
|
[SerializeField] public BlockPuzzlePanel blockPuzzlePanel;
|
|
[SerializeField] private ShapeRecycleSlot shapeRecycleSlot;
|
|
|
|
[Header("数据")]
|
|
[SerializeField] private BlockPuzzleData puzzleData;
|
|
[SerializeField] private bool initializeOnStart = true;
|
|
|
|
private BlockPuzzleValidator validator;
|
|
private ShapeFactory shapeFactory;
|
|
|
|
private void Start()
|
|
{
|
|
if (initializeOnStart)
|
|
{
|
|
Initialize();
|
|
}
|
|
|
|
CameraKit.Instance?.RegisterCamera(CameraEnum.BlockPuzzle, GetComponentInChildren<ICinemachineCamera>());
|
|
}
|
|
|
|
public override void OnSingletonDestroy()
|
|
{
|
|
CameraKit.Instance?.UnRegisterCamera(CameraEnum.BlockPuzzle);
|
|
}
|
|
|
|
public void Initialize(BlockPuzzleData puzzleData)
|
|
{
|
|
this.puzzleData = puzzleData;
|
|
ClearGame();
|
|
Initialize();
|
|
}
|
|
|
|
public void Initialize()
|
|
{
|
|
// 初始化网格
|
|
grid.Initialize(puzzleData.gridWidth, puzzleData.gridHeight, puzzleData.cellSize);
|
|
// 初始化网格上图形
|
|
shapeFactory = new ShapeFactory(shapeRoot);
|
|
foreach (var shapeData in puzzleData.gridShapeDataInfos)
|
|
{
|
|
var shape = shapeFactory.CreateBlockShape(shapeData.shapeKey);
|
|
shape.Rotate(shapeData.rotationAngle);
|
|
grid.TrySnapToGrid(shape, shapeData.rootCell);
|
|
shape.GetComponent<ShapeDragger>().IsDraggable = shapeData.isDraggable;
|
|
}
|
|
|
|
grid.GridVisualizer.UpdateAllCellsVisual();
|
|
|
|
// 加载验证器
|
|
validator = ResourceKit.LoadAssetSync<BlockPuzzleValidator>(puzzleData.validatorName);
|
|
|
|
// 组装事件逻辑
|
|
AssembleEventLogic();
|
|
|
|
Debug.Log("网格系统初始化完成");
|
|
}
|
|
|
|
private void PreCheckGameState()
|
|
{
|
|
var shapes = grid.GetShapes();
|
|
var validateResult = validator.Validate(shapes);
|
|
}
|
|
|
|
private void SubmitGameResult()
|
|
{
|
|
var shapes = grid.GetShapes();
|
|
var validateResult = validator.Validate(shapes);
|
|
|
|
// 如果验证通过, 则设置变量并弹出对话
|
|
if (validateResult.isPass)
|
|
{
|
|
StorageSystem.Instance.SetValue("$block_puzzle_pass", true);
|
|
DialogController.Instance.StartDialogNode("方块拼图完成");
|
|
}
|
|
}
|
|
|
|
public void ClearGame()
|
|
{
|
|
grid.Clear();
|
|
// shapeRack.Clear();
|
|
shapeRoot.DestroyAllChildren();
|
|
}
|
|
|
|
// --------------------- 维修面板同步 -------------------
|
|
|
|
private string selectedShapeName;
|
|
|
|
/// <summary>
|
|
/// 组装各系统之间相互逻辑
|
|
/// </summary>
|
|
private void AssembleEventLogic()
|
|
{
|
|
// 由面板触发
|
|
blockPuzzlePanel.Panel.OnDeviceSelected += OnPanelShapeSelected;
|
|
blockPuzzlePanel.Panel.OnSubmit.AddListener(SubmitGameResult);
|
|
blockPuzzlePanel.Panel.OnPopUp.AddListener(PopUpShape);
|
|
|
|
// 由网格触发
|
|
grid.OnShapePlaced += PreCheckGameState;
|
|
|
|
// 由Shape触发
|
|
shapeFactory.OnDragStart += OnShapeDragStart;
|
|
shapeFactory.OnDragEnd += OnShapeDragEnd;
|
|
shapeFactory.OnDragUpdate += OnShapeDragUpdate;
|
|
}
|
|
|
|
private void OnPanelShapeSelected(BlockShapeInfo shapeData)
|
|
{
|
|
// 在屏幕上更新选中的图形
|
|
selectedShapeName = shapeData.shapeName;
|
|
blockPuzzlePanel.ShowShapeInScreen(shapeData);
|
|
}
|
|
|
|
public void OnValidateResult(ValidateResult validateResult)
|
|
{
|
|
// 先更新进度条
|
|
|
|
// 再更新校验结果,包括锁定按钮等UI
|
|
|
|
}
|
|
|
|
public void OnShapeDragStart(IBlockShape blockShape)
|
|
{
|
|
// 更新选中图形
|
|
|
|
// 回收抽屉高亮,半开
|
|
shapeRecycleSlot.PreRecycle();
|
|
shapeRecycleSlot.SetRecycleAvaliable(true);
|
|
}
|
|
|
|
public void OnShapeDragEnd(IBlockShape blockShape, bool isPlaced)
|
|
{
|
|
//
|
|
|
|
// TODO: 如果吸附到回收处,应该播放动画,并提示回收成功
|
|
}
|
|
|
|
public void OnShapeDragUpdate(IBlockShape blockShape)
|
|
{
|
|
// 更新回收槽状态
|
|
shapeRecycleSlot.UpdateSlotState(blockShape);
|
|
}
|
|
|
|
public void PopUpShape()
|
|
{
|
|
if (selectedShapeName == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// 弹出形状
|
|
var blockShape = shapeFactory.CreateBlockShape(selectedShapeName);
|
|
shapeRecycleSlot.PopUpShape(blockShape);
|
|
blockShape.GetComponent<ShapeDragger>().CurrentState = DragState.Idle;
|
|
|
|
// 删除按钮
|
|
blockPuzzlePanel.Panel.RemoveDeviceButton(selectedShapeName);
|
|
selectedShapeName = null;
|
|
blockPuzzlePanel.ClearShapeInScreen();
|
|
}
|
|
|
|
// --------------------- 吸附校验 ---------------------
|
|
|
|
public bool TrySnapToRecycleSlot(BlockShape blockShape)
|
|
{
|
|
// 先判断是否吸附到回收槽
|
|
if (shapeRecycleSlot.CurrentState == PositionState.Open)
|
|
{
|
|
shapeRecycleSlot.RecycleShape(blockShape);
|
|
// TODO: 向面板添加回收的形状
|
|
blockPuzzlePanel.Panel.OnDeviceRecycle(blockShape);
|
|
// 延时后进行销毁
|
|
ActionKit.Delay(1.0f, () => {
|
|
shapeFactory.RecycleBlockShape(blockShape);
|
|
}).Start(this);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// ---------------- 编辑器状态逻辑 ----------------
|
|
|
|
/// <summary>
|
|
/// 仅加载配置项,不应用到游戏
|
|
/// </summary>
|
|
public void LoadConfig()
|
|
{
|
|
if (BlockPuzzleKit.TryLoadBlockPuzzleData(puzzleData.puzzleName, out var blockPuzzleData))
|
|
{
|
|
puzzleData = blockPuzzleData;
|
|
Debug.Log("加载配置项成功");
|
|
}
|
|
else
|
|
{
|
|
Debug.Log("加载配置项失败");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 将配置项应用到编辑器
|
|
/// </summary>
|
|
public void ApplyConfig()
|
|
{
|
|
ClearGame();
|
|
|
|
shapeFactory = new ShapeFactory(shapeRoot);
|
|
grid.InitializeInEditor(puzzleData.gridWidth, puzzleData.gridHeight, puzzleData.cellSize);
|
|
// shapeRack.InitInEditor(puzzleData.shapeRackDataInfos);
|
|
|
|
foreach (var shapeData in puzzleData.gridShapeDataInfos)
|
|
{
|
|
var shape = shapeFactory.CreateBlockShape(shapeData.shapeKey);
|
|
shape.Rotate(shapeData.rotationAngle);
|
|
grid.TrySnapToGrid(shape, shapeData.rootCell);
|
|
}
|
|
}
|
|
|
|
public void SaveConfig()
|
|
{
|
|
var gridShapeDataInfos = grid.ShapeDict?.Values.ToArray();
|
|
// var shapeRackDataInfos = shapeRack.blockShapeDataList?.ToArray();
|
|
|
|
puzzleData.gridShapeDataInfos = gridShapeDataInfos;
|
|
// puzzleData.shapeRackDataInfos = shapeRackDataInfos;
|
|
|
|
BlockPuzzleKit.SaveBlockPuzzleData(puzzleData, puzzleData.puzzleName);
|
|
}
|
|
|
|
public void CreateShapeInEditor(string shapeKey)
|
|
{
|
|
if (shapeFactory == null)
|
|
{
|
|
shapeFactory = new ShapeFactory(shapeRoot);
|
|
}
|
|
shapeFactory.CreateBlockShape(shapeKey);
|
|
}
|
|
}
|
|
}
|