模拟魔方还原

第一次写博客,还不知道怎么写。

自己制作的魔方还原项目,写入cfop高级公式

先上几张效果图吧 ↓

这是刚开始时,未打乱

模拟魔方还原_第1张图片

这是在打乱过程中

模拟魔方还原_第2张图片

还原之后,除了中心块朝向不同(当然,魔方还原也没有要求中心块朝向)

模拟魔方还原_第3张图片

这是一年前做的小项目了,当时使用的Unity3D5.6版本开发

开发的是mvc初步项目设计架构。

引入自己写的dll库文件以达到后期可以移植的可能性。

数据模型

编写时首先使用控制台应用编写数据模型的模拟还原。

首先搭建魔方结构(自己写的Vec3)

/// 
    /// 魔方管理
    /// 
    /// 
    ///     所有方块的旋转由此文件管理封装
    ///     
    /// 使用:
    ///     构造器中Init创建一个魔方
    ///     ...
    public class RubikCube
    {
        /// 
        /// 所有旋转事件的集合
        /// 
        List[] list_event = new List[9];
        #region 方块变量
        /// 
        /// 角块
        /// 
        public Cube[][][] hornbiock { get; private set; }
        /// 
        /// 棱块
        /// 
        public Cube[][][] edgeCube { get; private set; }
        /// 
        /// 中心块
        /// 
        public Cube[][][] centreCube { get; private set; }
        #endregion
        public RubikCube()
        {
            Init();
        }
        /// 
        /// 方块对象初始化
        /// 
        private void Init()
        {
            #region 集合数组
            for (int i = 0; i < list_event.Length; i++)
            {
                list_event[i] = new List();
            }
            #endregion
            #region 角块
            hornbiock = new Hornblock[2][][];
            for (int i = 0; i < 2; i++)
            {
                hornbiock[i] = new Hornblock[2][];
                for (int j = 0; j < 2; j++)
                {
                    hornbiock[i][j] = new Hornblock[2];
                    for (int k = 0; k < 2; k++)
                    {
                        hornbiock[i][j][k] = new Hornblock(new RubikCubeVector3(ESurface.U, ESurface.F, ESurface.R));
                    }
                }
            }
            hornbiock[0][0][0].Twirl_U().Twirl_U().ToState();
            hornbiock[0][0][1].Twirl_U().ToState();
            hornbiock[0][1][0].Twirl_R().Twirl_R().Twirl_D().ToState();
            hornbiock[0][1][1].Twirl_F().Twirl_F().ToState();
            hornbiock[1][0][0].Twirl_U(false).ToState();
            hornbiock[1][0][1].ToState();
            hornbiock[1][1][0].Twirl_R().Twirl_R().ToState();
            hornbiock[1][1][1].Twirl_R().Twirl_R().Twirl_D(false).ToState();
            for (int i = 0; i < 2; i++)
            {
                for (int j = 0; j < 2; j++)
                {
                    for (int k = 0; k < 2; k++)
                    {
                        hornbiock[i][j][k].Position = hornbiock[i][j][k].StatePosition;
                        hornbiock[i][j][k].SetListEvent(list_event);
                    }
                }
            }
            //hornbiock[0][0][0]//UBL
            //hornbiock[0][0][1]//UFL
            //hornbiock[0][1][0]//DBL
            //hornbiock[0][1][1]//DFL
            //hornbiock[1][0][0]//UBR
            //hornbiock[1][0][1]//UFR
            //hornbiock[1][1][0]//DBR
            //hornbiock[1][1][1]//DFR
            list_event[(int)ESurface.U].Add(hornbiock[0][0][0]); list_event[(int)ESurface.U].Add(hornbiock[0][0][1]); list_event[(int)ESurface.U].Add(hornbiock[1][0][0]); list_event[(int)ESurface.U].Add(hornbiock[1][0][1]);
            list_event[(int)ESurface.D].Add(hornbiock[0][1][0]); list_event[(int)ESurface.D].Add(hornbiock[0][1][1]); list_event[(int)ESurface.D].Add(hornbiock[1][1][0]); list_event[(int)ESurface.D].Add(hornbiock[1][1][1]);
            list_event[(int)ESurface.F].Add(hornbiock[0][0][1]); list_event[(int)ESurface.F].Add(hornbiock[0][1][1]); list_event[(int)ESurface.F].Add(hornbiock[1][0][1]); list_event[(int)ESurface.F].Add(hornbiock[1][1][1]);
            list_event[(int)ESurface.B].Add(hornbiock[0][0][0]); list_event[(int)ESurface.B].Add(hornbiock[0][1][0]); list_event[(int)ESurface.B].Add(hornbiock[1][0][0]); list_event[(int)ESurface.B].Add(hornbiock[1][1][0]);
            list_event[(int)ESurface.R].Add(hornbiock[1][0][0]); list_event[(int)ESurface.R].Add(hornbiock[1][0][1]); list_event[(int)ESurface.R].Add(hornbiock[1][1][0]); list_event[(int)ESurface.R].Add(hornbiock[1][1][1]);
            list_event[(int)ESurface.L].Add(hornbiock[0][0][0]); list_event[(int)ESurface.L].Add(hornbiock[0][0][1]); list_event[(int)ESurface.L].Add(hornbiock[0][1][0]); list_event[(int)ESurface.L].Add(hornbiock[0][1][1]);
            #endregion
            #region 棱块
            edgeCube = new EdgeCube[2][][];
            for (int i = 0; i < 2; i++)
            {
                edgeCube[i] = new EdgeCube[3][];
                for (int j = 0; j < 3; j++)
                {
                    edgeCube[i][j] = new EdgeCube[2];
                    for (int k = 0; k < 2; k++)
                    {
                        edgeCube[i][j][k] = new EdgeCube(new RubikCubeVector2(ESurface.U, ESurface.F));
                    }
                }
            }//end -- 上下两层棱块初始化
            edgeCube[0][0][0].Twirl_U().Twirl_U().ToState();
            edgeCube[0][0][1].Twirl_U().ToState();
            edgeCube[0][1][0].Twirl_U().Twirl_U().Twirl_B().ToState();
            edgeCube[0][1][1].Twirl_F(false).ToState();
            edgeCube[0][2][0].Twirl_F().Twirl_F().Twirl_D().Twirl_D().ToState();
            edgeCube[0][2][1].Twirl_F().Twirl_F().Twirl_D(false).ToState();
            edgeCube[1][0][0].Twirl_U(false).ToState();
            edgeCube[1][0][1].ToState();
            edgeCube[1][1][0].Twirl_U().Twirl_U().Twirl_B(false).ToState();
            edgeCube[1][1][1].Twirl_F().ToState();
            edgeCube[1][2][0].Twirl_F().Twirl_F().Twirl_D().ToState();
            edgeCube[1][2][1].Twirl_F().Twirl_F().ToState();

            for (int i = 0; i < 2; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    for (int k = 0; k < 2; k++)
                    {
                        edgeCube[i][j][k].Position = edgeCube[i][j][k].StatePosition;
                        edgeCube[i][j][k].SetListEvent(list_event);
                    }
                }
            }
            //edgeCube[0][0][0]// U B M
            //edgeCube[0][0][1]// U L S
            //edgeCube[0][1][0]// L B E
            //edgeCube[0][1][1]// L F E
            //edgeCube[0][2][0]// D B M
            //edgeCube[0][2][1]// D L S
            //edgeCube[1][0][0]// U R S
            //edgeCube[1][0][1]// U F M
            //edgeCube[1][1][0]// R B E
            //edgeCube[1][1][1]// R F E
            //edgeCube[1][2][0]// D R S
            //edgeCube[1][2][1]// D F M
            list_event[(int)ESurface.U].Add(edgeCube[0][0][0]); list_event[(int)ESurface.U].Add(edgeCube[0][0][1]); list_event[(int)ESurface.U].Add(edgeCube[1][0][0]); list_event[(int)ESurface.U].Add(edgeCube[1][0][1]);
            list_event[(int)ESurface.D].Add(edgeCube[0][2][0]); list_event[(int)ESurface.D].Add(edgeCube[0][2][1]); list_event[(int)ESurface.D].Add(edgeCube[1][2][0]); list_event[(int)ESurface.D].Add(edgeCube[1][2][1]);
            list_event[(int)ESurface.F].Add(edgeCube[0][1][1]); list_event[(int)ESurface.F].Add(edgeCube[1][0][1]); list_event[(int)ESurface.F].Add(edgeCube[1][1][1]); list_event[(int)ESurface.F].Add(edgeCube[1][2][1]);
            list_event[(int)ESurface.B].Add(edgeCube[0][0][0]); list_event[(int)ESurface.B].Add(edgeCube[0][1][0]); list_event[(int)ESurface.B].Add(edgeCube[0][2][0]); list_event[(int)ESurface.B].Add(edgeCube[1][1][0]);
            list_event[(int)ESurface.R].Add(edgeCube[1][0][0]); list_event[(int)ESurface.R].Add(edgeCube[1][1][0]); list_event[(int)ESurface.R].Add(edgeCube[1][1][1]); list_event[(int)ESurface.R].Add(edgeCube[1][2][0]);
            list_event[(int)ESurface.L].Add(edgeCube[0][0][1]); list_event[(int)ESurface.L].Add(edgeCube[0][1][0]); list_event[(int)ESurface.L].Add(edgeCube[0][1][1]); list_event[(int)ESurface.L].Add(edgeCube[0][2][1]);
            //
            list_event[(int)ESurface.M].Add(edgeCube[0][0][0]); list_event[(int)ESurface.M].Add(edgeCube[0][2][0]); list_event[(int)ESurface.M].Add(edgeCube[1][0][1]); list_event[(int)ESurface.M].Add(edgeCube[1][2][1]);
            list_event[(int)ESurface.S].Add(edgeCube[0][0][1]); list_event[(int)ESurface.S].Add(edgeCube[0][2][1]); list_event[(int)ESurface.S].Add(edgeCube[1][0][0]); list_event[(int)ESurface.S].Add(edgeCube[1][2][0]);
            list_event[(int)ESurface.E].Add(edgeCube[0][1][0]); list_event[(int)ESurface.E].Add(edgeCube[0][1][1]); list_event[(int)ESurface.E].Add(edgeCube[1][1][0]); list_event[(int)ESurface.E].Add(edgeCube[1][1][1]);
            #endregion
            #region 中心块
            centreCube = new CentreCube[2][][];
            for (int i = 0; i < 2; i++)
            {
                centreCube[i] = new CentreCube[3][];
                for (int j = 0; j < 3; j++)
                {
                    centreCube[i][j] = new CentreCube[1];
                    for (int k = 0; k < 1; k++)
                    {
                        centreCube[i][j][k] = new CentreCube(new RubikCubeVector1(ESurface.U));
                    }
                }
            }
            ((RubikCubeVector1)centreCube[0][0][0].Position).C = ESurface.U;
            ((RubikCubeVector1)centreCube[0][1][0].Position).C = ESurface.L;
            ((RubikCubeVector1)centreCube[0][2][0].Position).C = ESurface.F;
            ((RubikCubeVector1)centreCube[1][0][0].Position).C = ESurface.B;
            ((RubikCubeVector1)centreCube[1][1][0].Position).C = ESurface.R;
            ((RubikCubeVector1)centreCube[1][2][0].Position).C = ESurface.D;
            for (int i = 0; i < 2; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    for (int k = 0; k < 1; k++)
                    {
                        centreCube[i][j][k].ToState();
                        centreCube[i][j][k].SetListEvent(list_event);
                    }
                }
            }
            list_event[(int)ESurface.U].Add(centreCube[0][0][0]);
            list_event[(int)ESurface.D].Add(centreCube[1][2][0]);
            list_event[(int)ESurface.F].Add(centreCube[0][2][0]);
            list_event[(int)ESurface.B].Add(centreCube[1][0][0]);
            list_event[(int)ESurface.R].Add(centreCube[1][1][0]);
            list_event[(int)ESurface.L].Add(centreCube[0][1][0]);
            //
            list_event[(int)ESurface.M].Add(centreCube[0][0][0]); list_event[(int)ESurface.M].Add(centreCube[1][0][0]); list_event[(int)ESurface.M].Add(centreCube[0][2][0]); list_event[(int)ESurface.M].Add(centreCube[1][2][0]);
            list_event[(int)ESurface.E].Add(centreCube[1][0][0]); list_event[(int)ESurface.E].Add(centreCube[0][1][0]); list_event[(int)ESurface.E].Add(centreCube[1][1][0]); list_event[(int)ESurface.E].Add(centreCube[0][2][0]);
            list_event[(int)ESurface.S].Add(centreCube[0][0][0]); list_event[(int)ESurface.S].Add(centreCube[1][2][0]); list_event[(int)ESurface.S].Add(centreCube[0][1][0]); list_event[(int)ESurface.S].Add(centreCube[1][1][0]);

            #endregion
        }

        #region 转动事件
        public object Twirl(ESurface es, bool clockwise = true)
        {
            switch (es)
            {
                case ESurface.U: Twirl_U(clockwise); break;
                case ESurface.D: Twirl_D(clockwise); break;
                case ESurface.F: Twirl_F(clockwise); break;
                case ESurface.B: Twirl_B(clockwise); break;
                case ESurface.R: Twirl_R(clockwise); break;
                case ESurface.L: Twirl_L(clockwise); break;
                case ESurface.M: Twirl_M(clockwise); break;
                case ESurface.S: Twirl_S(clockwise); break;
                case ESurface.E: Twirl_E(clockwise); break;
                default:
                    break;
            }
            return null;
        }
        public void Twirl_B(bool clockwise)
        {
            foreach (Cube item in list_event[(int)ESurface.B])
            {
                item.Twirl_B(clockwise);
            }
        }

        public void Twirl_D(bool clockwise)
        {
            foreach (Cube item in list_event[(int)ESurface.D])
            {
                item.Twirl_D(clockwise);
            }
        }

        public void Twirl_F(bool clockwise)
        {
            foreach (Cube item in list_event[(int)ESurface.F])
            {
                item.Twirl_F(clockwise);
            }
        }

        public void Twirl_L(bool clockwise)
        {
            foreach (Cube item in list_event[(int)ESurface.L])
            {
                item.Twirl_L(clockwise);
            }
        }

        public void Twirl_R(bool clockwise)
        {
            foreach (Cube item in list_event[(int)ESurface.R])
            {
                item.Twirl_R(clockwise);
            }
        }

        public void Twirl_U(bool clockwise)
        {
            foreach (Cube item in list_event[(int)ESurface.U])
            {
                item.Twirl_U(clockwise);
            }
        }

        public void Twirl_M(bool clockwise)
        {
            foreach (Cube item in list_event[(int)ESurface.M])
            {
                item.Twirl_M(clockwise);
            }
        }

        public void Twirl_S(bool clockwise)
        {
            foreach (Cube item in list_event[(int)ESurface.S])
            {
                item.Twirl_S(clockwise);
            }
        }

        public void Twirl_E(bool clockwise)
        {
            foreach (Cube item in list_event[(int)ESurface.E])
            {
                item.Twirl_E(clockwise);
            }
        }
        #endregion
    }
/// 
    /// 魔方-方块
    /// 
    public abstract class Cube
    {
        public IMedlTwirl medlTwirl { protected get; set; }
        public Cube(RubikCubePosition position) { this.position = position; statePosition = position; }

        /// 
        /// 所有事件的集合的引用
        /// 
        protected List[] list_event = null;

        /// 
        /// 位置坐标
        /// 
        protected RubikCubePosition position;
        public RubikCubePosition Position { get { return position; } set { position = value; } }
        /// 
        /// 初始位置坐标
        /// 
        protected RubikCubePosition statePosition;
        public RubikCubePosition StatePosition { get { return statePosition; } }
        /// 
        /// 将当前坐标做为复原坐标
        /// 
        public void ToState() { statePosition = position; }
        /// 
        /// 设置集合的引用
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        public void SetListEvent(List[] list_event)
        {
            this.list_event = list_event;
        }
        public abstract Cube Copy();

        public Cube Twirl(ESurface es, bool clockwise = true)
        {
            switch (es)
            {
                case ESurface.U: return Twirl_U(clockwise);
                case ESurface.D: return Twirl_D(clockwise);
                case ESurface.F: return Twirl_F(clockwise);
                case ESurface.B: return Twirl_B(clockwise);
                case ESurface.R: return Twirl_R(clockwise);
                case ESurface.L: return Twirl_L(clockwise);
            }
            return null;
        }
        /// 
        /// 转动上层
        /// 
        /// 是否顺时针
        public abstract Cube Twirl_U(bool clockwise = true);
        /// 
        /// 转动下层
        /// 
        /// 是否顺时针
        public abstract Cube Twirl_D(bool clockwise = true);
        /// 
        /// 转动前层
        /// 
        /// 是否顺时针
        public abstract Cube Twirl_F(bool clockwise = true);
        /// 
        /// 转动后层
        /// 
        /// 是否顺时针
        public abstract Cube Twirl_B(bool clockwise = true);
        /// 
        /// 转动右层
        /// 
        /// 是否顺时针
        public abstract Cube Twirl_R(bool clockwise = true);
        /// 
        /// 转动左层
        /// 
        /// 是否顺时针
        public abstract Cube Twirl_L(bool clockwise = true);
        /// 
        /// 转动M层(绕X轴)
        /// 
        /// 是否顺时针
        /// 
        public virtual Cube Twirl_M(bool clockwise = true) { return this; }
        /// 
        /// 转动S层(绕Z轴)
        /// 
        /// 是否顺时针
        /// 
        public virtual Cube Twirl_S(bool clockwise = true) { return this; }
        /// 
        /// 转动E层(绕Y轴)
        /// 
        /// 是否顺时针
        /// 
        public virtual Cube Twirl_E(bool clockwise = true) { return this; }
    }
角块、棱块、中心块均继承Cube类并重写函数。

魔方的旋转每次都涉及到九个方块的旋转,也就是说初始化魔方数据模型时需要对相应的‘面’进行注册旋转监听

比如我要旋转上层(U面)会调用到下面的函数

public override Cube Twirl_U(bool clockwise = true)
        {
            //判断是不是在旋转时受到影响(二次保护)
            if (!position.IsHaveSurface(ESurface.U))
                return this;
            RubikCubeVector3 tempPosition = (RubikCubeVector3)position.Copy();
            position = new RubikCubeVector3(
                RubikCubePosition.Twirl_U(tempPosition.U, clockwise),
                RubikCubePosition.Twirl_U(tempPosition.F, clockwise),
                RubikCubePosition.Twirl_U(tempPosition.R, clockwise)
                );
            //修改监听
            if (list_event != null)
                RecomposeListener(tempPosition);
            //转动模型
            if (medlTwirl != null)
                medlTwirl.Twirl(ESurface.U, clockwise);
            return this;
        }

旋转之后进行监听设置

 之前的上面前面右面的方块之前受影响的是《F面U面R面》

旋转(假设是顺时针)之后将会移除R面的监听,并向L面注册事件。

紧接着带动模型的旋转(这里的模型是说Unity项目中的模型,或者其他引擎的模型脚本

对数据魔方的旋转监听,外部的项目不需涉及其中旋转)

魔方还原过程由公式库决定

/// 
    /// 魔方公式库
    /// 
    public abstract class EquationStore
    {
        /// 
        /// 将公式拼接至此集合中并返回
        /// 
        protected List actions;
        /// 
        /// 返回公式集
        /// 
        /// 传入棱方块
        /// 传入角方块
        /// 
        public virtual List GetEquation(EdgeCube[] v2, Hornblock[] v3 = null)
        {
            actions = new List();
            return actions;
        }

        /// 
        /// 将从数据库读取的字符串存为List《Action》
        /// 
        /// 
        /// 公式集
        protected List WriterActionsByString(string str)
        {
            List tempActions = new List();
            for (int i = 0; i < str.Length; i++)
            {
                switch (str[i])
                {
                    case 'u': tempActions.Add(new Action(ESurface.U, false)); break;
                    case 'd': tempActions.Add(new Action(ESurface.D, false)); break;
                    case 'f': tempActions.Add(new Action(ESurface.F, false)); break;
                    case 'b': tempActions.Add(new Action(ESurface.B, false)); break;
                    case 'r': tempActions.Add(new Action(ESurface.R, false)); break;
                    case 'l': tempActions.Add(new Action(ESurface.L, false)); break;
                    case 'm': tempActions.Add(new Action(ESurface.M, false)); break;
                    case 's': tempActions.Add(new Action(ESurface.S, false)); break;
                    case 'e': tempActions.Add(new Action(ESurface.E, false)); break;

                    case 'U': tempActions.Add(new Action(ESurface.U)); break;
                    case 'D': tempActions.Add(new Action(ESurface.D)); break;
                    case 'F': tempActions.Add(new Action(ESurface.F)); break;
                    case 'B': tempActions.Add(new Action(ESurface.B)); break;
                    case 'R': tempActions.Add(new Action(ESurface.R)); break;
                    case 'L': tempActions.Add(new Action(ESurface.L)); break;
                    case 'M': tempActions.Add(new Action(ESurface.M)); break;
                    case 'S': tempActions.Add(new Action(ESurface.S)); break;
                    case 'E': tempActions.Add(new Action(ESurface.E)); break;
                }
            }
            return tempActions;
        }

        /// 
        /// 临时块模拟转动公式转动
        /// 
        /// 公式
        /// 
        /// 
        protected void TempCubeSimulationTwirl(List equations, ref EdgeCube[] v2, ref Hornblock[] v3)
        {
            foreach (Action equa in equations)
            {
                if (v2 != null)
                    foreach (EdgeCube edge in v2)
                    {
                        if (edge.Position.IsHaveSurface(equa.Es))
                        {
                            edge.Twirl(equa.Es, equa.Clockwise);
                        }
                    }
                if (v3 != null)
                    foreach (Hornblock horn in v3)
                        if (horn.Position.IsHaveSurface(equa.Es))
                        {
                            horn.Twirl(equa.Es, equa.Clockwise);
                        }
            }
        }
        protected string V2V3ToString(EdgeCube[] v2, Hornblock[] v3)
        {
            string str = "";
            for (int i = 0; i < v3.Length; i++)
            {
                str += (int)(v3[i].Position.ComparisonRotation());
            }
            for (int i = 0; i < v2.Length; i++)
            {
                str += (int)(v2[i].Position.ComparisonRotation());
            }
            return str;
        }
        protected void FormatArray(ref EdgeCube[] v2s, ref Hornblock[] v3s)
        {
            EdgeCube[] copy2 = new EdgeCube[v2s.Length];
            Hornblock[] copy3 = new Hornblock[v3s.Length];
            for (int i = 0; i < 4; i++)
            {
                if (v2s[i].Position.IsHaveSurface(ESurface.B))
                    copy2[0] = v2s[i];
                else if (v2s[i].Position.IsHaveSurface(ESurface.L))
                    copy2[1] = v2s[i];
                else if (v2s[i].Position.IsHaveSurface(ESurface.R))
                    copy2[2] = v2s[i];
                else if (v2s[i].Position.IsHaveSurface(ESurface.F))
                    copy2[3] = v2s[i];
                //
                if (v3s[i].Position.IsHaveSurface(ESurface.B) && v3s[i].Position.IsHaveSurface(ESurface.L))
                    copy3[0] = v3s[i];
                else if (v3s[i].Position.IsHaveSurface(ESurface.L) && v3s[i].Position.IsHaveSurface(ESurface.F))
                    copy3[1] = v3s[i];
                else if (v3s[i].Position.IsHaveSurface(ESurface.B) && v3s[i].Position.IsHaveSurface(ESurface.R))
                    copy3[2] = v3s[i];
                else if (v3s[i].Position.IsHaveSurface(ESurface.R) && v3s[i].Position.IsHaveSurface(ESurface.F))
                    copy3[3] = v3s[i];
            }
            v2s = copy2;
            v3s = copy3;
        }
    }
这是每个步骤的公式库声明(文件有点大)
模拟魔方还原_第4张图片

对还原度测试是在控制台中进行

Unity项目

发布为Dll文件导入Unity项目中

由于魔方返回的公式是一瞬间的,所以在unity中需要缓存然后处理

using UnityEngine;
using System.Collections;
using DRubikCube;
using System;
using System.Collections.Generic;
using UnityEngine.UI;

public class SceneManager : MonoBehaviour
{
    /// 
    /// 魔方--{[中心]}
    /// 
    [Header("魔方变量")]
    public GameObject[] centreModel;
    /// 
    /// 魔方--{[棱块]}
    /// 
    public GameObject[] edgeModel;
    /// 
    /// 魔方--{[角块]}
    /// 
    public GameObject[] hornblockModel;
    /// 
    /// 魔方轴心(看不见的那个块)
    /// 
    public GameObject axisCentre;


    /// 
    /// 是否开启协程
    /// 
    public bool isCoroutine = false;
    // Use this for initialization
    void Start()
    {
        //创建魔方
        RubikCube.Ins.CreateRubikCube(Twirl);
        GUIClick.nowMessage = "正在创建魔方";
        //为魔方数组做坐标引用,并为数据绑定模型源
        RubikCube.Ins.RubikCubeModel(centreModel, edgeModel, hornblockModel);
    }
    /// 
    /// 魔方每一个面的旋转回调
    /// 
    /// 
    /// 
    private void Twirl(ESurface twirlType, bool clockwise)
    {
        RubikCube.Ins.actions.Add(new DRubikCube.Action(twirlType, clockwise));
        if (!isCoroutine)
        {
            isCoroutine = true;
            StartCoroutine(Run());
        }
        Debug.Log("SceneManager--Twirl");
    }
    /// 
    ///  转动函数
    /// 
    /// 
    private IEnumerator Run()
    {
        yield return ModelTwirl();
        yield return ModelAxis();
        RubikCube.Ins.actions = new List();
        GUIMessage.ShowMessageToTSMessageBox("System:" + GUIClick.nowMessage + "<完成>");
        isCoroutine = false;
    }
    private IEnumerator ModelTwirl()
    {
        int i = 0;
        while (RubikCube.Ins.actions.Count > i)
        {
            if (RubikCube.Ins.actions[i].Es == ESurface.M)
                RubikCube.Ins.X += RubikCube.Ins.actions[i].Clockwise ? 1 : -1;
            if (RubikCube.Ins.actions[i].Es == ESurface.S)
                RubikCube.Ins.Z += RubikCube.Ins.actions[i].Clockwise ? 1 : -1;
            if (RubikCube.Ins.actions[i].Es == ESurface.E)
                RubikCube.Ins.Y += RubikCube.Ins.actions[i].Clockwise ? 1 : -1;
            RubikCube.Ins.Twirl(RubikCube.Ins.actions[i].Es, RubikCube.Ins.actions[i].Clockwise);
            GUIMessage.ShowMessageToTSMessageBox(RubikCube.Ins.actions[i].Es + " -- " + RubikCube.Ins.actions[i].Clockwise);
            i++;
            yield return new WaitForSeconds(1f);
            Debug.Log("--------------------------------------------");
        }
    }
    private IEnumerator ModelAxis()
    {
        while (RubikCube.Ins.X != 0 || RubikCube.Ins.Y != 0 || RubikCube.Ins.Z != 0)
        {
            if (RubikCube.Ins.X != 0)
            {
                RubikCube.Ins.Twirl(ESurface.L, RubikCube.Ins.X > 0);
                RubikCube.Ins.Twirl(ESurface.M, RubikCube.Ins.X < 0);
                RubikCube.Ins.Twirl(ESurface.R, RubikCube.Ins.X < 0);
                GUIMessage.ShowMessageToTSMessageBox("X" + " -- " + (RubikCube.Ins.X < 0));
                RubikCube.Ins.X += RubikCube.Ins.X > 0 ? -1 : 1;
                yield return new WaitForSeconds(0.55f);
            }
            if (RubikCube.Ins.Y != 0)
            {
                RubikCube.Ins.Twirl(ESurface.U, RubikCube.Ins.Y < 0);
                RubikCube.Ins.Twirl(ESurface.E, RubikCube.Ins.Y < 0);
                RubikCube.Ins.Twirl(ESurface.D, RubikCube.Ins.Y > 0);
                GUIMessage.ShowMessageToTSMessageBox("Y"+ " -- " + (RubikCube.Ins.Y < 0));
                RubikCube.Ins.Y += RubikCube.Ins.Y > 0 ? -1 : 1;
                yield return new WaitForSeconds(0.55f);
            }
            if (RubikCube.Ins.Z != 0)
            {
                RubikCube.Ins.Twirl(ESurface.F, RubikCube.Ins.Z < 0);
                RubikCube.Ins.Twirl(ESurface.S, RubikCube.Ins.Z < 0);
                RubikCube.Ins.Twirl(ESurface.B, RubikCube.Ins.Z > 0);
                GUIMessage.ShowMessageToTSMessageBox("Z" + " -- " + (RubikCube.Ins.Z < 0));
                RubikCube.Ins.Z += RubikCube.Ins.Z > 0 ? -1 : 1;
                yield return new WaitForSeconds(0.55f);
            }
        }
    }
}

其中的Action是魔方项目中封装的 ↓

#region 程序集 DRubikCube, Version=1.0.0.1, Culture=neutral, PublicKeyToken=9a1f26c121d1aafa
// D:\aUnity\RubikCubeTest\Assets\Plugins\DRubikCube.dll
#endregion

namespace DRubikCube
{
    //
    // 摘要:
    //     动作封装
    public class Action
    {
        public Action(ESurface es, bool clockwise = true);

        //
        // 摘要:
        //     旋转类型
        public ESurface Es { get; }
        //
        // 摘要:
        //     是否顺时针
        public bool Clockwise { get; }
    }
}

对于项目还增加了观察者脚本拿出来用于学习

观察者脚本链接

这里留一个百度云的下载链接吧,仅供学习交流

链接:https://pan.baidu.com/s/12S9jlH6_X6rUhF8dGNBTTA 密码:1pxa

可能不是最新的,但一定是能用的,

你可能感兴趣的:(个人项目)