Be a Supporter!

Mindblowing Flash HitTest problem

  • 362 Views
  • 4 Replies
New Topic Respond to this Topic
Rapelsin
Rapelsin
  • Member since: May. 31, 2010
  • Offline.
Forum Stats
Member
Level 04
Blank Slate
Mindblowing Flash HitTest problem 2010-06-06 11:38:56 Reply

This little problem blows, at least my mind. First of all here's my code.

import com.asgamer.helicopter.PixelPerfectCollisionDetection
import com.asgamer.helicopter.Helicopter
import flash.events.Event;

var heli:Helicopter = new Helicopter(stage);
			addChild(heli);

addEventListener(Event.ENTER_FRAME, frame)
			
		function frame (e:Event) {
	
	vCam.y = heli.y
	
	if ( PixelPerfectCollisionDetection.isColliding( heli, walls, this, true, 1))
	 {
		debug_txt.text = "Hit!"
	}
	else
	{debug_txt.text = "Not Hit!" }
}

And here's my prototype http://megaswf.com/view/1c312c72844d78df e72f6e61e757ed0e.html

The problem is that technically it should display "Hit!" whenever it touches any of the grey space, for some reason it won't work for the bigger block of grey in the bottom.

I'm using this PixelPerfect Detection.

package com.asgamer.helicopter
{
	import flash.display.BitmapData;
	import flash.display.BitmapDataChannel;
	import flash.display.BlendMode;
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	public class PixelPerfectCollisionDetection
	{
		/** Get the collision rectangle between two display objects. **/
		public static function getCollisionRect(target1:DisplayObject, target2:DisplayObject, commonParent:DisplayObjectContainer, pixelPrecise:Boolean = false, tolerance:Number = 0):Rectangle
		{
			// get bounding boxes in common parent's coordinate space
			var rect1:Rectangle = target1.getBounds(commonParent);
			var rect2:Rectangle = target2.getBounds(commonParent);
			// find the intersection of the two bounding boxes
			var intersectionRect:Rectangle = rect1.intersection(rect2);
			if (intersectionRect.size.length> 0)
			{
				if (pixelPrecise)
				{
					// size of rect needs to integer size for bitmap data
					intersectionRect.width = Math.ceil(intersectionRect.width);
					intersectionRect.height = Math.ceil(intersectionRect.height);
					// get the alpha maps for the display objects
					var alpha1:BitmapData = getAlphaMap(target1, intersectionRect, BitmapDataChannel.RED, commonParent);
					var alpha2:BitmapData = getAlphaMap(target2, intersectionRect, BitmapDataChannel.GREEN, commonParent);
					// combine the alpha maps
					alpha1.draw(alpha2, null, null, BlendMode.LIGHTEN);
					// calculate the search color
					var searchColor:uint;
					if (tolerance <= 0)
					{
						searchColor = 0x010100;
					}
					else
					{
						if (tolerance> 1) tolerance = 1;
						var byte:int = Math.round(tolerance * 255);
						searchColor = (byte <<16) | (byte <<8) | 0;
					}
					// find color
					var collisionRect:Rectangle = alpha1.getColorBoundsRect(searchColor, searchColor);
					collisionRect.x += intersectionRect.x;
					collisionRect.y += intersectionRect.y;
					return collisionRect;
				}
				else
				{
					return intersectionRect;
				}
			}
			else
			{
				// no intersection
				return null;
			}
		}
		/** Gets the alpha map of the display object and places it in the specified channel. **/
		private static function getAlphaMap(target:DisplayObject, rect:Rectangle, channel:uint, commonParent:DisplayObjectContainer):BitmapData
		{
			// calculate the transform for the display object relative to the common parent
			var parentXformInvert:Matrix = commonParent.transform.concatenatedMatrix.clone();
			parentXformInvert.invert();
			var targetXform:Matrix = target.transform.concatenatedMatrix.clone();
			targetXform.concat(parentXformInvert);
			// translate the target into the rect's space
			targetXform.translate(-rect.x, -rect.y);
			// draw the target and extract its alpha channel into a color channel
			var bitmapData:BitmapData = new BitmapData(rect.width, rect.height, true, 0);
			bitmapData.draw(target, targetXform);
			var alphaChannel:BitmapData = new BitmapData(rect.width, rect.height, false, 0);
			alphaChannel.copyChannel(bitmapData, bitmapData.rect, new Point(0, 0), BitmapDataChannel.ALPHA, channel);
			return alphaChannel;
		}
		/** Get the center of the collision's bounding box. **/
		public static function getCollisionPoint(target1:DisplayObject, target2:DisplayObject, commonParent:DisplayObjectContainer, pixelPrecise:Boolean = false, tolerance:Number = 0):Point
		{
			var collisionRect:Rectangle = getCollisionRect(target1, target2, commonParent, pixelPrecise, tolerance);
			if (collisionRect != null && collisionRect.size.length> 0)
			{
				var x:Number = (collisionRect.left + collisionRect.right) / 2;
				var y:Number = (collisionRect.top + collisionRect.bottom) / 2;
				return new Point(x, y);
			}
			return null;
		}
		/** Are the two display objects colliding (overlapping)? **/
		public static function isColliding(target1:DisplayObject, target2:DisplayObject, commonParent:DisplayObjectContainer, pixelPrecise:Boolean = false, tolerance:Number = 0):Boolean
		{
			var collisionRect:Rectangle = getCollisionRect(target1, target2, commonParent, pixelPrecise, tolerance);
			if (collisionRect != null && collisionRect.size.length> 0) return true;
			else return false;
		}
	}
}

Any help will be very much appreciated, thanks!


Rape l Sin or I R Apelsin, which ever suits me best...

Now I'll Trololo your face with an Apelsin!

GustTheASGuy
GustTheASGuy
  • Member since: Nov. 2, 2005
  • Offline.
Forum Stats
Member
Level 08
Blank Slate
Response to Mindblowing Flash HitTest problem 2010-06-06 13:50:33 Reply

It looks like it only works in a rectangular area. You must be drawing a fixed part of the world to the bitmapdata you use for collision.


BBS Signature
Rapelsin
Rapelsin
  • Member since: May. 31, 2010
  • Offline.
Forum Stats
Member
Level 04
Blank Slate
Response to Mindblowing Flash HitTest problem 2010-06-06 14:06:18 Reply

At 6/6/10 01:50 PM, GustTheASGuy wrote: It looks like it only works in a rectangular area. You must be drawing a fixed part of the world to the bitmapdata you use for collision.

You got any idea how to fix that, I'm not that big on AS :)


Rape l Sin or I R Apelsin, which ever suits me best...

Now I'll Trololo your face with an Apelsin!

Xyresic
Xyresic
  • Member since: Dec. 15, 2006
  • Offline.
Forum Stats
Member
Level 19
Musician
Response to Mindblowing Flash HitTest problem 2010-06-06 22:28:00 Reply

At 6/6/10 02:06 PM, Rapelsin wrote: You got any idea how to fix that, I'm not that big on AS :)

this post is completely unrelated, but i had to lol when you said that. yoiu've got code there that i can't even start to decipher, don't be so modest :P


bork bork bork

Rapelsin
Rapelsin
  • Member since: May. 31, 2010
  • Offline.
Forum Stats
Member
Level 04
Blank Slate
Response to Mindblowing Flash HitTest problem 2010-06-07 06:59:08 Reply

At 6/6/10 10:28 PM, crapatflash wrote:
At 6/6/10 02:06 PM, Rapelsin wrote: You got any idea how to fix that, I'm not that big on AS :)
this post is completely unrelated, but i had to lol when you said that. yoiu've got code there that i can't even start to decipher, don't be so modest :P

Thing is I'm using another person's code, I think it was Grant Skinner's PixelPerfectCollisionDetection ported to AS3. The first code is me though :)


Rape l Sin or I R Apelsin, which ever suits me best...

Now I'll Trololo your face with an Apelsin!