[开发者心得] “数据结构课作业笔记”#012-数组-二维数组-地雷冲击波-并发

[复制链接]
853 |0
脑的研发记录 发表于 2023-12-2 14:57:21 | 显示全部楼层 |阅读模式
本帖最后由 脑的研发记录 于 2023-12-2 14:57 编辑

“数据结构课作业笔记”#012-数组-二维数组-地雷冲击波



所用编辑器版本0.27.0.0

目录总览:
零.故事背景
壹.二维数组的起源故事
贰.所需语法
叁.应用说明

.相关参考链接 (返回主站

参数:10:00-14:26代码+文案

零.故事背景
距离上一篇帖子过了快一周了,想着下一篇帖子拿做一个方块生成器当案例,但是需要的功能和新代码有点多,还没确定帖子顺序,想象一下子多出一百行都是新函数的代码,就开始头秃起来了。放弃速推,看看能不能再拿新的小案例推进代码演化。后来在补作业中度过了一周,想起来触发器还能凑一波文案,就敲定了本次开发流程:拿触发器做地雷,踩中地雷同时生成好几个冲击波,这样的一种爆裂冲击波效果。
后续有三个技术点,一个是从固定位置生成到从玩家上生成,一个是从固定方向生成,到以玩家朝向生成,还有一个就是编辑数据的导入导出。把这几个办出来,参考动效编辑器代码已适配027 [单脚本][MyClearAct] 简单好用动效编辑器 , 小白也能做技能动效 口袋方舟论坛|面向全年龄的UGC互动内容平台与交流社区 (ark.online),搓一个方块武器编辑器,这样地刺就不用代码生成,只要拖拖方块,一键导出,导入,点击按钮,就能看到地刺出现。然后整一个适配方块武器数据的动效编辑器,可以控制多个地刺和冲击波同时产生这样的效果。
这是上学期期末大作业也是方块编辑器的平面样例。程序和源代码放在一个文件夹里了。下面的视频简介里有注释,读完说明里面的文案,点击里面的应用程序就能跑。源代码查看方式如视频。


壹.二维数组的起源故事
首先是清理视野,上一篇帖子的最终成果的注释删除。“数据结构课作业笔记”#011-数组-二维数组 口袋方舟论坛|面向全年龄的UGC互动内容平台与交流社区 (ark.online)
效果如下



class ooh {
    n: Model;
    id: string;
}


@Component
export default class adds extends Script {

    protected buildx: Array<Array<ooh>> = new Array(4);
    // 声明数组,一个数组里面有4个小数组,每个小数组里面有10个项,就是10个对象
    protected i: number = 0;
    protected flag_grow: number = 0;


    /** 当脚本被实例后,会在第一帧更新前调用此函数 */
    protected onStart(): void {

        // for (var j = 0; j < this.build.length; j++) {
        //     this.build[j] = new ooh();
        // }

        for (var j = 0; j < this.buildx.length; j++) {
            this.buildx[j] = new Array(10);
            // 对大数组的一项,就是一个小数组,是小数组的预加载,规定数组的格式。new是分配内存。
            for (var k = 0; k < this.buildx[j].length; k++) {
                this.buildx[j][k] = new ooh();
                // 这里的new也是分配内存,分配了一个内存,把内存里面的数值放进到buildx里面。  
                // 为什么两次分配内存?
                // 也可以说是存储内存的带有的凭证,把凭证放进去。但是我们看不见这个凭证。因为如果能看见这个凭证,之前的教程就会面目全非,简单来说凭证本身也占用内存,第一次分配内存是分配给小数组凭证的内存。
                // 教程起点是就着能用的开发,目前没有这个凭证的新的需求。所以就不讲凭证究竟是什么。
                // 所以目前两种理解都可以,因为这两种理解目前不影响开发。


                // 这样就是二维数组形式j是行,k是列。一行的10个空间
                console.log(j + " " + k);
            }
        }

        AssetUtil.asyncDownloadAsset("197386");

        setTimeout(() => {

            for (var j = 0; j < this.buildx.length; j++) {
                for (var k = 0; k < this.buildx[j].length; k++) {
                    let box = GameObject.spawn("197386", {
                        transform: new Transform(new Vector(k * 300,j * 50 , 25*k), new Rotation(0, 0, 0), new Vector((1 + j * j) / 90, 1, (1 + j * j) / 90)),
                        replicates: true
                    }) as Model;
                    this.buildx[j][k].n = box;
                }
            }


        }, 3000);
    }
}







然后由于是一瞬间生成的,需要延时,像之前的冲击波,地刺一样,慢慢生长,这样看出来生长顺序
修改了一半,代码替换的过程记录,注意注释讲的修改背景:偷懒失败。
循环的延时写法

    AssetUtil.asyncDownloadAsset("197386");


        // setTimeout(() => {

        //     for (var j = 0; j < this.buildx.length; j++) {
        //         for (var k = 0; k < this.buildx[j].length; k++) {
        //             let box = GameObject.spawn("197386", {
        //                 transform: new Transform(new Vector(k * 300,j * 50 , 25*k), new Rotation(0, 0, 0), new Vector((1 + j * j) / 90, 1, (1 + j * j) / 90)),
        //                 replicates: true
        //             }) as Model;
        //             this.buildx[j][k].n = box;
        //         }
        //     }


        // }, 3000);


        // 因为计时器不断计时,原来以为循环里放计时器就能自动循环一次,计时1秒,结果报错。
        // 换成timeout延时器,循环一次延时一次,但是循环是一瞬间完成的,每个循环直接却没有间隔,就导致和一瞬间生成没有区别,代码直接寄
        // 于是就开始穷举别的方案,每一秒生成一次,然后才意识到计时器本身就是循环,for用setInterval()代替了,
        // 两层循环倒是犯难了,一层数的慢,另一层数的快,过了几天,灵感乍现,用if做分情况,一个if里面数数慢,另一个if数数快。这样if代替了for循环


        // 变量从for循环里提取出来
        var j = 0

        setTimeout(() => {
            var timer = setInterval(() => {
                // for (; j < this.buildx.length; j++) {
                // for变成if,由于k每到buildx[j].length,都会使得第一层循环重新开始,j增加1,然后第二层循环继续。
                // 就像每数到10,都会重新数10,1,2,3,...,11,12,13,14,...j就相当于10位数,k就相当于个位数

                // 这个if替换第一个for
                if (k == this.buildx[j].length) {
                    j++;
                }

                // 这个if也替换了,写出来才看出来和第一个if可以合并
                if (k == this.buildx[j].length) {
                    k = 0;
                }
                // for (var k = 0; k < this.buildx[j].length; k++) {

                // 这是数数快的那个for的替换
                if(k<this.buildx[j].length){

                }


                let box = GameObject.spawn("197386", {
                    transform: new Transform(new Vector(k * 300, j * 50, 25 * k), new Rotation(0, 0, 0), new Vector((1 + j * j) / 90, 1, (1 + j * j) / 90)),
                    replicates: true
                }) as Model;
                this.buildx[j][k].n = box;
                // }

            }, 3000);
        }, 1000)
    }
}




修改出来,可以替换原来部分的代码跑了。但是编辑器红色报错。

AssetUtil.asyncDownloadAsset("197386");


        // setTimeout(() => {

        //     for (var j = 0; j < this.buildx.length; j++) {
        //         for (var k = 0; k < this.buildx[j].length; k++) {
        //             let box = GameObject.spawn("197386", {
        //                 transform: new Transform(new Vector(k * 300,j * 50 , 25*k), new Rotation(0, 0, 0), new Vector((1 + j * j) / 90, 1, (1 + j * j) / 90)),
        //                 replicates: true
        //             }) as Model;
        //             this.buildx[j][k].n = box;
        //         }
        //     }


        // }, 3000);


        // 因为计时器不断计时,原来以为循环里放计时器就能自动循环一次,计时1秒,结果报错。
        // 换成timeout延时器,循环一次延时一次,但是循环是一瞬间完成的,每个循环直接却没有间隔,就导致和一瞬间生成没有区别,代码直接寄
        // 于是就开始穷举别的方案,每一秒生成一次,然后才意识到计时器本身就是循环,for用setInterval()代替了,
        // 两层循环倒是犯难了,一层数的慢,另一层数的快,过了几天,灵感乍现,用if做分情况,一个if里面数数慢,另一个if数数快。这样if代替了for循环


        // 变量从for循环里提取出来
        var j = 0


        var k = 0

        setTimeout(() => {
            var timer = setInterval(() => {
                // for (; j < this.buildx.length; j++) {
                // for变成if,由于k每到buildx[j].length,都会使得第一层循环重新开始,j增加1,然后第二层循环继续。
                // 就像每数到10,都会重新数10,1,2,3,...,11,12,13,14,...j就相当于10位数,k就相当于个位数


                // 这个if替换第一个for
                if (k == this.buildx[j].length) {
                    j++;
                    k = 0;
                }

                // 这个if也替换了,写出来才看出来和第一个if可以合并
                // if (k == this.buildx[j].length) {
                //     k = 0;
                // }


                // for (var k = 0; k < this.buildx[j].length; k++) {

                // 这是那个数数快的for的替换
                else if (k < this.buildx[j].length) {
                    let box = GameObject.spawn("197386", {
                        transform: new Transform(new Vector(k * 300, j * 50, 25 * k), new Rotation(0, 0, 0), new Vector((1 + j * j) / 90, 1, (1 + j * j) / 90)),
                        replicates: true
                    }) as Model;
                    this.buildx[j][k].n = box;
                    k++;
                }
                console.log(j+" "+k);
                // }

            }, 100);
        }, 1000)
    }



可以再修改,因为改的时候发现j没有最大值,就会导致j增加,但是数组中分配了4个小数组,j=5,第五个小数组不存在,于是就报错了。


清理视野,删除注释


     var j = 0
        var k = 0

        setTimeout(() => {
            var timer = setInterval(() => {

                if(j<this.buildx.length){

                }else{

                }


                if (k == this.buildx[j].length) {
                    j++;
                    k = 0;
                }
                else if (k < this.buildx[j].length) {
                    let box = GameObject.spawn("197386", {
                        transform: new Transform(new Vector(k * 300, j * 50, 25 * k), new Rotation(0, 0, 0), new Vector((1 + j * j) / 90, 1, (1 + j * j) / 90)),
                        replicates: true
                    }) as Model;
                    this.buildx[j][k].n = box;
                    k++;
                }


                console.log(j+" "+k);
                // }

            }, 100);
        }, 1000)
    }




然后把下面的if else if 放进第一个if里面,另一else不用管。可以对比刚才清理视野的代码找不同。

  var j = 0
        var k = 0

        setTimeout(() => {
            var timer = setInterval(() => {

                if(j<this.buildx.length){

                    if (k == this.buildx[j].length) {
                        j++;
                        k = 0;
                    }
                    else if (k < this.buildx[j].length) {
                        let box = GameObject.spawn("197386", {
                            transform: new Transform(new Vector(k * 300, j * 50, 25 * k), new Rotation(0, 0, 0), new Vector((1 + j * j) / 90, 1, (1 + j * j) / 90)),
                            replicates: true
                        }) as Model;
                        this.buildx[j][k].n = box;
                        k++;
                    }
                    
                }else{

                }


                // if (k == this.buildx[j].length) {
                //     j++;
                //     k = 0;
                // }
                // else if (k < this.buildx[j].length) {
                //     let box = GameObject.spawn("197386", {
                //         transform: new Transform(new Vector(k * 300, j * 50, 25 * k), new Rotation(0, 0, 0), new Vector((1 + j * j) / 90, 1, (1 + j * j) / 90)),
                //         replicates: true
                //     }) as Model;
                //     this.buildx[j][k].n = box;
                //     k++;
                // }


                console.log(j+" "+k);
                // }

            }, 100);
        }, 1000)
    }




这样看日志输出,会有好几个40,这是因为计数器一直在跑动,else空,就是什么也不执行,现在可以利用一下,用于删除计时器,节约消耗,对比找不同。

   var j = 0
        var k = 0

        setTimeout(() => {
            var timer = setInterval(() => {

                if(j<this.buildx.length){
                    if (k == this.buildx[j].length) {
                        j++;
                        k = 0;
                    }
                    else if (k < this.buildx[j].length) {
                        let box = GameObject.spawn("197386", {
                            transform: new Transform(new Vector(k * 300, j * 50, 25 * k), new Rotation(0, 0, 0), new Vector((1 + j * j) / 90, 1, (1 + j * j) / 90)),
                            replicates: true
                        }) as Model;
                        this.buildx[j][k].n = box;
                        k++;
                    }
                }else{
                    clearInterval(timer);
                }
                console.log(j+" "+k);
                // }

            }, 100);
        }, 1000)






新建脚本,复制粘贴直接跑。



class ooh {
    n: Model;
    id: string;
}


@Component
export default class adds extends Script {

    protected buildx: Array<Array<ooh>> = new Array(4);
    // 声明数组,一个数组里面有4个小数组,每个小数组里面有10个项,就是10个对象
    protected i: number = 0;
    protected flag_grow: number = 0;


    /** 当脚本被实例后,会在第一帧更新前调用此函数 */
    protected onStart(): void {

        // for (var j = 0; j < this.build.length; j++) {
        //     this.build[j] = new ooh();
        // }

        for (var j = 0; j < this.buildx.length; j++) {
            this.buildx[j] = new Array(10);
            // 对大数组的一项,就是一个小数组,是小数组的预加载,规定数组的格式。new是分配内存。
            for (var k = 0; k < this.buildx[j].length; k++) {
                this.buildx[j][k] = new ooh();
                // 这里的new也是分配内存,分配了一个内存,把内存里面的数值放进到buildx里面。  
                // 为什么两次分配内存?
                // 也可以说是存储内存的带有的凭证,把凭证放进去。但是我们看不见这个凭证。因为如果能看见这个凭证,之前的教程就会面目全非,简单来说凭证本身也占用内存,第一次分配内存是分配给小数组凭证的内存。
                // 教程起点是就着能用的开发,目前没有这个凭证的新的需求。所以就不讲凭证究竟是什么。
                // 所以目前两种理解都可以,因为这两种理解目前不影响开发。


                // 这样就是二维数组形式j是行,k是列。一行的10个空间
                console.log(j + " " + k);
            }
        }

        AssetUtil.asyncDownloadAsset("197386");


        // setTimeout(() => {

        //     for (var j = 0; j < this.buildx.length; j++) {
        //         for (var k = 0; k < this.buildx[j].length; k++) {
        //             let box = GameObject.spawn("197386", {
        //                 transform: new Transform(new Vector(k * 300,j * 50 , 25*k), new Rotation(0, 0, 0), new Vector((1 + j * j) / 90, 1, (1 + j * j) / 90)),
        //                 replicates: true
        //             }) as Model;
        //             this.buildx[j][k].n = box;
        //         }
        //     }


        // }, 3000);


        // 因为计时器不断计时,原来以为循环里放计时器就能自动循环一次,计时1秒,结果报错。
        // 换成timeout延时器,循环一次延时一次,但是循环是一瞬间完成的,每个循环直接却没有间隔,就导致和一瞬间生成没有区别,代码直接寄
        // 于是就开始穷举别的方案,每一秒生成一次,然后才意识到计时器本身就是循环,for用setInterval()代替了,
        // 两层循环倒是犯难了,一层数的慢,另一层数的快,过了几天,灵感乍现,用if做分情况,一个if里面数数慢,另一个if数数快。这样if代替了for循环


        // 变量从for循环里提取出来
        var j = 0
        var k = 0

        setTimeout(() => {
            var timer = setInterval(() => {

                if(j<this.buildx.length){
                    if (k == this.buildx[j].length) {
                        j++;
                        k = 0;
                    }
                    else if (k < this.buildx[j].length) {
                        let box = GameObject.spawn("197386", {
                            transform: new Transform(new Vector(k * 300, j * 50, 25 * k), new Rotation(0, 0, 0), new Vector((1 + j * j) / 90, 1, (1 + j * j) / 90)),
                            replicates: true
                        }) as Model;
                        this.buildx[j][k].n = box;
                        k++;
                    }
                }else{
                    clearInterval(timer);
                }
                console.log(j+" "+k);
                // }

            }, 100);
        }, 1000)
    }
}







就此,效果出来了,可以拿阶梯生长的例子说明并发,每行阶梯都是一起生长,不是一个阶梯生长完,另一个阶梯再继续生长。并发就是讲在这整个阶梯出现完所用的时间里,在某一瞬间,只有一个阶梯生长,但是宏观看这一段时间阶梯看起来都像是一起生长,这就是并发,只要速度做够快,一个接着一个也能模拟出齐头并进。


然后清理视野,准备引入新代码




class ooh {
    n: Model;
    id: string;
}

@Component
export default class adds extends Script {

    protected buildx: Array<Array<ooh>> = new Array(4);
    // 声明数组,一个数组里面有4个小数组,每个小数组里面有10个项,就是10个对象
    protected i: number = 0;
    protected flag_grow: number = 0;


    /** 当脚本被实例后,会在第一帧更新前调用此函数 */
    protected onStart(): void {

        for (var j = 0; j < this.buildx.length; j++) {
            this.buildx[j] = new Array(10);
            // 对大数组的一项,就是一个小数组,是小数组的预加载,规定数组的格式。new是分配内存。
            for (var k = 0; k < this.buildx[j].length; k++) {
                this.buildx[j][k] = new ooh();

                console.log(j + " " + k);
            }
        }

        AssetUtil.asyncDownloadAsset("197386");


        var j = 0
        var k = 0

        setTimeout(() => {
            var timer = setInterval(() => {

                if (j < this.buildx.length) {
                    if (k == this.buildx[j].length) {
                        j++;
                        k = 0;
                    }
                    else if (k < this.buildx[j].length) {
                        let box = GameObject.spawn("197386", {
                            transform: new Transform(new Vector(k * 300, j * 50, 25 * k), new Rotation(0, 0, 0), new Vector((1 + j * j) / 90, 1, (1 + j * j) / 90)),
                            replicates: true
                        }) as Model;
                        this.buildx[j][k].n = box;
                        k++;
                    }
                } else {
                    clearInterval(timer);
                }
                console.log(j + " " + k);
                // }

            }, 100);
        }, 1000)
    }
}







改了改代码动态生成触发器,实现了踩到方块,阶梯消失
复制粘贴直接跑,阶梯生成完,跳到方块上面,然后就能看到阶梯逐渐消失




class ooh {
    n: Model;
    id: string;
}

@Component
export default class adds extends Script {

    protected buildx: Array<Array<ooh>> = new Array(4);
    // 声明数组,一个数组里面有4个小数组,每个小数组里面有10个项,就是10个对象
    protected i: number = 0;
    protected flag_grow: number = 0;


    /** 当脚本被实例后,会在第一帧更新前调用此函数 */
    protected async onStart(): Promise<void> {

        for (var j = 0; j < this.buildx.length; j++) {
            this.buildx[j] = new Array(10);
            // 对大数组的一项,就是一个小数组,是小数组的预加载,规定数组的格式。new是分配内存。
            for (var k = 0; k < this.buildx[j].length; k++) {
                this.buildx[j][k] = new ooh();

                console.log(j + " " + k);
            }
        }

        AssetUtil.asyncDownloadAsset("197386");

        AssetUtil.asyncDownloadAsset("197388");

        AssetUtil.asyncDownloadAsset("Trigger");
        var j = 0
        var k = 0

        setTimeout(() => {
            var timer = setInterval(() => {

                if (j < this.buildx.length) {
                    if (k == this.buildx[j].length) {
                        j++;
                        k = 0;
                    }
                    else if (k < this.buildx[j].length) {
                        let box = GameObject.spawn("197386", {
                            transform: new Transform(new Vector(k * 300, j * 50, 25 * k), new Rotation(0, 0, 0), new Vector((1 + j * j) / 90, 1, (1 + j * j) / 90)),
                            replicates: true
                        }) as Model;
                        this.buildx[j][k].n = box;
                        k++;
                    }
                } else {
                    clearInterval(timer);
                }
                console.log(j + " " + k);
                // }

            }, 100);
        }, 1000)




        let trigger: Trigger;

        setTimeout(async () => {
            // if (SystemUtil.isServer()) {
            trigger = await GameObject.asyncSpawn("Trigger", {
                replicates: true,
                transform: new Transform(new Vector(100, 150, 25), Rotation.zero, Vector.one)
            }) as Trigger;
            console.log("trigger gameObjectId: " + trigger.gameObjectId);

            let box = GameObject.spawn("197386", {
                transform: new Transform(new Vector(100, 150, -25), new Rotation(0, 0, 0), new Vector(1, 1, 1)),
                replicates: true
            }) as Model;


            // }
        }, 2000);


        

        setTimeout(() => {
            trigger.onEnter.add(() => {
                j = 0;
                k=0;
                var timer = setInterval(() => {

                    if (j < this.buildx.length) {
                        if (k == this.buildx[j].length) {
                            j++;
                            k = 0;
                        }
                        else if (k < this.buildx[j].length) {
                            this.buildx[j][k].n.setVisibility(PropertyStatus.Off, true);
                            this.buildx[j][k].n.setCollision(PropertyStatus.Off, true);
                            k++;
                        }
                    } else {
                        clearInterval(timer);
                    }
                    console.log(j + " " + k);
                    // }

                }, 100);
            })
        }, 3000);
    }
}










注释处,新增复位功能。即else里面加一个循环,怎么生成的,就怎么消失,On变成Off,实现生成完毕5秒后消失



class ooh {
    n: Model;
    id: string;
}

@Component
export default class adds extends Script {

    protected buildx: Array<Array<ooh>> = new Array(4);
    // 声明数组,一个数组里面有4个小数组,每个小数组里面有10个项,就是10个对象
    protected i: number = 0;
    protected flag_grow: number = 0;


    /** 当脚本被实例后,会在第一帧更新前调用此函数 */
    protected async onStart(): Promise<void> {

        for (var j = 0; j < this.buildx.length; j++) {
            this.buildx[j] = new Array(10);
            // 对大数组的一项,就是一个小数组,是小数组的预加载,规定数组的格式。new是分配内存。
            for (var k = 0; k < this.buildx[j].length; k++) {
                this.buildx[j][k] = new ooh();

                console.log(j + " " + k);
            }
        }

        AssetUtil.asyncDownloadAsset("197386");

        AssetUtil.asyncDownloadAsset("197388");

        AssetUtil.asyncDownloadAsset("Trigger");
        var j = 0
        var k = 0

        setTimeout(() => {
            var timer = setInterval(() => {

                if (j < this.buildx.length) {
                    if (k == this.buildx[j].length) {
                        j++;
                        k = 0;
                    }
                    else if (k < this.buildx[j].length) {
                        let box = GameObject.spawn("197386", {
                            transform: new Transform(new Vector(k * 300, j * 50, 25 * k), new Rotation(0, 0, 0), new Vector((1 + j * j) / 90, 1, (1 + j * j) / 90)),
                            replicates: true
                        }) as Model;
                        this.buildx[j][k].n = box;
                        // 新增生成后隐藏
                        this.buildx[j][k].n.setVisibility(PropertyStatus.Off, true);
                        this.buildx[j][k].n.setCollision(PropertyStatus.Off, true);
                        k++;
                    }
                } else {
                    clearInterval(timer);
                }
                console.log(j + " " + k);
                // }

            }, 100);
        }, 1000)




        let trigger: Trigger;

        setTimeout(async () => {
            // if (SystemUtil.isServer()) {
            trigger = await GameObject.asyncSpawn("Trigger", {
                replicates: true,
                transform: new Transform(new Vector(100, 150, 25), Rotation.zero, Vector.one)
            }) as Trigger;
            console.log("trigger gameObjectId: " + trigger.gameObjectId);

            let box = GameObject.spawn("197386", {
                transform: new Transform(new Vector(100, 150, -25), new Rotation(0, 0, 0), new Vector(1, 1, 1)),
                replicates: true
            }) as Model;


            // }
        }, 2000);




        setTimeout(() => {
            trigger.onEnter.add(() => {
                j = 0;
                k=0;
                var timer = setInterval(() => {

                    if (j < this.buildx.length) {
                        if (k == this.buildx[j].length) {
                            j++;
                            k = 0;
                        }
                        else if (k < this.buildx[j].length) {
                            this.buildx[j][k].n.setVisibility(PropertyStatus.On, true);
                            this.buildx[j][k].n.setCollision(PropertyStatus.On, true);
                            k++;
                        }
                    } else {
                        // 延时5秒复位
                        setTimeout(() => {
                            for(j=0; j<this.buildx.length; j++){
                                for(k=0; k<this.buildx[j].length; k++){
                                    this.buildx[j][k].n.setVisibility(PropertyStatus.Off, true);
                                    this.buildx[j][k].n.setCollision(PropertyStatus.Off, true);
                                }
                            }
                            clearInterval(timer);
                        }, 5000);
                        
                    }
                    console.log(j + " " + k);
                    // }

                }, 100);
            })
        }, 3000);
    }
}








修改方块生成的大小这一行代码,就能生成一个短暂出现的跑酷阶梯,运行工程2s秒后跑到触发器上。




class ooh {
    n: Model;
    id: string;
}

@Component
export default class adds extends Script {

    protected buildx: Array<Array<ooh>> = new Array(4);
    // 声明数组,一个数组里面有4个小数组,每个小数组里面有10个项,就是10个对象
    protected i: number = 0;
    protected flag_grow: number = 0;


    /** 当脚本被实例后,会在第一帧更新前调用此函数 */
    protected async onStart(): Promise<void> {

        for (var j = 0; j < this.buildx.length; j++) {
            this.buildx[j] = new Array(10);
            // 对大数组的一项,就是一个小数组,是小数组的预加载,规定数组的格式。new是分配内存。
            for (var k = 0; k < this.buildx[j].length; k++) {
                this.buildx[j][k] = new ooh();

                console.log(j + " " + k);
            }
        }

        AssetUtil.asyncDownloadAsset("197386");
        AssetUtil.asyncDownloadAsset("197388");
        AssetUtil.asyncDownloadAsset("Trigger");
        var j = 0
        var k = 0

        setTimeout(() => {
            var timer = setInterval(() => {

                if (j < this.buildx.length) {
                    if (k == this.buildx[j].length) {
                        j++;
                        k = 0;
                    }
                    else if (k < this.buildx[j].length) {
                        let box = GameObject.spawn("197386", {
                            transform: new Transform(new Vector(k * 300, j * 30 , 25 * k), new Rotation(0, 0, 0), new Vector(1, (1 + j * j) / 20, (1 + j * j) / 20)),
                            replicates: true
                        }) as Model;
                        this.buildx[j][k].n = box;
                        // 新增生成后隐藏
                        this.buildx[j][k].n.setVisibility(PropertyStatus.Off, true);
                        this.buildx[j][k].n.setCollision(PropertyStatus.Off, true);
                        k++;
                    }
                } else {
                    clearInterval(timer);
                }
                console.log(j + " " + k);
                // }

            }, 100);
        }, 1000)



        let trigger: Trigger;

        setTimeout(async () => {
            // if (SystemUtil.isServer()) {
            trigger = await GameObject.asyncSpawn("Trigger", {
                replicates: true,
                transform: new Transform(new Vector(100, 150, 25), Rotation.zero, Vector.one)
            }) as Trigger;
            console.log("trigger gameObjectId: " + trigger.gameObjectId);

            let box = GameObject.spawn("197386", {
                transform: new Transform(new Vector(100, 150, -25), new Rotation(0, 0, 0), new Vector(1, 1, 1)),
                replicates: true
            }) as Model;


            // }
        }, 2000);


        setTimeout(() => {
            trigger.onEnter.add(() => {
                j = 0;
                k = 0;
                var timer = setInterval(() => {

                    if (j < this.buildx.length) {
                        if (k == this.buildx[j].length) {
                            j++;
                            k = 0;
                        }
                        else if (k < this.buildx[j].length) {
                            this.buildx[j][k].n.setVisibility(PropertyStatus.On, true);
                            this.buildx[j][k].n.setCollision(PropertyStatus.On, true);
                            k++;
                        }
                    } else {
                        // 延时5秒复位
                        setTimeout(() => {
                            for (j = 0; j < this.buildx.length; j++) {
                                for (k = 0; k < this.buildx[j].length; k++) {
                                    this.buildx[j][k].n.setVisibility(PropertyStatus.Off, true);
                                    this.buildx[j][k].n.setCollision(PropertyStatus.Off, true);
                                }
                            }
                            clearInterval(timer);
                        }, 5000);
                    }
                    console.log(j + " " + k);
                    // }

                }, 100);
            })
        }, 3000);
    }
}







复制粘贴直接跑。修改成地雷,踩中之后会有方块堆积,在初始化中四个小数组存各自冲击方向,然后踩中后生成方块



class ooh {
    n: Model;
    id: string;
}

@Component
export default class adds extends Script {

    protected buildx: Array<Array<ooh>> = new Array(4);
    // 声明数组,一个数组里面有4个小数组,每个小数组里面有10个项,就是10个对象
    protected i: number = 0;
    protected flag_grow: number = 0;


    /** 当脚本被实例后,会在第一帧更新前调用此函数 */
    protected async onStart(): Promise<void> {

        for (var j = 0; j < this.buildx.length; j++) {
            this.buildx[j] = new Array(10);
            // 对大数组的一项,就是一个小数组,是小数组的预加载,规定数组的格式。new是分配内存。
            for (var k = 0; k < this.buildx[j].length; k++) {
                this.buildx[j][k] = new ooh();

                console.log(j + " " + k);
            }
        }

        AssetUtil.asyncDownloadAsset("197386");
        AssetUtil.asyncDownloadAsset("197388");
        AssetUtil.asyncDownloadAsset("Trigger");
        var j = 0
        var k = 0

        setTimeout(() => {
            var timer = setInterval(() => {

                if (j < this.buildx.length) {
                    if (k == this.buildx[j].length) {
                        j++;
                        k = 0;
                    }
                    else if (k < this.buildx[j].length) {
                        if (j == 0) {
                            let box = GameObject.spawn("197386", {
                                transform: new Transform(new Vector(100 + k * 50, 150 , 25 + 25 * k), new Rotation(0, 0, 0), new Vector(1, 1, 1*k*k/10)),
                                replicates: true
                            }) as Model;
                            this.buildx[j][k].n = box;
                        }
                        else if (j == 1) {
                            let box = GameObject.spawn("197386", {
                                transform: new Transform(new Vector(100 - k * 50, 150, 25 + 25 * k), new Rotation(0, 0, 0), new Vector(1, 1, 1*k*k/10)),
                                replicates: true
                            }) as Model;
                            this.buildx[j][k].n = box;
                        } else if (j == 2) {
                            let box = GameObject.spawn("197386", {
                                transform: new Transform(new Vector(100 , 150 - j * 30, 25 + 25 * k), new Rotation(0, 0, 0), new Vector(1, 1, 1*k*k/10)),
                                replicates: true
                            }) as Model;
                            this.buildx[j][k].n = box;
                        } else if (j == 3) {
                            let box = GameObject.spawn("197386", {
                                transform: new Transform(new Vector(100 , 150 + j * 30, 25 + 25 * k), new Rotation(0, 0, 0), new Vector(1, 1, 1*k*k/10)),
                                replicates: true
                            }) as Model;
                            this.buildx[j][k].n = box;
                        }
                        // 生成后隐藏
                        this.buildx[j][k].n.setVisibility(PropertyStatus.Off, true);
                        this.buildx[j][k].n.setCollision(PropertyStatus.Off, true);

                        k++;
                    }
                } else {
                    clearInterval(timer);
                }
                console.log(j + " " + k);
                // }

            }, 100);
        }, 1000)



        let trigger: Trigger;

        setTimeout(async () => {
            // if (SystemUtil.isServer()) {
            trigger = await GameObject.asyncSpawn("Trigger", {
                replicates: true,
                transform: new Transform(new Vector(100, 150, 25), Rotation.zero, Vector.one)
            }) as Trigger;
            console.log("trigger gameObjectId: " + trigger.gameObjectId);

            let box = GameObject.spawn("197386", {
                transform: new Transform(new Vector(100, 150, -25), new Rotation(0, 0, 0), new Vector(1, 1, 1)),
                replicates: true
            }) as Model;


            // }
        }, 2000);


        setTimeout(() => {
            trigger.onEnter.add(() => {
                j = 0;
                k = 0;
                var timer = setInterval(() => {

                    if (j < this.buildx.length) {
                        if (k == this.buildx[j].length) {
                            j++;
                            k = 0;
                        }
                        else if (k < this.buildx[j].length) {
                            this.buildx[j][k].n.setVisibility(PropertyStatus.On, true);
                            this.buildx[j][k].n.setCollision(PropertyStatus.On, true);
                            k++;
                        }
                    } else {
                        // 延时3秒复位
                        setTimeout(() => {
                            for (j = 0; j < this.buildx.length; j++) {
                                for (k = 0; k < this.buildx[j].length; k++) {
                                    this.buildx[j][k].n.setVisibility(PropertyStatus.Off, true);
                                    this.buildx[j][k].n.setCollision(PropertyStatus.Off, true);
                                }
                            }
                            clearInterval(timer);
                        }, 3000);
                    }
                    console.log(j + " " + k);
                    // }

                }, 100);
            })
        }, 3000);
    }
}










不过出现bug就是一条一条生成的,不是一块生成的。这就需要修改代码
这是修改过程,需要改成每次每行小数组的相同位置输出完毕,然后在依次打印小数组的下一位置。
原来是
【0】【1,2,3,4....9,10】
【1】【1,2,3,4....9,10】

....
【3】【1,2,3,4....9,10】

现在是
【1,2,3,4】【0】
【1,2,3,4】【1】

【1,2,3,4】【2】

....
【1,2,3,4】【9】
【1,2,3,4】【10】


穷举法数数字可知,每次循环都得第一个数组下标增加,然后再加到满之后,另一个数组下标,就是小数组下标才增加。
修改过程如下,

trigger.onEnter.add(() => {
                j = 0;
                k = 0;
                var timer = setInterval(() => {

                    // if (j < this.buildx.length) {
                    //     if (k == this.buildx[j].length) {
                    //         j++;
                    //         k = 0;
                    //     }
                    //     else if (k < this.buildx[j].length) {
                    //         this.buildx[j][k].n.setVisibility(PropertyStatus.On, true);
                    //         this.buildx[j][k].n.setCollision(PropertyStatus.On, true);
                    //         k++;
                    //     }
                    // } else {
                    //     // 延时3秒复位
                    //     setTimeout(() => {
                    //         for (j = 0; j < this.buildx.length; j++) {
                    //             for (k = 0; k < this.buildx[j].length; k++) {
                    //                 this.buildx[j][k].n.setVisibility(PropertyStatus.Off, true);
                    //                 this.buildx[j][k].n.setCollision(PropertyStatus.Off, true);
                    //             }
                    //         }
                    //         clearInterval(timer);
                    //     }, 3000);
                    // }



                    // 剥离嵌套的if
                    if (k == this.buildx[j].length) {
                        j++;
                        k = 0;
                    }
                    else if (k < this.buildx[j].length) {
                        this.buildx[j][k].n.setVisibility(PropertyStatus.On, true);
                        this.buildx[j][k].n.setCollision(PropertyStatus.On, true);
                        k++;
                    }


                    // 注意控制复位的代码
                    if (j == this.buildx.length) {
                        k++;
                        j = 0;
                    }
                    // 复位功能
                    else if (j < this.buildx.length) {
                        // 核心是jk频率交换,循环频率,从k比j快,到j比k快
                        this.buildx[j][k].n.setVisibility(PropertyStatus.On, true);
                        this.buildx[j][k].n.setCollision(PropertyStatus.On, true);
                        j++;
                    }



                    if (j < this.buildx.length) {

                    } else {
                        // 延时3秒复位
                        setTimeout(() => {
                            for (j = 0; j < this.buildx.length; j++) {
                                for (k = 0; k < this.buildx[j].length; k++) {
                                    this.buildx[j][k].n.setVisibility(PropertyStatus.Off, true);
                                    this.buildx[j][k].n.setCollision(PropertyStatus.Off, true);
                                }
                            }
                            clearInterval(timer);
                        }, 3000);
                    }

                    // 判断停止输出,各行都到头了
                    if (k < this.buildx[j].length+1) {

                    } else {
                        // 延时3秒复位
                        setTimeout(() => {
                            for (j = 0; j < this.buildx.length; j++) {
                                for (k = 0; k < this.buildx[j].length; k++) {
                                    this.buildx[j][k].n.setVisibility(PropertyStatus.Off, true);
                                    this.buildx[j][k].n.setCollision(PropertyStatus.Off, true);
                                }
                            }
                            clearInterval(timer);
                        }, 3000);
                    }





                    console.log(j + " " + k);
                    // }

                }, 100);
            })







然后修改完了,注意多了一个if,专门管理复位。因为不这样做会出bug,穷举法数数,能发现j=4的时候,数组只有0,1,2,3,没有4,于是会报错。表现为生成黑色,且生成几个物体就停止生成了。


最终成果



class ooh {
    n: Model;
    id: string;
}

@Component
export default class adds extends Script {

    protected buildx: Array<Array<ooh>> = new Array(4);
    // 声明数组,一个数组里面有4个小数组,每个小数组里面有10个项,就是10个对象
    protected i: number = 0;
    protected flag_grow: number = 0;


    /** 当脚本被实例后,会在第一帧更新前调用此函数 */
    protected async onStart(): Promise<void> {

        for (var j = 0; j < this.buildx.length; j++) {
            this.buildx[j] = new Array(10);
            // 对大数组的一项,就是一个小数组,是小数组的预加载,规定数组的格式。new是分配内存。
            for (var k = 0; k < this.buildx[j].length; k++) {
                this.buildx[j][k] = new ooh();

                console.log(j + " " + k);
            }
        }

        AssetUtil.asyncDownloadAsset("197386");
        AssetUtil.asyncDownloadAsset("197388");
        AssetUtil.asyncDownloadAsset("Trigger");
        var j = 0
        var k = 0

        setTimeout(() => {
            var timer = setInterval(() => {

                if (j < this.buildx.length) {
                    if (k == this.buildx[j].length) {
                        j++;
                        k = 0;
                    }
                    else if (k < this.buildx[j].length) {
                        if (j == 0) {
                            let box = GameObject.spawn("197386", {
                                transform: new Transform(new Vector(100 + k * 50, 150, 25 + 25 * k), new Rotation(0, 0, 0), new Vector(1, 1, 1 * k * k / 10)),
                                replicates: true
                            }) as Model;
                            this.buildx[j][k].n = box;
                        }
                        else if (j == 1) {
                            let box = GameObject.spawn("197386", {
                                transform: new Transform(new Vector(100 - k * 50, 150, 25 + 25 * k), new Rotation(0, 0, 0), new Vector(1, 1, 1 * k * k / 10)),
                                replicates: true
                            }) as Model;
                            this.buildx[j][k].n = box;
                        } else if (j == 2) {
                            let box = GameObject.spawn("197386", {
                                transform: new Transform(new Vector(100, 150 - j * 30, 25 + 25 * k), new Rotation(0, 0, 0), new Vector(1, 1, 1 * k * k / 10)),
                                replicates: true
                            }) as Model;
                            this.buildx[j][k].n = box;
                        } else if (j == 3) {
                            let box = GameObject.spawn("197386", {
                                transform: new Transform(new Vector(100, 150 + j * 30, 25 + 25 * k), new Rotation(0, 0, 0), new Vector(1, 1, 1 * k * k / 10)),
                                replicates: true
                            }) as Model;
                            this.buildx[j][k].n = box;
                        }
                        // 生成后隐藏
                        this.buildx[j][k].n.setVisibility(PropertyStatus.Off, true);
                        this.buildx[j][k].n.setCollision(PropertyStatus.Off, true);

                        k++;
                    }
                } else {
                    clearInterval(timer);
                }
                console.log(j + " " + k);
                // }

            }, 100);
        }, 1000)



        let trigger: Trigger;

        setTimeout(async () => {
            // if (SystemUtil.isServer()) {
            trigger = await GameObject.asyncSpawn("Trigger", {
                replicates: true,
                transform: new Transform(new Vector(100, 150, 25), Rotation.zero, Vector.one)
            }) as Trigger;
            console.log("trigger gameObjectId: " + trigger.gameObjectId);

            let box = GameObject.spawn("197386", {
                transform: new Transform(new Vector(100, 150, -25), new Rotation(0, 0, 0), new Vector(1, 1, 1)),
                replicates: true
            }) as Model;


            // }
        }, 2000);


        setTimeout(() => {
            trigger.onEnter.add(() => {
                j = 0;
                k = 0;
                var timer = setInterval(() => {

                    // if (j < this.buildx.length) {
                    //     if (k == this.buildx[j].length) {
                    //         j++;
                    //         k = 0;
                    //     }
                    //     else if (k < this.buildx[j].length) {
                    //         this.buildx[j][k].n.setVisibility(PropertyStatus.On, true);
                    //         this.buildx[j][k].n.setCollision(PropertyStatus.On, true);
                    //         k++;
                    //     }
                    // } else {
                    //     // 延时3秒复位
                    //     setTimeout(() => {
                    //         for (j = 0; j < this.buildx.length; j++) {
                    //             for (k = 0; k < this.buildx[j].length; k++) {
                    //                 this.buildx[j][k].n.setVisibility(PropertyStatus.Off, true);
                    //                 this.buildx[j][k].n.setCollision(PropertyStatus.Off, true);
                    //             }
                    //         }
                    //         clearInterval(timer);
                    //     }, 3000);
                    // }



                    // 剥离嵌套的if
                    // if (k == this.buildx[j].length) {
                    //     j++;
                    //     k = 0;
                    // }
                    // else if (k < this.buildx[j].length) {
                    //     this.buildx[j][k].n.setVisibility(PropertyStatus.On, true);
                    //     this.buildx[j][k].n.setCollision(PropertyStatus.On, true);
                    //     k++;
                    // }





                    // if (j < this.buildx.length) {

                    // } else {
                    //     // 延时3秒复位
                    //     setTimeout(() => {
                    //         for (j = 0; j < this.buildx.length; j++) {
                    //             for (k = 0; k < this.buildx[j].length; k++) {
                    //                 this.buildx[j][k].n.setVisibility(PropertyStatus.Off, true);
                    //                 this.buildx[j][k].n.setCollision(PropertyStatus.Off, true);
                    //             }
                    //         }
                    //         clearInterval(timer);
                    //     }, 3000);
                    // }

                    // 判断停止输出,各行都到头了


                    if(j==4){
                        j=0;
                        k++;
                    }

                    if (k < this.buildx[j].length ) {
                        // 注意控制复位的代码
                        if (j == this.buildx.length) {
                            k++;
                            j = 0;
                        }
                        // 复位功能
                        else if (j < this.buildx.length) {
                            // 核心是jk频率交换,循环频率,从k比j快,到j比k快
                            this.buildx[j][k].n.setVisibility(PropertyStatus.On, true);
                            this.buildx[j][k].n.setCollision(PropertyStatus.On, true);
                            j++;
                        }

                    } else {
                        // 延时3秒复位
                        setTimeout(() => {
                            var mj,nk
                            for (mj = 0; mj < this.buildx.length; mj++) {
                                for (nk = 0; nk < this.buildx[j].length; nk++) {
                                    this.buildx[mj][nk].n.setVisibility(PropertyStatus.Off, true);
                                    this.buildx[mj][nk].n.setCollision(PropertyStatus.Off, true);
                                }
                            }
                            clearInterval(timer);
                        }, 3000);
                    }


                    console.log(j + " " + k);
                    // }

                }, 100);
            })
        }, 3000);
    }
}





贰.所需语法
“数据结构课作业笔记”#011-数组-二维数组 口袋方舟论坛|面向全年龄的UGC互动内容平台与交流社区 (ark.online)
触发器 | 产品手册 (ark.online)
江湖救急——不用现成的对象池代码,如何动态生成方块? 口袋方舟论坛|面向全年龄的UGC互动内容平台与交流社区 (ark.online)


然后循环改间隔计时,看代码描述即可理解控制计时器与if替代数数循环



@Component
export default class NewScript2 extends Script {

    protected j: number
    protected k: number
    /** 当脚本被实例后,会在第一帧更新前调用此函数 */
    protected onStart(): void {
        this.j = 0;
        this.k = 0;
        // for (this.k = 0; this.k < 10; this.k++) {
        //     for (this.j = 0; this.j < 4; this.j++) {
        //         console.log(this.j + " " + this.k);
        //     }
        // }
        var timer = setInterval(() => {
            // if (this.j == 4) {
            //     this.j = 0;
            //     this.k++;
            // }
            // if (this.k == 10) {
            //     clearInterval(timer);
            // }

            if (this.k == 10) {
                clearInterval(timer);
            } else {
                if (this.j == 4) {
                    this.j = 0;
                    this.k++;
                }
            }



            console.log(this.j + " " + this.k);
        }, 100);
    }

}







for循环的几种形式



@Component
export default class NewScript2 extends Script {

    protected j: number
    protected k: number
    /** 当脚本被实例后,会在第一帧更新前调用此函数 */
    protected onStart(): void {
        this.j = 0;
        this.k = 0;

        // 常见形式
        for (this.k = 0; this.k < 10; this.k++) {
            for (this.j = 0; this.j < 4; this.j++) {
                console.log(this.j + " " + this.k);
            }
        }


        // 加一可以放括号外部
        for (this.k = 0; this.k < 10;) {
            for (this.j = 0; this.j < 4;) {
                console.log(this.j + " " + this.k);
                this.j++
            }
            this.k++
        }


        // 初始化可以放外部
        this.k = 0
        for (; this.k < 10;) {
            this.j = 0
            for (; this.j < 4;) {
                console.log(this.j + " " + this.k);
                this.j++
            }
            this.k++
        }


        // 都可以放外部
        for (; ;) {
            if (this.k < 10) {
                this.j = 0
            } else {
                break;
            }

            for (; ;) {
                if (this.j < 4) {
                    console.log(this.j + " " + this.k);
                    this.j++
                } else {
                    break;
                }
            }
            this.k++
        }



        console.log(this.j + " " + this.k);
    }

}





行序优先和列序优先
行序就是行填充的慢,填完了一行的全部座位,再填下一行
列序就是列填充的慢,填完了一列的全部座位,再填下一列



class ooh {
    n: Model;
    id: string;
}

@Component
export default class adds extends Script {

    protected buildx: Array<Array<ooh>> = new Array(4);
    // 声明数组,一个数组里面有4个小数组,每个小数组里面有10个项,就是10个对象
    protected i: number = 0;
    protected flag_grow: number = 0;


    /** 当脚本被实例后,会在第一帧更新前调用此函数 */
    protected async onStart(): Promise<void> {

        for (var j = 0; j < this.buildx.length; j++) {
            this.buildx[j] = new Array(10);
            for (var k = 0; k < this.buildx[j].length; k++) {
                this.buildx[j][k] = new ooh();
                console.log(j + " " + k);
            }
        }


        for (var k = 0; k < this.buildx[j].length; k++) {
            for (var j = 0; j < this.buildx.length; j++) {
                this.buildx[j][k] = new ooh();
                console.log(j + " " + k);
            }
            if(j==4){
                j=0;
                k++;
            }
        }


    }

}


叁.应用说明
方块生成编辑器,一些简单带物理模拟的特效,体素特效。
把地雷的数据导出,然后导入进适配的动效编辑器,从固定位置生成到从玩家上生成,从固定方向生成,到以玩家朝向为方向生成。在补充如动效编辑器里的多技能组合,触发连招,技能二阶段触发协议。
数学函数可视化
.相关参考链接 (返回主站
普通大学生“数据结构”课作业笔记#000-目录-逻辑结构与存储结构 口袋方舟论坛|面向全年龄的UGC互动内容平台与交流社区 (ark.online)


回复

使用道具 举报

热门版块
快速回复 返回顶部 返回列表