wkt
July 17th, 2009, 08:52 AM
Hi there
http://www.kirupa.com/forum/showpost.php?p=1922772&postcount=4 (http://www.kirupa.com/forum/showpost.php?p=1922772&postcount=4)
This is for BitmapData hittesting 2 objects. The restriction is that it does not work when the registration point is not at the top left corner of the object. So I made some changes, hoping to make it work like this.
MovieClip.prototype.pixelHitTest = function(mc:MovieClip, threshold:Number):Boolean {
threshold = threshold ? treshold : 1;
var xOffset:Number = this.getBounds(this).x;
var yOffset:Number = this.getBounds(this).y;
var xOffsetMC:Number = this.getBounds(mc).x;
var yOffsetMC:Number = this.getBounds(mc).y;
var thisBitmap:BitmapData = new BitmapData(this.width, this.height, true, 0);
thisBitmap.draw(this, new Matrix(1, 0, 0, 1, - xOffset, -yOffset));
var mcBitmap:BitmapData = new BitmapData(mc.width, mc.height, true, 0);
mcBitmap.draw(mc, new Matrix(1, 0, 0, 1, - xOffsetMC, -yOffsetMC));
if (thisBitmap.hitTest(new Point(this.x+xOffset, this.y+yOffset), threshold, mcBitmap, new Point(mc.x+xOffsetMC, mc.y+yOffsetMC), threshold)) {
return true;
}
return false;
}
I just modified the original according to the instructions on another website. However, it doesn't quite work. Where's the problem?
Thanks in advance.
TOdorus
July 17th, 2009, 09:44 AM
A bit offtopic:
This seems like an unneeded extra step. If you're going to use bitmapdata's use bitmapdata's and not movieClips. Now you've got a draw() call each hittest. That is a VERY expensive hittest.
Ontopic:
You might want to display the bitmapdatas in a bitmap to check what is happening. A bitmap cannot have negative pixels (pixels with x < 0 or y < 0), so anything drawn left or above of the reference point is cropped from the result. That's why I find it weird that your code has a matrix with -offset. That would mean the graphic would be pushed into the negatives instead of towards the positives. I don't know of a way to check how much of the contents of your movieClip are left and up of the reference point, but you should add these offsets to your matrix rather then subtract them. The point the bitmapdatas need to be at in the hittest then should be the same as the position of the original movieClip minus the offsets.
Oh and to make sure you don't do something wrong in the matrix, I can advise to create a new matrix and use it's methods. That way you know you're not putting some numbers in the wrong cell. At the moment it looks ok, but you never know when you start rotating and stuff.
var transMatrix:Matrix = new Matrix()
transMatrix.translate(xOffset, yOffset)
wkt
July 18th, 2009, 04:08 AM
Hm... how should a BitmapData hitTest function be written so that a test can be carried out between 2 moviclips which registration points are not at the top left corner, at pixel level?
Any examples that I can take a look at?
TOdorus
July 18th, 2009, 08:15 AM
http://labs.boulevart.be/index.php/2007/06/08/skinner-collision-detection-in-as3/
EDIT this is the site I was looking for:
http://www.gskinner.com/blog/archives/2005/08/flash_8_shape_b.html
wkt
July 18th, 2009, 10:27 AM
What about in AS2.0?
TOdorus
July 18th, 2009, 11:01 AM
Have you looked at the collision detection function? I haven't used AS2 for a while, but I don't think there's much AS3 in there. AS3 makes it execute faster ofcourse but as far as I can tell it can be ported to AS2 as is. Maybe try and see what compiler errors come up, should be easy enough.
/**
* GTween by Grant Skinner. Aug 1, 2005
* Visit www.gskinner.com/blog (http://www.gskinner.com/blog) for documentation, updates and more free code.
*
*
* Copyright (c) 2005 Grant Skinner
*
* 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.
**/
import flash.display.BitmapData;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Rectangle;
class com.gskinner.sprites.CollisionDetection {
static public function checkForCollision(p_clip1:MovieClip,p_clip2:MovieC lip,p_alphaTolerance:Number):Rectangle {
// set up default params:
if (p_alphaTolerance == undefined) { p_alphaTolerance = 255; }
// get bounds:
var bounds1:Object = p_clip1.getBounds(_root);
var bounds2:Object = p_clip2.getBounds(_root);
// rule out anything that we know can't collide:
if (((bounds1.xMax < bounds2.xMin) || (bounds2.xMax < bounds1.xMin)) || ((bounds1.yMax < bounds2.yMin) || (bounds2.yMax < bounds1.yMin)) ) {
return null;
}
// determine test area boundaries:
var bounds:Object = {};
bounds.xMin = Math.max(bounds1.xMin,bounds2.xMin);
bounds.xMax = Math.min(bounds1.xMax,bounds2.xMax);
bounds.yMin = Math.max(bounds1.yMin,bounds2.yMin);
bounds.yMax = Math.min(bounds1.yMax,bounds2.yMax);
// set up the image to use:
var img:BitmapData = new BitmapData(bounds.xMax-bounds.xMin,bounds.yMax-bounds.yMin,false);
// draw in the first image:
var mat:Matrix = p_clip1.transform.concatenatedMatrix;
mat.tx -= bounds.xMin;
mat.ty -= bounds.yMin;
img.draw(p_clip1,mat, new ColorTransform(1,1,1,1,255,-255,-255,p_alphaTolerance));
// overlay the second image:
mat = p_clip2.transform.concatenatedMatrix;
mat.tx -= bounds.xMin;
mat.ty -= bounds.yMin;
img.draw(p_clip2,mat, new ColorTransform(1,1,1,1,255,255,255,p_alphaToleranc e),"difference");
// find the intersection:
var intersection:Rectangle = img.getColorBoundsRect(0xFFFFFFFF,0xFF00FFFF);
// if there is no intersection, return null:
if (intersection.width == 0) { return null; }
// adjust the intersection to account for the bounds:
intersection.x += bounds.xMin;
intersection.y += bounds.yMin;
return intersection;
}
}
Powered by vBulletin® Version 4.1.10 Copyright © 2012 vBulletin Solutions, Inc. All rights reserved.