A la hora de programar un juego las coliciones de Graficos son muy importantes, por eso he desarrollado esta clase que me permite agrupar objetos y clasificarlos
por grupos para detectar coliciones entre ellos.
Primero lo primero.. la clase que se encarga de detectar las colociones:
/** By ::[PHOXER]:: http://www.phoxer.com v 1.1; */ package phoxer.Games{ import flash.display.BitmapData; import flash.display.BlendMode; import flash.display.DisplayObject; import flash.display.Sprite; import flash.geom.ColorTransform; import flash.geom.Matrix; import flash.geom.Point; import flash.geom.Rectangle; public class HitTest { public static function complexHitTestObject( target1:DisplayObject, target2:DisplayObject, accurracy:Number = 1 ):Boolean { return complexIntersectionRectangle( target1, target2, accurracy ).width != 0; } public static function intersectionRectangle( target1:DisplayObject, target2:DisplayObject ):Rectangle { if (! target1.root||! target2.root||! target1.hitTestObject(target2)) { return new Rectangle(); } var bounds1:Rectangle=target1.getBounds(target1.root); var bounds2:Rectangle=target2.getBounds(target2.root); var intersection:Rectangle = new Rectangle(); intersection.x=Math.max(bounds1.x,bounds2.x); intersection.y=Math.max(bounds1.y,bounds2.y); intersection.width= Math.min( ( bounds1.x + bounds1.width ) - intersection.x, ( bounds2.x + bounds2.width ) - intersection.x ); intersection.height = Math.min( ( bounds1.y + bounds1.height ) - intersection.y, ( bounds2.y + bounds2.height ) - intersection.y ); return intersection; } public static function complexIntersectionRectangle( target1:DisplayObject, target2:DisplayObject, accurracy:Number = 1 ):Rectangle { if (accurracy<=0) { throw new Error("ArgumentError: Error #5001: Invalid value for accurracy",5001); } if (! target1.hitTestObject(target2)) { return new Rectangle(); } var hitRectangle:Rectangle=intersectionRectangle(target1,target2); if (hitRectangle.width*accurracy<1||hitRectangle.height*accurracy<1) { return new Rectangle(); } var bitmapData:BitmapData=new BitmapData(hitRectangle.width*accurracy,hitRectangle.height*accurracy,false,0x000000); bitmapData.draw( target1, HitTest.getDrawMatrix( target1, hitRectangle, accurracy ), new ColorTransform( 1, 1, 1, 1, 255, -255, -255, 255 ) ); bitmapData.draw( target2, HitTest.getDrawMatrix( target2, hitRectangle, accurracy ), new ColorTransform( 1, 1, 1, 1, 255, 255, 255, 255 ), BlendMode.DIFFERENCE ); var intersection:Rectangle=bitmapData.getColorBoundsRect(0xFFFFFFFF,0xFF00FFFF); bitmapData.dispose(); if (accurracy!=1) { intersection.x/=accurracy; intersection.y/=accurracy; intersection.width/=accurracy; intersection.height/=accurracy; } intersection.x+=hitRectangle.x; intersection.y+=hitRectangle.y; return intersection; } protected static function getDrawMatrix( target:DisplayObject, hitRectangle:Rectangle, accurracy:Number ):Matrix { var localToGlobal:Point; var matrix:Matrix; var rootConcatenatedMatrix:Matrix=target.root.transform.concatenatedMatrix; localToGlobal = target.localToGlobal( new Point( ) ); matrix=target.transform.concatenatedMatrix; matrix.tx=localToGlobal.x-hitRectangle.x; matrix.ty=localToGlobal.y-hitRectangle.y; matrix.a=matrix.a/rootConcatenatedMatrix.a; matrix.d=matrix.d/rootConcatenatedMatrix.d; if (accurracy!=1) { matrix.scale( accurracy, accurracy ); } return matrix; } } }
y aquí mi clase HitObjectsGroup:
/** By ::[PHOXER]:: http://www.phoxer.com v 2.7; */ package phoxer.Games{ import flash.display.DisplayObject; import flash.events.TimerEvent; import flash.utils.Timer; public class HitObjectsGroup{ private var objects:Array; private var htmr:Timer; public function HitObjectsGroup(tm:int=10){ objects=new Array(); htmr= new Timer(tm,0); } public function addObject(clp:DisplayObject,grp:String,bk:Function=null,hit:DisplayObject=null,rm:Boolean=true,nbk:Function=null,rpt:Boolean=true,ign:Array=null):void{ var obj:Object = new Object(); obj.clip=clp; obj.hit=(hit!=null)? hit:clp; obj.grp=grp; obj.hgrp=""; obj.ign=ign; obj.bk=bk; obj.nbk=nbk; obj.rm=rm; obj.rpt=rpt; obj.hrp=true; obj.nrp=true; objects.push(obj); } public function removeObject(obj:Object):void{ for (var i:int=0;i<objects.length;i++){ if(objects[i]===obj){ objects.splice(i,1); break; } } } public function removeObjectByClip(clip:DisplayObject):void{ for (var i:int=0;i<objects.length;i++){ if(objects[i].clip===clip){ objects.splice(i,1); break; } } } public function removeGroup(grp:String):void{ for (var i:int=0;i<objects.length;i++){ if(objects[i].grp===grp){ objects.splice(i,1); } } } public function removeAllObjects():void{ objects=new Array(); } public function startCheck():void{ htmr.addEventListener(TimerEvent.TIMER,checkHits,false,0,true); htmr.start(); } public function stopCheck():void{ htmr.stop(); htmr.removeEventListener(TimerEvent.TIMER,checkHits); } private function checkHits(e:TimerEvent):void{ if(objects.length>1){ for (var a:int=0;a<objects.length;a++){ var t1:Object=objects[a]; if(checkClip(t1.clip)){ for (var b:int=0;b<objects.length;b++){ var t2:Object=objects[b]; if(checkClip(t2.clip)){ if(t1.grp!=t2.grp){ if(t1.clip.hitTestObject(t2.clip)){ if(!ignoreGroup(t1.ign,t2.grp)){ if(HitTest.complexHitTestObject(t1.hit,t2.hit)){ if(t1.bk!=null && t1.hrp){ if(!t1.rpt){ t1.hrp=false; } t1.hgrp=t2.grp; t1.bk(t1); } if(t2.bk!=null && t2.hrp){ if(!t2.rpt){ t2.hrp=false; } t2.hgrp=t1.grp; t2.bk(t2); } if(t1.rm){ removeObject(t1); } if(t2.rm){ removeObject(t2); } t1.nrp=true; t2.nrp=true; break; }else{ onNoHit(t1); onNoHit(t2); } } }else{ onNoHit(t1); onNoHit(t2); } } } } } } } } private function onNoHit(obj:Object):void{ if(obj.nrp && obj.nbk!=null){ if(!obj.rpt){ obj.nrp=false; } obj.nbk(obj); } obj.hrp=true; } private function checkClip(clp:DisplayObject):Boolean{ if(clp!=null){ return clp.visible; } return false; } private function ignoreGroup(ign:Array,grp:String):Boolean{ if(ign!=null){ for(var i:int=0;i<ign.length;i++){ if(ign[i]==grp){ return true; break; } } } return false; } } }
Mi clase utiliza grupos de Objetos para guardar información y funciona con cualquier otra clase de coliciones externas, asi sea como la Utils de Adobe:
y es muy facil de implementar:
import phoxer.Games.HitObjectsGroup; var htsgrp:HitObjectsGroup = new HitObjectsGroup(100); htsgrp.addObject(ball,"balls",onHitObject); htsgrp.addObject(scuare,"scuares",onHitObject); function onHitObject(dt:Object):void{ //datos de las coliciones entre los objetos } htsgrp.startCheck();
Gracias a esta clase he desarrollado todos mis juegos facilitandome mucho la parte de las coliciones.
He desarrollado un juego parecido al Invaders con esta clase:
Aqui pueden ver mas juegos desarrollados por mi utilizando la clase de Colisiones:
www.BeatsGames.com -Mi pagina de juegos
BeatsGames -Mis Juegos en Facebook
