zoukankan      html  css  js  c++  java
  • Unity3D入门 俄罗斯方块总结(二)

    俄罗斯实现中使用Unity语法总结...

    1.Instantiate

    Instantiate中克隆一个Object以及他的子结点,也可包括位置信息。

    a.CreateBlock()函数内,随机选取七种block的gameObject里一种,进行动态block实例化:

            Instantiate(blocks[random]);//此次clone的是gameObject,

    b.SetBlock()内进行,检测block是否可以静止后,如果是,则Block的静态绘制,

        Instantiate(cube,new Vector3(xPos + x, yPos - y, 0), Quaternion.identity);//此次clone的是每一个myCube,进行实际的绘制

    c.Block.cs中进行Block的初始化过程,实例化每个子结点

                var cube = (Transform)Instantiate(Manager.manager.cube, new Vector3(x - childSize, childSize - y, 0), Quaternion.identity);

    实例化通常用于实例投射物(如子弹、榴弹、破片、飞行的铁球等),AI敌人,粒子爆炸。也就是常用于:多个重复性的Object。

    本次用于两种类型实例化,一个是Block,一个是绘制的myCube。

    2.yield  中断

    参考:http://blog.csdn.net/huang9012/article/details/29595747

    1.特定时间延时:

     void Start () {
         StartCoroutine(Destroy());//start 和 destroy同时进行?
     } 
     IEnumerator Destroy(){
        yield return WaitForSeconds(3.0f);//延时3s后才进行下面的操作
         Destroy(gameObject);
     }

    2.yield return null,中断,在下一帧才继续执行下面的代码

    3.yield return的作用是在执行到这行代码之后,将控制权立即交还给外部。yield return之后的代码会在外部代码再次调用MoveNext时才会执行,直到下一个yield return——或是迭代结束。

    游戏中需要使用yield的场景:
    • 游戏结算分数时,分数从0逐渐上涨,而不是直接显示最终分数

    • 人物对话时,文字一个一个很快的出现,而不是一下突然出现
    • 10、9、8……0的倒计时

    • 某些游戏(如拳皇)掉血时血条UI逐渐减少,而不是突然降低到当前血量

    本次俄罗斯方块中使用的情况:

    Block.cs中:

    Fall函数内:

    while(true)
    {
      //...是否达到静止状态?
      ...
      //没有,则继续下降
      yield return null;//下一帧才继续运行fall函数
    }

    平移block的延迟操作:在平移函数最后进行延迟一下...

    yield return new WaitForSeconds(.1f);

    Manger.cs中:

        IEnumerator CheckRows(int yStart, int size){//检测这个block包含的几行内,是否满足一行全为true
            yield return null;//在SetBlock()中进行新的静态绘制block后,等一帧再检测是否有满行的情况
            if (yStart < 1)yStart = 1;
            int count = 1;
            for (int y = yStart;y < yStart + size;y++){
                int x;
                for (x = maxBlockSize;x < fieldWidth - maxBlockSize;x++){
                    if (!fields[x, y]){
                        break;
                    }
                }
                if (x == fieldWidth - maxBlockSize){//
                    yield return StartCoroutine(SetRows(y));//消行操作,并将控制权交给函数SetRows(),来重置整个场景的静态cube,并且不急着计分,而是先把消行上面的数据进行下移动,并且是平稳的插值下移,直到所有的下移结束,才进行计分...
    //为什么此地需要yield?因为SetRows需要平稳的下降、结束... Score += 10 * count; y--; count++; } } CreateBlock(blockRandom); }

    yield:一个是迭代,while循环中需要逐次返回值,一个是平稳的下降cube操作

    IEnumerator CheckRows(int yStart, int size){//检测这个block包含的几行内,是否满足一行全为true
            yield return null;
            if (yStart < 1)yStart = 1;
            int count = 1;
            for (int y = yStart;y < yStart + size;y++){
                int x;
                for (x = maxBlockSize;x < fieldWidth - maxBlockSize;x++){
                    if (!fields[x, y]){
                        break;
                    }
                }//如果行内有全为true的一行或多行
                if (x == fieldWidth - maxBlockSize){//
                    Debug.Log("1111");
                    yield return StartCoroutine(SetRows(y));//消行操作,并将控制权交给函数SetRows(),
                    Debug.Log("2222");
                    Score += 10 * count;
                    y--;
                    count++;
                }
            }
            CreateBlock(blockRandom);
        }
        
        IEnumerator SetRows(int yStart){
            for (int y = yStart;y < fieldHeight - 1;y++){//对于消去行后,上面的cube数据全部下移一行
                for (int x = maxBlockSize;x < fieldWidth - maxBlockSize;x++){
                    fields[x, y] = fields[x, y + 1];
                }
            }
            
            for (int x = maxBlockSize;x < fieldWidth - maxBlockSize;x++){
                fields[x, fieldHeight - 1] = false;
            }
            
            var cubes = GameObject.FindGameObjectsWithTag("Cube");//搜索所有cube
            int cubeToMove = 0;
            for (int i = 0;i < cubes.Length;i++){
                GameObject cube = cubes[i];
                if (cube.transform.position.y > yStart){//如果是在这行以上的cube,  cubeToMove记录需要移动的cube数量
                    cubeYposition[cubeToMove] = (int)(cube.transform.position.y);//保存这些需要移动小cube的位置
                    cubeTransforms[cubeToMove++] = cube.transform;//???不理解,cubeTransforms直接代表了cube的位置吗?
                }
                else if (cube.transform.position.y == yStart){
                    Destroy(cube);//这行的删除
                }
            }
            
            float t = 0;
            while (t <= 1f){
                t += Time.deltaTime * 5f;
                for(int i = 0;i < cubeToMove;i++){//平稳的插值下移
                    cubeTransforms[i].position = new Vector3(cubeTransforms[i].position.x, Mathf.Lerp(cubeYposition[i], cubeYposition[i] - 1, t),
                        cubeTransforms[i].position.z);
                }
                Debug.Log("33333");
                yield return null;
            }
            
            if (++clearTimes == TimeToAddSpeed){
                blockNormalFallSpeed += addSpeed;
                clearTimes = 0;
            }
            
        }

    消行后的打印结果是:

    11111

    33333

    33333

    33333...//执行了1s时间的消行后下移操作,用了两个yield...

    22222

    3.FindGameObjectsWithTag

    4.IEnumerator

    5.StartCoroutine

    6.Time

  • 相关阅读:
    【MOSS】SPUser的操作
    退出登录跳出框架页
    F12转到定义时,总是显示从元数据 转载粘贴
    简易代码生成器
    C语言I博客作业04
    第一周作业
    C语言I博客作业02
    C语言I博客作业02
    【DukeImage】Week_5 Segmentation
    【LeetCode】#7 Reverse Integer
  • 原文地址:https://www.cnblogs.com/dust-fly/p/4418965.html
Copyright © 2011-2022 走看看