08

直线移动检测可否抵达的例子

类别: Flash\Ria鼠标炸弹 @ 2010.06.08 08:11 已阅1,862次
标签: , , ,

最近的项目由于团队中初级ASer比较多,本来是做自动寻路的,硬是被砍到直线碰撞,可惜悲剧的是,直线碰撞都跟我说有问题。

昨天一个哥们一直是让角色没走一步与像素点碰撞判断是否可走。我再多废话一遍:这样既有误差,效率也不高。

今天放此例,表明直线碰撞的推荐做法是,先画一条直线与通断模型进行碰撞测试,证实可抵达之后再直接让角色移过去(速度控制之后再做,与此例无关)。

实例效果:
黑色区域表示不可抵达,红色小方块表示需要移动的物体。

Document Class :

?View Code ACTIONSCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package  
{
	import flash.display.SimpleButton;
	import com.gskinner.motion.GTween;
	import com.gskinner.motion.easing.Sine;
 
	import org.mousebomb.display.RealHitTest;
 
	import flash.display.Sprite;
	import flash.events.MouseEvent;
 
	/**
	 * @author Mousebomb (mousebomb@gmail.com)
	 * @date 2010-6-8
	 */
	public class HitTestMain extends Sprite 
	{
		public var pz : Sprite ;
		public var line : Sprite = new Sprite();
		public var box : Sprite;
		public var showBtn : SimpleButton;
		private var boxTween : GTween;
 
		private var curX : int = 300;
		private var curY : int = 200;
 
		public function HitTestMain()
		{
			addChild(line);
			boxTween = new GTween(box,.3,null,{ease:Sine.easeOut});
			curX=box.x;
			curY=box.y;
			line.graphics.lineStyle(3, 0xff0000);
			line.graphics.moveTo(curX, curY);
			stage.addEventListener(MouseEvent.CLICK, onClick);
			showBtn.addEventListener(MouseEvent.CLICK, onShowClick);
		}
 
		private function onShowClick(event : MouseEvent) : void
		{
			if(pz.parent)
			{
				removeChild(pz);
				removeChild(line);
			}else{
				addChildAt(pz,0);
				addChildAt(line,1);
			}
		}
 
		private function onClick(event : MouseEvent) : void
		{
			line.graphics.lineTo(event.stageX, event.stageY);
			if(RealHitTest.hitTestObj(line, pz))
			{
				line.graphics.clear();
				line.graphics.lineStyle(3, 0xff0000);
				line.graphics.moveTo(curX, curY);
			}
			else
			{
				curX = event.stageX;
				curY = event.stageY;
				boxTween.setValues({x:curX,y:curY});
			}
		}
	}
}

RealHitTest:

?View Code ACTIONSCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package org.mousebomb.display 
{
	import flash.display.BlendMode;
	import flash.display.DisplayObjectContainer;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Rectangle;
 
	/**
	 * Flash自带的HitTestObject有问题,这个类是真正的HitTest
	 * @author Mousebomb (mousebomb@gmail.com)
	 * @date 2010-3-14
	 */
	public class RealHitTest 
	{
		private static var bmp : Bitmap = new Bitmap();
 
		/**
		 * 此方法的思路由ryan-liu提出
		 * @return 是否重叠
		 * @param src 要比较的对象
		 * @param target 与之比较的对象
		 * src和target的容器必须是同意对象,或者原点坐标对齐
		 */
		public static function hitTestObj(src : DisplayObject,target : DisplayObject) : Boolean
		{
			//获取要比较的对象的区域以偏移位图
			var srcBound : Rectangle = src.getBounds(src.parent);
			var bmd : BitmapData = new BitmapData(srcBound.width, srcBound.height, false, 0);
			//bmp.bitmapData = bmd;
			var mtx1 : Matrix = new Matrix();
			var mtx2 : Matrix = new Matrix();
			mtx1.rotate(src.rotation * Math.PI / 180);
			mtx1.tx = src.x-srcBound.x;
			mtx1.ty = src.y-srcBound.y;
			mtx2.rotate(target.rotation * Math.PI / 180);
			mtx2.tx = target.x - srcBound.x;
			mtx2.ty = target.y - srcBound.y;
			bmd.fillRect(bmd.rect, 0);
			bmd.draw(src, mtx1, new ColorTransform(1, 1, 1, 1, -255, 255, 255, 255));
			bmd.draw(target, mtx2, new ColorTransform(1, 1, 1, 1, 255, -255, -255, 255), BlendMode.DIFFERENCE);
			var rect : Rectangle = bmd.getColorBoundsRect(0xffffff, 0xffffff);
			//碰撞检测结束
			//Rectangle四个属性为0则没搜索到
			return (rect.x != 0 || rect.y != 0 || rect.width != 0 || rect.height != 0);
		}
 
		public static function debug(s : DisplayObjectContainer):void
		{
			s.addChild(bmp);
			bmp.x = 500;
			bmp.y = 300;
		}
	}
}

源文件点此下载

本文对您有用吗? 何不留下评论继续交流, 或者在您的博客上引用本文继续探讨.
您可以订阅读者对本文的回应或者订阅本博客以在您的阅读器中自动获取更新.

本文居然还有同伙!有兴趣不?

才 2 条评论 - “直线移动检测可否抵达的例子”

  1. 直线移动检测可否抵达的例子 : : 9RIA.Com 天地会博客聚合 Unknow Unknow 说:

    [...] : GTween;   private var curX : int = [...] Copyright © 转载本文请保留链接:http://www.flashj.cn/wp/zhixian-pengzhuang-yidong.html [...]

  2. 小柯南 Windows XP Firefox 3.6.3 说:

    挺深奥的问题哦,UP

    [回复]

您再来一条评论吧?