HitTest BitmapData : Détection précise des collisions
Commentaires fermés sur HitTest BitmapData : Détection précise des collisions
Le cours AS3 de cette semaine vous propose d’améliorer la détection des collisions par défaut de Flash.
A savoir : le fameux HitTest !
2 Experts ActionScript proposent des classes de détections des collisions beaucoup plus précises et performantes.
La détection des collisions utilise des objets BitmapData.
Voici ce que vous allez apprendre dans ce Cours ActionScript :
- Une méthode simple de détection des collisions.
- Une méthode encore plus précise de détections des collisions.
- Les inconvénients et les avantages des 2 méthodes.
- Le chargement dynamiques de 2 images pour effectuer des tests de collisions.
Cette formation AS3 vous permettra d’utiliser une méthode de détection des collisions beaucoup plus précises et efficace dans vos jeux flash.
Détection des collisions
Version démonstration
Détection des collisions simple
Déplacez le robot pour tester la méthode de détection des collisions simple.
1 | http://e6msyji6epr.exactdn.com/wp-content/uploads/2012/04/collisionsSimple.swf |
[codesyntax lang= »actionscript3″ title= »HitTestSimple www.mikechambers.com » bookmarkname= »HitTestSimple www.mikechambers.com »]
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 | /** * 1ère méthode pour tester une collision. * http://www.mikechambers.com/blog/2009/06/24/using-bitmapdata-hittest-for-collision-detection/ * */ private function HitTestSimple() : void { var androidRect:Rectangle = oLoaderAndroid.getBounds(this); var androidOffset:Matrix = oLoaderAndroid.transform.matrix; androidOffset.tx = oLoaderAndroid.x - androidRect.x; androidOffset.ty = oLoaderAndroid.y - androidRect.y; var oLoaderAndroidBmpData:BitmapData = new BitmapData(androidRect.width, androidRect.height, true, 0); oLoaderAndroidBmpData.draw(oLoaderAndroid, androidOffset); var robotRect:Rectangle = oLoaderRobot.getBounds(this); var oLoaderRobotBmpData:BitmapData = new BitmapData(robotRect.width, robotRect.height, true, 0); var robotOffset:Matrix = oLoaderRobot.transform.matrix; robotOffset.tx = oLoaderRobot.x - robotRect.x; robotOffset.ty = oLoaderRobot.y - robotRect.y; oLoaderRobotBmpData.draw(oLoaderRobot, robotOffset); var rLoc:Point = new Point(robotRect.x, robotRect.y); var bLoc:Point = new Point(androidRect.x, androidRect.y); // il y a collision entre les 2 Display Object if (oLoaderRobotBmpData.hitTest(rLoc, 255, oLoaderAndroidBmpData, bLoc, 255)) oLoaderAndroid.filters = [new GlowFilter()]; else oLoaderAndroid.filters = []; // libère les ressources mémoires oLoaderAndroidBmpData.dispose(); oLoaderRobotBmpData.dispose(); } |
[/codesyntax]
Détection des collisions précise
Déplacez le robot pour tester la méthode de détection des collisions beaucoup plus précise.
1 | http://e6msyji6epr.exactdn.com/wp-content/uploads/2012/04/collisionsBest.swf |
[codesyntax lang= »actionscript3″ title= »Collision www.tink.ws » bookmarkname= »Collision www.tink.ws »]
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 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | package com.utils { import flash.display.BlendMode; import flash.geom.ColorTransform; import flash.geom.Matrix; import flash.geom.Point; import flash.display.BitmapData; import flash.geom.Rectangle; import flash.display.DisplayObject; /** * @author * @url : http://www.tink.ws/blog/as-30-hittest/ * * */ public class Collision { 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 either of the items don't have a reference to stage, then they are not in a display list // or if a simple hitTestObject is false, they cannot be intersecting. if( !target1.root || !target2.root || !target1.hitTestObject( target2 ) ) return new Rectangle(); // Get the bounds of each DisplayObject. var bounds1:Rectangle = target1.getBounds( target1.root ); var bounds2:Rectangle = target2.getBounds( target2.root ); // Determine test area boundaries. 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 a simple hitTestObject is false, they cannot be intersecting. if( !target1.hitTestObject( target2 ) ) return new Rectangle(); var hitRectangle:Rectangle = intersectionRectangle( target1, target2 ); // If their boundaries are no interesecting, they cannot be intersecting. 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 ); // Draw the first target. bitmapData.draw( target1, Collision.getDrawMatrix( target1, hitRectangle, accurracy ), new ColorTransform( 1, 1, 1, 1, 255, -255, -255, 255 ) ); // Overlay the second target. bitmapData.draw( target2, Collision.getDrawMatrix( target2, hitRectangle, accurracy ), new ColorTransform( 1, 1, 1, 1, 255, 255, 255, 255 ), BlendMode.DIFFERENCE ); // Find the intersection. var intersection:Rectangle = bitmapData.getColorBoundsRect( 0xFFFFFFFF,0xFF00FFFF ); bitmapData.dispose(); // Alter width and positions to compensate for accurracy 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; } } } |
[/codesyntax]
Télécharger le code source complet
Télécharger “Détection des collisions” ex-detection-collisions.zip – Téléchargé 671 fois – 136,90 KoConsultez la méthode de détection des collisions simple sur le site de Mike Chambers.
Consultez la méthode de détection des collisions plus précise sur le site Tink.
Et vous, utilisez-vous d’autres techniques pour détecter les collisions ?
Il existe d’autres techniques pour détecter les collisions. Notamment avec des tests sur la position, hauteur, largeur de 2 movieclip.
C’est la solution souvent utilisé dans les jeux flash avec un moteur de tile.
Partagez vos techniques dans les commentaires ci-dessous !