前言
游戏需要实现一个点击输入图片的需求,输入12个后进行判断,如果和答案顺序不符合就清空重新输入。游戏效果如图所示。
对象池原理
对象池的应用主要是因为Unity实例和销毁游戏对象非常消耗性能,所以把需要经常实例销毁的游戏对象隐藏存起来,而不是直接销毁,然后在需要使用的时候优先从池子里把脏数据(隐藏后未经处理的游戏对象)清洗使用,如果池子里不够再创建新的游戏对象。
代码
接收点击事件的类
using UnityEngine;
using UnityEngine.EventSystems;
public enum InputType
{
Dian,
Xian
}
public class PeidianshiInput : MonoBehaviour,IPointerClickHandler
{
public InputType type;
public void OnPointerClick(PointerEventData eventData)
{
PeidianshiInputManager.instance.Show(type);
}
}
对象池类
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PeidianshiInputManager : MonoBehaviour
{
public static PeidianshiInputManager instance;
private bool isGameOver;
private int length = 0;//记录输入的长度
public Transform parent;
public Image dian, xian;//生成的两种对象
public float dis = 14;//生成对象的间隔距离
private const int inputCount = 12;
private Image i;//临时保存image
//两种类型的数据
private int dianPoolCount;
private List<Image> dianPool = new List<Image>();
private int xianPoolCount;
private List<Image> xianPool = new List<Image>();
private List<InputType> answerList = new List<InputType>();
private List<InputType> rightAnswerList = new List<InputType>();
void Start()
{
if (instance == null)
instance = this;
//初始化答案
rightAnswerList.Add(InputType.Xian);
rightAnswerList.Add(InputType.Xian);
rightAnswerList.Add(InputType.Dian);
rightAnswerList.Add(InputType.Dian);
rightAnswerList.Add(InputType.Dian);
rightAnswerList.Add(InputType.Dian);
rightAnswerList.Add(InputType.Xian);
rightAnswerList.Add(InputType.Xian);
rightAnswerList.Add(InputType.Xian);
rightAnswerList.Add(InputType.Xian);
rightAnswerList.Add(InputType.Dian);
rightAnswerList.Add(InputType.Dian);
}
/// <summary>
/// 对象创建和储存
/// </summary>
/// <param name="type"></param>
public void Show(InputType type)
{
if (isGameOver)
return;
if(length == 0)
{
switch (type)
{
case InputType.Dian:
if(dianPoolCount > 0)
{
RefresPoolGO(type);
}
else
{
i = Instantiate(dian, parent);
i.rectTransform.localPosition = new Vector3(-131, 63, 0);
dianPool.Add(i);
}
break;
case InputType.Xian:
if (xianPoolCount > 0)
{
RefresPoolGO(type);
}
else
{
i = Instantiate(xian, parent);
i.rectTransform.localPosition = new Vector3(-131, 63, 0);
xianPool.Add(i);
}
break;
}
answerList.Add(type);
++length;
return;
}
if (length <= inputCount)
{
switch (type)
{
case InputType.Dian:
if(dianPoolCount > 0)
{
RefresPoolGO(type);
}
else
{
i = Instantiate(dian, parent);
i.rectTransform.localPosition = new Vector3(-131 + length * dis, 63, 0);
dianPool.Add(i);
}
break;
case InputType.Xian:
if (xianPoolCount > 0)
{
RefresPoolGO(type);
}
else
{
i = Instantiate(xian, parent);
i.rectTransform.localPosition = new Vector3(-131 + length * dis, 63, 0);
xianPool.Add(i);
}
break;
}
answerList.Add(type);
++length;
if(length == inputCount)
{
Check();
}
}
}
/// <summary>
/// 核对答案
/// </summary>
private void Check()
{
for (int i = 0; i < inputCount; i++)
{
if(!(answerList[i] == rightAnswerList[i]))
{
foreach (var item in dianPool)
{
item.gameObject.SetActive(false);
}
foreach (var item in xianPool)
{
item.gameObject.SetActive(false);
}
dianPoolCount = dianPool.Count;
xianPoolCount = xianPool.Count;
answerList.Clear();
length = 0;
return;
}
}
isGameOver = true;
Debug.Log("sucess");
}
/// <summary>
/// 清洗数据
/// </summary>
/// <param name="type"></param>
void RefresPoolGO(InputType type)
{
switch (type)
{
case InputType.Dian:
dianPool[dianPoolCount - 1].rectTransform.localPosition = new Vector3(-131 + length * dis, 63, 0);
dianPool[dianPoolCount - 1].gameObject.SetActive(true);
--dianPoolCount;
break;
case InputType.Xian:
xianPool[xianPoolCount - 1].rectTransform.localPosition = new Vector3(-131 + length * dis, 63, 0);
xianPool[xianPoolCount - 1].gameObject.SetActive(true);
--xianPoolCount;
break;
}
}
}