方块消除游戏开发笔记
下面是简单的展示,具体演示视频可在文章末尾观看
项目概述
-
这个项目是一个使用Unity引擎和C#编写的方块消除游戏。玩家的目标是选择并消除相邻的相同颜色方块,以获得高分。以下是游戏代码的概述和关键功能。
-
游戏规则: 在限定时间内消除指定分数的方块,当鼠标移动到方块上方会高亮显示,当选择该方块后该方块会变为透明表示选中。需要注意的是不同颜色方块的分数值不一样,而且只能选择当前的相邻的同颜色方块,若是选择违反规则就会取消选中哦。
游戏概述
- 游戏使用Unity引擎和C#编写。
- 游戏网格的大小由
gridSize
参数定义,决定了游戏中的方块布局。 - 方块之间的间距由
blockSpacing
参数定义,用于调整方块之间的距离。 - 方块的大小由
cellSize
参数定义,用于设置方块的尺寸。 - 游戏包括一个得分计数器、剩余时间和游戏结束状态。
public int gridSize = 8; // 游戏网格大小
public float blockSpacing = 30.0f; // 方块之间的间距
private int cellSize = 40; // 方块的大小
private int[,] grid; // 存储方块颜色的二维数组
private Color[] colors; // 可用的方块颜色数组
private int score = 0; // 得分
private float timeLeft = 60.0f; // 剩余时间
private bool isGameOver = false; // 游戏结束标志
private bool[,] selectedGrid; // 用于跟踪方块选择状态的二维数组
private Vector2Int currentSelection = new Vector2Int(-1, -1); // 当前选中的方块坐标
1.游戏初始化
在 Start
方法中,游戏进行了初始化:
void Start()
{
InitializeGrid();
InitializeSelection();
}
InitializeGrid
方法用于随机初始化游戏网格的方块颜色,为玩家提供初始游戏状态。
// 初始化游戏网格
void InitializeGrid()
{
grid = new int[gridSize, gridSize];
colors = new Color[4] { Color.red, Color.blue, Color.green, Color.yellow };
for (int i = 0; i < gridSize; i++)
{
for (int j = 0; j < gridSize; j++)
{
grid[i, j] = Random.Range(0, 4); // 随机分配方块颜色
}
}
}
InitializeSelection
方法初始化了选择状态的数组,确保玩家可以开始选择方块。
// 初始化方块选择状态数组
void InitializeSelection()
{
selectedGrid = new bool[gridSize, gridSize];
for (int i = 0; i < gridSize; i++)
{
for (int j = 0; j < gridSize; j++)
{
selectedGrid[i, j] = false;
}
}
}
2.游戏逻辑
- 游戏的主要逻辑位于
Update
方法中,其中包括倒计时、检查游戏结束状态等。
// 更新游戏状态的方法
void Update()
{
// 如果游戏尚未结束
if (!isGameOver)
{
// 减少剩余时间
if (timeLeft > 0)
{
timeLeft -= Time.deltaTime; // 以每帧的时间差来减少剩余时间
}
else
{
timeLeft = 0; // 时间耗尽,不再减少
isGameOver = true; // 时间耗尽,游戏结束
}
}
}
-
Update
方法中的逻辑控制游戏的进行。首先,它检查游戏是否结束(isGameOver
标志)。如果游戏没有结束,它将减少剩余时间timeLeft
的值,通过每帧的时间差(Time.deltaTime
)来模拟时间的流逝。如果剩余时间小于等于零,它将确保timeLeft
的值为零,并将isGameOver
标志设置为true
,表示游戏已结束。 -
OnGUI
方法用于绘制游戏界面,包括显示剩余时间、得分、游戏结束状态以及方块的选择状态。这部分代码负责游戏界面的呈现。
// 在GUI中绘制游戏界面的方法
void OnGUI()
{
// 绘制剩余时间和得分
GUI.Label(new Rect(10, 10, 200, 20), "剩余时间: " + Mathf.Ceil(timeLeft));
GUI.Label(new Rect(10, 30, 200, 20), "得分: " + score);
// 如果游戏结束
if (isGameOver)
{
// 根据得分和剩余时间显示游戏结果
if (score >= 50 && timeLeft >= 0)
GUI.Label(new Rect(10, 50, 200, 20), "游戏胜利!");
else
GUI.Label(new Rect(10, 50, 200, 20), "游戏结束!");
// 提供重新开始按钮
if (GUI.Button(new Rect(10, 70, 100, 30), "重新开始"))
{
RestartGame(); // 玩家点击重新开始时调用 RestartGame 方法
}
}
// 绘制游戏网格中的方块
for (int x = 0; x < gridSize; x++)
{
for (int y = 0; y < gridSize; y++)
{
int colorIndex = grid[x, y];
Color blockColor = colors[colorIndex];
bool isSelected = selectedGrid[x, y];
GUI.color = isSelected ? Color.white : blockColor;
// 方块按钮,用于处理方块选择
if (GUI.Button(new Rect(255 + x * blockSpacing, 50 + y * blockSpacing, cellSize, cellSize), ""))
{
HandleGridSelection(x, y); // 玩家点击方块时调用 HandleGridSelection 方法
}
}
}
// 如果当前有方块被选中,绘制“确认消除”按钮
if (currentSelection.x != -1 && currentSelection.y != -1)
{
if (GUI.Button(new Rect(10, 100, 100, 30), "确认消除"))
{
ConfirmElimination(); // 玩家点击“确认消除”时调用 ConfirmElimination 方法
}
}
}
-
OnGUI
方法是游戏界面的主要呈现部分。它使用GUI.Label
来显示剩余时间和得分,以及根据游戏结束状态显示相应的消息(游戏胜利或游戏结束)。 -
如果游戏结束,它还提供了一个重新开始按钮,玩家可以点击这个按钮来重新开始游戏。
-
此外,
OnGUI
方法还绘制了游戏网格中的方块。它使用GUI.Button
来创建方块按钮,这些按钮可用于处理方块的选择(点击方块时调用HandleGridSelection
方法)。在绘制方块按钮时,根据方块是否被选中
3. 方块选择和消除
-
HandleGridSelection
方法处理方块的选择,允许玩家选择相邻的相同颜色的方块,否则清除选择状态。代码详细解释如下:- 如果当前没有方块被选中,允许选择当前方块。
- 如果当前已选中方块,允许选择与之相邻位置的相同颜色方块。
- 如果当前已选中方块,但选择的方块与之不相邻,重置选择状态,再次允许选择。
// 处理方块选择的方法
void HandleGridSelection(int x, int y)
{
// 如果当前没有选中的方块
if (currentSelection.x == -1 && currentSelection.y == -1)
{
currentSelection = new Vector2Int(x, y); // 设置当前选中的方块坐标
selectedGrid[x, y] = true; // 标记选中状态为 true
}
// 如果当前已有选中的方块且新选中方块与当前方块在同一行或同一列
else if (currentSelection.x == x || currentSelection.y == y)
{
// 如果新选中方块与当前方块颜色相同
if (grid[x, y] == grid[currentSelection.x, currentSelection.y])
{
currentSelection = new Vector2Int(x, y); // 更新当前选中的方块坐标
selectedGrid[x, y] = true; // 标记选中状态为 true
}
// 如果新选中方块与当前方块颜色不同
else
{
InitializeSelection(); // 重置所有方块的选择状态
currentSelection = new Vector2Int(x, y); // 设置当前选中的方块坐标
selectedGrid[x, y] = true; // 标记选中状态为 true
}
}
// 如果新选中方块与当前方块不在同一行或同一列
else
{
InitializeSelection(); // 重置所有方块的选择状态
currentSelection = new Vector2Int(x, y); // 设置当前选中的方块坐标
selectedGrid[x, y] = true; // 标记选中状态为 true
}
}
-
ConfirmElimination
方法用于确认消除选定的方块,计算分数,重新生成方块,并检查游戏状态。代码详细解释如下:- 计算选定方块的颜色和分数。
- 标记选定方块为已消除状态。
- 更新得分。
- 重置选择状态,允许玩家选择新的方块。
- 调用
RegenerateBlocks
方法重新生成方块。 - 检查游戏状态,包括判断游戏是否胜利或结束。
下面展示的就是上面截图的消除效果,不同颜色方块得分不同,消除后会随机生成不同颜色的方块。
// 确认消除选定的方块的方法
void ConfirmElimination()
{
int selectedColor = grid[currentSelection.x, currentSelection.y]; // 获取当前选中方块的颜色
int lineScore = 0; // 初始化本次消除的得分
// 遍历整个游戏网格
for (int x = 0; x < gridSize; x++)
{
for (int y = 0; y < gridSize; y++)
{
// 如果方块被选中
if (selectedGrid[x, y])
{
grid[x, y] = -1; // 标记方块为已消除,使用 -1 表示已消除状态
lineScore += selectedColor; // 累加得分,每个选中方块的颜色与当前选中方块颜色相同
}
}
}
score += lineScore; // 更新总得分
currentSelection = new Vector2Int(-1, -1); // 重置当前选中方块的坐标
InitializeSelection(); // 重置所有方块的选择状态
// 调用重新生成格子的方法,用于填充已消除的方块位置
RegenerateBlocks();
CheckGameStatus(); // 检查游戏状态,包括胜利和结束条件
Debug.Log($"消除了 {lineScore} 分的格子,总分 {score}"); // 在控制台中显示本次消除的得分和总得分
}
4. 重新生成方块
RegenerateBlocks
方法在方块消除后,重新生成新的方块,以保持游戏的进行。
// 重新生成已消除的方块
void RegenerateBlocks()
{
for (int x = 0; x < gridSize; x++)
{
for (int y = 0; y < gridSize; y++)
{
if (grid[x, y] == -1)
{
// 如果格子已消除,随机生成新的颜色
grid[x, y] = Random.Range(0, 4);
}
}
}
}
5. 游戏状态检查
CheckGameStatus
方法检查游戏是否结束或胜利。游戏结束条件包括得分达到一定目标或剩余时间耗尽。
// 检查游戏状态
void CheckGameStatus()
{
if (score >= 50 && timeLeft >= 0)
{
isGameOver = true;
Debug.Log("游戏胜利!");
}
if (timeLeft <= 0)
{
isGameOver = true;
Debug.Log("游戏结束!");
}
}
6. 重新开始游戏
RestartGame
方法用于重新开始游戏,将游戏状态重置为初始状态。
// 重新开始游戏
void RestartGame()
{
InitializeGrid();
InitializeSelection();
score = 0;
timeLeft = 60.0f;
isGameOver = false;
}
7. 待完善的功能
尽管这个项目已经实现了基本的游戏逻辑,但还有一些功能可以进一步完善:
- 生成结果逻辑: 目前的代码尚未包含生成结果的逻辑。您可以扩展游戏以在消除方块后计算和显示结果,例如最高分、排名等。
- 界面改进: 可以通过改进界面元素、添加动画效果和用户提示来提高游戏的可视性和用户交互性。
8.完整视频展示:
方块消除小游戏