另类像素级精确选择对象法—蓝图法

from:http://bbs.9ria.com/forum.php?mod=viewthread&tid=16763

另类像素级精确选择对象法—蓝图法

本方法主要是运用bitmapData以及ColorTransform类。
  实现原理是把“层深值”图像化然后根据鼠标当前像素颜色值去取对象。

  至于为什么叫蓝图法,原因是这张用来判断的图片显示的时候基本全是蓝和黑色,要出现其他颜色的话对象数量就必须达到一个巨大的量。所以在同一层级不上万个对象的情况下图片基本就是蓝黑色的。实际用的办法比较另类,也是属于一时

突发奇想的结果。

判断对象主要分三种情况
1、全静态显示对象处理
2、动态显示对象处理
3、混合对象处理

一、全静态显示对象取得当前鼠标所在位置对象的过程如下:

正常版DEMO: 静态物体精确选择_正常版.swf
蓝图版DEMO: 静态物体精确选择_蓝图版.swf 

1、初始化对象。
2、建立对象索引表或者把需要判断的对象addChild到相应容器中。
3、创建一个蓝图的bitmapData尺寸是场景大小。
4、遍历某一层级容器下的显示列表比如stage的,前提是这个容器必须是DisplayObjectContainer子类。同时利用 ColorTransform类和DisplayObject对象的transform.colorTransform属性把对象设置成单色,颜色值等于 层深值。由于深度值在这个层级下肯定是唯一的,那么每个对象就变成了有唯一颜色的单色对象(完全透明区域不会变色,仍然保持完全透明)。
5、把单色对象按深度从小到大的顺序向蓝图bitmapData里draw(),draw()完再次设置DisplayObject对象的 transform.colorTransform属性为空把对象颜色恢复正常。最终循环完成的时一张蓝黑色的图片也就是蓝图就生成了。
6、生成的蓝图并不需要显示或者addChild到任何地方存在即可。
7、用enterFrame或者鼠标事件或者setInterval来作为触发来获得当前鼠标的X,Y坐标。
8、用bitmapData的getPixel(x,y)方法从蓝图中获取相应坐标的颜色值,也就是获得当前鼠标下那点的蓝图颜色。而这个颜色就是一个深度,那么直接stage.getChildAt()就可以方便的返回这个深度的对象了。

  全静态的蓝图只需要制作一次,因为里面的视觉元素根本不会变化。如果场景平移那么蓝图也相应平移即可。所以比较 消耗资源的就是初始化的时候,之后由于只调用了getPixel()和getChildAt()可以说速度相当优异(100000次循环在100毫秒以 内,那么单次大概0.001毫秒以下)。

二、动态对象获取

DEMO: 动态物体精确选择.swf 

基本原理和静态的相同,但是由于待选对象是运动的可能是动画可能是复杂移动,那么蓝图只做一次明显就无法满足。那么就需要随时刷新蓝图,但是如果对象过多 明显draw()这个占资源的东西会造成太多的系统消耗。那么我们就不要去把所有动态对象做进蓝图,只需要把鼠标点所在的那个点下的动态对象做成蓝图并取 色即可。
  这里获取当前点下的目标列表可以使用stage.getObjectsUnderPoint(point)方法。而获得对象深度值则使用getChildIndex(dislplayObject)来取得唯一颜色值。
  在触发判断的瞬间把列表中的对象变色并且取得鼠标坐标点颜色然后再把对象变回去。由于过程很快实际显示上不会有任何影响。

三、混合对象处理
  比如游戏场景中的房屋街道家具树木这些都是静态对象,而玩家敌人宠物或者一些场景动画就属于动态对象。混合处理就是把静态的做静态蓝图,再在对动态对 象获取的时候把静态对象从列表中排除。检测结果如果没有任何动态对象被选中再检测静态对象,毕竟静态对象只需要获取一次颜色就可以直接返回对象。

DEMO源代码: 像素级精确选择.rar

猜你喜欢

转载自chaimzane.iteye.com/blog/1853905