“克隆体克隆”一道一定要跨过的鸿沟

Scratch 少儿编程 418浏览 0评论

友情提示:视频教程观看时请手动设置清晰度。

在重构塔防游戏《保卫萝卜》中遇到几个有关“克隆”的问题,这里分享一下我的解决思路方法,这也是茂财2020的最后一更。

 

“克隆体克隆”一道一定要跨过的鸿沟

 

分享讨论问题之前科普两个知识点(高手忽略):

第一个是局部变量或者称为私有变量

“克隆体克隆”一道一定要跨过的鸿沟

 


定义了一个私有变量,那么克隆出的克隆体就人手一份有了自己的这个私有变量,并且互不干扰,就像每人得到一个小篮子(私有变量),怎么装?装什么东西都与别人无关了。
除了自定义的私有变量外,其实系统已经预建好多私有变量,当克隆发生时,这些变量同样会被克隆体继承。

“克隆体克隆”一道一定要跨过的鸿沟

 

“克隆体克隆”一道一定要跨过的鸿沟

 

“克隆体克隆”一道一定要跨过的鸿沟

 

第二个就是本体(角色本身)与克隆体执行的模块
只能是本体执行绿旗引导的代码

“克隆体克隆”一道一定要跨过的鸿沟

 

 

只能是克隆体执行克隆体启动这段代码

“克隆体克隆”一道一定要跨过的鸿沟

 

除了这两个事件,其他的呢?该谁执行呢?

“克隆体克隆”一道一定要跨过的鸿沟

 


答案是:本体与克隆体一起执行这些事件引导的代码块!~
执行下面这段代码的结果是:本体与克隆体都会说“吃了吗?”

“克隆体克隆”一道一定要跨过的鸿沟

 

 

“克隆体克隆”一道一定要跨过的鸿沟

 

有点意思了,如果我想通过除了点击绿旗以外的其他事件来执行克隆这个行为,就会有不可控的事情发生–指数级克隆,克隆体的数量就会很快到达上限300个。

如何避免此事情发生呢?这就是我要分享的第一个克隆的入门级问题!~
按需求执行!!克隆体除了执行“当克隆体启动时”,按需求执行其他事件引导的程序。

这个大部分人知道技巧就是用私有变量来标识本体与克隆体,如用_isClone=0标识本体,_isClone=1标识克隆体,那么就可以在其他事件引导的代码后控制本体或是克隆体能执行这段代码了!~

“克隆体克隆”一道一定要跨过的鸿沟

 

 

“克隆体克隆”一道一定要跨过的鸿沟

 


如果不要克隆体参与某个事件,就可以用下面这种方式。

“克隆体克隆”一道一定要跨过的鸿沟

 


但是在很多情况下不让克隆体参与克隆是不现实的,比如在《保卫萝卜》中需要克隆多个防御塔(先拿瓶子举例吧),瓶子需要发射子弹的,也就要用到克隆,“克隆体克隆”这个魔咒就来了!~这是我要说的克隆入门级的第二个问题。

可能聪明的朋友会说我可用多个角色来代替克隆体啊,我想说这样的朋友可以毕业了,老师已经教不了了你了,对自己都这么狠啊!~
再把要解决的问题复述一遍:已经克隆了好多个瓶子(防御塔turret),每个瓶子在攻击范围内要发射(克隆)子弹,这就是典型的指数级克隆啊。

破解第一招—-乾坤大挪移
克隆体与克隆体的克隆体分离,语言有点扭,就是将子弹单独作为一个角色来处理,瓶子发射(克隆)子弹,是克隆别人,不是自己,这样就轻松躲过“自己克隆自己”这个魔咒。

解决了这个麻烦,紧跟着另一个问题又出现了:克隆出的子弹怎么知道谁是自己的本体啊?要面向什么方向?先出现在哪个瓶子的位置呢?这就涉及到角色之间的数据传递了,所以要用到全局变量了。瓶子在克隆子弹之前将自己的属性(方向、位置什么的)存储到全局变量里(或全局列表中),子弹克隆体接受传递过来的这些属性参数完成自己的克隆。这种技术叫做“现场保护”。通过这种方式将瓶子的属性(基因)复制给子弹,子弹接受后要及时销毁,否则会传递给其他子弹。

这样来看貌似解决这个问题,其实不然,如果瓶子数不多的情况下,这种方法无疑是最好的,但如果瓶子数量很大,在多线程的机制下,就会出现2个或者多个子弹公用一套基因的,因为共有的传递介质只有一套啊,所以不可避免的会出现个别瓶子炮出现“哑弹”情况,其他的瓶子会联发的现象。

怎么破?
怎么破?
怎么破?

破局绝招—-“九阴白骨爪”第五式唯我独尊

呵呵,招式是瞎诌的,回归本质,将本体、克隆体、克隆体的克隆体作为一个角色进行处理,巧妙利用“克隆体克隆”,利用”当克隆体启动”这个多线程引导程序避免数据传输错误的现象。

貌似抽象了点,用瓶子和子弹来描述就是:克隆体瓶子克隆体启动的代码块可以看做是一个线程,有多少个瓶子克隆体就有多少个线程(这个比喻好理解,具体线程数还与CPU的核心数有关的,不扯那么远了)。那么每一个瓶子克隆出来的子弹就不会与其他的子弹发生数据上的重叠。理论上就是这个样子的。

怎么实现呢?

前面介绍过了,标识克隆体与本体的方法,同样适用于克隆体与克隆体的克隆体。

具体一点就是瓶子在克隆子弹的时候需要设置一个私有的变量(_type)用来标识子弹,避免其执行瓶子克隆体的代码。

“克隆体克隆”一道一定要跨过的鸿沟

 

同样子弹也有自己代码块,不过需要提前识别

“克隆体克隆”一道一定要跨过的鸿沟

 

 

这样做的好处就是瓶子将需要的信息(从哪里发射–位置,发射时的方向)等信息同步传递给自己的克隆体–子弹。

这样再多的瓶子发射再多的子弹也不会张冠李戴了,完美解决。

不过这里仍旧有个问题,也是在重构中碰到的,就是瓶子在克隆子弹时将_type改成了bullet,自己的私有属性变成了bullet,接下来如果要放置新瓶子炮就会被当做子弹bullet处理,根本就放不下,一放就会被当做子弹发射出去!~

又该怎么破解呢?
哈哈,“需求催生技术”,肯定有破法!

这里先卖个关子,不做解答,我会在2021年重构版《保卫萝卜》里分享破解之法。~

转自公众号:
嘻嘻哈哈学编程

您必须 登录 才能发表评论!