写在阅读之前(项目在最后)
如果你是一个初入Unity的小白,本是兴致勃勃想开启自己的游戏创作之旅,却受够了干巴巴的Unity+C#课程,听了一堆课程还是不知道“我是谁、我在哪、我要做什么”,那么请务必看完本篇文章;如果是大佬或准备靠Unity吃饭的程序员可以划走了,因为收获不会很大。
适合接触Unity不久的大学生(哪个学计算机的大学生不想自己做一个游戏?),C++课上教的东西还算明白(为数不多的要求),有时间学习又不着急工作的(就是玩嘿嘿),以学习和提升能力为主(咳咳)。希望各位兄弟能够不被Unity的复杂劝退,体会到做成项目的喜悦!
看完这篇文章,至少能教会简单的扫雷游戏制作思路,下文会:
努力讲清楚从0开始的制作方法!
听不懂方法?直接上源码!
源码也不知道往哪粘?直接给项目!
先上运行效果+外行都能看得懂的简单介绍:
欢迎场景:
开始场景,能够自定义行列和雷的数量,并检查雷的数量是否小于行×列,能够实现退出游戏。
运行一个10×5的场景,10个雷:
左键单击开始,右键标记,能够实现标记足够时,单机数字自动展开其余块。
游玩场景:
不是类的块全部点开后,会有按钮提示胜利。或者点到雷了,会提示失败。
简单的演示完了,如果觉得页面和操作过于垃圾,就可以点走了,因为接下来就是做这个垃圾(手动狗头)。
思路讲解
首先要知道Unity和C++黑窗口的区别,Unity是有图形页面的,因此脑海中一定要清楚先实现逻辑再实现图像。
本项目分“欢迎场景”和“游戏场景”,先实现游戏场景。
1. 对于“欢迎场景”给的Row(行)和Colunm(列),首先生成Row×Colunm的棋盘(逻辑棋盘,用int数组就可)。此处假设Row和Colunm已经接收到,声明一个静态变量用着就行。
2.初始化逻辑棋盘所有值为0,0代表此处及周围没有雷,1代表周围有1个雷,2代表......,9代表此处就是雷。
3.随机生成Boom个雷,也就是在0到Row×Colunm中随机选取Boom个不同的数,这些选取的数字就是雷,接下来将这些数转成2维的就行了,例如行列为5的情况下,0就是(0, 0),3就是(0, 2),8就是(1, 3)。这里记住数组是从0开始的,和c++一样,就是简单的将一维数组变为二维时的下标对应方法。
4.将逻辑棋盘中对应的值设置为9。
5.来一个双层循环,从(0, 0)一直遍历到(Row-1, Colunm-1),计算所有格子周围8块中雷(逻辑棋盘==9)有多少,并给此块赋值。
6.至此逻辑棋盘初始化完毕!
7.再来一个双层循环,开始用Instantiate方法生成对应于逻辑棋盘的方块到指定位置(最上面声明一个List来存放对应预制体),并把这些方块存在实物棋盘中(GameObject[,] blocksObj)。
8.至此棋盘已经声明完毕,设置两个共有的属性来做逻辑棋盘和实物棋盘的接口。(这句话可能表达的不清楚,就是其它脚本得访问这两个数组,但不可能给它声明成共有静态的(其实也可以,但是为了"安全"起见,还是养好习惯),所以创建了两个属性来进行访问,不理解的可以百度搜索“C#属性”)。
9.接下来对每个方块写脚本。每个方块有三种状态:盖着、掀开、标记(这里通俗的说了),设置一个共有的枚举来存放三个状态,并初始化每个方块为盖着状态。
10.我们需要对方块左键和右键操作,左键掀开右键标记,但是创建的按钮只能接受左键(又好像是对左键右键不做区分),所以继承IPointerClickHandler类并写相应代码(网上直接找的,我也不会写)。
11.对于左键点击,如果是盖着状态,就掀开;若是掀开状态,就和辅助掀开(点数字时),做好方块状态切换就行。右键就是标记状态和盖着状态的切换。
12.“掀开”操作是重中之重,用递归来写,就是检测周围8个块有没有0(逻辑棋盘),有就对0那个块执行“掀开”操作。当然掀到9就输了(doge)。
13.“辅助掀开”借助“掀开”操作,检测周围8个块的标记数量是否够点击的这个块的数值,若够了,就对周围没有标记的块执行“掀开”。
14.关键逻辑做完了,接下来判断下赢和输就行了。
欢迎场景的实现
做好UI放好按钮就行,用SceneManagement进行场景切换(记得using相应的东西,并在build中把场景加进去)。写一个GameData脚本(网上抄的),功能是切换场景是不销毁,把欢迎场景写的行列和雷的数量传到游戏场景就行了。
代码实现
什么?有思路不会写代码?那代码也给放上来。
这就是该项目所有的代码......名字,从左到右简单介绍一下。
Ans判断输赢的。
CameraMove是摄像机移动。因为可以设计一个10000×10000(自己定)的棋盘,摄像机照不完,用WASD来移动Camera的。
TitleData生成不重复随机数的一个类(网上找的)。
GameController初始化逻辑棋盘和实物棋盘的。
StartGame是欢迎场景接受行列和跳转场景的。
GameData切换场景不销毁,存行列雷数值的。
Block是处理每个方块左键右键,掀开和辅助掀开的。
关键的就是GameController和Block这两个脚本,基本对应了思路讲解,下面具体放一下代码:
GameController脚本(还不算太长)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameController : MonoBehaviour
{
[SerializeField] List<GameObject> blocks;
int row;
int colunm;
int boom;
int[,] plane;
GameObject[,] blocksObj;
private void Start()
{
row = GameData.Instance.Row;
colunm = GameData.Instance.Colunm;
boom = GameData.Instance.Boom;
plane = new int[row, colunm];
blocksObj = new GameObject[row, colunm];
InitPlane();
}
void InitPlane()
{
for(int i=0; i<row; i++)
{
for