一、前言
嗨,大家好,我是新发。下班坐地铁的时候,好几次看到其他人在玩消消乐,既然大家都这么喜欢玩,那我就写个Unity
制作水果消消乐的教程吧。
我会根据内容点分成好几篇文章来讲,希望对想学Unity
的同学有所帮助,创作不易,喜欢的同学欢迎关注、点赞、收藏,文章目录如下:
第一篇:生成冰块阵列
第二篇:随机生成水果
第三篇:水果拖动与交换逻辑
第四篇:使用DOTween插件实现水果的滑动效果
第五篇:水果的消除检测,实现消除效果
第六篇:水果下落与新水果生成
第七篇:水果消除特效
第八篇:游戏得分加分效果
第九篇:使用UGUI显示游戏UI
游戏运行效果如下:
最终的Demo
工程已上传到GitHub
,感兴趣的同学可以自行下载下来学习。
GitHub
地址:https://github.com/linxinfa/UnityXiaoXiaoLeDemo
注:我使用的Unity
版本为2020.1.14f1c1
。
本篇讲随机生成水果的实现,本篇的效果:
二、导入水果图片素材
导入水果图片素材到工程中。
如下:
注意图片格式设置为Sprite (2D and UI)
。
三、制作水果预设
创建一个GameRes
文件夹用来存放预设。
在场景中创建一个FruitSpawner
空节点。
把水果的图片拖到FruitSpawner
子节点中,再拖到GameRes
文件夹中,这样就制作好一个水果预设了。
同理,制作其他水果预设。
四、水果生成器
现在,我们要使用代码来随机生成水果。
我们先分析一下,每一个水果有什么字段属性?有水果类型、图片、索引…
现在创建一个FruitItem.cs
脚本。
代码如下:
// FruitItem.cs
using UnityEngine;
/// <summary>
/// 水果脚本
/// </summary>
public class FruitItem : MonoBehaviour
{
/// <summary>
/// 行号
/// </summary>
public int rowIndex;
/// <summary>
/// 列号
/// </summary>
public int columIndex;
/// <summary>
/// 水果类型
/// </summary>
public int fruitType;
/// <summary>
/// 水果图片
/// </summary>
public GameObject fruitSpriteObj;
}
我们需要什么行为呢?
1 创建水果图片;
2 根据行号列号设置坐标。
添加对应的函数。
// FruitItem.cs
private Transform m_selfTransform;
private void Awake()
{
m_selfTransform = transform;
}
/// <summary>
/// 创建水果图片
/// </summary>
/// <param name="fruitType">水果类型</param>
/// <param name="prefab">水果图片预设</param>
public void CreateFruitBg(int fruitType, GameObject prefab)
{
if (null != fruitSpriteObj) return;
this.fruitType = fruitType;
fruitSpriteObj = Instantiate(prefab);
fruitSpriteObj.transform.localScale = Vector3.one * GlobalDef.CELL_SIZE;
fruitSpriteObj.transform.SetParent(m_selfTransform, false);
}
/// <summary>
/// 设置坐标
/// </summary>
public void UpdatePosition(int rowIndex, int columIndex)
{
this.rowIndex = rowIndex;
this.columIndex = columIndex;
var targetPos = new Vector3((columIndex - GlobalDef.COLUM_COUNT / 2f) * GlobalDef.CELL_SIZE + GlobalDef.CELL_SIZE / 2f, (rowIndex - GlobalDef.ROW_COUNT / 2f) * GlobalDef.CELL_SIZE + GlobalDef.CELL_SIZE / 2f, 0);
m_selfTransform.localPosition = targetPos;
}
现在,我们再创建一个生成器脚本:FruitSpawner.cs
,用来随机生成多行多列的水果。
代码如下:
// FruitSpawner.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FruitSpawner : MonoBehaviour
{
/// <summary>
/// 水果预设
/// </summary>
public GameObject[] fruitPrefabs;
/// <summary>
/// 生成出来的水果二维数组
/// </summary>
public ArrayList fruitList;
/// <summary>
/// 水果的根节点
/// </summary>
private Transform m_fruitRoot;
private void Awake()
{
m_fruitRoot = transform;
}
private void Start()
{
SpawnFruitArrayList();
}
/// <summary>
/// 生成多行多列水果
/// </summary>
private void SpawnFruitArrayList()
{
fruitList = new ArrayList();
for (int rowIndex = 0; rowIndex < GlobalDef.ROW_COUNT; ++rowIndex)
{
ArrayList temp = new ArrayList();
for (int columIndex = 0; columIndex < GlobalDef.COLUM_COUNT; ++columIndex)
{
var item = AddRandomFruitItem(rowIndex, columIndex);
temp.Add(item);
}
// 存到数组中
fruitList.Add(temp);
}
}
/// <summary>
/// 随机一个水果
/// </summary>
private FruitItem AddRandomFruitItem(int rowIndex, int columIndex)
{
// 随机一个水果类型
var fruitType = Random.Range(0, fruitPrefabs.Length);
var item = new GameObject("item");
item.transform.SetParent(m_fruitRoot, false);
item.AddComponent<BoxCollider2D>().size = Vector2.one * GlobalDef.CELL_SIZE;
var bhv = item.AddComponent<FruitItem>();
bhv.UpdatePosition(rowIndex, columIndex);
bhv.CreateFruitBg(fruitType, fruitPrefabs[fruitType]);
return bhv;
}
}
五、挂FruitSpawner脚本
将FruitSpawner
脚本挂到FruitSpawner
节点上。
把之前做的所有水果预设赋值给脚本的Fruit Prefabs
数组。
六、运行测试
运行Unity,测试效果如下:
我们显示有点异常,调整一下FruitSpawner
的z
轴,确保它在冰块的前面。
再调整FruitSpawner
与IceSpawner
为相同的缩放值。
再次运行Unity
,效果正常了。
场景中的层级如下:
下一篇讲水果的拖动交换逻辑的实现。
[点击进入下一篇]