主题:  老大难的问题,Flash中hitTest的层关系

5D荣誉斑竹

职务:普通成员
等级:2
金币:2.0
发贴:617
#12002/7/12 8:35:33
关于flash5,Mx中的hitTest对应场景深度的老问题,不知道大家对他有什么好的解决办法?
在场景中当两个mc重合在一起,用鼠标hitTest监测他们的重合部分时mc的depth会失效,
flash会把你最先拖到场景中去的mc当作hitTest最先监测到的mc,mc的深度变得毫无意义。
最具代表性的就是窗口问题,下面的a和b是两个能够拖动的窗口,其他都很正常,但是当
把a拖动到b的上面时,在用鼠标点击他们的重合部分,你会发现即使已经将b用swapDepth
移动到a的下面一层,但b还是会在点击后跑到a的上面来!这是就是因为我在把mc放到场景中时是先放的b,所以不管b在第几层depth,都会比其他mc先监测到,然后执行语句。也就是说将b放到a的上面来咯!请看下面这个例子:


现在有些用flash制作窗口的大多都有这个不太明显的bug,当然两个窗口容易改,只不过是
多写几行代码,如果是多个怎么办?是个不确定的数字怎么办?
我的解决方法是这样的:把hittest和数组结合,让数组代替depth模拟层次。请看下面的代码:

total = 4;
//可以根据需要改变窗口的多少,注意必须在场景中存在!;
_root.onLoad = function() {
    layer = new Array(total-1);
    for (i=0; i        layer[i] = total-1-i;//layer[i]的值越小,层数越小,但是位置最考上;
    }
    //初始化窗口的上下层情况;
    j = 0;
    //layer[]中的下标;
    temp = 0;
    //中间变量;
    m = 1;
};
_root.onEnterFrame = function() {
    _root.onMouseDown = function() {
        for (i=0; i            if (_root["mc"+layer[i]].hitTest(_xmouse, _ymouse, true)) {
                temp = layer[i];
                j = i;
                break;
            }
            //找到鼠标所点击的窗口,这个窗口是相对最上层的;
        }
        if (i == total) {
            temp = layer[0];
            j = 0;
            m=0;
        }else{
            m=1;
        }
        //鼠标没有点击在任何窗口上;
        for (i=j; i>0; i--) {
            if (i == 0) {
                break;
            }
            layer[i] = layer[i-1];//将层数以此下移;
        }
        layer[0] = temp;
        for (i=0; i            _root["mc"+layer[i+1]]._alpha = (4-(i+1))*100/total;//根据mc的多少来分配透明度
            _root["mc"+layer[i]].swapDepths(1000-i);//体现层数向上
        }
        _root["mc"+layer[0]]._alpha = 100;
        if(m)startDrag("mc" add layer[0]);
    };
    _root.onMouseUp = function() {
        stopDrag();
    };
};




这样就能够解决问题了,不管多少mc也是如此,当然mc太多的时候效率低一些,但至少已经没有bug了:),跟定还会有更好的方法,希望大家继续讨论。
源文件

编辑历史:[这消息被柳叶吹风编辑过(编辑时间2002-07-12 18:10:25)]
[这消息被柳叶吹风编辑过(编辑时间2002-07-13 13:41:42)]


IT编辑

职务:普通成员
等级:6
金币:10.0
发贴:7769
#22002/7/12 9:38:37

  我来给大家讲讲hitTest吧,以便大家理解。
  在Flash中,我们可以用MovieClip对象的hitTest方法检测动画中的碰撞情况。hitTest方法可以用来检查一个实体(被拖拽到场景中的符号)对象是否已经与一个电影剪辑实体碰撞,返回值为true或false。
  hitTest方法的参数可以是碰撞区域的x或y轴坐标,也可以使用另一个电影剪辑的目标路径作为碰撞区,如:
  
  _root.onMouseDown = function() {
for (i=0; i if (_root["mc"+layer[i]].hitTest(_xmouse, _ymouse, true)) {
temp = layer[i];
j = i;
break;
}
                        



5D荣誉版主

职务:普通成员
等级:2
金币:1.0
发贴:515
#32002/7/13 10:52:23
用button做不就没这么麻烦了吗?



IT编辑

职务:普通成员
等级:6
金币:10.0
发贴:7769
#42002/7/13 13:43:20
原标题我记不得了,如果有什么问题你把你的标题再贴上来吧。

我想这样改一下,看得人可能会多一点,真是对不起。



5D荣誉斑竹

职务:普通成员
等级:2
金币:2.0
发贴:617
#52002/7/13 15:07:33
柳叶兄:没关系,我知道你是好意,谢谢你哦!我只是觉得题目和我要说的差得比较远,所以,还是想改回来。
mmommo兄:button毕竟不是mc,button可做的事情太少了,非常局限,不管是flash5还是flashMX对mc的操作都远远多于对button的操作,如果从每个窗口实现的功能来说的话,请问谁会把一个窗口做成button呢?再说窗口里面也许还会有button的呀,那岂不是乱套了!

编辑历史:[这消息被桃人编辑过(编辑时间2002-07-13 15:10:51)]


janlay

职务:管理员
等级:7
金币:28.0
发贴:7244
#62002/7/13 22:52:12
和技术无关的联系请使用悄悄话功能 :),另外,桃人可以编辑自己的帖子啊。

现在button和mc之间的界限较以前模糊多了,通过action,mc和button之间可以互相转换。

编辑历史:[这消息被janlay编辑过(编辑时间2002-07-13 22:55:10)]


5D荣誉版主

职务:普通成员
等级:2
金币:1.0
发贴:515
#72002/7/15 14:16:42
桃人在上个帖子中说
引用:
柳叶兄:没关系,我知道你是好意,谢谢你哦!我只是觉得题目和我要说的差得比较远,所以,还是想改回来。:D
mmommo兄:button毕竟不是mc,button可做的事情太少了,非常局限,不管是flash5还是flashMX对mc的操作都远远多于对button的操作,如果从每个窗口实现的功能来说的话,请问谁会把一个窗口做成button呢?再说窗口里面也许还会有button的呀,那岂不是乱套了! :)

我就是用button做弹出窗口的,每个窗口mc最下一层就是一个和窗口等大的空button,在mx中,可以用语句控制button的一切啊,很方便的。
随便句个例子:
如有5个window
_global.highest_level=10
for(i=1;i<=5;i++){
eval("win"+i).btn.useHandCursor =false
eval("win"+i).btn.i=i
eval("win"+i).btn.onRelease=function(){
_root["win"+this.i].swapDepth(_global.highest_level)
_global.highest_level++
}
}

正好就这个例子我也有点问题要问:
我使用了绝对路径来调用btn本身所在的mc
我一直搞不懂这样的情况下是用_parent还是什么。
我记得好几次用_parent都行不通
在f5中btn的object action 中调用本身所在的mc用this就没问题。
在mx中用f5的写法用this也是没问题
可要是写在frame上我就糊涂了,所以只好用绝对路径了。
还请大家帮忙解释一下这种路径问题。

编辑历史:[这消息被mmommo编辑过(编辑时间2002-07-15 14:20:16)]


janlay

职务:管理员
等级:7
金币:28.0
发贴:7244
#82002/7/16 2:56:13
引用:
eval("win"+i).btn.onRelease=function(){
_root["win"+this.i].swapDepth(_global.highest_level)
_global.highest_level++
...


在对对象自定义方法是,路径确实是一个很尴尬的问题

如果在路径前加上_root,则肯定是引用_root下的对象无疑。
但是,如果加了this,就表示引用指定的对象;如果没加(看起来和加this一样),则引用的是当前桢所在的路径。

你可以参考一下这个源文件:
www.5dmedia.com/bbs/NewsDetail.asp?id=376349



Demon.S

职务:版主
等级:5
金币:10.0
发贴:2468
#92002/7/16 11:32:58
_global定义的东西再次使用的时候直接用名称就可以了
例如
_global.a="b";
使用(任何地方)
mc.c=a;



5D荣誉版主

职务:普通成员
等级:2
金币:1.0
发贴:515
#102002/7/16 16:33:59
画魔在上个帖子中说
引用:
_global定义的东西再次使用的时候直接用名称就可以了
例如
_global.a="b";
使用(任何地方)
mc.c=a;

理论上是这样。但是经常会出错。特别是在function里。我好几次都出现这种莫名其妙的问题。但是加上_globla.a就没问题啦。