转盘游戏实现

效果

在这里插入图片描述

思路

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;
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值