一、前言
嗨,大家好,我是新发。下班坐地铁的时候,好几次看到其他人在玩消消乐,既然大家都这么喜欢玩,那我就写个Unity
制作水果消消乐的教程吧。
我会根据内容点分成好几篇文章来讲,希望对想学Unity
的同学有所帮助,创作不易,喜欢的同学欢迎关注、点赞、收藏,文章目录如下:
第一篇:生成冰块阵列
第二篇:随机生成水果
第三篇:水果拖动与交换逻辑
第四篇:使用DOTween插件实现水果的滑动效果
第五篇:水果的消除检测,实现消除效果
第六篇:水果下落与新水果生成
第七篇:水果消除特效
第八篇:游戏得分加分效果
第九篇:使用UGUI显示游戏UI
游戏运行效果如下:
最终的Demo
工程已上传到GitHub
,感兴趣的同学可以自行下载下来学习。
GitHub
地址:https://github.com/linxinfa/UnityXiaoXiaoLeDemo
注:我使用的Unity
版本为2020.1.14f1c1
。
本篇讲水果的消除检测,实现消除效果,本篇的效果:
二、遍历检测函数
我们思考一下,什么条件可以消除水果?
横向或者纵向,有三个或以上相同的水果连在一起,则可以消除掉。
我们把需要消除的水果先缓存到一个数组中,定义个数组,并封装一个AddMatchFruit
函数。
// FruitSpawner.cs
/// <summary>
/// 需要消除掉的水果数组
/// </summary>
private ArrayList m_matchFruits;
/// <summary>
/// 添加匹配的水果到缓存中(匹配的水果会被消除掉)
/// </summary>
private void AddMatchFruit(FruitItem item)
{
if (null == m_matchFruits)
m_matchFruits = new ArrayList();
int index = m_matchFruits.IndexOf(item);
if (-1 == index)
m_matchFruits.Add(item);
}
现在,我们先写一个横向的检测,遍历每一行,判断a、a+1、a+2是否相同,相同则把这些水果塞入到m_matchFruits
中。
// FruitSpawner.cs
/// <summary>
/// 横线检测水果
/// </summary>
private bool CheckHorizontalMatch()
{
bool isMatch = false;
for (int rowIndex = 0; rowIndex < GlobalDef.ROW_COUNT; ++rowIndex)
{
for (int columIndex = 0; columIndex < GlobalDef.COLUM_COUNT - 2; ++columIndex)
{
var item1 = GetFruitItem(rowIndex, columIndex);
var item2 = GetFruitItem(rowIndex, columIndex + 1);
var item3 = GetFruitItem(rowIndex, columIndex + 2);
if (item1.fruitType == item2.fruitType && item2.fruitType == item3.fruitType)
{
isMatch = true;
AddMatchFruit(item1);
AddMatchFruit(item2);
AddMatchFruit(item3);
}
}
}
return isMatch;
}
同理,纵向检测的也封装一个函数。
// FruitSpawner.cs
/// <summary>
/// 纵向检测水果
/// </summary>
/// <returns></returns>
private bool CheckVerticalMatch()
{
bool isMatch = false;
for (int columIndex = 0; columIndex < GlobalDef.COLUM_COUNT; ++columIndex)
{
for (int rowIndex = 0; rowIndex < GlobalDef.ROW_COUNT - 2; ++rowIndex)
{
var item1 = GetFruitItem(rowIndex, columIndex);
var item2 = GetFruitItem(rowIndex + 1, columIndex);
var item3 = GetFruitItem(rowIndex + 2, columIndex);
if (item1.fruitType == item2.fruitType && item2.fruitType == item3.fruitType)
{
isMatch = true;
AddMatchFruit(item1);
AddMatchFruit(item2);
AddMatchFruit(item3);
}
}
}
return isMatch;
}
三、水果消除
现在,检测到匹配的水果已经塞到m_matchFruits
数组中,我们要消除水果,则遍历这个数组进行消除即可。
先给FruitItem
封装一个销毁水果图片的接口。
// FruitItem.cs
/// <summary>
/// 销毁水果图片
/// </summary>
public void DestroyFruitBg()
{
Destroy(fruitSpriteObj);
fruitSpriteObj = null;
}
接着,在FruitSpawner
中封装一个
/// <summary>
/// 消除水果
/// </summary>
private void RemoveMatchFruit()
{
for (int i = 0; i < m_matchFruits.Count; ++i)
{
var item = m_matchFruits[i] as FruitItem;
item.DestroyFruitBg();
}
}
四、ExchangeAndMatch函数
现在,我们可以在FruitSpawner
的ExchangeAndMatch
函数中调用上面封装的函数了,如下:
// FruitSpawner.cs
/// <summary>
/// 交换水果并检测是否可以消除
/// </summary>
IEnumerator ExchangeAndMatch(FruitItem item1, FruitItem item2)
{
Exchange(item1, item2);
yield return new WaitForSeconds(0.3f);
if (CheckHorizontalMatch() || CheckVerticalMatch())
{
// 消除匹配的水果
RemoveMatchFruit();
yield return new WaitForSeconds(0.6f);
// TODO 上面的水果掉落下来
// TODO 生成新的水果
m_matchFruits = new ArrayList();
// TODO 再次执行一次检测
}
else
{
// 没有任何水果匹配,交换回来
Exchange(item1, item2);
}
}
五、运行测试
运行Unity,测试效果如下:
我们看到,水果消除成功了,不过消除后上面的水果不会掉下来,也不会生成新的水果。
下一篇就讲消除后水果下落和新水果生成。
[点击进入下一篇]