特殊甜品的产生
如果消除到4个,可以在被消除的4个甜品的随机一个位置随机生成一个行消除或列消除的甜品
特殊甜品的产生
如果消除到4个,可以在被消除的4个甜品的随机一个位置随机生成一个行消除或列消除的甜品
L型匹配
T型匹配
public struct SweetPrefab { public SweetType type; public GameObject prefab; int num; private int x; }
//标记为public的字段才会显示在Inpector面板中
5:00 利用结构体 来初始化字典
行匹配列表
列匹配列表
完成匹配列表
行匹配
如果匹配的甜品有三个或者以上(if(matchRowSweet.count>3)),那么我们就应该加入行匹配列表,如果我们行匹配列表中存在三个或者以上甜品,那么我们就应该依次队每一个甜品进行列匹配。如果存在列匹配的甜品个数在2个或者以上的时候(如果没达到2个 清除列列表),我们就把这几个甜品加入到我们列匹配列表中,最后我们把全部满足条件的甜品放在我们的完成匹配列表中,如果行匹配之后,我们完成匹配列表中元素个数小于三 将三个列表清空
列匹配同理
填充的本质:决定某个甜品对象往哪里移动:
目的地: 正下方? 左下方? 右下方?
优先前往正下方,其次考虑左下方与右下方。
每一个甜品遍历左下方正下方与右下方看是否为空,以某甜品为例右下方为空,此时让空物体的下一个甜品往上遍历,如果空甜品上方物体可以移动则可以让甜品往下移动(问题)
(1)新建2D项目
(2)导入素材包
(3)在Asserts下新建文件夹
其中Animation存放动画,GameResources是导入的资源文件夹。Prefabs存放预制。Scenes存放场景。Scripts存放脚本。
(4)新建 Create Empty,游戏物体用于甜品的交互,移动,特效等,在模型层上进行控制。重命名为NormalSweetPrefab。
在GameManager下新建2D 的Sprite,重命名为sweet,用于控制甜品的渲染。然后将图标托给Sprite,发现较大。新建一个3D的Cube,默认为一个单位,调整Sprite的大小与Cube大致相同。
最后将预制体NormalSweetPrefab拖到Prefabs文件夹内。
(5)ctrl+D复制NormalSweetPrefab,建立格子背景预制。格子背景一经实例化创建出来,位置和大小就没有变化。所以不比分模型层和渲染层。删除渲染层。重命名为Grid。根据需求调整大小。最后将层级改为-1.
最后将预制体Grid拖到Prefabs文件夹内。
游戏管理的创建,巧克力的生成
(1)创建背景
新建2D的Sprite,将图片拖给它。调整图片大小覆盖摄像机。重命名为Background。
(2)游戏管理
控制整个游戏的运行,甜品的产生、消除等。右键Create Empty,重命名为GameManager。
然后在其身上挂一个同名的脚本。即GameManager.cs。将脚本拖到Scripts文件夹下。
(3)保存场景
Ctrl+S保存场景,命名为Game,将其拖到Scenes文件夹下。
(4)编辑脚本
双击GameManager.cs脚本,进行VS编辑。
做成单例模式。
// 单例
private static GameManager _instance; // ctr+r+e快捷键构建GET SET
public static GameManager Instance
{
get
{
return _instance;
}
set
{
_instance = value;
}
}
所有东西开始前实例化GameManager。即最先初始化。
private void Awake()
{
_instance = this;
}
定义行列数。
// 大网格的行列数
public int xColumn;
public int yRow;
然后进入unity,点击GameManager,在Inspector面板上可以设置行列数。
定义网格背景。
// 地图网格背景对象
public GameObject gridPrefab;
然后在unity的Inspector面板上将创建的Grid预制托给它。
整个地图实例化网格背景
在Start()方法中:
// 地图的实例化
for (int x = 0; x < xColumn; x++)
{
for (int y = 0; y < yRow; y++)
{
// 实例化棋子的背景(地图的实例化)
GameObject chessBg = Instantiate(gridPrefab, new Vector3(x,y,0),Quaternion.identity);
// 使chess父对象为GameManager
chessBg.transform.SetParent(transform);
}
}
棋子背景产生了,但位置不正确。下节课纠正位置。
修改背景层级为-2,位于最下方。
甜品的类型枚举,结构体,字典的创建
(1)枚举类型。
// 棋子的种类
public enum ChessType
{
EMPTY, // 空
NORMAL, // 一般类型
BARRIER, // 障碍
ROW_CLEAR, // 行消除
COLUMN_CLEAR, // 列消除
RAINBOWCHESS, // 彩虹
COUNT // 标记类型
}
(2)预制体字典。
// 棋子预制体的字典,我们可以通过棋子的种类来得到对应的棋子游戏物体
public Dictionary<ChessType, GameObject> chessPrefabDict;
(3)定义结构体使其显示在unity的inspector面板中。
// 结构体可序列化,可在unity中自由修改
[System.Serializable]
public struct ChessPrefab
{
public ChessType type;
public GameObject prefab;
}
(4)结构体数组,存储所有棋子的类型,使其显示在unity的inspector面板中,可以进行修改。
// 结构体数组,
public ChessPrefab[] chessPrefabs;
(5)预制体字典的实例化。将结构体中的值赋给字典。
在Start方法中。
// 字典的实例化
chessPrefabDict = new Dictionary<ChessType, GameObject>();
for (int i = 0; i < chessPrefabs.Length; i++)
{
if (!chessPrefabDict.ContainsKey(chessPrefabs[i].type))
{
// 传入键值
chessPrefabDict.Add(chessPrefabs[i].type, chessPrefabs[i].prefab);
}
}
(1)甜品数组
// 棋子数组,存放生成的棋子,用于后续操作
private GameChess[,] chesses;
(2)2层循环产生甜品
代码
(3)自定义甜品类:为了对甜品进行操作(移动、消除、动画播放、自身属性)。因此写一个甜品的基础脚本。
代码
(4)自定义甜品类初始化
代码
(1)将写好的自定义基础脚本挂载到预制体上。
(2)使用
// 棋子数组,存放生成的棋子,用于后续操作
private GameChess[,] chesses;
// 初始化界面,产生棋子
代码
新建移动脚本并将其挂载到预制上。
(1)移动算法实现:
(2)在自定义基础脚本里面添加一些东西。
// 棋子移动组件
private MovedChess movedComponent;
public MovedChess MovedComponent
{
get
{
return movedComponent;
}
}
// 判断棋子是否可以移动
public bool CanMove()
{
return movedComponent != null;
}
在上方加一个判断,是否能够更改x,y的值。
public int X
{
get
{
return x;
}
set
{
if (CanMove())
{
x = value;
}
}
}
public int Y
{
get
{
return y;
}
set
{
if (CanMove())
{
y = value;
}
}
}
在Awake方法里为移动组件赋值。
movedComponent = GetComponent<MovedChess>();
新建一个脚本ColorChess.cs来进行甜品不同类型的生成。由于GameManager.cs中已经定义的甜品的类型,注意这里是消除的类型(为了实现特殊消除)。因此这里为了生成不同样式的甜品,认为生成不同颜色的甜品。
删除GameManager.cs里中Update中的return;可以解决结算界面分数与实际所得分数不同的问题。
饼干消除算法:在饼干的周围有消除就把饼干一起消除。遍历消除的每一个甜品的四周,看是否有障碍物。有就消除掉。
掰掰!
666,6666,666
1.解决旋转特效出现停顿的方法:
做一个旋转特效的时候出现停顿,原因是unity动画自动是曲线会有平滑作用,想要匀速就要改成直线
方法:
点击key右键改变both tangents改变成linear即可,所有的key都要改变
1为什么只有行遍历不满足才列遍历
2