一直知道在flash.geos包里面有一个Rectangle对象却很少用过。无意中试用了一下发现可用的地方还很广。所以一冲动把现在的项目中的很多地方都改成了Rectangle判断了。
应用一:屏幕滚屏
滚屏是游戏中最常做的一项工作,一般的思路是map.x++ map.y++,然后随时判断map是否走到了头。
下面的代码中我用了一张4000*4000的图片来说明两种方式:
一般的做法如下:判断每一步是否超过边界如果超过边界则等于边界。
var map:Loader=new Loader(); //地图容器
var speed:int=7; //移动速度
map.load (new URLRequest("2.jpg"));
map.contentLoaderInfo.addEventListener (Event.COMPLETE,oncomplete);
addChild (map);
function oncomplete (evt:Event)
{
stage.addEventListener (KeyboardEvent.KEY_DOWN,onkeydown);
}
function onkeydown2(evt:KeyboardEvent)
{
switch (evt.keyCode)
{
case Keyboard.LEFT :
if (map.x+7<0) map.x+=7;
else map.x=0;
break;
case Keyboard.RIGHT :
if (map.x-7>stage.stageWidth-map.width) map.x-=7;
else map.x=stage.stageWidth-map.width
break;
case Keyboard.UP :
if (map.y+7<0) map.y+=7;
else map.y=0;
break;
case Keyboard.DOWN :
if (map.y-7>stage.stageHeight-map.height) map.y-=7;
else map.y=stage.stageHeight-map.height
break;
}
}
使用Rectangle的方法,见如下代码
var map:Loader=new Loader(); //地图容器
var rec:Rectangle; //当前显示区域的范围
var maxRec:Rectangle; //地图的矩形范围
var speed:int=7;
map.load (new URLRequest("2.jpg"));
map.contentLoaderInfo.addEventListener (Event.COMPLETE,oncomplete);
addChild (map);
function oncomplete (evt:Event)
{
maxRec=map.getBounds(map);//以自己的坐标系返回矩形
rec=new Rectangle(0,0,800,600);//显示的范围
map.scrollRect=rec;//确定地图的可显示范围
stage.addEventListener (KeyboardEvent.KEY_DOWN,onkeydown);
}
function onkeydown (evt:KeyboardEvent)
{
rec=map.scrollRect;
switch (evt.keyCode)
{
case Keyboard.LEFT :
rec.x-=7;
break;
case Keyboard.RIGHT :
rec.x+=7;
break;
case Keyboard.UP :
rec.y-=7;
break;
case Keyboard.DOWN :
rec.y+=7;
break;
}
if(rec.x<0) rec.x=0;
else if(rec.x>maxRec.width-rec.width) rec.x=maxRec.width-rec.width;
if(rec.y<0) rec.y=0;
else if(rec.y>maxRec.height-rec.height) rec.y=maxRec.height-rec.height;
//if(maxRec.containsRect(rec)) 如果你无需十分精确可以关闭以上4行,把这一句打开
map.scrollRect=rec;
}
两种方式的比较:效率上相差不大,不过使用Rectangel的好处是利用显示对象的scrollRect属性可以把区域之外的内容不显示出来。
注意事项:scrollRect的增量方向正好与物体的相反,可以想象为一个是移动物体,一个是移动屏幕。
应用二:找出屏幕外围的显示对象。
基本思路:将Rectangle对象的坐标系设置为屏幕坐标系,利用DisplayObject.getBounds(stage)返回其他物体在屏幕坐标系中的位置,然后利用Rectangle对象的相交测试方法检测(有点类似于碰撞检测)
以下是一个例子
var rec:Rectangle = new Rectangle(0, 0, ShareData.SCENEWIDTH, ShareData.SCENEHEIGHT);
for (var i = 0; i < gameContainer.numChildren; i++)
{
var build = gameContainer.getChildAt(i);
if(build.getBounds(stage).intersects(rec))
{
build.visible = true;
ShareData.visualList[build.name]=build;
}
else
{
build.visible = false;
if(ShareData.visualList[build]!=null)
delete ShareData.visualList[build];
}
}
应用三:对两个并不存在的对象进行碰撞检测
有的时候你想进行碰撞的两个物体并不存在,那么我们就无法通过正常的hitTest手段检测两个物体是否发生了碰撞。这个时候通过Rectangle对象无疑是最方便的。
下面举出两个例子来说明一下这种应用:
首先说明上图的假设并不多见,但我只是想通过这个不怎么恰当的例子说明Rectangle的一种应用。
上图如果我们只想知道“葡萄MM“是否走到了矩形A的区域,而不管其他的。这个时候我们的Rectangle又一次发挥了作用。
因为这个建筑和mm的位置都是针对与地图坐标系的,所以我们可以针对于建筑左顶点的偏移量来确定矩形A的坐标和宽度高度
同样我们可以通过葡萄mm的左顶点和矩形B相对于这一点的偏移量来矩形B的坐标和大小。
假设建筑的左顶点坐标为:2000,1200, 矩形相对于左顶点的偏移量为50,50,大小为80,30
那么我们可以很快得到矩形A初始值:recA=new (2000+50,1200+30,80,30)
同理我们可以得到矩形B的区域了,有了这两个矩形那么我们只要调用一下任意一个矩形的相交判断方法就行了recA.intersects(recB)
总结:虽然并没有测试这样所带来的效率,但是会有很多地方可以为我们的判断带来很大的方便