分享
 
 
 

Director动态事件传递

王朝other·作者佚名  2008-05-21
窄屏简体版  字體: |||超大  

Director 动态事件传递

有时在Director开发过程中会遇到一些棘手的问题,其中的原因之一是由于行为中包含有某些“陷阱”事件,比如点击了一个带有行为的角色,那么此点击事件将停滞在此角色上,虽然你想让其下的角色也能够识别并对事件做出响应。

下面的样本文件演示了这个问题:如果你点击了上面的角色,则只能获得从上面角色发送来的消息,即使你的点击碰巧发生在两个角色交叠的范围之内。

虽然你想让鼠标事件通过角色层向下传递,但由于Director在行为中获得事件的方式,这一点根本无法做到。例如,使用pass命令不会有任何效果。

或许你会想到使用sendSprite命令告诉位于当前角色下面的任何角色:一个事件已经发生,需要做出适当的响应。

或许你想让行为做这样的事情:使用交叠测试来寻找其下的角色,即使被上方的角色遮挡,仍可以将点击事件传递给下方的角色。

PROPERTY pnIntersectSprite

on beginSprite me

me .FindLowerSprite()

END beginSprite

on mouseUp me

me .TransmitClick()

END mouseUp

on FindLowerSprite me

nSprite = me . spriteNum - 1

rMyRect = sprite ( me . spriteNum ). rect

pnIntersectSprite = 0

repeat with nTest = nSprite down to 1

rTestRect = sprite (nTest). rect

rIntersect = intersect ( rMyRect, rTestRect )

if rIntersect <> rect ( 0 , 0 , 0 , 0 ) then

pnIntersectSprite = nTest

exit repeat

end if

end repeat

END FindLowerSprite

on TransmitClick me

if pnIntersectSprite <> 0 then

sendSprite ( pnIntersectSprite, #mouseUp )

end if

END TransmitClick

初看起来这可能是一个具有可行性的解决方案,但如果你点击下面样本文件中的红色矩形,将会看到仍然存在的一些问题。

看到了吗?不管你在角色2中的何处点击,角色1都非常“警惕”。也就是说,虽然没有直接点击两角色交叠的地方,但程序认为你这样做了。

这便是问题所在,而要想解决此问题,首先需要查明给出角色是否真的和一个附带此行为的角色相交叠,其次必须确定当事件被传递时下面的角色是否碰巧位于鼠标下方,如果不是的话就不将此事件发送给下面的角色层。

PROPERTY pnIntersectSprite

on beginSprite me

me .FindLowerSprite()

END beginSprite

on mouseUp me

me .TransmitEvent( #mouseUp )

END mouseUp

on FindLowerSprite me

nSprite = me . spriteNum - 1

rMyRect = sprite ( me . spriteNum ). rect

pnIntersectSprite = 0

repeat with nTest = nSprite down to 1

rTestRect = sprite (nTest). rect

rIntersect = intersect ( rMyRect, rTestRect )

if rIntersect <> rect ( 0 , 0 , 0 , 0 ) then

pnIntersectSprite = nTest

exit repeat

end if

end repeat

END FindLowerSprite

on TransmitEvent me , yEvent

if pnIntersectSprite <> 0 then

pMousePoint = the mouseLoc

rTestRect = sprite (pnIntersectSprite). rect

if pMousePoint. inside ( rTestRect ) then

sendSprite ( pnIntersectSprite, yEvent )

end if

end if

END TransmitEvent

由于确定了单击发生时鼠标是否位于下层角色之上,上面的行为将给出更可靠的结果,下面的样本文件动态演示了这一点。

Director 动态事件传递

那么更下层的其他角色该怎么办呢?忽略它们吗?也就是说,为什么不将此事件传递给所有下层的角色呢?

我们必须考虑的很重要的一点就是运行时间问题。Director允许在单帧中显示多达1000个角色,所以为了从一个行为中传递此事件,我们可能需要测试999次。

但其他一些事件也有可能发生,像mouseDown、mouseEnter等等,忽略它们并不是一个好的想法,因此可以在getPropertyDescriptionList中添加一些参数,以允许我们确定哪些事件将获得消息,哪些事件不获得消息。

最后,我们还应考虑到可见性和运动状态。因为Director是一个动态的工作环境,角色有时会重叠,有时不会重叠,所以最好能够动态侦测交叠状态,此外还可以添加一个参数,以使我们能够选择是否给一个已设置为不可见的角色发送事件。

下面的影片包含了一个基本完成的行为,允许Director动态判定一个给定角色是否正和当前角色及鼠标位置交叠,一旦如此,行为将向底层角色发送指定的任何事件。

稍后的Director影片使用了此行为的一个修改版本。原来的行为认为舞台上没有动画发生,虽然这样的行为已经非常适合于静态使用了,但稍后的版本更适合于动态使用。

当然,你可以根据自己的需要添加其他参数,以最大限度的提高代码库的利用率。

就象你看到的那样,背景动画并不会导致行为失效,因为它能够很清楚的判定两个矩形何时交叠,何时不交叠,并做出恰当的响应。

下面是最终影片中完整的“动态事件传递”行为的全部代码。

PROPERTY pnIntersectSprite

PROPERTY pbPropagateMouseDown

PROPERTY pbPropagateMouseUp

PROPERTY pbPropagateMouseEnter

PROPERTY pbPropagateMouseLeave

PROPERTY pbPropagateMouseWithin

PROPERTY pbPropagateRightMouseDown

PROPERTY pbPropagateRightMouseUp

PROPERTY pbPropagateToInvisibleSprite

PROPERTY pbAssumeStaticStage

on beginSprite me

me .FindLowerSprite()

END beginSprite

on mouseDown me

if pbPropagateMouseDown = TRUE then

me .TransmitEvent( #mouseDown )

end if

END mouseDown

on mouseUp me

if pbPropagateMouseUp = TRUE then

me .TransmitEvent( #mouseUp )

end if

END mouseUp

on mouseEnter me

if pbPropagateMouseEnter = TRUE then

me .TransmitEvent( #mouseEnter )

end if

END mouseEnter

on mouseLeave me

if pbPropagateMouseLeave = TRUE then

me .TransmitEvent( #mouseLeave )

end if

END mouseLeave

on mouseWithin me

if pbPropagateMouseWithin = TRUE then

me .TransmitEvent( #mouseWithin )

end if

END mouseWithin

on rightMouseDown me

if pbPropagateRightMouseDown = TRUE then

me .TransmitEvent( #rightMouseDown )

end if

END rightMouseDown

on rightMouseUp me

if pbPropagateRightMouseUp = TRUE then

me .TransmitEvent( #rightMouseUp )

end if

END rightMouseUp

on FindLowerSprite me

pnIntersectSprite = 0

if pbAssumeStaticStage = TRUE then

nSprite = me . spriteNum - 1

rMyRect = sprite ( me . spriteNum ). rect

repeat with nTest = nSprite down to 1

rTestRect = sprite (nTest). rect

rIntersect = intersect ( rMyRect, rTestRect )

if rIntersect <> rect ( 0 , 0 , 0 , 0 ) then

pnIntersectSprite = nTest

exit repeat

end if

end repeat

end if

END FindLowerSprite

on TransmitEvent me , yEvent

pMousePoint = the mouseLoc

if pnIntersectSprite <> 0 then

rTestRect = sprite (pnIntersectSprite). rect

if pMousePoint. inside ( rTestRect ) then

if sprite (pnIntersectSprite). visible = TRUE or ( sprite (pnIntersectSprite). visible = FALSE and pbPropagateToInvisibleSprite = TRUE ) then

sendSprite ( pnIntersectSprite, yEvent )

end if

end if

else if pnIntersectSprite = 0 and pbAssumeStaticStage = FALSE then

bFoundIntersect = FALSE

nSprite = me . spriteNum - 1

rMyRect = sprite ( me . spriteNum ). rect

repeat with nTest = nSprite down to 1

rTestRect = sprite (nTest). rect

rIntersect = intersect ( rMyRect, rTestRect )

if rIntersect <> rect ( 0 , 0 , 0 , 0 ) then

bFoundIntersect = TRUE

exit repeat

end if

end repeat

if bFoundIntersect = TRUE then

rTestRect = sprite (nTest). rect

if pMousePoint. inside ( rTestRect ) then

if sprite (nTest). visible = TRUE or ( sprite (nTest). visible = FALSE and pbPropagateToInvisibleSprite = TRUE ) then

sendSprite ( nTest, yEvent )

end if

end if

end if

end if

END TransmitEvent

on getPropertyDescriptionList me

if the currentSpriteNum > 0 then

lMyPropList = [:]

lMyPropList. addProp ( # pbPropagateMouseDown, [ # comment: "Propagate mouseDown?" , # format: # boolean, # default: FALSE ] )

lMyPropList. addProp ( # pbPropagateMouseUp, [ # comment: "Propagate mouseUp?" , # format: # boolean, # default: TRUE ] )

lMyPropList. addProp ( # pbPropagateMouseEnter, [ # comment: "Propagate mouseEnter?" , # format: # boolean, # default: FALSE ] )

lMyPropList. addProp ( # pbPropagateMouseLeave, [ # comment: "Propagate mouseLeave?" , # format: # boolean

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有