Discuss Scratch

Nolan_Dong
New to Scratch
5 posts

是否有更好的办法处理两个克隆体的相撞事件?

如果是两个对象相撞很简单就不提了。
如果是一个对象撞另一个克隆体,可以在克隆体里写检测代码,再发广播通知对象。
但如果是两个克隆体相撞好像就很难处理了,比如飞行游戏里不限量的子弹与不限量的敌对飞机,如何处理?

我现在想到的是在双方克隆体内都写检测代码,然后各自处理事件,但我担心二者的并发机制并不保障都有相同的机会能够正确地检测到碰撞。
举例来说,敌方飞机即将碰到我的飞机,这时我打出一发子弹命中敌方飞机。敌方飞机检测到子弹相撞后是否应当立即销毁自己?
如果立即销毁,那么我的子弹有可能此时还没有检测到碰撞事件,这就变成了我的子弹打死了一架敌方飞机,但并没有按原计划那样的与敌同归于尽。
如果延时销毁,保留一点时间确保我的子弹有机会识别到碰撞事件,这又可能让我的飞机先检测到了碰撞事件,这样的后果就是我本来有机会先打爆敌机的,结果由于延时算法,我的飞机被撞了。

大家有什么好的解决思路可以提示我吗?
gejiarui
Scratcher
3 posts

是否有更好的办法处理两个克隆体的相撞事件?

可以让敌方飞机碰到我方子弹后先不立即销毁,但是取消碰到我方飞机的判定,延时一会再销毁。
Nolan_Dong
New to Scratch
5 posts

是否有更好的办法处理两个克隆体的相撞事件?

主要还是计算精度问题,延时销毁就会造成更多的误判,比如一架飞机吸收了我方多枚子弹,在飞机有一定血量的时候还有可能一次碰撞被重复计算了多次,本来二血的飞机被一颗子弹打没了。

当然,精度好像本身是个无解的问题,就算是实体撞击实体,由于代码不能跨对象操作,只能通过广播,除了代码形式上好看,并不能保证运行上一定被及时地优先处理。scratch本身还是不太适合做这些复杂的计算。
scientificscratch
Scratcher
66 posts

是否有更好的办法处理两个克隆体的相撞事件?

让我想想……
InCryst
Scratcher
6 posts

是否有更好的办法处理两个克隆体的相撞事件?

我的操作方法是在销毁之前加一句“等待0秒”,这样销毁之前的时间会正好使碰撞判断1次(前提是你没有使用运行时不刷新屏幕)。
TwilightSparkleLover
Scratcher
100+ posts

是否有更好的办法处理两个克隆体的相撞事件?

这是我方子弹的脚本
当作为克隆体启动时
重复执行
如果 <碰到 [敌方灰机 v] ?> 那么
等待 (0.000000000000000000000000000000000000000000000000000001) 秒
如果 <碰到 [敌方灰机 v] ?> 那么
删除本克隆体
end
end
end
这是我方灰机的脚本
当作为克隆体启动时
重复执行
如果 <碰到 [敌方灰机 v] ?> 那么
等待 (0.000000000000000000000000000000000000000000000000000001) 秒
如果 <碰到 [敌方灰机 v] ?> 那么
game over
end
end
end
这是敌方灰机的脚本
当作为克隆体启动时
重复执行
如果 <碰到 [我方子弹 v] ?> 那么
等待 (0.000000000000000000000000000000000000000000000000000001) 秒
如果 <碰到 [我方子弹 v] ?> 那么
删除本克隆体
end
end
end

Last edited by TwilightSparkleLover (Jan. 15, 2018 12:32:51)


scratch中文专区欢迎你! ::sensing
https:/ /scratch.mit.edu/studios/4659772/ ::sound
大家也可以看一下我的跳舞的线 ::motion
https:/ /scratch.mit.edu/studios/5290366/ ::operators
没办法,中文专区非常的冷清...
Nolan_Dong
New to Scratch
5 posts

是否有更好的办法处理两个克隆体的相撞事件?

等待0秒的思路有可能是可行的,我在处理多次广播消息的时候感觉scratch的表现和一些线程问题相关。
等待0秒还是0.000001秒应当都可以,重要的就是给了其他循环线程有机会处理自己的检测逻辑。
不过还没去试,先谢过楼上几位。
ErShiSi
New to Scratch
1 post

是否有更好的办法处理两个克隆体的相撞事件?

无论等待0秒还是等待0.1秒,都不稳定。有时会判定碰撞多次,有时还是会miss掉本次碰撞,不知道哪位大佬有别的解决方案呢?
king1550
Scratcher
100+ posts

是否有更好的办法处理两个克隆体的相撞事件?

要放個延遲,不要太長就好

我住在台灣,今年14歲 希望大家多多關注!

我的遊戲天堂:https://scratch.mit.edu/studios/3631162/

關注我:https://scratch.mit.edu/users/king1550/

platfomer:https://scratch.mit.edu/studios/3838501/
cc_scratch_cc
Scratcher
24 posts

是否有更好的办法处理两个克隆体的相撞事件?

ErShiSi wrote:

无论等待0秒还是等待0.1秒,都不稳定。有时会判定碰撞多次,有时还是会miss掉本次碰撞,不知道哪位大佬有别的解决方案呢?

有一个简单的方案,就是广播并等待

对于子弹
当作为克隆体启动时
重复执行
如果 <碰到 [敌人 v] ?> 那么
广播 [发生碰撞 v] 并等待
删除本克隆体
end
end

对于敌人
当接收到 [发生碰撞 v]
如果 <碰到 [子弹 v] ?> 那么
end

Last edited by cc_scratch_cc (July 11, 2018 14:23:47)

cc_scratch_cc
Scratcher
24 posts

是否有更好的办法处理两个克隆体的相撞事件?

高级一点的方案,可以用 仲裁者模式

即子弹和飞机各自检测碰撞,然后把自己的编号发送到列表。

然后仲裁者角色, 不停从两个列表中取出碰撞影响的对象ID, 仲裁后 再发送死亡通知书给 子弹 、敌机

仲裁者脚本可以确保 一个子弹消灭一个敌人, 或者做更多复杂的判定

wushitoutou
New to Scratch
1 post

是否有更好的办法处理两个克隆体的相撞事件?

cc_scratch_cc wrote:

高级一点的方案,可以用 仲裁者模式

即子弹和飞机各自检测碰撞,然后把自己的编号发送到列表。

然后仲裁者角色, 不停从两个列表中取出碰撞影响的对象ID, 仲裁后 再发送死亡通知书给 子弹 、敌机

仲裁者脚本可以确保 一个子弹消灭一个敌人, 或者做更多复杂的判定

怎么发送对像的ID?仲裁者发出的通知,怎么让发生碰撞的飞机克隆识别,而没发生的不识别。
cc_scratch_cc
Scratcher
24 posts

是否有更好的办法处理两个克隆体的相撞事件?

* wrote:

cc_scratch_cc wrote:

高级一点的方案,可以用 仲裁者模式

即子弹和飞机各自检测碰撞,然后把自己的编号发送到列表。

然后仲裁者角色, 不停从两个列表中取出碰撞影响的对象ID, 仲裁后 再发送死亡通知书给 子弹 、敌机

仲裁者脚本可以确保 一个子弹消灭一个敌人, 或者做更多复杂的判定

怎么发送对像的ID?仲裁者发出的通知,怎么让发生碰撞的飞机克隆识别,而没发生的不识别。
没有办法在消息里附带,但是你可以把ID加入到一个列表变量中,这样对方就知道有谁参与了碰撞

changchangli
Scratcher
62 posts

是否有更好的办法处理两个克隆体的相撞事件?

等待0秒就相当于说(没有)??
说 []
??

——————————不完美的分界线———————————
大家好,我是changchangli,是个完完全全的渣新(哭+焦急),这是我最近的作品https://scratch.mit.edu/projects/236820365/
请大家过来玩玩这个游戏,并提出意见!!你们也可以关注我的工作室https://scratch.mit.edu/studios/2911066/
大家都可以添加自己的作品!!
suzeqi
Scratcher
1 post

是否有更好的办法处理两个克隆体的相撞事件?

Emmm
runlhy
Scratcher
12 posts

是否有更好的办法处理两个克隆体的相撞事件?

我在制作一个类似的游戏中也遇到了这个问题,这里分享一下解决思路:

分为三个解决方案:
解决1. 使用等待0.01秒方式,问题:一颗子弹有时会碰撞多个目标,有时无法碰撞目标。

解决2. 使用广播模式,子弹碰撞目标后,不删除子弹先发送广播,目标收到后广播再发送返回的广播,子弹接收到广播再删除子弹。需要广播两次,可以解决子弹碰撞多个目标或无法碰撞目标的问题。但此刻产生了一个新的问题,再子弹接收到返回广播时删除克隆体会将所有子弹的克隆体都删掉。

解决3. 如果能让接收返回的广播时,只删除碰到目标子弹就达到要求了,这里我使用了克隆体的私有变量来解决,为子弹添加序号,在碰撞时记录当前子弹序号,然后在删除子弹时判断记录的序号和子弹的序号就完成了。

建议配合此例子来学习,观看Enemy 和 shipBullet 脚本~。

https://scratch.mit.edu/projects/282851685/

w23x
Scratcher
16 posts

是否有更好的办法处理两个克隆体的相撞事件?

runlhy wrote:

我在制作一个类似的游戏中也遇到了这个问题,这里分享一下解决思路:

分为三个解决方案:
解决1. 使用等待0.01秒方式,问题:一颗子弹有时会碰撞多个目标,有时无法碰撞目标。

解决2. 使用广播模式,子弹碰撞目标后,不删除子弹先发送广播,目标收到后广播再发送返回的广播,子弹接收到广播再删除子弹。需要广播两次,可以解决子弹碰撞多个目标或无法碰撞目标的问题。但此刻产生了一个新的问题,再子弹接收到返回广播时删除克隆体会将所有子弹的克隆体都删掉。

解决3. 如果能让接收返回的广播时,只删除碰到目标子弹就达到要求了,这里我使用了克隆体的私有变量来解决,为子弹添加序号,在碰撞时记录当前子弹序号,然后在删除子弹时判断记录的序号和子弹的序号就完成了。

建议配合此例子来学习,观看Enemy 和 shipBullet 脚本~。

https://scratch.mit.edu/projects/282851685/

克隆体的私有变量来解决—我也常用这种方法。
Billy_boom_boom
Scratcher
23 posts

是否有更好的办法处理两个克隆体的相撞事件?

等待0秒应该行,子弹那边要先做等待,在这一瞬间飞机删除
子弹
当作为克隆体启动时
重复执行
如果 <碰到 [飞机 v] ?> 那么
播放声音 [飞机爆炸 v]
广播 [plane v]
等待 (0) 秒
删除本克隆体
end
end
飞机
当作为克隆体启动时
重复执行
如果 <碰到 [子弹 v] ?> 那么
删除本克隆体
end
end
还有
当接收到 [有人试验了 v]
询问 [行吗] 并等待
如果 <(回答) = [行]> 那么
说 [OK]
停止 [回帖 v]
否则
说 (连接 [真的不行吗?] [(疑惑不解的表情)])
再见
end

Powered by DjangoBB