拼图测试场景
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using A2W;
|
||||
using Unity.Cinemachine;
|
||||
using UnityEngine;
|
||||
@@ -15,11 +16,10 @@ public class MusicGame : SceneSingleton<MusicGame>
|
||||
public Vector3 judgeLine;
|
||||
private List<GameObject> tickNote = new List<GameObject>();
|
||||
double startDsp;
|
||||
|
||||
public int Sroce = 0;
|
||||
void Start()
|
||||
{
|
||||
mainCamera = Camera.main;
|
||||
|
||||
}
|
||||
|
||||
void Update()
|
||||
@@ -27,6 +27,11 @@ public class MusicGame : SceneSingleton<MusicGame>
|
||||
// if (Keyboard.current.qKey.wasPressedThisFrame) Play();
|
||||
}
|
||||
|
||||
public async Task openGameUI()
|
||||
{
|
||||
await UIManager.instance.ShowPanel<MusicGamePanel>();
|
||||
}
|
||||
|
||||
public void Play()
|
||||
{
|
||||
mainCamera.transform.position = new Vector3(0, 100, -10);
|
||||
@@ -93,11 +98,13 @@ public class MusicGame : SceneSingleton<MusicGame>
|
||||
// ActivateTick(musicData.musicTicks[tickId]);
|
||||
else
|
||||
{
|
||||
UIManager.instance.HidePanel<MusicGamePanel>();
|
||||
gameObject.GetComponent<AudioSource>().Stop();
|
||||
isPlaying = false;
|
||||
tickId = 0;
|
||||
noteId = 0;
|
||||
mainCamera.GetComponent<CinemachineBrain>().enabled = true;
|
||||
Debug.Log("完成所有tick");
|
||||
Debug.Log($"完成所有tick,分数{Sroce}");
|
||||
GameFlowMgr.instance.completeLevel(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ public class Note : MonoBehaviour
|
||||
Debug.Log($"音符 {Uid}击中");
|
||||
judged = true;
|
||||
lastSpaceTime = double.NegativeInfinity;
|
||||
MusicGame.instance.Sroce += 10;
|
||||
MusicGame.instance.onNoteHit(Uid);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -12,8 +12,8 @@ public class PianoInteractable : MonoBehaviour, IInteractable
|
||||
Debug.Log("OnExitInteractionRange");
|
||||
}
|
||||
|
||||
public void OnInteract()
|
||||
public async void OnInteract()
|
||||
{
|
||||
MusicGame.instance.Play();
|
||||
await MusicGame.instance.openGameUI();
|
||||
}
|
||||
}
|
||||
20
Assets/Gameplay/Scripts/Frist/SceneInit.cs
Normal file
20
Assets/Gameplay/Scripts/Frist/SceneInit.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System.Threading.Tasks;
|
||||
using A2W;
|
||||
using UnityEngine;
|
||||
|
||||
public class SceneInit : MonoBehaviour
|
||||
{
|
||||
MessagePanel messagePanel;
|
||||
async Task Init()
|
||||
{
|
||||
// messagePanel = await UIManager.instance.ShowPanel<MessagePanel>();
|
||||
// messagePanel.AddMessage("寻找有关于音乐的物品");
|
||||
// Debug.Log("寻找有关于音乐的物品");
|
||||
}
|
||||
async void Start()
|
||||
{
|
||||
messagePanel = await UIManager.instance.ShowPanel<MessagePanel>();
|
||||
messagePanel.AddMessage("Search for items related to music");
|
||||
Debug.Log("寻找有关于音乐的物品");
|
||||
}
|
||||
}
|
||||
2
Assets/Gameplay/Scripts/Frist/SceneInit.cs.meta
Normal file
2
Assets/Gameplay/Scripts/Frist/SceneInit.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 03f01a4a562213c419a7595dcf397006
|
||||
8
Assets/Gameplay/Scripts/Level02.meta
Normal file
8
Assets/Gameplay/Scripts/Level02.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5ed5b94a8be4cdb4f9c5f81eab4a0a36
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
244
Assets/Gameplay/Scripts/Level02/PuzzleManager.cs
Normal file
244
Assets/Gameplay/Scripts/Level02/PuzzleManager.cs
Normal file
@@ -0,0 +1,244 @@
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
2
Assets/Gameplay/Scripts/Level02/PuzzleManager.cs.meta
Normal file
2
Assets/Gameplay/Scripts/Level02/PuzzleManager.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b8ae299b38a43194f8fc79c347b32d26
|
||||
22
Assets/Gameplay/Scripts/Level02/PuzzlePiece.cs
Normal file
22
Assets/Gameplay/Scripts/Level02/PuzzlePiece.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
// PuzzlePiece.cs
|
||||
using UnityEngine;
|
||||
|
||||
public class PuzzlePiece : MonoBehaviour
|
||||
{
|
||||
[HideInInspector] public int correctRow; // 正确位置的行
|
||||
[HideInInspector] public int correctCol; // 正确位置的列
|
||||
[HideInInspector] public int currentRow; // 当前位置的行
|
||||
[HideInInspector] public int currentCol; // 当前位置的列
|
||||
[HideInInspector] public bool isEmpty; // 是否是空白块
|
||||
|
||||
private PuzzleManager puzzleManager;
|
||||
|
||||
public void Initialize(PuzzleManager manager, int row, int col)
|
||||
{
|
||||
puzzleManager = manager;
|
||||
correctRow = row;
|
||||
correctCol = col;
|
||||
currentRow = row;
|
||||
currentCol = col;
|
||||
}
|
||||
}
|
||||
2
Assets/Gameplay/Scripts/Level02/PuzzlePiece.cs.meta
Normal file
2
Assets/Gameplay/Scripts/Level02/PuzzlePiece.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 01e544aac3c5cce42bc8ef6c375e9ad7
|
||||
55
Assets/Gameplay/Scripts/UI/MusicGamePanel.cs
Normal file
55
Assets/Gameplay/Scripts/UI/MusicGamePanel.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using A2W;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class MusicGamePanel : UIPanel
|
||||
{
|
||||
// Start is called once before the first execution of Update after the MonoBehaviour is created
|
||||
public TMP_Text scoreText;
|
||||
public TMP_Text tipText;
|
||||
public TMP_Text tipText2;
|
||||
public Button startButton;
|
||||
|
||||
public override UniTask Hide()
|
||||
{
|
||||
return UniTask.CompletedTask;
|
||||
}
|
||||
|
||||
public override void Init()
|
||||
{
|
||||
tipText.gameObject.SetActive(true);
|
||||
startButton.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
public override UniTask Show()
|
||||
{
|
||||
return UniTask.CompletedTask;
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
// startButton.onClick.AddListener(() =>
|
||||
// {
|
||||
// tipText.gameObject.SetActive(false);
|
||||
// startButton.gameObject.SetActive(false);
|
||||
// });
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
bool isStart = false;
|
||||
void Update()
|
||||
{
|
||||
scoreText.text = MusicGame.instance.Sroce.ToString();
|
||||
if (Keyboard.current.spaceKey.wasPressedThisFrame && !isStart)
|
||||
{
|
||||
isStart = true;
|
||||
tipText.gameObject.SetActive(false);
|
||||
tipText2.gameObject.SetActive(false);
|
||||
MusicGame.instance.Play();
|
||||
startButton.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/Gameplay/Scripts/UI/MusicGamePanel.cs.meta
Normal file
2
Assets/Gameplay/Scripts/UI/MusicGamePanel.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f7eee0888c08622498d86d24e7e99efd
|
||||
Reference in New Issue
Block a user