/** * CollisionDetectionクラス * 複雑な形状の衝突判定 * * @author scratchbrain * @version 1.0.0 * @update 2008/07/08 * @web site http://www.scratchbrain.net/ * @blog http://www.scratchbrain.net/blog/ver2/ * * Licensed under the MIT License * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package net.scratchbrain.geom{ import flash.display.BitmapData; import flash.display.BlendMode; import flash.display.DisplayObject; import flash.display.DisplayObjectContainer; import flash.geom.Matrix; import flash.geom.ColorTransform; import flash.geom.Rectangle; public class CollisionDetection{ public static function checkForCollision(p_obj1:DisplayObject,p_obj2:DisplayObject):Rectangle { // それぞれの境界ボックス取得 var bounds1:Object = p_obj1.getBounds(p_obj1.root); var bounds2:Object = p_obj2.getBounds(p_obj2.root); // 重なっている部分がまったくない場合は処理中断 if (((bounds1.right < bounds2.left) || (bounds2.right < bounds1.left)) || ((bounds1.bottom < bounds2.top) || (bounds2.bottom < bounds1.top)) ) { return null; } // 交差する領域の境界ボックスを算出 var bounds:Object = {}; bounds.left = Math.max(bounds1.left,bounds2.left); bounds.right= Math.min(bounds1.right,bounds2.right); bounds.top = Math.max(bounds1.top,bounds2.top); bounds.bottom = Math.min(bounds1.bottom,bounds2.bottom); // 交差する領域の境界ボックスの幅と高さを算出 var w:Number = bounds.right-bounds.left; var h:Number = bounds.bottom-bounds.top; // どちらか1ピクセル未満の場合、『ArgumentError: Error #2015: BitmapData が無効です。』が出る if(w < 1 || h < 1) { // trace(w,h); return null; } // 交差する領域の境界ボックスと同じサイズのBitmapDataを生成 var bitmapData:BitmapData = new BitmapData(w,h,false); // オブジェクト1を描画 var matrix:Matrix = p_obj1.transform.concatenatedMatrix; matrix.tx -= bounds.left;// x方向平行移動 matrix.ty -= bounds.top; // y方向平行移動 bitmapData.draw(p_obj1,matrix,new ColorTransform(1,1,1,1,255,-255,-255,255)); // オブジェクト2を重ね塗り matrix = p_obj2.transform.concatenatedMatrix; matrix.tx -= bounds.left;// x方向平行移動 matrix.ty -= bounds.top; // y方向平行移動 bitmapData.draw(p_obj2,matrix,new ColorTransform(1,1,1,1,255,255,255,255),BlendMode.DIFFERENCE); // 完全に重なる部分(0xFF00FFFF)の領域を取得 var intersection:Rectangle = bitmapData.getColorBoundsRect(0xFFFFFFFF,0xFF00FFFF); //『ArgumentError: Error #2015: BitmapData が無効です。』予防 /*try{ bitmapData.dispose(); }catch(e:Error){}*/ // 完全に重なる部分がない場合 if (intersection.width == 0) { return null; } // 位置調整 intersection.x += bounds.left; intersection.y += bounds.top; return intersection; } } }