效果
思路
1.轮盘的移动
方法1:
3行的转盘上最多同时出现3+1=4行元素
一开始我使每一列4个元素同时向下移动,某个元素移动小于下方界限时,将其移动到最上方看不见的地方,这样实现循环移动。
这个方法可行,但遇到大小不同的元素时,渲染层级出现问题。
故采用方法2:
使整列的节点向下移动,移动1个元素的标准高度后还原,并将其子元素中的sprite向下传递,最上方的元素传入新数据
2.停止转动
从一个结果数组中依次从下到上取某一列的结果,并标记已取出,没有值可以取出时停止移动。
代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Game : MonoBehaviour
{
public Transform root;//根节点
private int[] itemColStates=new int[6] {0,0,0,0,0,0 };//某列元素状态 0为静置 1为转动 2为准备停止
public Sprite[] itemSprites;//元素图片集合
private int[] result = new int[]{0, 0, 7, 2, 3, 4, 5, 0, 7, 2, 3, 4, 5, 0, 7, 2, 3, 4, 5 ,0,7,2,3,4,5};//停止时的结果 第一个元素0没使用
public Transform[] itemNodes0;//列节点
public Transform[] itemNodes1;
public Transform[] itemNodes2;
public Transform[] itemNodes3;
public Transform[] itemNodes4;
public Transform[] itemNodes5;
public Transform[] itemColNodes;//列节点
private Transform[][] itemnodes;//总节点
public Button start;
public Button stop;
private int row = 5;//行数
private int col = 6;//列数
private float colPosYStart = -235f;//每一列起始位置
private float colPosYEnd = -352f;//每一列刷新图像时的位置
private float speed;//转盘转动时 元素y轴每一帧移动的坐标值
private int[] stopDelay = new int[6];
// Start is called before the first frame update
void Start()
{
itemnodes = new Transform[][] { itemNodes0, itemNodes1, itemNodes2, itemNodes3, itemNodes4, itemNodes5 };
speed = (colPosYEnd - colPosYStart) / 3;
start.onClick.AddListener(() => {
startGame();
start.gameObject.SetActive(false);
stop.gameObject.SetActive(true);
});
stop.onClick.AddListener(()=> {
stopGame(50);
start.gameObject.SetActive(true);
stop.gameObject.SetActive(false);
});
for (int i = 0; i < col; i++)
{
for (int j = 0; j < row; j++)
{
itemnodes[i][j].GetComponent<Image>().sprite = itemSprites[Random.Range(0, 14)];//设置随机图片
itemnodes[i][j].GetComponent<Image>().SetNativeSize();//设置图片为原始尺寸
}
}
}
// Update is called once per frame
void Update()
{
//遍历每一列
for (int i = 0; i < col; i++)
{
//某一列处于旋转状态
if (itemColStates[i]==1)
{
//使该列向下移动
itemColNodes[i].localPosition += new Vector3(0,speed);
//已经达到最底部
if (itemColNodes[i].localPosition.y<=colPosYEnd)
{
//恢复整列原来的位置
itemColNodes[i].localPosition = new Vector3(itemColNodes[i].localPosition.x,colPosYStart);
//除第一行外 由下到上替换图片
for (int j = row-1; j <= 1; j--)
{
itemnodes[i][j].GetComponent<Image>().sprite = itemnodes[i][j - 1].GetComponent<Image>().sprite;
itemnodes[i][j].GetComponent<Image>().SetNativeSize();
}
itemnodes[i][0].GetComponent<Image>().sprite = itemSprites[Random.Range(0, 14)];//设置随机图片
itemnodes[i][0].GetComponent<Image>().SetNativeSize();//设置图片为原始尺寸
}
//某一列停止延时计算
if (stopDelay[i]>0)
{
stopDelay[i]--;
//某一列应该停止旋转
if (stopDelay[i]<=0)
{
itemColStates[i] = 2;//准备停止
}
}
}
//某一列处于准备停止状态
else if (itemColStates[i] == 2)
{
//使该列向下移动
itemColNodes[i].localPosition += new Vector3(0,speed);
//已经达到最底部
if (itemColNodes[i].localPosition.y <= colPosYEnd)
{
//恢复整列原来的位置
itemColNodes[i].localPosition = new Vector3(itemColNodes[i].localPosition.x, colPosYStart);
//除第一行外 由下到上替换图片
for (int j = row - 1; j <= 1; j--)
{
//sprite向下传递
itemnodes[i][j].GetComponent<Image>().sprite = itemnodes[i][j - 1].GetComponent<Image>().sprite;
itemnodes[i][j].GetComponent<Image>().SetNativeSize();
}
int spriteIndex = GetColResult(i);//获取结果
//结果值已经全部取出
if (spriteIndex==-1)
{
itemColStates[i] = 0;
}
else
{
itemnodes[i][0].GetComponent<Image>().sprite = itemSprites[result[spriteIndex]];//设置图片
result[spriteIndex] = -1;//标记已取值
itemnodes[i][0].GetComponent<Image>().SetNativeSize();//设置图片为原始尺寸
}
}
}
}
}
/// <summary>
/// 开启
/// </summary>
private void startGame() {
for (int i = 0; i < col; i++)
{
itemColStates[i] = 1;
}
}
/// <summary>
/// 停止
/// </summary>
/// <param name="delay"></param>
private void stopGame(int delay) {
for (int i = 0; i < col; i++)
{
stopDelay[i] = delay + i * 25;//为每一列设置停止延时
}
}
/// <summary>
/// 获取某列自下到上的一个结果索引
/// </summary>
/// <param name="col">某列</param>
/// <returns>返回取出元素的索引</returns>
private int GetColResult(int col) {
//该列从最后一个元素到第一个元素都为nil时停止,否则将该值取出,将对应图案显示在元素上
int resultCount = this.col * (row - 1);
int k = resultCount - this.col + col;
while (k>=1)
{
if (result[k]!=-1)
{
return k;
}
else
{
k -= this.col;
}
}
return -1;
}
}