F9 for actions

Some possibly useful and definitely unuseful ActionScript 3.0 code.

Oct 17

Exploration of Radial Collision

I was fortunate enough to meet Terry Paton at this year’s MAX conference. If you don’t know, he’s a Flash game developer that produces some great work and contributes a lot of knowledge to the online web of Flash resources - definitely a recommended follow.

Anyway, he made a blog post showing simple distance-based radial collision technique that he uses often in his games. The technique wasn’t new to me, but something about his post lit a fire in me to explore the idea to an extent that I’ve never put down in code before.

While playing around with the concept, I thought to myself that knowing when something hits something else is great, but often for games you want to know where something hit the other thing and usually you want one or the other or both of those objects to react upon that collision, much like things react to collisions in the physical world. It’s also useful knowing if something collides with a certain coordinate, such as the current position of the mouse.

So I took Terry’s code and expanded upon it with the idea that instead of getting back a true or false on whether objects are colliding, instead if there is a collision, you get back a data object with some really useful information about that collision. Here is the Collider Class:

package  {
	import flash.display.Sprite;
	import flash.display.DisplayObject;
	
	public class Collider {
		
		public static var lastCollision:Object;
		private static var pointsprite:Sprite;

		public function Collider() {
			// constructor code
		}
		
		public static function checkPointCollision( px:Number, py:Number, o1:DisplayObject, customRadius:Number = 0 ):Object {
			
			if( !pointsprite ) {
				pointsprite = new Sprite();
				pointsprite.graphics.beginFill( 0, 0 );
				pointsprite.graphics.drawCircle( 0, 0, 1 );
				pointsprite.graphics.endFill();
			}
			
			pointsprite.x = px;
			pointsprite.y = py;
			return Collider.checkCollision( pointsprite, o1, customRadius );
		}


		public static function checkCollision( o1:DisplayObject, o2:DisplayObject, customRadius1:Number = 0, customRadius2:Number = 0 ):Object {
			
			var dx:Number = o1.x - o2.x;
			var dy:Number = o1.y - o2.y;
			
			var csquared:Number = dx*dx+dy*dy;
			var dist:Number = Math.abs(Math.sqrt(csquared));
		
			var r1:Number;
			var r2:Number;
			
			if( customRadius1 != 0 ) {
				r1 = customRadius1;
			} else {
				r1 = (o1.width*.5);
			}
			
			if( customRadius2 != 0 ) {
				r2 = customRadius2;
			} else {
				r2 = (o2.width*.5);
			}
			
			var tr:Number = r1+r2;
			
			if (dist = 360 ) {
				realDegrees -= 360;
			}
			while ( realDegrees < 0 ) {
				realDegrees += 360;
			}
			return realDegrees;
		}
	}
}

And here it is in action, followed by the timeline code for the swf

import flash.display.Sprite;
import flash.display.DisplayObject;

var bumpers:Vector.<Bumper> = new Vector.<Bumper>();
var collision:Object = {};
init();

function init():void {
	
	for( var i:int = 0; i < 40; i++ ) {
		var b:Bumper = new Bumper();
		
		//b.x = Math.random()*stage.stageWidth;
		//b.y = Math.random()*stage.stageHeight;
		b.x = 90*Math.cos(i) + stage.stageWidth*.5;
		b.y = 90*Math.sin(i) + stage.stageHeight*.5;
		
		bumpers.push(b);
		addChild(b);
	}
	
	this.addEventListener( Event.ENTER_FRAME, onFrame );
}

function onFrame( e:Event ):void {
	
	for( var i:int = 0; i < bumpers.length; i++ ) {
		
		collision = Collider.checkCollision( player, bumpers[i] );
		if( collision ) {
			
			arrow.rotation = collision.angle;
			arrow.x = collision.x;
			arrow.y = collision.y;
			
			player.xvel =  8*Math.cos( collision.radians );
			player.yvel =  8*Math.sin( collision.radians );
			
			bumpers[i].xvel +=  Math.cos( collision.oppositeRadians );
			bumpers[i].yvel +=  Math.sin( collision.oppositeRadians );
			
		}
		
		collision = Collider.checkPointCollision( mouseX, mouseY, player );
		if( collision ) {
			player.xvel = 5*Math.cos( collision.oppositeRadians );
			player.yvel = 5*Math.sin( collision.oppositeRadians );
		}
	}
}

It’s not perfect, but for getting you up and running with collisions it does a pretty decent job. Enjoy

DOWNLOAD THE SOURCE


  1. f9foractions posted this