本帖最后由 脑的研发记录 于 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)
|