244 lines
7.4 KiB
C#
244 lines
7.4 KiB
C#
// PuzzleManager.cs
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using TMPro;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
|
||
public class PuzzleManager : MonoBehaviour
|
||
{
|
||
[Header("拼图设置")]
|
||
public Texture2D puzzleImage; // 拼图原图
|
||
public int gridSize = 3; // 网格大小(3x3)
|
||
public float spacing = 5f; // 拼图块间距
|
||
|
||
[Header("UI引用")]
|
||
public RectTransform puzzleArea; // 拼图区域
|
||
public Transform piecesContainer; // 拼图块容器
|
||
public TMP_Text completedText; // 完成提示文本
|
||
|
||
private List<PuzzlePiece> pieces = new List<PuzzlePiece>();
|
||
private PuzzlePiece emptyPiece; // 空白拼图块
|
||
private Vector2 pieceSize; // 拼图块尺寸
|
||
|
||
void Start()
|
||
{
|
||
CreatePuzzle();
|
||
ShufflePieces();
|
||
}
|
||
|
||
// 创建拼图
|
||
void CreatePuzzle()
|
||
{
|
||
// 计算拼图块尺寸
|
||
float areaWidth = puzzleArea.rect.width;
|
||
float areaHeight = puzzleArea.rect.height;
|
||
pieceSize = new Vector2(areaWidth / gridSize, areaHeight / gridSize);
|
||
|
||
// 创建拼图块
|
||
for (int row = 0; row < gridSize; row++)
|
||
{
|
||
for (int col = 0; col < gridSize; col++)
|
||
{
|
||
// 跳过最后一个位置(作为空白)
|
||
if (row == gridSize - 1 && col == gridSize - 1)
|
||
{
|
||
CreateEmptyPiece(row, col);
|
||
continue;
|
||
}
|
||
|
||
// 创建拼图块GameObject
|
||
GameObject pieceObj = new GameObject($"Piece_{row}_{col}");
|
||
pieceObj.transform.SetParent(piecesContainer);
|
||
|
||
// 添加Image组件
|
||
Image img = pieceObj.AddComponent<Image>();
|
||
|
||
// 设置拼图块纹理
|
||
Sprite sprite = CreateSpriteForPiece(row, col);
|
||
img.sprite = sprite;
|
||
|
||
// 设置位置和大小
|
||
RectTransform rt = pieceObj.GetComponent<RectTransform>();
|
||
rt.sizeDelta = pieceSize - Vector2.one * spacing;
|
||
rt.anchoredPosition = GetPiecePosition(row, col);
|
||
|
||
// 添加拼图块组件
|
||
PuzzlePiece piece = pieceObj.AddComponent<PuzzlePiece>();
|
||
piece.Initialize(this, row, col);
|
||
pieces.Add(piece);
|
||
|
||
// 添加按钮组件用于点击
|
||
Button btn = pieceObj.AddComponent<Button>();
|
||
btn.onClick.AddListener(() => OnPieceClick(piece));
|
||
}
|
||
}
|
||
|
||
completedText.gameObject.SetActive(false);
|
||
}
|
||
|
||
// 创建空白拼图块
|
||
void CreateEmptyPiece(int row, int col)
|
||
{
|
||
GameObject emptyObj = new GameObject("EmptyPiece");
|
||
emptyObj.transform.SetParent(piecesContainer);
|
||
|
||
// 设置位置
|
||
RectTransform rt = emptyObj.AddComponent<RectTransform>();
|
||
rt.sizeDelta = pieceSize - Vector2.one * spacing;
|
||
rt.anchoredPosition = GetPiecePosition(row, col);
|
||
|
||
emptyPiece = emptyObj.AddComponent<PuzzlePiece>();
|
||
emptyPiece.Initialize(this, row, col);
|
||
emptyPiece.isEmpty = true;
|
||
}
|
||
|
||
// 创建拼图块的Sprite
|
||
Sprite CreateSpriteForPiece(int row, int col)
|
||
{
|
||
// 计算在原图中的位置
|
||
int texWidth = puzzleImage.width / gridSize;
|
||
int texHeight = puzzleImage.height / gridSize;
|
||
|
||
// 创建纹理
|
||
Texture2D pieceTex = new Texture2D(texWidth, texHeight);
|
||
Color[] pixels = puzzleImage.GetPixels(
|
||
col * texWidth,
|
||
(gridSize - 1 - row) * texHeight,
|
||
texWidth,
|
||
texHeight
|
||
);
|
||
|
||
pieceTex.SetPixels(pixels);
|
||
pieceTex.Apply();
|
||
|
||
return Sprite.Create(
|
||
pieceTex,
|
||
new Rect(0, 0, texWidth, texHeight),
|
||
new Vector2(0.5f, 0.5f)
|
||
);
|
||
}
|
||
|
||
// 获取拼图块位置
|
||
Vector2 GetPiecePosition(int row, int col)
|
||
{
|
||
float startX = -puzzleArea.rect.width / 2 + pieceSize.x / 2;
|
||
float startY = puzzleArea.rect.height / 2 - pieceSize.y / 2;
|
||
|
||
return new Vector2(
|
||
startX + col * pieceSize.x,
|
||
startY - row * pieceSize.y
|
||
);
|
||
}
|
||
|
||
// 打乱拼图
|
||
void ShufflePieces()
|
||
{
|
||
int shuffleCount = 100;
|
||
|
||
for (int i = 0; i < shuffleCount; i++)
|
||
{
|
||
var adjacentPieces = GetAdjacentPieces(emptyPiece);
|
||
if (adjacentPieces.Count > 0)
|
||
{
|
||
int randomIndex = Random.Range(0, adjacentPieces.Count);
|
||
var targetPiece = adjacentPieces[randomIndex];
|
||
|
||
// 只交换空白块与相邻块
|
||
SwapPieces(targetPiece, emptyPiece);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 获取相邻的拼图块
|
||
List<PuzzlePiece> GetAdjacentPieces(PuzzlePiece piece)
|
||
{
|
||
List<PuzzlePiece> adjacent = new List<PuzzlePiece>();
|
||
Vector2[] directions = { Vector2.up, Vector2.down, Vector2.left, Vector2.right };
|
||
|
||
foreach (Vector2 dir in directions)
|
||
{
|
||
PuzzlePiece adjacentPiece = GetPieceAtPosition(
|
||
piece.currentRow + (int)dir.y,
|
||
piece.currentCol + (int)dir.x
|
||
);
|
||
|
||
if (adjacentPiece != null)
|
||
{
|
||
adjacent.Add(adjacentPiece);
|
||
}
|
||
}
|
||
|
||
return adjacent;
|
||
}
|
||
|
||
// 点击拼图块
|
||
public void OnPieceClick(PuzzlePiece piece)
|
||
{
|
||
if (IsAdjacentToEmpty(piece))
|
||
{
|
||
SwapPieces(piece, emptyPiece);
|
||
|
||
if (CheckPuzzleComplete())
|
||
{
|
||
completedText.gameObject.SetActive(true);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 检查是否与空白块相邻
|
||
bool IsAdjacentToEmpty(PuzzlePiece piece)
|
||
{
|
||
int rowDiff = Mathf.Abs(piece.currentRow - emptyPiece.currentRow);
|
||
int colDiff = Mathf.Abs(piece.currentCol - emptyPiece.currentCol);
|
||
|
||
return (rowDiff == 1 && colDiff == 0) || (rowDiff == 0 && colDiff == 1);
|
||
}
|
||
|
||
// 交换两个拼图块
|
||
void SwapPieces(PuzzlePiece piece1, PuzzlePiece piece2)
|
||
{
|
||
// 交换位置
|
||
Vector2 tempPos = piece1.GetComponent<RectTransform>().anchoredPosition;
|
||
piece1.GetComponent<RectTransform>().anchoredPosition =
|
||
piece2.GetComponent<RectTransform>().anchoredPosition;
|
||
piece2.GetComponent<RectTransform>().anchoredPosition = tempPos;
|
||
|
||
// 交换行列信息
|
||
int tempRow = piece1.currentRow;
|
||
int tempCol = piece1.currentCol;
|
||
|
||
piece1.currentRow = piece2.currentRow;
|
||
piece1.currentCol = piece2.currentCol;
|
||
|
||
piece2.currentRow = tempRow;
|
||
piece2.currentCol = tempCol;
|
||
}
|
||
|
||
// 获取指定位置的拼图块
|
||
PuzzlePiece GetPieceAtPosition(int row, int col)
|
||
{
|
||
if (row < 0 || row >= gridSize || col < 0 || col >= gridSize)
|
||
return null;
|
||
|
||
foreach (PuzzlePiece piece in pieces)
|
||
{
|
||
if (piece.currentRow == row && piece.currentCol == col)
|
||
return piece;
|
||
}
|
||
|
||
return emptyPiece.currentRow == row && emptyPiece.currentCol == col ? emptyPiece : null;
|
||
}
|
||
|
||
// 检查拼图是否完成
|
||
bool CheckPuzzleComplete()
|
||
{
|
||
foreach (PuzzlePiece piece in pieces)
|
||
{
|
||
if (piece.currentRow != piece.correctRow || piece.currentCol != piece.correctCol)
|
||
return false;
|
||
}
|
||
|
||
return emptyPiece.currentRow == gridSize - 1 && emptyPiece.currentCol == gridSize - 1;
|
||
}
|
||
} |