master 0a37c8e7a3c6 cached
48 files
375.1 KB
107.7k tokens
1 requests
Download .txt
Showing preview only (394K chars total). Download the full file or copy to clipboard to get everything.
Repository: photonstorm/Flixel-Power-Tools
Branch: master
Commit: 0a37c8e7a3c6
Files: 48
Total size: 375.1 KB

Directory structure:
gitextract_y9trc_t2/

├── .gitignore
├── CHANGELOG.md
├── LICENSE.md
├── README.md
├── lib/
│   ├── flixel-v2.55.swc
│   ├── neoart-flectrum-v1.0.swc
│   └── neoart-flod-v2.0.swc
└── src/
    └── org/
        └── flixel/
            └── plugin/
                └── photonstorm/
                    ├── API/
                    │   └── FlxKongregate.as
                    ├── BaseTypes/
                    │   ├── Bullet.as
                    │   └── MouseSpring.as
                    ├── FX/
                    │   ├── BaseFX.as
                    │   ├── BlurFX.as
                    │   ├── CenterSlideFX.as
                    │   ├── FloodFillFX.as
                    │   ├── GlitchFX.as
                    │   ├── PlasmaFX.as
                    │   ├── RainbowLineFX.as
                    │   ├── RevealFX.as
                    │   ├── SineWaveFX.as
                    │   ├── StarfieldFX.as
                    │   └── WowCopperFX.as
                    ├── FlxBar.as
                    ├── FlxBitmapFont.as
                    ├── FlxButtonPlus.as
                    ├── FlxCollision.as
                    ├── FlxColor.as
                    ├── FlxControl.as
                    ├── FlxControlHandler.as
                    ├── FlxCoreUtils.as
                    ├── FlxDelay.as
                    ├── FlxDisplay.as
                    ├── FlxExplode.as
                    ├── FlxExtendedSprite.as
                    ├── FlxFlectrum.as
                    ├── FlxFlod.as
                    ├── FlxGradient.as
                    ├── FlxGridOverlay.as
                    ├── FlxLinkedGroup.as
                    ├── FlxMath.as
                    ├── FlxMouseControl.as
                    ├── FlxPowerTools.as
                    ├── FlxScreenGrab.as
                    ├── FlxScrollZone.as
                    ├── FlxScrollingText.as
                    ├── FlxSpecialFX.as
                    ├── FlxVelocity.as
                    ├── FlxWeapon.as
                    └── PNGEncoder.as

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================

### ACTIONSCRIPT ###

# Build and Release Folders
bin/
bin-debug/
bin-release/

# Project property files
.actionScriptProperties
.flexProperties
.settings/
.project


### OS SPECIAL FILES ###

# Windows
Thumbs.db
ehthumbs.db
Desktop.ini
$RECYCLE.BIN/

# OSX (MAC)
.DS_Store
.AppleDouble
.LSOverride
Icon
._*
.Spotlight-V100
.Trashes

# Linux
.*
!.gitignore
*~



================================================
FILE: CHANGELOG.md
================================================
## v1.9 Released ##

#### 10th October 2011

FlxBar - v1.6 Lots of bug fixes, more documentation, 2 new test cases, ability to set currentValue added

#### 9th October 2011

FlxCollision - v1.6 Fixed bug in pixelPerfectCheck that stopped non-square rotated objects from colliding properly (thanks to joon on the flixel forums for spotting)
FlxWeapon - v1.3 Added bullet elasticity and bulletsFired counter

#### 15th August 2011

FlxWeapon - v1.2 Added useParentDirection boolean
FlxControlHandler - v1.8 Added isPressedUp/Down/Left/Right handlers
FlxVelocity - v1.6 New Method: velocityFromFacing

#### 11th August 2011

Created WeaponTest9 - destructable terrain

#### 8th August 2011

GlitchFX - v1.2 Fixed updateFromSource github issue #8 (thanks CoderBrandon)
FlxControlHandler - v1.7 Modified update function so gravity is applied constantly
Several new demos created

#### 4th August 2011

FlxCoreUtils - v1.1 Added get mouseIndex and gameContainer
FlxColor - v1.5 Added RGBtoWebString

#### 3rd August 2011

FlxWeapon - v1.1 Added pre-fire, fire and post-fire callbacks and sound support, rnd factors, boolean returns and currentBullet
Bullet - v1.1 Updated to support fire callbacks, sounds, random variances and lifespan
FlxKongregate - v1.0 First release


## v1.8 Released ##

#### 31st July 2011

FlxDelay - v1.4 Modified abort so it no longer runs the stop callback (thanks to Cambrian-Man)

#### 29th July 2011

FlxFlod : Added full FlxFlectrum support
FlxFlectrum - new class

#### 28th July 2011

FlxExtendedSprite : Added Gravity, Friction and Tolerance support
FlxButtonPlus : Added scrollFactor to buttonNormal and buttonHighlight
 
#### 27th July 2011

Added createCameraWall to FlxCollision and created lots more tests
FlxMouseControl: Added Mouse Zone, Mouse Speed and refactored addToStack process

#### 21st July 2011

FlxMouseControl and FlxExtendedSprite given a serious overhaul and now provide for totally draggable sprites!

#### 21st June 2011

Added support for fixed widths in FlxBitmapFont, and the ability to align the text left/right/center within that width.
Updated BitmapFontTest3 to demonstrate this.



================================================
FILE: LICENSE.md
================================================
Simplified BSD License
======================

Copyright © 2011, Richard Davey  
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: 

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer. 
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution. 

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies, 
either expressed or implied, of the FreeBSD Project.


================================================
FILE: README.md
================================================
Flixel Power Tools
==================

Version 1.9 (final release)

November 28th 2013

By Richard Davey, [Photon Storm](http://www.photonstorm.com)

The [Flixel Power Tools](http://www.photonstorm.com/flixel-power-tools) are a package
of classes designed to provide extra functionality to your Flixel 2.5+ games.


Quick Install Guide
-------------------

Copy the `src` and `lib` folders into your ActionScript project. All the classes for Flixel Power Tools should be contained in

	src/org/flixel/plugin/photonstorm

Now read the "Getting Started Guide" in the `Docs` folder; it contains important information that will 
help you compile!


Getting Started Guide
---------------------

There is a comprehensive Getting Started Guide in both Word and PDF format in the `Docs` branch:

https://github.com/FlixelCommunity/Flixel-Power-Tools/tree/docs

Documentation is also provided built-in to the classes. AS3 IDEs such as FlashDevelop will
provide context-sensitive help for all classes and functions in the Flixel Power Tools.

Finally check out the home page at http://www.photonstorm.com/flixel-power-tools for updates.


Test Suite
----------

Get the full Test Suite from here:

https://github.com/FlixelCommunity/Flixel-Power-Tools/tree/test-suite

The Flixel Power Tools come with a comprehensive Test Suite. Use it to visually see the 
tools in action, and then learn from the source code and comments within.

To run the Test Suite launch the following SWF:

    Test Suite/bin/FlixelPowerTools.swf

If you don't have Flash Player installed locally then open `index.html` in a browser.


Classes
-------

The following classes are currently in the Flixel Power Tools:

* FlxBar
* FlxBitmapFont
* FlxButtonPlus
* FlxCollision
* FlxColor
* FlxControl (includes FlxControlHandler)
* FlxCoreUtils
* FlxDelay
* FlxDisplay
* FlxExtendedSprite
* FlxFlod (includes FlxFlectrum)
* FlxGradient
* FlxGridOverlay
* FlxLinkedGroup
* FlxMath
* FlxMouseControl
* FlxScreenGrab
* FlxScrollingText
* FlxScrollZone
* FlxSpecialFX
* FlxVelocity
* FlxWeapon

APIs Include

* FlxKongregate

Special FX Includes

* BlurFX
* CenterSlideFX
* FloodFillFX
* GlitchFX
* PlasmaFX
* RainbowLineFX
* RevealFX
* SineWaveFX
* StarfieldFX

Contributing
------------

I'm afraid that the Flixel Power Tools are no longer maintained by myself. I have moved on to [other things](http://phaser.io).

I would strongly suggest you start using the [Flixel Commmunity](https://github.com/FlixelCommunity) version of Flixel which contains updated versions of these tools.

License
-------

Copyright 2011 Richard Davey. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:

   1. Redistributions of source code must retain the above copyright notice, this list of
      conditions and the following disclaimer.

   2. Redistributions in binary form must reproduce the above copyright notice, this list
      of conditions and the following disclaimer in the documentation and/or other materials
      provided with the distribution.

THIS SOFTWARE IS PROVIDED BY RICHARD DAVEY ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RICHARD DAVEY OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

The views and conclusions contained in the software and documentation are those of the
authors and should not be interpreted as representing official policies, either expressed
or implied, of the FreeBSD Project.

[1]: https://github.com/photonstorm/Flixel-Power-Tools/issues
[fpt]: https://github.com/photonstorm/Flixel-Power-Tools
[ff]: http://flixel.org/forums/


================================================
FILE: src/org/flixel/plugin/photonstorm/API/FlxKongregate.as
================================================
/**
 * FlxKongregate
 * -- Part of the Flixel Power Tools set
 * 
 * v1.0 First release
 * 
 * @version 1.0 - August 1st 2011
 * @link http://www.photonstorm.com
 * @author Richard Davey / Photon Storm
*/

package org.flixel.plugin.photonstorm.API 
{
	import flash.display.DisplayObject;
	import flash.display.Loader;
	import flash.errors.IOError;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.net.URLRequest;
	import flash.system.Security;
	
	import org.flixel.*;
	
	/**
	 *	Allows for easy access to the Kongregate API
	 * 
	 *	Todo: Add in the functions for Chat Integration - you can still use them via the FlxKongregate.api object.
	 */
	public class FlxKongregate 
	{
		/**
		 * The Kongregate API object. You can make calls directly to this once the API has connected.
		 */
		public static var api:*;
		
		/**
		 * true if the API has loaded otherwise false. Loaded is not the same thing as connected, it just means it's ready for the connection.
		 */
		public static var hasLoaded:Boolean = false;
		
		/**
		 * Is the game running locally in Shadow API mode (true) or from Kongregates servers (false)
		 */
		public static var isLocal:Boolean = false;
		
		private static var shadowAPI:String = "http://www.kongregate.com/flash/API_AS3_Local.swf";
		private static var apiLoader:Loader;
		private static var loadCallback:Function;
		
		public function FlxKongregate() 
		{
		}
		
		/**
		 * Loads the Kongregate API and if successful connects to the service.
		 * Note that your game must have access to Stage by this point.
		 * 
		 * @param	callback	This function is called if the API loads successfully. Do not call any API function until this has happened.
		 */
		public static function init(callback:Function):void
		{
			try
			{
				var parameters:Object = FlxG.stage.loaderInfo.parameters;
			}
			catch (e:Error)
			{
				throw new Error("FlxKongregate: No access to FlxG.stage - only call this once your game has access to the display list");
				return;
			}
			
			var apiPath:String;
			
			if (parameters.kongregate_api_path)
			{
				Security.allowDomain(parameters.kongregate_api_path);
				apiPath = parameters.kongregate_api_path;
			}
			else
			{
				Security.allowDomain(shadowAPI);
				apiPath = shadowAPI;
				isLocal = true;
			}
			
			loadCallback = callback;
			
			apiLoader = new Loader();
			apiLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, apiLoadComplete, false, 0, true);
			apiLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, apiLoadError, false, 0, true);
			apiLoader.load(new URLRequest(apiPath));
			
			FlxG.stage.addChild(apiLoader);
		}
		
		/**
		 * Remove the API from memory (when possible) and removes it from the display list also
		 */
		public static function disconnect():void
		{
			api = null;
			
			hasLoaded = false;
			
			FlxG.stage.removeChild(apiLoader);
		}
		
		private static function apiLoadComplete(event:Event):void
		{
			api = event.target.content;
			
			hasLoaded = true;

			Security.allowDomain(api.loaderInfo.url);

			if (loadCallback is Function)
			{
				loadCallback.call();
			}
			
		}
		
		private static function apiLoadError(error:IOError):void
		{
			trace("Error loading Kongregate API", error);
		}
		
		/**
		 * Use the addLoadListener function to register an event listener which will be triggered when content of the specified type is loaded by the user.
		 * These MUST be set-up *before* you call FlxKongregate.connect()
		 * See: http://www.kongregate.com/developer_center/docs/shared-content-api
		 * 
		 * @param	contentType		Type of content to listen for
		 * @param	callback		Function to call when content load request has been made
		 */
		public static function addLoadListener(contentType:String, callback:Function):void
		{
			api.sharedContent.addLoadListener(contentType, callback);
		}
		
		/**
		 * Register an event listener with the API. Useful for capturing guest to user login requests for example.
		 * See: http://www.kongregate.com/developer_center/docs/handling-guests
		 * 
		 * @param	contentType		The event to listen for (i.e. "login")
		 * @param	callback		Funcation to call when this event is received
		 */
		public static function addEventListener(contentType:String, callback:Function):void
		{
			api.services.addEventListener(contentType, callback);
		}
		
		/**
		 * Connect to the Kongregate API. This should be called only after the init callback reports a succesful load of the API
		 */
		public static function connect():void
		{
			if (hasLoaded)
			{
				api.services.connect();
			}
		}
		
		/**
		 * The isGuest function can be called to determine if the player is currently signed into Kongregate or not
		 */
		public static function get isGuest():Boolean
		{
			return api.services.isGuest();
		}
		
		/**
		 * You can use the getUsername() function to retrieve the username of the current player. It will begin with Guest if the user is not signed in.
		 */
		public static function get getUserName():String
		{
			return api.services.getUsername();
		}
		
		/**
		 * You can use the getUserId() function to retrieve the unique user id of the current player. It will return 0 if the user is not signed in.
		 */
		public static function get getUserId():Number
		{
			try
			{
				return api.services.getUserId();
			}
			catch (e:Error)
			{
				return 0;
			}
			
			return 0;
		}
		
		/**
		 * If you are using the Authentication API you can use the getGameAuthToken function to get the player's game authentication token.
		 */
		public static function get getGameAuthToken():String
		{
			return api.services.getGameAuthToken();
		}
		
		/**
		 * If the player is a guest, and you want to display the sign-in/registration UI to them you can use the showSignInBox function.
		 */
		public static function showSignInBox():void
		{
			if (api.services.isGuest())
			{
				api.services.showSignInBox();
			}
		}
		
		/**
		 * This call works the same way as showSigninBox, but it focuses the registration form rather than the sign-in form.
		 */
		public static function showRegistrationBox():void
		{
			if (api.services.isGuest())
			{
				api.services.showRegistrationBox();
			}
		}
		
		/**
		 * If a player is logged-in and you want to allow them to post a shout on their profile page, you may bring up the shout box, optionally populated with some initial content.
		 * 
		 * @param	message		The optional initial content
		 */
		public static function showShoutBox(message:String = ""):void
		{
			if (api.services.isGuest() == false)
			{
				api.services.showShoutBox(message);
			}
		}
		
		/**
		 * If you need to resize your game's enclosing container, you may do so with resizeGame call. The enclosing iframe will resize around your game.
		 * Games may not be resized smaller than their initial dimensions. This call requires special permission from Kongregate to use.
		 * 
		 * @param	width		New width (in pixels) of the container
		 * @param	height		New height (in pixels) of the container
		 */
		public static function resizeGame(width:int, height:int):void
		{
			api.services.resizeGame(width, height);
		}
		
		/**
		 * Submit a statistic to the Kongregate server. Make sure you have defined the stat before calling this.
		 * See the Kongregate API documentation for details.
		 * 
		 * @param	name		The name of the statistic
		 * @param	value		The value to submit (will be converted to an integer server-side)
		 */
		public static function submitStats(name:String, value:Number):void
		{
			api.stats.submit(name, value);
		}
		
		/**
		 * Bring up the "purchase items" dialog box by using the purchaseItems method on the microtransaction services object.
		 * Your game must be in the Kongregate Microtransactions beta to use this function.
		 * See: http://www.kongregate.com/developer_center/docs/microtransaction-client-api
		 * 
		 * @param	items		The array of item identifier strings or item/metadata objects.
		 * @param	callback	The callback function
		 */
		public static function purchaseItem(items:Array, callback:Function):void
		{
			api.mtx.purchaseItems(items, callback);
		}
		
		/**
		 * Request the inventory of any user.
		 * Your game must be in the Kongregate Microtransactions beta to use this function.
		 * See: http://www.kongregate.com/developer_center/docs/microtransaction-client-api
		 * 
		 * @param	username	The username to request inventory for, or null for the current player
		 * @param	callback	The callback function
		 */
		public static function requestUserItemList(username:String, callback:Function):void
		{
			api.mtx.requestUserItemList(username, callback);
		}
		
		/**
		 * Display the Kred purchasing Dialog.
		 * Your game must be in the Kongregate Microtransactions beta to use this function.
		 * See: http://www.kongregate.com/developer_center/docs/microtransaction-client-api
		 * 
		 * @param	purchaseMethod	 The purchase method to display. Should be "offers" or "mobile"
		 */
		public static function showKredPurchaseDialog(purchaseMethod:String):void
		{
			api.mtx.showKredPurchaseDialog(purchaseMethod);
		}
		
		/**
		 * The browse function causes a list of shared content to appear in the user's browser.
		 * This will allow them to view, rate, or load shared content for your game.
		 * See: http://www.kongregate.com/developer_center/docs/shared-content-api
		 * 
		 * @param	contentType		Type of content to browse
		 * @param	sortOrder		Optional constant specifying how to sort content (see API docs)
		 * @param	label			Optional, only browse content saved with the specified label
		 */
		public static function browseSharedContent(contentType:String, sortOrder:String=null, label:String=null):void
		{
			api.sharedContent.browse(contentType, sortOrder, label);
		}
		
		/**
		 * Use the save function to submit shared content on the Kongregate back-end.
		 * See: http://www.kongregate.com/developer_center/docs/shared-content-api
		 * 
		 * @param	type		Type of content the user wishes to save, 12 characters max.
		 * @param	content		Value of content to be saved. We strongly recommend keeping these values under 100K.
		 * @param	callback	Function to call when save has finished.
		 * @param	thumb		Optional but highly recommended! Send us a DisplayObject that we will snapshotted and used as a thumbnail for the content.
		 * @param	label		Optional, label for sub-classing the shared content.
		 */
		public static function saveSharedContent(type:String, content:String, callback:Function, thumb:DisplayObject = null, label:String = null):void
		{
			api.sharedContent.save(type, content, callback, thumb, label);
		}
		
		/**
		 * Export a DisplayObject to be converted to a user avatar. It is highly recommended that avatars be at least 40 x 40px.
		 * See: http://www.kongregate.com/developer_center/docs/avatar-api
		 * 
		 * @param	avatar		Can be null, but highly recommended that you send yourself. If null, we will snapshot the stage.
		 * @param	callback	Function to call when content load request has been made
		 */
		public static function submitAvatar(avatar:DisplayObject, callback:Function):void
		{
			api.images.submitAvatar(avatar, callback);
		}
	}

}

================================================
FILE: src/org/flixel/plugin/photonstorm/BaseTypes/Bullet.as
================================================
/**
 * Bullet
 * -- Part of the Flixel Power Tools set
 * 
 * v1.2 Removed "id" and used the FlxSprite ID value instead
 * v1.1 Updated to support fire callbacks, sounds, random variances and lifespan
 * v1.0 First release
 * 
 * @version 1.2 - October 10th 2011
 * @link http://www.photonstorm.com
 * @author Richard Davey / Photon Storm
*/

package org.flixel.plugin.photonstorm.BaseTypes 
{
	import org.flixel.FlxPoint;
	import org.flixel.FlxSprite;
	import org.flixel.plugin.photonstorm.FlxMath;
	import org.flixel.plugin.photonstorm.FlxVelocity;
	import org.flixel.plugin.photonstorm.FlxWeapon;
	import flash.utils.getTimer;

	public class Bullet extends FlxSprite
	{
		protected var weapon:FlxWeapon;
		
		protected var bulletSpeed:int;
		
		//	Acceleration or Velocity?
		public var accelerates:Boolean;
		public var xAcceleration:int;
		public var yAcceleration:int;
		
		public var rndFactorAngle:uint;
		public var rndFactorSpeed:uint;
		public var rndFactorLifeSpan:uint;
		public var lifespan:uint;
		public var launchTime:uint;
		public var expiresTime:uint;
		
		protected var animated:Boolean;
		
		public function Bullet(weapon:FlxWeapon, id:uint)
		{
			super(0, 0);
			
			this.weapon = weapon;
			this.ID = id;
			
			//	Safe defaults
			accelerates = false;
			animated = false;
			bulletSpeed = 0;
			
			exists = false;
		}
		
		/**
		 * Adds a new animation to the sprite.
		 * 
		 * @param	Name		What this animation should be called (e.g. "run").
		 * @param	Frames		An array of numbers indicating what frames to play in what order (e.g. 1, 2, 3).
		 * @param	FrameRate	The speed in frames per second that the animation should play at (e.g. 40 fps).
		 * @param	Looped		Whether or not the animation is looped or just plays once.
		 */
		override public function addAnimation(Name:String, Frames:Array, FrameRate:Number = 0, Looped:Boolean = true):void
		{
			super.addAnimation(Name, Frames, FrameRate, Looped);
			
			animated = true;
		}
		
		public function fire(fromX:int, fromY:int, velX:int, velY:int):void
		{
			x = fromX + FlxMath.rand( -weapon.rndFactorPosition.x, weapon.rndFactorPosition.x);
			y = fromY + FlxMath.rand( -weapon.rndFactorPosition.y, weapon.rndFactorPosition.y);
			
			if (accelerates)
			{
				acceleration.x = xAcceleration + FlxMath.rand( -weapon.rndFactorSpeed, weapon.rndFactorSpeed);
				acceleration.y = yAcceleration + FlxMath.rand( -weapon.rndFactorSpeed, weapon.rndFactorSpeed);
			}
			else
			{
				velocity.x = velX + FlxMath.rand( -weapon.rndFactorSpeed, weapon.rndFactorSpeed);
				velocity.y = velY + FlxMath.rand( -weapon.rndFactorSpeed, weapon.rndFactorSpeed);
			}
			
			postFire();
		}
		
		public function fireAtMouse(fromX:int, fromY:int, speed:int):void
		{
			x = fromX + FlxMath.rand( -weapon.rndFactorPosition.x, weapon.rndFactorPosition.x);
			y = fromY + FlxMath.rand( -weapon.rndFactorPosition.y, weapon.rndFactorPosition.y);
			
			if (accelerates)
			{
				FlxVelocity.accelerateTowardsMouse(this, speed + FlxMath.rand( -weapon.rndFactorSpeed, weapon.rndFactorSpeed), maxVelocity.x, maxVelocity.y);
			}
			else
			{
				FlxVelocity.moveTowardsMouse(this, speed + FlxMath.rand( -weapon.rndFactorSpeed, weapon.rndFactorSpeed));
			}
			
			postFire();
		}
		
		public function fireAtPosition(fromX:int, fromY:int, toX:int, toY:int, speed:int):void
		{
			x = fromX + FlxMath.rand( -weapon.rndFactorPosition.x, weapon.rndFactorPosition.x);
			y = fromY + FlxMath.rand( -weapon.rndFactorPosition.y, weapon.rndFactorPosition.y);
			
			if (accelerates)
			{
				FlxVelocity.accelerateTowardsPoint(this, new FlxPoint(toX, toY), speed + FlxMath.rand( -weapon.rndFactorSpeed, weapon.rndFactorSpeed), maxVelocity.x, maxVelocity.y);
			}
			else
			{
				FlxVelocity.moveTowardsPoint(this, new FlxPoint(toX, toY), speed + FlxMath.rand( -weapon.rndFactorSpeed, weapon.rndFactorSpeed));
			}
			
			postFire();
		}
		
		public function fireAtTarget(fromX:int, fromY:int, target:FlxSprite, speed:int):void
		{
			x = fromX + FlxMath.rand( -weapon.rndFactorPosition.x, weapon.rndFactorPosition.x);
			y = fromY + FlxMath.rand( -weapon.rndFactorPosition.y, weapon.rndFactorPosition.y);
			
			if (accelerates)
			{
				FlxVelocity.accelerateTowardsObject(this, target, speed + FlxMath.rand( -weapon.rndFactorSpeed, weapon.rndFactorSpeed), maxVelocity.x, maxVelocity.y);
			}
			else
			{
				FlxVelocity.moveTowardsObject(this, target, speed + FlxMath.rand( -weapon.rndFactorSpeed, weapon.rndFactorSpeed));
			}
			
			postFire();
		}
		
		public function fireFromAngle(fromX:int, fromY:int, fireAngle:int, speed:int):void
		{
			x = fromX + FlxMath.rand( -weapon.rndFactorPosition.x, weapon.rndFactorPosition.x);
			y = fromY + FlxMath.rand( -weapon.rndFactorPosition.y, weapon.rndFactorPosition.y);
			
			var newVelocity:FlxPoint = FlxVelocity.velocityFromAngle(fireAngle + FlxMath.rand( -weapon.rndFactorAngle, weapon.rndFactorAngle), speed + FlxMath.rand( -weapon.rndFactorSpeed, weapon.rndFactorSpeed));
			
			if (accelerates)
			{
				acceleration.x = newVelocity.x;
				acceleration.y = newVelocity.y;
			}
			else
			{
				velocity.x = newVelocity.x;
				velocity.y = newVelocity.y;
			}
			
			postFire();
		}
		
		private function postFire():void
		{
			if (animated)
			{
				play("fire");
			}
			
			if (weapon.bulletElasticity > 0)
			{
				elasticity = weapon.bulletElasticity;
			}
			
			exists = true;
			
			launchTime = getTimer();
			
			if (weapon.bulletLifeSpan > 0)
			{
				lifespan = weapon.bulletLifeSpan + FlxMath.rand( -weapon.rndFactorLifeSpan, weapon.rndFactorLifeSpan);
				expiresTime = getTimer() + lifespan;
			}
			
			if (weapon.onFireCallback is Function)
			{
				weapon.onFireCallback.apply();
			}
			
			if (weapon.onFireSound)
			{
				weapon.onFireSound.play();
			}
		}
		
		public function set xGravity(gx:int):void
		{
			acceleration.x = gx;
		}
		
		public function set yGravity(gy:int):void
		{
			acceleration.y = gy;
		}
		
		public function set maxVelocityX(mx:int):void
		{
			maxVelocity.x = mx;
		}
		
		public function set maxVelocityY(my:int):void
		{
			maxVelocity.y = my;
		}
		
		override public function update():void
		{
			if (lifespan > 0 && getTimer() > expiresTime)
			{
				kill();
			}
			
			if (FlxMath.pointInFlxRect(x, y, weapon.bounds) == false)
			{
				kill();
			}
		}
		
	}

}

================================================
FILE: src/org/flixel/plugin/photonstorm/BaseTypes/MouseSpring.as
================================================
package org.flixel.plugin.photonstorm.BaseTypes 
{
	import org.flixel.*;
	import org.flixel.plugin.photonstorm.FlxExtendedSprite;
	
	public class MouseSpring 
	{
		public var sprite:FlxExtendedSprite;
		
		/**
		 * The tension of the spring, smaller numbers create springs closer to the mouse pointer
		 * @default 0.1
		 */
		public var tension:Number = 0.1;
		
		/**
		 * The friction applied to the spring as it moves
		 * @default 0.95
		 */
		public var friction:Number = 0.95;
		
		/**
		 * The gravity controls how far "down" the spring hangs (use a negative value for it to hang up!)
		 * @default 0
		 */
		public var gravity:Number = 0;
		
		private var retainVelocity:Boolean = false;
		
		private var vx:Number = 0;
		private var vy:Number = 0;
	
		private var dx:Number = 0;
		private var dy:Number = 0;
		
		private var ax:Number = 0;
		private var ay:Number = 0;
		
		/**
		 * Adds a spring between the mouse and a Sprite.
		 * 
		 * @param	sprite				The FlxExtendedSprite to which this spring is attached
		 * @param	retainVelocity		true to retain the velocity of the spring when the mouse is released, or false to clear it
		 * @param	tension				The tension of the spring, smaller numbers create springs closer to the mouse pointer
		 * @param	friction			The friction applied to the spring as it moves
		 * @param	gravity				The gravity controls how far "down" the spring hangs (use a negative value for it to hang up!)
		 */
		public function MouseSpring(sprite:FlxExtendedSprite, retainVelocity:Boolean = false, tension:Number = 0.1, friction:Number = 0.95, gravity:Number = 0)
		{
			this.sprite = sprite;
			this.retainVelocity = retainVelocity;
			this.tension = tension;
			this.friction = friction;
			this.gravity = gravity;
		}
		
		/**
		 * Updates the spring physics and repositions the sprite
		 */
		public function update():void
		{
			dx = FlxG.mouse.x - sprite.springX;
			dy = FlxG.mouse.y - sprite.springY;
			
			ax = dx * tension;
			ay = dy * tension;
			
			vx += ax;
			vy += ay;
			
			vy += gravity;
			vx *= friction;
			vy *= friction;
			
			sprite.x += vx;
			sprite.y += vy;
		}
		
		/**
		 * Resets the internal spring physics
		 */
		public function reset():void
		{
			vx = 0;
			vy = 0;
		
			dx = 0;
			dy = 0;
			
			ax = 0;
			ay = 0;
		}
		
	}

}

================================================
FILE: src/org/flixel/plugin/photonstorm/FX/BaseFX.as
================================================
/**
 * BaseFX - Special FX Plugin
 * -- Part of the Flixel Power Tools set
 * 
 * v1.1 Fixed some documentation
 * v1.0 First release
 * 
 * @version 1.1 - June 10th 2011
 * @link http://www.photonstorm.com
 * @author Richard Davey / Photon Storm
*/

package org.flixel.plugin.photonstorm.FX 
{
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import org.flixel.FlxSprite;
	import flash.display.BitmapData;
	
	public class BaseFX 
	{
		/**
		 * Set to false to stop this effect being updated by the FlxSpecialFX Plugin. Set to true to enable.
		 */
		public var active:Boolean;
		
		/**
		 * The FlxSprite into which the effect is drawn. Add this to your FlxState / FlxGroup to display the effect.
		 */
		public var sprite:FlxSprite;
		
		/**
		 * A scratch bitmapData used to build-up the effect before passing to sprite.pixels
		 */
		internal var canvas:BitmapData;
		
		/**
		 * TODO A snapshot of the sprite background before the effect is applied
		 */
		internal var back:BitmapData;
		
		internal var image:BitmapData;
		internal var sourceRef:FlxSprite;
		internal var updateFromSource:Boolean;
		internal var clsRect:Rectangle;
		internal var clsPoint:Point;
		internal var clsColor:uint;
		
		//	For staggered drawing updates
		internal var updateLimit:uint = 0;
		internal var lastUpdate:uint = 0;
		internal var ready:Boolean = false;
		
		internal var copyRect:Rectangle;
		internal var copyPoint:Point;
		
		public function BaseFX() 
		{
			active = false;
		}
		
		/**
		 * Starts the effect runnning
		 * 
		 * @param	delay	How many "game updates" should pass between each update? If your game runs at 30fps a value of 0 means it will do 30 updates per second. A value of 1 means it will do 15 updates per second, etc.
		 */
		public function start(delay:uint = 0):void
		{
			updateLimit = delay;
			lastUpdate = 0;
			ready = true;
		}
		
		/**
		 * Pauses the effect from running. The draw function is still called each loop, but the pixel data is stopped from updating.<br>
		 * To disable the SpecialFX Plugin from calling the FX at all set the "active" parameter to false.
		 */
		public function stop():void
		{
			ready = false;
		}
		
		public function destroy():void
		{
			if (sprite)
			{
				sprite.kill();
			}
			
			if (canvas)
			{
				canvas.dispose();
			}
			
			if (back)
			{
				back.dispose();
			}
			
			if (image)
			{
				image.dispose();
			}
			
			sourceRef = null;
			
			active = false;
		}
		
	}

}

================================================
FILE: src/org/flixel/plugin/photonstorm/FX/BlurFX.as
================================================
/**
 * BlurFX - Special FX Plugin
 * -- Part of the Flixel Power Tools set
 * 
 * v1.0 First release
 * 
 * @version 1.0 - June 10th 2011
 * @link http://www.photonstorm.com
 * @author Richard Davey / Photon Storm
*/

package org.flixel.plugin.photonstorm.FX 
{
	import flash.display.BitmapData;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.utils.Dictionary;
	import flash.filters.BlurFilter;
	
	import org.flixel.*;
	import org.flixel.plugin.photonstorm.*;
	
	/**
	 * Creates a blur effect
	 */
	public class BlurFX extends BaseFX
	{
		private var objects:Array;
		private var blurFilter:BlurFilter;
		
		public function BlurFX() 
		{
		}
		
		/**
		 * Creates a new BlurFX the given width/height in size.<br>
		 * The blur X / Y / Quality parameters all control the strength of the effect.<br>
		 * Add the resulting FlxSprite to your display to see the effect.
		 * 
		 * @param	width			The width (in pixels) of the resulting FlxSprite containing the Blur effect
		 * @param	height			The height (in pixels) of the resulting FlxSprite containing the Blur effect
		 * @param	blurX			The amount of horizontal blur.
		 * @param	blurY			The amount of vertical blur.
		 * @param	blurQuality		The number of times to perform the blur. Default is 1 (fastest, single pass) up to a maxium of 15 (very VERY expensive!)
		 * 
		 * @return	An FlxSprite containing the updating blur effect
		 */
		public function create(width:int, height:int, blurX:Number, blurY:Number, blurQuality:int = 1):FlxSprite
		{
			sprite = new FlxSprite(0, 0).makeGraphic(width, height, 0x0, true);
			
			objects = new Array;
			
			blurFilter = new BlurFilter(blurX, blurY, blurQuality);
			
			copyPoint = new Point(0, 0);
			copyRect = new Rectangle(0, 0, width, height);
			
			return sprite;
		}
		
		/**
		 * Adds an FlxSprite to the BlurFX. Every loop this sprite will be drawn to the FX and then blurred if the FlxSprite is both onScreen() and visible.
		 * 
		 * @param	source		The FlxSprite to add to the blur effect
		 * @param	autoRemove	If true and the FlxSprite.exists value ever equals false then BlurFX will automatically remove it
		 */
		public function addSprite(source:FlxSprite, autoRemove:Boolean = true):void
		{
			objects.push( { sprite: source, autoRemove: autoRemove } );
			
			if (active == false)
			{
				active = true;
			}
		}
		
		/**
		 * Removes the FlxSprite from the effect
		 * 
		 * @param	source		The FlxSprite to remove from the blur effect
		 */
		public function removeSprite(source:FlxSprite):void
		{
			for (var i:int = 0; i < objects.length; i++)
			{
				if (objects[i].sprite == source)
				{
					objects.splice(i, 1);
					break;
				}
			}
		}
		
		public function draw():void
		{
			if (ready)
			{
				//	Write every object to the canvas
				for each (var obj:Object in objects)
				{
					//	Removal check
					if (obj.sprite.exists == false)
					{
						removeSprite(obj.sprite);
					}
					else
					{
						if (obj.sprite.visible && obj.sprite.onScreen())
						{
							sprite.stamp(obj.sprite, obj.sprite.x, obj.sprite.y);
						}
					}
				}
				
				//	We'll use the update timer to control how often the blur is run, not how often the objects are drawn
				if (lastUpdate != updateLimit)
				{
					lastUpdate++;
					
					return;
				}
				
				//	Then blur it
				sprite.pixels.applyFilter(sprite.pixels, copyRect, copyPoint, blurFilter);
				
				lastUpdate = 0;
				
				sprite.dirty = true;
			}
		}
		
	}

}

================================================
FILE: src/org/flixel/plugin/photonstorm/FX/CenterSlideFX.as
================================================
/**
 * CenterSlideFX - Special FX Plugin
 * -- Part of the Flixel Power Tools set
 * 
 * v1.1 Refactored main loop a little and added reverse function
 * v1.0 First release
 * 
 * @version 1.1 - June 13th 2011
 * @link http://www.photonstorm.com
 * @author Richard Davey / Photon Storm
*/

package org.flixel.plugin.photonstorm.FX 
{
	import flash.display.BitmapData;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	import org.flixel.*;
	import org.flixel.plugin.photonstorm.*;
	
	/**
	 * Makes an image expand or collapse from its center
	 */
	public class CenterSlideFX extends BaseFX
	{
		/**
		 * True when the effect has completed. False while the effect is running.
		 */
		public var complete:Boolean;
		
		/**
		 * A function that is called once the effect is has finished running and is complete
		 */
		public var completeCallback:Function;
		
		private var pixels:uint;
		private var direction:uint;
		
		private var sideA:Rectangle;
		private var sideB:Rectangle;
		private var pointA:Point;
		private var pointB:Point;
		
		public static const REVEAL_VERTICAL:uint = 0;
		public static const REVEAL_HORIZONTAL:uint = 1;
		public static const HIDE_VERTICAL:uint = 2;
		public static const HIDE_HORIZONTAL:uint = 3;
		
		public function CenterSlideFX() 
		{
		}
		
		/**
		 * Creates a new CenterSlide effect from the given FlxSprite. The original sprite remains unmodified.<br>
		 * The resulting FlxSprite will take on the same width / height and x/y coordinates of the source FlxSprite.
		 * 
		 * @param	source				The FlxSprite providing the image data for this effect. The resulting FlxSprite takes on the source width, height and x/y position.
		 * @param	direction			REVEAL_VERTICAL, REVEAL_HORIZONTAL, HIDE_VERTICAL or HIDE_HORIZONTAL
		 * @param	pixels				How many pixels to slide update (default 1)
		 * @param	backgroundColor		The background colour of the FlxSprite the effect is drawn in to (default 0x0 = transparent)
		 * 
		 * @return	An FlxSprite with the effect running through it, which should be started with a call to CenterSlideFX.start()
		 */
		public function createFromFlxSprite(source:FlxSprite, direction:uint = 0, pixels:uint = 1, backgroundColor:uint = 0x0):FlxSprite
		{
			return create(source.pixels, source.x, source.y, direction, pixels, backgroundColor);
		}
		
		/**
		 * Creates a new CenterSlide effect from the given Class (which must contain a Bitmap) usually from an Embedded bitmap.
		 * 
		 * @param	source				The Class providing the bitmapData for this effect, usually from an Embedded bitmap.
		 * @param	x					The x coordinate (in game world pixels) that the resulting FlxSprite will be created at.
		 * @param	y					The x coordinate (in game world pixels) that the resulting FlxSprite will be created at.
		 * @param	direction			REVEAL_VERTICAL, REVEAL_HORIZONTAL, HIDE_VERTICAL or HIDE_HORIZONTAL
		 * @param	pixels				How many pixels to slide update (default 1)
		 * @param	backgroundColor		The background colour of the FlxSprite the effect is drawn in to (default 0x0 = transparent)
		 * 
		 * @return	An FlxSprite with the effect running through it, which should be started with a call to CenterSlideFX.start()
		 */
		public function createFromClass(source:Class, x:int, y:int, direction:uint = 0, pixels:uint = 1, backgroundColor:uint = 0x0):FlxSprite
		{
			return create((new source).bitmapData, x, y, direction, pixels, backgroundColor);
		}
		
		/**
		 * Creates a new CenterSlide effect from the given bitmapData.
		 * 
		 * @param	source				The bitmapData image to use for this effect.
		 * @param	x					The x coordinate (in game world pixels) that the resulting FlxSprite will be created at.
		 * @param	y					The x coordinate (in game world pixels) that the resulting FlxSprite will be created at.
		 * @param	direction			REVEAL_VERTICAL, REVEAL_HORIZONTAL, HIDE_VERTICAL or HIDE_HORIZONTAL
		 * @param	pixels				How many pixels to slide update (default 1)
		 * @param	backgroundColor		The background colour of the FlxSprite the effect is drawn in to (default 0x0 = transparent)
		 * 
		 * @return	An FlxSprite with the effect running through it, which should be started with a call to CenterSlideFX.start()
		 */
		public function createFromBitmapData(source:BitmapData, x:int, y:int, direction:uint = 0, pixels:uint = 1, backgroundColor:uint = 0x0):FlxSprite
		{
			return create(source, x, y, direction, pixels, backgroundColor);
		}
		
		private function create(source:BitmapData, x:int, y:int, direction:uint = 0, pixels:uint = 1, backgroundColor:uint = 0x0):FlxSprite
		{
			sprite = new FlxSprite(x, y).makeGraphic(source.width, source.height, backgroundColor);
			
			canvas = new BitmapData(source.width, source.height, true, backgroundColor);
			
			image = source.clone();
			
			clsRect = new Rectangle(0, 0, canvas.width, canvas.height);
			clsColor = backgroundColor;
			
			this.direction = direction;
			this.pixels = pixels;
			
			var midway:int = int(source.height / 2);
			
			switch (direction)
			{
				case REVEAL_VERTICAL:
					sideA = new Rectangle(0, 0, source.width, pixels);
					sideB = new Rectangle(0, source.height - pixels, source.width, pixels);
					pointA = new Point(0, midway);
					pointB = new Point(0, midway);
					break;
					
				case REVEAL_HORIZONTAL:
					midway = int(source.width / 2);
					sideA = new Rectangle(0, 0, pixels, source.height);
					sideB = new Rectangle(source.width - pixels, 0, pixels, source.height);
					pointA = new Point(midway, 0);
					pointB = new Point(midway, 0);
					break;
					
				case HIDE_VERTICAL:
					canvas = image.clone();
					sprite.pixels = canvas;
					sprite.dirty = true;
					sideA = new Rectangle(0, 0, source.width, midway);
					sideB = new Rectangle(0, midway, source.width, source.height - midway);
					pointA = new Point(0, 0);
					pointB = new Point(0, midway);
					break;
					
				case HIDE_HORIZONTAL:
					canvas = image.clone();
					sprite.pixels = canvas;
					sprite.dirty = true;
					midway = int(source.width / 2);
					sideA = new Rectangle(0, 0, midway, source.height);
					sideB = new Rectangle(midway, 0, source.width - midway, source.height);
					pointA = new Point(0, 0);
					pointB = new Point(midway, 0);
					break;
			}
			
			active = true;
			complete = false;
			
			return sprite;
		}
		
		public function reverse():void
		{
			if (direction == REVEAL_VERTICAL)
			{
				direction = HIDE_VERTICAL;
				complete = false;
			}
			else if (direction == REVEAL_HORIZONTAL)
			{
				direction = HIDE_HORIZONTAL;
				complete = false;
			}
		}
		
		public function draw():void
		{
			if (ready && complete == false)
			{
				if (lastUpdate != updateLimit)
				{
					lastUpdate++;
					
					return;
				}
				
				canvas.fillRect(clsRect, clsColor);
				canvas.copyPixels(image, sideA, pointA, null, null, true);
				canvas.copyPixels(image, sideB, pointB, null, null, true);
				
				switch (direction)
				{
					case REVEAL_VERTICAL:
						sideA.height += pixels;
						pointA.y -= pixels;
						sideB.height += pixels;
						sideB.y -= pixels;
						break;
						
					case REVEAL_HORIZONTAL:
						sideA.width += pixels;
						pointA.x -= pixels;
						sideB.width += pixels;
						sideB.x -= pixels;
						break;
						
					case HIDE_VERTICAL:
						sideA.height -= pixels;
						pointA.y += pixels;
						sideB.height -= pixels;
						sideB.y += pixels;
						break;
						
					case HIDE_HORIZONTAL:
						sideA.width -= pixels;
						pointA.x += pixels;
						sideB.width -= pixels;
						sideB.x += pixels;
						break;
				}
				
				//	Are we finished?
				if ((direction == REVEAL_VERTICAL && pointA.y < 0) || (direction == REVEAL_HORIZONTAL && pointA.x < 0))
				{
					canvas = image.clone();
					complete = true;
				}
				else if ((direction == HIDE_VERTICAL && sideA.height <= 0) || (direction == HIDE_HORIZONTAL && sideA.width <= 0))
				{
					canvas.fillRect(clsRect, clsColor);
					complete = true;
				}
				
				lastUpdate = 0;
				
				sprite.pixels = canvas;
				sprite.dirty = true;
				
				if (complete && completeCallback is Function)
				{
					completeCallback.call();
				}
			}
		}
		
	}

}

================================================
FILE: src/org/flixel/plugin/photonstorm/FX/FloodFillFX.as
================================================
/**
 * FloodFillFX - Special FX Plugin
 * -- Part of the Flixel Power Tools set
 * 
 * v1.1 Renamed - was "DropDown", but now a more accurate "flood fill"
 * v1.0 First release
 * 
 * @version 1.1 - May 31st 2011
 * @link http://www.photonstorm.com
 * @author Richard Davey / Photon Storm
*/

package org.flixel.plugin.photonstorm.FX 
{
	import flash.display.BitmapData;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	import org.flixel.*;
	import org.flixel.plugin.photonstorm.*;
	
	/**
	 * Creates a flood fill effect FlxSprite, useful for bringing in images in cool ways
	 */
	public class FloodFillFX extends BaseFX
	{
		private var complete:Boolean;
		private var chunk:uint;
		private var offset:uint;
		private var dropDirection:uint;
		private var dropRect:Rectangle;
		private var dropPoint:Point;
		private var dropY:uint;
		
		public function FloodFillFX() 
		{
		}
		
		/**
		 * Creates a new Flood Fill effect from the given image
		 * 
		 * @param	source				The source image bitmapData to use for the drop
		 * @param	x					The x coordinate to place the resulting effect sprite
		 * @param	y					The y coordinate to place the resulting effect sprite
		 * @param	width				The width of the resulting effet sprite. Doesn't have to match the source image
		 * @param	height				The height of the resulting effet sprite. Doesn't have to match the source image
		 * @param	direction			0 = Top to bottom. 1 = Bottom to top. 2 = Left to Right. 3 = Right to Left.
		 * @param	pixels				How many pixels to drop per update (default 1)
		 * @param	split				Boolean (default false) - if split it will drop from opposite sides at the same time
		 * @param	backgroundColor		The background colour of the FlxSprite the effect is drawn in to (default 0x0 = transparent)
		 * 
		 * @return	An FlxSprite with the effect ready to run in it
		 */
		public function create(source:FlxSprite, x:int, y:int, width:uint, height:uint, direction:uint = 0, pixels:uint = 1, split:Boolean = false, backgroundColor:uint = 0x0):FlxSprite
		{
			sprite = new FlxSprite(x, y).makeGraphic(width, height, backgroundColor);
			
			canvas = new BitmapData(width, height, true, backgroundColor);
			
			if (source.pixels.width != width || source.pixels.height != height)
			{
				image = new BitmapData(width, height, true, backgroundColor);
				image.copyPixels(source.pixels, new Rectangle(0, 0, source.pixels.width, source.pixels.height), new Point(0, height - source.pixels.height));
			}
			else
			{
				image = source.pixels;
			}
			
			offset = pixels;
			
			dropDirection = direction;
			dropRect = new Rectangle(0, canvas.height - offset, canvas.width, offset);
			dropPoint = new Point(0, 0);
			dropY = canvas.height;
			
			active = true;
			
			return sprite;
		}
		
		public function draw():void
		{
			if (ready && complete == false)
			{
				if (lastUpdate != updateLimit)
				{
					lastUpdate++;
					
					return;
				}
				
				canvas.lock();
				
				switch (dropDirection)
				{
					//	Dropping Down
					case 0:
					
						//	Get a pixel strip from the picture (starting at the bottom and working way up)
						for (var y:int = 0; y < dropY; y += offset)
						{
							dropPoint.y = y;
							canvas.copyPixels(image, dropRect, dropPoint);
						}
						
						dropY -= offset;
						
						dropRect.y -= offset;
						
						if (dropY <= 0)
						{
							complete = true;
						}
					
						break;
				}
				
				lastUpdate = 0;
				
				canvas.unlock();
				
				sprite.pixels = canvas;
				sprite.dirty = true;
			}
		}
		
	}

}

================================================
FILE: src/org/flixel/plugin/photonstorm/FX/GlitchFX.as
================================================
/**
 * GlitchFX - Special FX Plugin
 * -- Part of the Flixel Power Tools set
 * 
 * v1.2 Fixed updateFromSource github issue #8 (thanks CoderBrandon)
 * v1.1 Added changeGlitchValues support
 * v1.0 First release
 * 
 * @version 1.2 - August 8th 2011
 * @link http://www.photonstorm.com
 * @author Richard Davey / Photon Storm
*/

package org.flixel.plugin.photonstorm.FX 
{
	import flash.display.BitmapData;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	import org.flixel.*;
	import org.flixel.plugin.photonstorm.*;
	
	/**
	 * Creates a static / glitch / monitor-corruption style effect on an FlxSprite
	 * 
	 * TODO:
	 * 
	 * Add reduction from really high glitch value down to zero, will smooth the image into place and look cool :)
	 * Add option to glitch vertically?
	 * 
	 */
	public class GlitchFX extends BaseFX
	{
		private var glitchSize:uint;
		private var glitchSkip:uint;
		
		public function GlitchFX() 
		{
		}
		
		public function createFromFlxSprite(source:FlxSprite, maxGlitch:uint, maxSkip:uint, autoUpdate:Boolean = false, backgroundColor:uint = 0x0):FlxSprite
		{
			sprite = new FlxSprite(source.x, source.y).makeGraphic(source.width + maxGlitch, source.height, backgroundColor);
			
			canvas = new BitmapData(sprite.width, sprite.height, true, backgroundColor);
			
			image = source.pixels;
			
			updateFromSource = autoUpdate;
			
			if (updateFromSource)
			{
				sourceRef = source;
			}
			
			glitchSize = maxGlitch;
			glitchSkip = maxSkip;
			
			clsColor = backgroundColor;
			clsRect = new Rectangle(0, 0, canvas.width, canvas.height);
			
			copyPoint = new Point(0, 0);
			copyRect = new Rectangle(0, 0, image.width, 1);
			
			active = true;
			
			return sprite;
		}
		
		public function changeGlitchValues(maxGlitch:uint, maxSkip:uint):void
		{
			glitchSize = maxGlitch;
			glitchSkip = maxSkip;
		}
		
		public function draw():void
		{
			if (ready)
			{
				if (lastUpdate != updateLimit)
				{
					lastUpdate++;
					
					return;
				}
				
				if (updateFromSource && sourceRef.exists)
				{
					image = sourceRef.framePixels;
				}
				
				canvas.lock();
				canvas.fillRect(clsRect, clsColor);
				
				var rndSkip:uint = 1 + int(Math.random() * glitchSkip);
				
				copyRect.y = 0;
				copyPoint.y = 0;
				copyRect.height = rndSkip;
				
				for (var y:int = 0; y < sprite.height; y += rndSkip)
				{
					copyPoint.x = int(Math.random() * glitchSize);
					canvas.copyPixels(image, copyRect, copyPoint);
					
					copyRect.y += rndSkip;
					copyPoint.y += rndSkip;
				}
						
				canvas.unlock();
				
				lastUpdate = 0;
				
				sprite.pixels = canvas;
				sprite.dirty = true;
			}
		}
		
	}

}

================================================
FILE: src/org/flixel/plugin/photonstorm/FX/PlasmaFX.as
================================================
/**
 * PlasmaFX - Special FX Plugin
 * -- Part of the Flixel Power Tools set
 * 
 * v1.4 Moved to the new Special FX Plugins
 * v1.3 Colours updated to include alpha values
 * v1.2 Updated for the Flixel 2.5 Plugin system
 * 
 * @version 1.4 - May 8th 2011
 * @link http://www.photonstorm.com
 * @author Richard Davey / Photon Storm
*/

package org.flixel.plugin.photonstorm.FX 
{
	import flash.display.BitmapData;
	import flash.geom.Rectangle;
	
	import org.flixel.*;
	import org.flixel.plugin.photonstorm.*;
	
	/**
	 * Creates a plasma effect FlxSprite
	 */
	
	public class PlasmaFX extends BaseFX
	{
		//private var pos1:uint;
		//private var pos2:uint;
		//private var pos3:uint;
		//private var pos4:uint;
		
		public var pos1:uint;
		public var pos2:uint;
		public var pos3:uint;
		public var pos4:uint;
		public var depth:uint = 128;
		
		private var tpos1:uint;
		private var tpos2:uint;
		private var tpos3:uint;
		private var tpos4:uint;
		
		private var aSin:Array;
		//private var previousColour:uint;
		private var colours:Array;
		private var step:uint = 0;
		private var span:uint;
		
		public function PlasmaFX():void
		{
		}
		
		public function create(x:int, y:int, width:uint, height:uint, scaleX:uint = 1, scaleY:uint = 1):FlxSprite
		{
			sprite = new FlxSprite(x, y).makeGraphic(width, height, 0x0);
			
			if (scaleX != 1 || scaleY != 1)
			{
				sprite.scale = new FlxPoint(scaleX, scaleY);
				sprite.x += width / scaleX;
				sprite.y += height / scaleY;
			}
			
			canvas = new BitmapData(width, height, true, 0x0);
			
			colours = FlxColor.getHSVColorWheel();
			
			//colours = FlxColor.getHSVColorWheel(140);	// now supports alpha :)
			//colours = FlxGradient.createGradientArray(1, 360, [0xff000000, 0xff000000, 0xff000000, 0x00000000, 0xff000000], 2);	//	Lovely black reveal for over an image
			//colours = FlxGradient.createGradientArray(1, 360, [0xff0000FF, 0xff000000, 0xff8F107C, 0xff00FFFF, 0xff0000FF], 1); // lovely purple black blue thingy
			
			span = colours.length - 1;
			
			aSin = new Array(512);
			
			for (var i:int = 0; i < 512; i++)
			{
				//var rad:Number = (i * 0.703125) * 0.0174532;
				var rad:Number = (i * 0.703125) * 0.0174532;
				
				//	Any power of 2!
				//	http://www.vaughns-1-pagers.com/computer/powers-of-2.htm
				//	256, 512, 1024, 2048, 4096, 8192, 16384
				aSin[i] = Math.sin(rad) * 1024;
				
				//aSin[i] = Math.cos(rad) * 1024;
			}
			
			active = true;
			
			tpos1 = 293;
			tpos2 = 483;
			tpos3 = 120;
			tpos4 = 360;
			
			pos1 = 0;
			pos2 = 5;
			pos3 = 0;
			pos4 = 0;
			
			return sprite;
		}
		
		public function draw():void
		{
			if (step < 10)
			{
				//trace(step, tpos1, tpos2, tpos3, tpos4, pos1, pos2, pos3, pos4, index);
				step++;
			}
			
			tpos4 = pos4;
			tpos3 = pos3;
			
			canvas.lock();
			
			for (var y:int = 0; y < canvas.height; y++)
			{
				tpos1 = pos1 + 5;
				tpos2 = pos2 + 3;
				
				//tpos1 = pos1;
				//tpos2 = pos2;
				
				tpos2 &= 511;
				tpos3 &= 511;
				
				for (var x:int = 0; x < canvas.width; x++)
				{
					tpos1 &= 511;
					tpos2 &= 511;
					
					var x2:int = aSin[tpos1] + aSin[tpos2] + aSin[tpos3] + aSin[tpos4];
				
					//var index:int = depth + (x2 >> 4);
					var index:int = depth + (x2 >> 4);
					//p = (128 + (p >> 4)) & 255;

					
					if (index <= 0)
					{
						index += span;
					}
					
					if (index >= span)
					{
						index -= span;
					}
						
					canvas.setPixel32(x, y, colours[index]);
					
					tpos1 += 5;
					tpos2 += 3;
				}
				
				tpos3 += 1;
				tpos4 += 3;
			}
			
			canvas.unlock();
			
			sprite.pixels = canvas;
			sprite.dirty = true;
			
			pos1 += 4;	// horizontal shift
			pos3 += 2;	// vertical shift
		}
		
	}

}

================================================
FILE: src/org/flixel/plugin/photonstorm/FX/RainbowLineFX.as
================================================
/**
 * RainbowLineFX - A Special FX Plugin
 * -- Part of the Flixel Power Tools set
 * 
 * v1.0 Built into the new FlxSpecialFX system
 * 
 * @version 1.0 - May 9th 2011
 * @link http://www.photonstorm.com
 * @author Richard Davey / Photon Storm
 * @see Requires FlxGradient, FlxMath
*/

package org.flixel.plugin.photonstorm.FX 
{
	import flash.display.BitmapData;
	import flash.geom.Rectangle;
	
	import org.flixel.*;
	import org.flixel.plugin.photonstorm.*;
	
	/**
	 * Creates a Rainbow Line Effect - typically a rainbow sequence of color values passing through a 1px high line
	 */
	public class RainbowLineFX extends BaseFX
	{
		private var lineColors:Array;
		private var maxColor:uint;
		private var currentColor:uint;
		private var fillRect:Rectangle;
		private var speed:uint;
		private var chunk:uint;
		private var direction:uint;
		private var setPixel:Boolean;
		
		public function RainbowLineFX() 
		{
		}
		
		/**
		 * Creates a Color Line FlxSprite.
		 * 
		 * @param	x			The x coordinate of the FlxSprite in game world pixels
		 * @param	y			The y coordinate of the FlxSprite in game world pixels
		 * @param	width		The width of the FlxSprite in pixels
		 * @param	height		The height of the FlxSprite in pixels
		 * @param	colors		An Array of color values used to create the line. If null (default) the HSV Color Wheel is used, giving a full spectrum rainbow effect
		 * @param	colorWidth	The width of the color range controls how much interpolation occurs between each color in the colors array (default 360)
		 * @param	colorSpeed	The speed at which the Rainbow Line cycles through its colors (default 1)
		 * @param	stepSize	The size of each "chunk" of the Rainbow Line - use a higher value for a more retro look (default 1)
		 * @param	fadeWidth	If you want the Line to fade from fadeColor to the first color in the colors array, and then out again, set this value to the amount of transition you want (128 looks good)
		 * @param	fadeColor	The default fade color is black, but if you need to alpha it, or change for a different color, set it here
		 * 
		 * @return	An FlxSprite which automatically updates each draw() to cycle the colors through it
		 */
		public function create(x:int, y:int, width:uint, height:uint = 1, colors:Array = null, colorWidth:uint = 360, colorSpeed:uint = 1, stepSize:uint = 1, fadeWidth:uint = 128, fadeColor:uint = 0xff000000):FlxSprite
		{
			sprite = new FlxSprite(x, y).makeGraphic(width, height, 0x0);
			
			canvas = new BitmapData(width, height, true, 0x0);
			
			if (colors is Array)
			{
				lineColors = FlxGradient.createGradientArray(1, colorWidth, colors);
			}
			else
			{
				lineColors = FlxColor.getHSVColorWheel();
			}
			
			currentColor = 0;
			maxColor = lineColors.length - 1;
			
			if (fadeWidth != 0)
			{
				var blackToFirst:Array = FlxGradient.createGradientArray(1, fadeWidth, [ fadeColor, fadeColor, fadeColor, lineColors[0] ]);
				var lastToBlack:Array = FlxGradient.createGradientArray(1, fadeWidth, [ lineColors[maxColor], fadeColor, fadeColor, fadeColor, fadeColor ]);
				
				var fadingColours:Array = blackToFirst.concat(lineColors);
				fadingColours = fadingColours.concat(lastToBlack);
				
				lineColors = fadingColours;
			
				maxColor = lineColors.length - 1;
			}
			
			direction = 0;
			setPixel = false;
			speed = colorSpeed;
			chunk = stepSize;
			fillRect = new Rectangle(0, 0, chunk, height);
			
			if (height == 1 && chunk == 1)
			{
				setPixel = true;
			}
			
			active = true;
			
			return sprite;
		}
		
		/**
		 * Change the colors cycling through the line by passing in a new array of color values
		 * 
		 * @param	colors				An Array of color values used to create the line. If null (default) the HSV Color Wheel is used, giving a full spectrum rainbow effect
		 * @param	colorWidth			The width of the color range controls how much interpolation occurs between each color in the colors array (default 360)
		 * @param	resetCurrentColor	If true the color pointer is returned to the start of the new color array, otherwise remains where it is
		 * @param	fadeWidth			If you want the Rainbow Line to fade from black to the first color in the colors array, and then out again, set this value to the amount of transition you want (128 looks good)
		 * @param	fadeColor			The default fade color is black, but if you need to alpha it, or change for a different color, set it here
		 */
		public function updateColors(colors:Array, colorWidth:uint = 360, resetCurrentColor:Boolean = false, fadeWidth:uint = 128, fadeColor:uint = 0xff000000):void
		{
			if (colors is Array)
			{
				lineColors = FlxGradient.createGradientArray(1, colorWidth, colors);
			}
			else
			{
				lineColors = FlxColor.getHSVColorWheel();
			}
			
			maxColor = lineColors.length - 1;
			
			if (fadeWidth != 0)
			{
				var blackToFirst:Array = FlxGradient.createGradientArray(1, fadeWidth, [ 0xff000000, 0xff000000, 0xff000000, lineColors[0] ]);
				var lastToBlack:Array = FlxGradient.createGradientArray(1, fadeWidth, [ lineColors[maxColor], 0xff000000, 0xff000000, 0xff000000, 0xff000000 ]);
				
				var fadingColours:Array = blackToFirst.concat(lineColors);
				fadingColours = fadingColours.concat(lastToBlack);
				
				lineColors = fadingColours;
			
				maxColor = lineColors.length - 1;
			}
			
			if (currentColor > maxColor || resetCurrentColor)
			{
				currentColor = 0;
			}
		}
		
		/**
		 * Doesn't need to be called directly as it's called by the FlxSpecialFX Plugin.<br>
		 * Set active to false if you wish to disable the effect.<br>
		 * Pass the effect to FlxSpecialFX.erase() if you wish to destroy this effect.
		 */
		public function draw():void
		{
			canvas.lock();
		
			fillRect.x = 0;
			
			for (var x:int = 0; x < canvas.width; x = x + chunk)
			{
				var c:int = FlxMath.wrapValue(currentColor + x, 1, maxColor);
				
				if (setPixel)
				{
					canvas.setPixel32(x, 0, lineColors[c]);
				}
				else
				{
					canvas.fillRect(fillRect, lineColors[c]);
					fillRect.x += chunk;
				}
			}
			
			canvas.unlock();
			
			if (direction == 0)
			{
				currentColor += speed;
				
				if (currentColor >= maxColor)
				{
					currentColor = 0;
				}
			}
			else
			{
				currentColor -= speed;
				
				if (currentColor < 0)
				{
					currentColor = maxColor;
				}
			}
			
			sprite.pixels = canvas;
			sprite.dirty = true;
		}
		
		/**
		 * Set the speed at which the Line cycles through its colors
		 */
		public function set colorSpeed(value:uint):void 
		{
			if (value < maxColor)
			{
				speed = value;
			}
		}
		
		/**
		 * The speed at which the Line cycles through its colors
		 */
		public function get colorSpeed():uint
		{
			return speed;
		}
		
		/**
		 * Set the size of each "chunk" of the Line. Use a higher value for a more retro look
		 */
		public function set stepSize(value:uint):void 
		{
			if (value < canvas.width && value > 0)
			{
				canvas.fillRect(new Rectangle(0, 0, canvas.width, canvas.height), 0x0);
				chunk = value;
				
				fillRect.x = 0;
				fillRect.width = chunk;
				
				if (value > 1)
				{
					setPixel = false;
				}
				else
				{
					setPixel = true;
				}
			}
		}
		
		/**
		 * The size of each "chunk" of the Line
		 */
		public function get stepSize():uint
		{
			return chunk;
		}
		
		/**
		 * Changes the color cycle direction.
		 * 
		 * @param	newDirection	0 = Colors cycle incrementally (line looks like it is moving to the left), 1 = Colors decrement (line moves to the right)
		 */
		public function setDirection(newDirection:uint):void
		{
			if (newDirection == 0 || newDirection == 1)
			{
				direction = newDirection;
			}
		}
		
	}

}

================================================
FILE: src/org/flixel/plugin/photonstorm/FX/RevealFX.as
================================================
/**
 * RevealFX - Special FX Plugin
 * -- Part of the Flixel Power Tools set
 * 
 * v1.1 Added changeGlitchValues support
 * v1.0 First release
 * 
 * @version 1.1 - June 13th 2011
 * @link http://www.photonstorm.com
 * @author Richard Davey / Photon Storm
*/

package org.flixel.plugin.photonstorm.FX 
{
	import flash.display.BitmapData;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	import org.flixel.*;
	import org.flixel.plugin.photonstorm.*;
	
	/**
	 * Creates a static / glitch / monitor-corruption style effect on an FlxSprite
	 * 
	 * TODO:
	 * 
	 * Add reduction from really high glitch value down to zero, will smooth the image into place and look cool :)
	 * Add option to glitch vertically?
	 * 
	 */
	public class RevealFX extends BaseFX
	{
		private var glitchSize:uint;
		private var glitchSkip:uint;
		
		public function RevealFX() 
		{
		}
		
		public function createFromFlxSprite(source:FlxSprite, maxGlitch:uint, maxSkip:uint, autoUpdate:Boolean = false, backgroundColor:uint = 0x0):FlxSprite
		{
			sprite = new FlxSprite(source.x, source.y).makeGraphic(source.width + maxGlitch, source.height, backgroundColor);
			
			canvas = new BitmapData(sprite.width, sprite.height, true, backgroundColor);
			
			image = source.pixels;
			
			updateFromSource = autoUpdate;
			
			glitchSize = maxGlitch;
			glitchSkip = maxSkip;
			
			clsColor = backgroundColor;
			clsRect = new Rectangle(0, 0, canvas.width, canvas.height);
			
			copyPoint = new Point(0, 0);
			copyRect = new Rectangle(0, 0, image.width, 1);
			
			active = true;
			
			return sprite;
		}
		
		public function changeGlitchValues(maxGlitch:uint, maxSkip:uint):void
		{
			glitchSize = maxGlitch;
			glitchSkip = maxSkip;
		}
		
		public function draw():void
		{
			if (ready)
			{
				if (lastUpdate != updateLimit)
				{
					lastUpdate++;
					
					return;
				}
				
				if (updateFromSource && sourceRef.exists)
				{
					image = sourceRef.framePixels;
				}
				
				canvas.lock();
				canvas.fillRect(clsRect, clsColor);
				
				var rndSkip:uint = 1 + int(Math.random() * glitchSkip);
				
				copyRect.y = 0;
				copyPoint.y = 0;
				copyRect.height = rndSkip;
				
				for (var y:int = 0; y < sprite.height; y += rndSkip)
				{
					copyPoint.x = int(Math.random() * glitchSize);
					canvas.copyPixels(image, copyRect, copyPoint);
					
					copyRect.y += rndSkip;
					copyPoint.y += rndSkip;
				}
						
				canvas.unlock();
				
				lastUpdate = 0;
				
				sprite.pixels = canvas;
				sprite.dirty = true;
			}
		}
		
	}

}

================================================
FILE: src/org/flixel/plugin/photonstorm/FX/SineWaveFX.as
================================================
/**
 * SineWaveFX - Special FX Plugin
 * -- Part of the Flixel Power Tools set
 * 
 * v1.0 First release
 * 
 * @version 1.0 - May 21st 2011
 * @link http://www.photonstorm.com
 * @author Richard Davey / Photon Storm
*/

package org.flixel.plugin.photonstorm.FX 
{
	import flash.display.BitmapData;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	import org.flixel.*;
	import org.flixel.plugin.photonstorm.*;
	
	/**
	 * Creates a sine-wave effect through an FlxSprite which can be applied vertically or horizontally
	 */
	public class SineWaveFX extends BaseFX
	{
		private var waveType:uint;
		private var waveVertical:Boolean;
		private var waveLength:uint;
		private var waveSize:uint;
		private var waveFrequency:Number;
		private var wavePixelChunk:uint;
		private var waveData:Array;
		private var waveDataCounter:uint = 0;
		private var waveLoopCallback:Function;
		
		public static const WAVETYPE_VERTICAL_SINE:uint = 0;
		public static const WAVETYPE_VERTICAL_COSINE:uint = 1;
		public static const WAVETYPE_HORIZONTAL_SINE:uint = 2;
		public static const WAVETYPE_HORIZONTAL_COSINE:uint = 3;
		
		public function SineWaveFX() 
		{
		}
		
		/**
		 * Creates a new SineWaveFX Effect from the given FlxSprite. The original sprite remains unmodified.<br>
		 * The resulting FlxSprite will take on the same width / height and x/y coordinates of the source FlxSprite.<br>
		 * For really cool effects you can SineWave an FlxSprite that is constantly updating (either through animation or an FX chain).
		 * 
		 * @param	source				The FlxSprite providing the image data for this effect. The resulting FlxSprite takes on the source width, height, x/y positions and scrollfactor.
		 * @param	type				WAVETYPE_VERTICAL_SINE, WAVETYPE_VERTICAL_COSINE, WAVETYPE_HORIZONTAL_SINE or WAVETYPE_HORIZONTAL_COSINE
		 * @param	size				The size in pixels of the sine wave. Either the height of the wave or the width (for vertical or horizontal waves)
		 * @param	length				The length of the wave in pixels. You should usually set this to the width or height of the source image, or a multiple of it.
		 * @param	frequency			The frequency of the peaks in the wave. MUST BE AN EVEN NUMBER! 2, 4, 6, 8, etc.
		 * @param	pixelsPerChunk		How many pixels to use per step. Higher numbers make a more chunky but faster effect. Make sure source.width/height divides by this value evenly.
		 * @param	updateFrame			When this effect is created it takes a copy of the source image data and stores it. Set this to true to grab a new copy of the image data every frame.
		 * @param	backgroundColor		The background color (0xAARRGGBB format) to draw behind the effect (default 0x0 = transparent)
		 * @return	An FlxSprite with the effect running through it, which should be started with a call to SineWaveFX.start()
		 */
		public function createFromFlxSprite(source:FlxSprite, type:uint, size:uint, length:uint, frequency:uint = 2, pixelsPerChunk:uint = 1, updateFrame:Boolean = false, backgroundColor:uint = 0x0):FlxSprite
		{
			var result:FlxSprite = create(source.pixels, source.x, source.y, type, size, length, frequency, pixelsPerChunk, backgroundColor);
			
			updateFromSource = updateFrame;
			
			if (updateFromSource)
			{
				sourceRef = source;
			}
			
			return result;
		}
		
		/**
		 * Creates a new SineWaveFX Effect from the given Class (which must contain a Bitmap).<br>
		 * If you need to update the source data at run-time then use createFromFlxSprite
		 * 
		 * @param	source				The Class providing the bitmapData for this effect, usually from an Embedded bitmap.
		 * @param	x					The x coordinate (in game world pixels) that the resulting FlxSprite will be created at.
		 * @param	y					The x coordinate (in game world pixels) that the resulting FlxSprite will be created at.
		 * @param	type				WAVETYPE_VERTICAL_SINE, WAVETYPE_VERTICAL_COSINE, WAVETYPE_HORIZONTAL_SINE or WAVETYPE_HORIZONTAL_COSINE
		 * @param	size				The size in pixels of the sine wave. Either the height of the wave or the width (for vertical or horizontal waves)
		 * @param	length				The length of the wave in pixels. You should usually set this to the width or height of the source image, or a multiple of it.
		 * @param	frequency			The frequency of the peaks in the wave. MUST BE AN EVEN NUMBER! 2, 4, 6, 8, etc.
		 * @param	pixelsPerChunk		How many pixels to use per step. Higher numbers make a more chunky but faster effect. Make sure source.width/height divides by this value evenly.
		 * @param	backgroundColor		The background color in 0xAARRGGBB format to draw behind the effect (default 0x0 = transparent)
		 * @return	An FlxSprite with the effect running through it, which should be started with a call to SineWaveFX.start()
		 */
		public function createFromClass(source:Class, x:int, y:int, type:uint, size:uint, length:uint, frequency:uint = 2, pixelsPerChunk:uint = 1, backgroundColor:uint = 0x0):FlxSprite
		{
			var result:FlxSprite = create((new source).bitmapData, x, y, type, size, length, frequency, pixelsPerChunk, backgroundColor);
			
			updateFromSource = false;
			
			return result;
		}
		
		/**
		 * Creates a new SineWaveFX Effect from the given bitmapData.<br>
		 * If you need to update the source data at run-time then use createFromFlxSprite
		 * 
		 * @param	source				The bitmapData image to use for this effect.
		 * @param	x					The x coordinate (in game world pixels) that the resulting FlxSprite will be created at.
		 * @param	y					The x coordinate (in game world pixels) that the resulting FlxSprite will be created at.
		 * @param	type				WAVETYPE_VERTICAL_SINE, WAVETYPE_VERTICAL_COSINE, WAVETYPE_HORIZONTAL_SINE or WAVETYPE_HORIZONTAL_COSINE
		 * @param	size				The size in pixels of the sine wave. Either the height of the wave or the width (for vertical or horizontal waves)
		 * @param	length				The length of the wave in pixels. You should usually set this to the width or height of the source image, or a multiple of it.
		 * @param	frequency			The frequency of the peaks in the wave. MUST BE AN EVEN NUMBER! 2, 4, 6, 8, etc.
		 * @param	pixelsPerChunk		How many pixels to use per step. Higher numbers make a more chunky but faster effect. Make sure source.width/height divides by this value evenly.
		 * @param	backgroundColor		The background color in 0xAARRGGBB format to draw behind the effect (default 0x0 = transparent)
		 * @return	An FlxSprite with the effect running through it, which should be started with a call to SineWaveFX.start()
		 */
		public function createFromBitmapData(source:BitmapData, x:int, y:int, type:uint, size:uint, length:uint, frequency:uint = 2, pixelsPerChunk:uint = 1, backgroundColor:uint = 0x0):FlxSprite
		{
			var result:FlxSprite = create(source, x, y, type, size, length, frequency, pixelsPerChunk, backgroundColor);
			
			updateFromSource = false;
			
			return result;
		}
		
		/**
		 * Internal function fed from createFromFlxSprite / createFromClass / createFromBitmapData
		 * 
		 * @param	source				The bitmapData image to use for this effect.
		 * @param	x					The x coordinate (in game world pixels) that the resulting FlxSprite will be created at.
		 * @param	y					The x coordinate (in game world pixels) that the resulting FlxSprite will be created at.
		 * @param	type				WAVETYPE_VERTICAL_SINE, WAVETYPE_VERTICAL_COSINE, WAVETYPE_HORIZONTAL_SINE or WAVETYPE_HORIZONTAL_COSINE
		 * @param	size				The size in pixels of the sine wave. Either the height of the wave or the width (for vertical or horizontal waves)
		 * @param	length				The length of the wave in pixels. You should usually set this to the width or height of the source image, or a multiple of it.
		 * @param	frequency			The frequency of the peaks in the wave. MUST BE AN EVEN NUMBER! 2, 4, 6, 8, etc.
		 * @param	pixelsPerChunk		How many pixels to use per step. Higher numbers make a more chunky but faster effect. Make sure source.width/height divides by this value evenly.
		 * @param	backgroundColor		The background color in 0xAARRGGBB format to draw behind the effect (default 0x0 = transparent)
		 * @return	An FlxSprite with the effect running through it, which should be started with a call to SineWaveFX.start()
		 */
		private function create(source:BitmapData, x:int, y:int, type:uint, size:uint, length:uint, frequency:uint = 2, pixelsPerChunk:uint = 1, backgroundColor:uint = 0x0):FlxSprite
		{
			if (type == WAVETYPE_VERTICAL_SINE || type == WAVETYPE_VERTICAL_COSINE)
			{
				waveVertical = true;
				
				if (pixelsPerChunk >= source.width)
				{
					throw new Error("SineWaveFX: pixelsPerChunk cannot be >= source.width with WAVETYPE_VERTICAL");
				}
			}
			else if (type == WAVETYPE_HORIZONTAL_SINE || type == WAVETYPE_HORIZONTAL_COSINE)
			{
				waveVertical = false;
				
				if (pixelsPerChunk >= source.height)
				{
					throw new Error("SineWaveFX: pixelsPerChunk cannot be >= source.height with WAVETYPE_HORIZONTAL");
				}
			}
			
			updateWaveData(type, size, length, frequency, pixelsPerChunk);
			
			//	The FlxSprite into which the sine-wave effect is drawn
			
			if (waveVertical)
			{
				sprite = new FlxSprite(x, y).makeGraphic(source.width, source.height + (waveSize * 3), backgroundColor);
			}
			else
			{
				sprite = new FlxSprite(x, y).makeGraphic(source.width + (waveSize * 3), source.height, backgroundColor);
			}
			
			//	The scratch bitmapData where we prepare the final sine-waved image
			canvas = new BitmapData(sprite.width, sprite.height, true, backgroundColor);
			
			//	Our local copy of the sprite image data
			image = source.clone();
			
			clsColor = backgroundColor;
			clsRect = new Rectangle(0, 0, canvas.width, canvas.height);
			
			copyPoint = new Point(0, 0);
			
			if (waveVertical)
			{
				copyRect = new Rectangle(0, 0, wavePixelChunk, image.height);
			}
			else
			{
				copyRect = new Rectangle(0, 0, image.width, wavePixelChunk);
			}
			
			active = true;
			
			return sprite;
		}
		
		/**
		 * Update the SineWave data without modifying the source image being used.<br>
		 * This call is fast enough that you can modify it in real-time.
		 * 
		 * @param	type				WAVETYPE_VERTICAL_SINE, WAVETYPE_VERTICAL_COSINE, WAVETYPE_HORIZONTAL_SINE or WAVETYPE_HORIZONTAL_COSINE
		 * @param	size				The size in pixels of the sine wave. Either the height of the wave or the width (for vertical or horizontal waves)
		 * @param	length				The length of the wave in pixels. You should usually set this to the width or height of the source image, or a multiple of it.
		 * @param	frequency			The frequency of the peaks in the wave. MUST BE AN EVEN NUMBER! 2, 4, 6, 8, etc.
		 * @param	pixelsPerChunk		How many pixels to use per step. Higher numbers make a more chunky but faster effect. Make sure source.width/height divides by this value evenly.
		 */
		public function updateWaveData(type:uint, size:uint, length:uint, frequency:uint = 2, pixelsPerChunk:uint = 1):void
		{
			if (type > WAVETYPE_HORIZONTAL_COSINE)
			{
				throw new Error("SineWaveFX: Invalid WAVETYPE");
			}
			
			if (FlxMath.isOdd(frequency))
			{
				throw new Error("SineWaveFX: frequency must be an even number");
			}
			
			waveType = type;
			waveSize = uint(size * 0.5);
			waveLength = uint(length / pixelsPerChunk);
			waveFrequency = frequency;
			wavePixelChunk = pixelsPerChunk;
			waveData = FlxMath.sinCosGenerator(waveLength, waveSize, waveSize, waveFrequency);
			
			if (waveType == WAVETYPE_VERTICAL_COSINE || waveType == WAVETYPE_HORIZONTAL_COSINE)
			{
				waveData = FlxMath.getCosTable();
			}
		}
		
		/**
		 * Use this to set a function to be called every time the wave has completed one full cycle.<br>
		 * Set to null to remove any previous callback.
		 * 
		 * @param	callback		The function to call every time the wave completes a full cycle (duration will vary based on waveLength)
		 */
		public function setLoopCompleteCallback(callback:Function):void
		{
			waveLoopCallback = callback;
		}
		
		/**
		 * Called by the FlxSpecialFX plugin. Should not be called directly.
		 */
		public function draw():void
		{
			if (ready)
			{
				if (lastUpdate != updateLimit)
				{
					lastUpdate++;
					
					return;
				}
				
				if (updateFromSource && sourceRef.exists)
				{
					image = sourceRef.framePixels;
				}
				
				canvas.lock();
				canvas.fillRect(clsRect, clsColor);
				
				var s:uint = 0;
				
				copyRect.x = 0;
				copyRect.y = 0;
				
				if (waveVertical)
				{
					for (var x:int = 0; x < image.width; x += wavePixelChunk)
					{
						copyPoint.x = x;
						copyPoint.y = waveSize + (waveSize / 2) + waveData[s];
						
						canvas.copyPixels(image, copyRect, copyPoint);
						
						copyRect.x += wavePixelChunk;
						
						s++;
					}
				}
				else
				{
					for (var y:int = 0; y < image.height; y += wavePixelChunk)
					{
						copyPoint.x = waveSize + (waveSize / 2) + waveData[s];
						copyPoint.y = y;
						
						canvas.copyPixels(image, copyRect, copyPoint);
						
						copyRect.y += wavePixelChunk;
						
						s++;
					}
				}
				
				//	Cycle through the wave data - this is what causes the image to "undulate"
				var t:Number = waveData.shift();
				waveData.push(t);
				
				waveDataCounter++;
				
				if (waveDataCounter == waveData.length)
				{
					waveDataCounter = 0;
					
					if (waveLoopCallback is Function)
					{
						waveLoopCallback.call();
					}
				}
				
				canvas.unlock();
				
				lastUpdate = 0;
				
				sprite.pixels = canvas;
				sprite.dirty = true;
			}
		}
		
		public function toString():String
		{
			var output:Array = [ "Type: " + waveType, "Size: " + waveSize, "Length: " + waveLength, "Frequency: " + waveFrequency, "Chunks: " + wavePixelChunk, "clsRect: " + clsRect ];
			
			return output.join(",");
		}
		
	}

}

================================================
FILE: src/org/flixel/plugin/photonstorm/FX/StarfieldFX.as
================================================
/**
 * StarfieldFX - Special FX Plugin
 * -- Part of the Flixel Power Tools set
 * 
 * v1.1 StarField moved to the FX Plugin system
 * v1.0 First release
 * 
 * @version 1.1 - May 21st 2011
 * @link http://www.photonstorm.com
 * @author Richard Davey / Photon Storm
*/

package org.flixel.plugin.photonstorm.FX 
{
	import flash.display.BitmapData;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.utils.getTimer;
	
	import org.flixel.*;
	import org.flixel.plugin.photonstorm.*;
	
	/**
	 * Creates a 2D or 3D Star Field effect on an FlxSprite for use in your game.
	 */
	public class StarfieldFX extends BaseFX
	{
		/**
		 * In a 3D starfield this controls the X coordinate the stars emit from, can be updated in real-time!
		 */
		public var centerX:int;
		
		/**
		 * In a 3D starfield this controls the Y coordinate the stars emit from, can be updated in real-time!
		 */
		public var centerY:int;
		
		/**
		 * How much to shift on the X axis every update. Negative values move towards the left, positiive to the right. 2D Starfield only. Can also be set via setStarSpeed()
		 */
		public var starXOffset:Number = -1;
		
		/**
		 * How much to shift on the Y axis every update. Negative values move up, positiive values move down. 2D Starfield only. Can also be set via setStarSpeed()
		 */
		public var starYOffset:Number = 0;
		
		private var stars:Array;
		private var starfieldType:int;
		
		private var backgroundColor:uint = 0xff000000;
		
		private var updateSpeed:int;
		private var tick:int;
		
		private var depthColours:Array;
		
		public static const STARFIELD_TYPE_2D:int = 1;
		public static const STARFIELD_TYPE_3D:int = 2;
		
		public function StarfieldFX() 
		{
		}
		
		/**
		 * Create a new StarField
		 * 
		 * @param	x				X coordinate of the starfield sprite
		 * @param	y				Y coordinate of the starfield sprite
		 * @param	width			The width of the starfield
		 * @param	height			The height of the starfield
		 * @param	quantity		The number of stars in the starfield (default 200)
		 * @param	type			Type of starfield. Either STARFIELD_TYPE_2D (default, stars move horizontally) or STARFIELD_TYPE_3D (stars flow out from the center)
		 * @param	updateInterval	How many ms should pass before the next starfield update (default 20)
		 */
		public function create(x:int, y:int, width:uint, height:uint, quantity:uint = 200, type:int = 1, updateInterval:int = 20):FlxSprite
		{
			sprite = new FlxSprite(x, y).makeGraphic(width, height, backgroundColor);
			
			canvas = new BitmapData(sprite.width, sprite.height, true, backgroundColor);
			
			starfieldType = type;
			
			updateSpeed = speed;
			
			//	Stars come from the middle of the starfield in 3D mode
			centerX = width >> 1;
			centerY = height >> 1;
				
			clsRect = new Rectangle(0, 0, width, height);
			clsPoint = new Point;
			clsColor = backgroundColor;
			
			stars = new Array();
			
			for (var i:uint = 0; i < quantity; i++)
			{
				var star:Object = new Object;
				
				star.index = i;
				star.x = int(Math.random() * width);
				star.y = int(Math.random() * height);
				star.d = 1;
				
				if (type == STARFIELD_TYPE_2D)
				{
					star.speed = 1 + int(Math.random() * 5);
				}
				else
				{
					star.speed = Math.random();
				}
				
				star.r = Math.random() * Math.PI * 2;
				star.alpha = 0;
				
				stars.push(star);
			}
			
			//	Colours array
			if (type == STARFIELD_TYPE_2D)
			{
				depthColours = FlxGradient.createGradientArray(1, 5, [0xff585858, 0xffF4F4F4]);
			}
			else
			{
				depthColours = FlxGradient.createGradientArray(1, 300, [0xff292929, 0xffffffff]);
			}
			
			active = true;
			
			return sprite;
		}
		
		/**
		 * Change the background color in the format 0xAARRGGBB of the starfield.<br />
		 * Supports alpha, so if you want a transparent background just pass 0x00 as the color.
		 * 
		 * @param	backgroundColor
		 */
		public function setBackgroundColor(backgroundColor:uint):void
		{
			clsColor = backgroundColor;
		}
		
		/**
		 * Change the number of layers (depth) and colors used for each layer of the starfield. Change happens immediately.
		 * 
		 * @param	depth			Number of depths (for a 2D starfield the default is 5)
		 * @param	lowestColor		The color given to the stars furthest away from the camera (i.e. the slowest stars), typically the darker colour
		 * @param	highestColor	The color given to the stars cloest to the camera (i.e. the fastest stars), typically the brighter colour
		 */
		public function setStarDepthColors(depth:int, lowestColor:uint = 0xff585858, highestColor:uint = 0xffF4F4F4):void
		{
			//	Depth is the same, we just need to update the gradient then
			depthColours = FlxGradient.createGradientArray(1, depth, [lowestColor, highestColor]);
			
			//	Run through the stars array, making sure the depths are all within range
			for each (var star:Object in stars)
			{
				star.speed = 1 + int(Math.random() * depth);
			}
		}
		
		/**
		 * Sets the direction and speed of the 2D starfield (doesn't apply to 3D)<br />
		 * You can combine both X and Y together to make the stars move on a diagnol
		 * 
		 * @param	xShift	How much to shift on the X axis every update. Negative values move towards the left, positiive to the right
		 * @param	yShift	How much to shift on the Y axis every update. Negative values move up, positiive values move down
		 */
		public function setStarSpeed(xShift:Number, yShift:Number):void
		{
			starXOffset = xShift;
			starYOffset = yShift;
		}
		
		/**
		 * The current update speed
		 */
		public function get speed():int
		{
			return updateSpeed;
		}
		
		/**
		 * Change the tick interval on which the update runs. By default the starfield updates once every 20ms. Set to zero to disable totally.
		 */
		public function set speed(newSpeed:int):void
		{
			updateSpeed = newSpeed;
		}
		
		private function update2DStarfield():void
		{
			for each (var star:Object in stars)
			{
				star.x += (starXOffset * star.speed);
				star.y += (starYOffset * star.speed);
				
				canvas.setPixel32(star.x, star.y, depthColours[star.speed - 1]);
				
				if (star.x > sprite.width)
				{
					star.x = 0;
				}
				else if (star.x < 0)
				{
					star.x = sprite.width;
				}
				
				if (star.y > sprite.height)
				{
					star.y = 0;
				}
				else if (star.y < 0)
				{
					star.y = sprite.height;
				}
			}
		}
		
		private function update3DStarfield():void
		{
			for each (var star:Object in stars)
			{
				star.d *= 1.1;
				star.x = centerX + ((Math.cos(star.r) * star.d) * star.speed);
				star.y = centerY + ((Math.sin(star.r) * star.d) * star.speed);
				
				star.alpha = star.d * 2;
				
				if (star.alpha > 255)
				{
					star.alpha = 255;
				}
				
				canvas.setPixel32(star.x, star.y, 0xffffffff);
				//canvas.setPixel32(star.x, star.y, FlxColor.getColor32(255, star.alpha, star.alpha, star.alpha));
				
				if (star.x < 0 || star.x > sprite.width || star.y < 0 || star.y > sprite.height)
				{
					star.d = 1;
					star.r = Math.random() * Math.PI * 2;
					star.x = 0;
					star.y = 0;
					star.speed = Math.random();
					star.alpha = 0;
					
					stars[star.index] = star;
				}
			}
		}
		
		public function draw():void
		{
			if (getTimer() > tick)
			{
				canvas.lock();
				canvas.fillRect(clsRect, clsColor);
				
				if (starfieldType == STARFIELD_TYPE_2D)
				{
					update2DStarfield();
				}
				else
				{
					update3DStarfield();
				}
				
				canvas.unlock();
				
				sprite.pixels = canvas;
				
				if (updateSpeed > 0)
				{
					tick = getTimer() + updateSpeed;
				}
			}
		}
		
	}

}

================================================
FILE: src/org/flixel/plugin/photonstorm/FX/WowCopperFX.as
================================================
/**
 * WowCopperFX - Special FX Plugin
 * -- Part of the Flixel Power Tools set
 * 
 * v1.0 First release
 * 
 * @version 1.4 - May 8th 2011
 * @link http://www.photonstorm.com
 * @author Original by Mathew Nolan / Flashtro.com
 * @author Ported with permission by Richard Davey / Photon Storm
*/

package org.flixel.plugin.photonstorm.FX 
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.geom.Matrix;
	import flash.geom.Rectangle;
	
	import org.flixel.*;
	import org.flixel.plugin.photonstorm.*;
	
	/**
	 * Creates a WOW Copper effect FlxSprite
	 */
	
	public class WowCopperFX extends BaseFX
	{
		private var colors:Array;
		private var step:uint = 0;
		private var span:uint;
		
		
		private var bmp_databg : BitmapData = new BitmapData( 1 , 64 , false , 0x00000100);
		//private var bmp_objbg : Bitmap = new Bitmap( bmp_databg , PixelSnapping.AUTO , false);
		private var bg2:Sprite = new Sprite;

		private var amount:int = 8;
		private var tab:int = 0;
		private var del:int = 0;
		private var max:int = 136;
		
		public function WowCopperFX():void
		{
		}
		
		public function create(x:int, y:int, width:uint, height:uint):FlxSprite
		{
			sprite = new FlxSprite(x, y).makeGraphic(width, height, 0x0);
			
			colors = [0x110011,
			0x220022,
			0x330033,
			0x440044,
			0x550055,
			0x660066,
			0x770077,
			0x880088,
			0x990099,
			0xaa00aa,
			0xbb00bb,
			0xcc00cc,
			0xdd00dd,
			0xee00ee,
			0xff00ff,
			0xff00ff,
			0xee00ee,
			0xdd00dd,
			0xcc00cc,
			0xbb00bb,
			0xaa00aa,
			0x990099,
			0x880088,
			0x770077,
			0x660066,
			0x550055,
			0x440044,
			0x330033,
			0x220022,
			0x110011,
			0x000001,
			0x000001,
			0x000001,
			0x000001,
			0x000001,
			0x000001,
			0x000001,
			0x000001,
			0x000001,
			0x000001,
			0x111100,
			0x222200,
			0x333300,
			0x444400,
			0x555500,
			0x666600,
			0x777700,
			0x888800,
			0x999900,
			0xaaaa00,
			0xbbbb00,
			0xcccc00,
			0xdddd00,
			0xeeee00,
			0xffff00,
			0xffff00,
			0xeeee00,
			0xdddd00,
			0xcccc00,
			0xbbbb00,
			0xaaaa00,
			0x999900,
			0x888800,
			0x777700,
			0x666600,
			0x555500,
			0x444400,
			0x333300,
			0x222200,
			0x111100,
			0x000001,
			0x000001,
			0x000001,
			0x000001,
			0x000001,
			0x000001,
			0x000001,
			0x000001,
			0x000001,
			0x000001,
			0x001111,
			0x002222,
			0x003333,
			0x004444,
			0x005555,
			0x006666,
			0x007777,
			0x008888,
			0x009999,
			0x00aaaa,
			0x00bbbb,
			0x00cccc,
			0x00dddd,
			0x00eeee,
			0x00ffff,
			0x00ffff,
			0x00eeee,
			0x00dddd,
			0x00cccc,
			0x00bbbb,
			0x00aaaa,
			0x009999,
			0x008888,
			0x007777,
			0x006666,
			0x005555,
			0x004444,
			0x003333,
			0x002222,
			0x001111,
			0x000001,
			0x000001,
			0x000001,
			0x000001,
			0x000001,
			0x000001,
			0x000001,
			0x000001,
			0x000001,
			0x000001,
			0x111111,
			0x222222,
			0x333333,
			0x444444,
			0x555555,
			0x666666,
			0x777777,
			0x888888,
			0x999999,
			0xaaaaaa,
			0xbbbbbb,
			0xcccccc,
			0xdddddd,
			0xeeeeee,
			0xffffff,
			0xffffff,
			0xeeeeee,
			0xdddddd,
			0xcccccc,
			0xbbbbbb,
			0xaaaaaa,
			0x999999,
			0x888888,
			0x777777,
			0x666666,
			0x555555,
			0x444444,
			0x333333,
			0x222222,
			0x111111,
			0x000001,
			0x000001,
			0x000001,
			0x000001,
			0x000001,
			0x000001,
			0x000001,
			0x000001,
			0x000001,
			0x000001];
			
			//canvas = new BitmapData(1, 64 , false , 0x00000100);
			canvas = new BitmapData(width, height, true, 0x0);

			active = true;
			
			return sprite;
		}
		
		public function draw():void
		{
			if (step < 10)
			{
				//trace(step, tpos1, tpos2, tpos3, tpos4, pos1, pos2, pos3, pos4, index);
				step++;
			}
			
			//canvas.setPixel(0, 31, colors[tab]);
			bmp_databg.setPixel(0, 31, colors[tab]);
			
			del++;
			
			if (del >= 2)
			{
				bmp_databg.scroll(0, -1);
				tab++;
				del = 0;
			}
			
			if (tab >= colors.length)
			{
				tab = 0;
			}
			
			bg2.graphics.clear();
			
			var bbcb:Matrix = new Matrix;
			
			for (var i:uint = 0; i < max; i += amount)
			{
				bg2.graphics.beginBitmapFill(bmp_databg, bbcb, true, false);
				bg2.graphics.moveTo(0, i);
				bg2.graphics.lineTo(0, i + amount);
				bg2.graphics.lineTo(320, i + amount );
				bg2.graphics.lineTo(320, i);
				bg2.graphics.endFill();
				bbcb.translate(0, 7);
			}
			
			canvas.draw(bg2);
			
			sprite.pixels = canvas;
			sprite.dirty = true;
			
			/*
			bmp_databg.setPixel(0,31,cols[tab])
			del++
			if(del>=2){
				bmp_databg.scroll(0,-1)
			tab++
			del=0
			}
			if(tab>=cols.length){
				tab=0
			}
				bg2.graphics.clear()
			var bbcb = new flash.geom.Matrix();
			for (var i:uint=0; i<max; i+=amount) {
				
				
				
				//m.ty =0
				
				bg2.graphics.beginBitmapFill(bmp_databg, bbcb,true,false);
				bg2.graphics.moveTo(0, i);
				bg2.graphics.lineTo(0, i+amount);
				bg2.graphics.lineTo(320, i+amount );
				bg2.graphics.lineTo(320, i);
				bg2.graphics.endFill();
				bbcb.translate(0,7)
					
			}
			*/
			
			
			//canvas.setPixel32(x, y, colours[index]);
					
			//sprite.pixels = canvas;
			//sprite.dirty = true;
			
		}
		
	}

}

================================================
FILE: src/org/flixel/plugin/photonstorm/FlxBar.as
================================================
/**
 * FlxBar
 * -- Part of the Flixel Power Tools set
 * 
 * v1.6 Lots of bug fixes, more documentation, 2 new test cases, ability to set currentValue added
 * v1.5 Fixed bug in "get percent" function that allows it to work with any value range
 * v1.4 Added support for min/max callbacks and "kill on min"
 * v1.3 Renamed from FlxHealthBar and made less specific / far more flexible
 * v1.2 Fixed colour values for fill and gradient to include alpha
 * v1.1 Updated for the Flixel 2.5 Plugin system
 * 
 * @version 1.6 - October 10th 2011
 * @link http://www.photonstorm.com
 * @author Richard Davey / Photon Storm
*/

package org.flixel.plugin.photonstorm 
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import org.flixel.*;
	
	/**
	 * FlxBar is a quick and easy way to create a graphical bar which can
	 * be used as part of your UI/HUD, or positioned next to a sprite. It could represent
	 * a loader, progress or health bar.
	 */
	public class FlxBar extends FlxSprite
	{
		private var canvas:BitmapData;
		
		private var barType:uint;
		private var barWidth:uint;
		private var barHeight:uint;
		
		private var parent:*;
		private var parentVariable:String;
		
		/**
		 * fixedPosition controls if the FlxBar sprite is at a fixed location on screen, or tracking its parent
		 */
		public var fixedPosition:Boolean = true;
		
		/**
		 * The positionOffset controls how far offset the FlxBar is from the parent sprite (if at all)
		 */
		public var positionOffset:FlxPoint;
		
		/**
		 * The minimum value the bar can be (can never be >= max)
		 */
		private var min:Number;
		
		/**
		 * The maximum value the bar can be (can never be <= min)
		 */
		private var max:Number;
		
		/**
		 * How wide is the range of this bar? (max - min)
		 */
		private var range:Number;
		
		/**
		 * What 1% of the bar is equal to in terms of value (range / 100)
		 */
		private var pct:Number;
		
		/**
		 * The current value - must always be between min and max
		 */
		private var value:Number;
		
		/**
		 * How many pixels = 1% of the bar (barWidth (or height) / 100)
		 */
		public var pxPerPercent:Number;
		
		private var emptyCallback:Function;
		private var emptyBar:BitmapData;
		private var emptyBarRect:Rectangle;
		private var emptyBarPoint:Point;
		private var emptyKill:Boolean;
		private var zeroOffset:Point = new Point;
		
		private var filledCallback:Function;
		private var filledBar:BitmapData;
		private var filledBarRect:Rectangle;
		private var filledBarPoint:Point;
		
		private var fillDirection:uint;
		private var fillHorizontal:Boolean;
		
		public static const FILL_LEFT_TO_RIGHT:uint = 1;
		public static const FILL_RIGHT_TO_LEFT:uint = 2;
		public static const FILL_TOP_TO_BOTTOM:uint = 3;
		public static const FILL_BOTTOM_TO_TOP:uint = 4;
		public static const FILL_HORIZONTAL_INSIDE_OUT:uint = 5;
		public static const FILL_HORIZONTAL_OUTSIDE_IN:uint = 6;
		public static const FILL_VERTICAL_INSIDE_OUT:uint = 7;
		public static const FILL_VERTICAL_OUTSIDE_IN:uint = 8;
		
		private static const BAR_FILLED:uint = 1;
		private static const BAR_GRADIENT:uint = 2;
		private static const BAR_IMAGE:uint = 3;
		
		/**
		 * Create a new FlxBar Object
		 * 
		 * @param	x			The x coordinate location of the resulting bar (in world pixels)
		 * @param	y			The y coordinate location of the resulting bar (in world pixels)
		 * @param	direction 	One of the FlxBar.FILL_ constants (such as FILL_LEFT_TO_RIGHT, FILL_TOP_TO_BOTTOM etc)
		 * @param	width		The width of the bar in pixels
		 * @param	height		The height of the bar in pixels
		 * @param	parentRef	A reference to an object in your game that you wish the bar to track
		 * @param	variable	The variable of the object that is used to determine the bar position. For example if the parent was an FlxSprite this could be "health" to track the health value
		 * @param	min			The minimum value. I.e. for a progress bar this would be zero (nothing loaded yet)
		 * @param	max			The maximum value the bar can reach. I.e. for a progress bar this would typically be 100.
		 * @param	border		Include a 1px border around the bar? (if true it adds +2 to width and height to accommodate it)
		 */
		public function FlxBar(x:int, y:int, direction:uint = FILL_LEFT_TO_RIGHT, width:int = 100, height:int = 10, parentRef:* = null, variable:String = "", min:Number = 0, max:Number = 100, border:Boolean = false):void
		{
			super(x, y);
			
			barWidth = width;
			barHeight = height;
			
			if (border)
			{
				makeGraphic(barWidth + 2, barHeight + 2, 0xffffffff, true);
				filledBarPoint = new Point(1, 1);
			}
			else
			{
				makeGraphic(barWidth, barHeight, 0xffffffff, true);
				filledBarPoint = new Point(0, 0);
			}
			
			canvas = new BitmapData(width, height, true, 0x0);
			
			if (parentRef)
			{
				parent = parentRef;
				parentVariable = variable;
			}
			
			setFillDirection(direction);
			
			setRange(min, max);
			
			createFilledBar(0xff005100, 0xff00F400, border);
			
			emptyKill = false;
		}
		
		/**
		 * Track the parent FlxSprites x/y coordinates. For example if you wanted your sprite to have a floating health-bar above their head.
		 * If your health bar is 10px tall and you wanted it to appear above your sprite, then set offsetY to be -10
		 * If you wanted it to appear below your sprite, and your sprite was 32px tall, then set offsetY to be 32. Same applies to offsetX.
		 * 
		 * @param	offsetX		The offset on X in relation to the origin x/y of the parent
		 * @param	offsetY		The offset on Y in relation to the origin x/y of the parent
		 * @see		stopTrackingParent
		 */
		public function trackParent(offsetX:int, offsetY:int):void
		{
			fixedPosition = false;
			
			positionOffset = new FlxPoint(offsetX, offsetY);
			
			if (parent.scrollFactor)
			{
				scrollFactor.x = parent.scrollFactor.x;
				scrollFactor.y = parent.scrollFactor.y;
			}
		}
		
		/**
		 * Sets a parent for this FlxBar. Instantly replaces any previously set parent and refreshes the bar.
		 * 
		 * @param	parentRef	A reference to an object in your game that you wish the bar to track
		 * @param	variable	The variable of the object that is used to determine the bar position. For example if the parent was an FlxSprite this could be "health" to track the health value
		 * @param	track		If you wish the FlxBar to track the x/y coordinates of parent set to true (default false)
		 * @param	offsetX		The offset on X in relation to the origin x/y of the parent
		 * @param	offsetY		The offset on Y in relation to the origin x/y of the parent
		 */
		public function setParent(parentRef:*, variable:String, track:Boolean = false, offsetX:int = 0, offsetY:int = 0):void
		{
			parent = parentRef;
			parentVariable = variable;
			
			if (track)
			{
				trackParent(offsetX, offsetY);
			}
			
			updateValueFromParent();
			updateBar();
		}
		
		/**
		 * Tells the health bar to stop following the parent sprite. The given posX and posY values are where it will remain on-screen.
		 * 
		 * @param	posX	X coordinate of the health bar now it's no longer tracking the parent sprite
		 * @param	posY	Y coordinate of the health bar now it's no longer tracking the parent sprite
		 */
		public function stopTrackingParent(posX:int, posY:int):void
		{
			fixedPosition = true;
			
			x = posX;
			y = posY;
		}
		
		/**
		 * Sets callbacks which will be triggered when the value of this FlxBar reaches min or max.<br>
		 * Functions will only be called once and not again until the value changes.<br>
		 * Optionally the FlxBar can be killed if it reaches min, but if will fire the empty callback first (if set)
		 * 
		 * @param	onEmpty			The function that is called if the value of this FlxBar reaches min
		 * @param	onFilled		The function that is called if the value of this FlxBar reaches max
		 * @param	killOnEmpty		If set it will call FlxBar.kill() if the value reaches min
		 */
		public function setCallbacks(onEmpty:Function, onFilled:Function, killOnEmpty:Boolean = false):void
		{
			if (onEmpty is Function)
			{
				emptyCallback = onEmpty;
			}
			
			if (onFilled is Function)
			{
				filledCallback = onFilled;
			}
			
			if (killOnEmpty)
			{
				emptyKill = true;
			}
		}
		
		/**
		 * If this FlxBar should be killed when its value reaches empty, set to true
		 */
		public function set killOnEmpty(value:Boolean):void
		{
			emptyKill = value;
		}
		
		public function get killOnEmpty():Boolean
		{
			return emptyKill;
		}
		
		/**
		 * Set the minimum and maximum allowed values for the FlxBar
		 * 
		 * @param	min			The minimum value. I.e. for a progress bar this would be zero (nothing loaded yet)
		 * @param	max			The maximum value the bar can reach. I.e. for a progress bar this would typically be 100.
		 */
		public function setRange(min:Number, max:Number):void
		{
			if (max <= min)
			{
				throw Error("FlxBar: max cannot be less than or equal to min");
				return;
			}
			
			this.min = min;
			this.max = max;
			
			range = max - min;
			
			if (range < 100)
			{
				pct = range / 100;
			}
			else
			{
				pct = range / 100;
			}
			
			if (fillHorizontal)
			{
				pxPerPercent = barWidth / 100;
			}
			else
			{
				pxPerPercent = barHeight / 100;
			}
			
			if (value)
			{
				if (value > max)
				{
					value = max;
				}
				
				if (value < min)
				{
					value = min;
				}
			}
			else
			{
				value = min;
			}
		}
		
		public function debug():void
		{
			trace("FlxBar - Min:", min, "Max:", max, "Range:", range, "pct:", pct, "pxp:", pxPerPercent, "Value:", value);
		}
		
		public function get stats():Object
		{
			var data:Object = {
				min: min,
				max: max,
				range: range,
				pct: pct,
				pxPerPct: pxPerPercent,
				fillH: fillHorizontal
			}
			
			return data;
		}
		
		/**
		 * Creates a solid-colour filled health bar in the given colours, with optional 1px thick border.
		 * All colour values are in 0xAARRGGBB format, so if you want a slightly transparent health bar give it lower AA values.
		 * 
		 * @param	empty		The color of the bar when empty in 0xAARRGGBB format (the background colour)
		 * @param	fill		The color of the bar when full in 0xAARRGGBB format (the foreground colour)
		 * @param	showBorder	Should the bar be outlined with a 1px solid border?
		 * @param	border		The border colour in 0xAARRGGBB format
		 */
		public function createFilledBar(empty:uint, fill:uint, showBorder:Boolean = false, border:uint = 0xffffffff):void
		{
			barType = BAR_FILLED;
			
			if (showBorder)
			{
				emptyBar = new BitmapData(barWidth, barHeight, true, border);
				emptyBar.fillRect(new Rectangle(1, 1, barWidth - 2, barHeight - 2), empty);
				
				filledBar = new BitmapData(barWidth, barHeight, true, border);
				filledBar.fillRect(new Rectangle(1, 1, barWidth - 2, barHeight - 2), fill);
			}
			else
			{
				emptyBar = new BitmapData(barWidth, barHeight, true, empty);
				filledBar = new BitmapData(barWidth, barHeight, true, fill);
			}
			
			filledBarRect = new Rectangle(0, 0, filledBar.width, filledBar.height);
			emptyBarRect = new Rectangle(0, 0, emptyBar.width, emptyBar.height);
		}
		
		/**
		 * Creates a gradient filled health bar using the given colour ranges, with optional 1px thick border.
		 * All colour values are in 0xAARRGGBB format, so if you want a slightly transparent health bar give it lower AA values.
		 * 
		 * @param	empty		Array of colour values used to create the gradient of the health bar when empty, each colour must be in 0xAARRGGBB format (the background colour)
		 * @param	fill		Array of colour values used to create the gradient of the health bar when full, each colour must be in 0xAARRGGBB format (the foreground colour)
		 * @param	chunkSize	If you want a more old-skool looking chunky gradient, increase this value!
		 * @param	rotation	Angle of the gradient in degrees. 90 = top to bottom, 180 = left to right. Any angle is valid
		 * @param	showBorder	Should the bar be outlined with a 1px solid border?
		 * @param	border		The border colour in 0xAARRGGBB format
		 */
		public function createGradientBar(empty:Array, fill:Array, chunkSize:int = 1, rotation:int = 180, showBorder:Boolean = false, border:uint = 0xffffffff):void
		{
			barType = BAR_GRADIENT;
			
			if (showBorder)
			{
				emptyBar = new BitmapData(barWidth, barHeight, true, border);
				FlxGradient.overlayGradientOnBitmapData(emptyBar, barWidth - 2, barHeight - 2, empty, 1, 1, chunkSize, rotation);
				
				filledBar = new BitmapData(barWidth, barHeight, true, border);
				FlxGradient.overlayGradientOnBitmapData(filledBar, barWidth - 2, barHeight - 2, fill, 1, 1, chunkSize, rotation);
			}
			else
			{
				emptyBar = FlxGradient.createGradientBitmapData(barWidth, barHeight, empty, chunkSize, rotation);
				filledBar = FlxGradient.createGradientBitmapData(barWidth, barHeight, fill, chunkSize, rotation);
			}
			
			emptyBarRect = new Rectangle(0, 0, emptyBar.width, emptyBar.height);
			filledBarRect = new Rectangle(0, 0, filledBar.width, filledBar.height);
		}
		
		/**
		 * Creates a health bar filled using the given bitmap images.
		 * You can provide "empty" (background) and "fill" (foreground) images. either one or both images (empty / fill), and use the optional empty/fill colour values 
		 * All colour values are in 0xAARRGGBB format, so if you want a slightly transparent health bar give it lower AA values.
		 * 
		 * @param	empty				Bitmap image used as the background (empty part) of the health bar, if null the emptyBackground colour is used
		 * @param	fill				Bitmap image used as the foreground (filled part) of the health bar, if null the fillBackground colour is used
		 * @param	emptyBackground		If no background (empty) image is given, use this colour value instead. 0xAARRGGBB format
		 * @param	fillBackground		If no foreground (fill) image is given, use this colour value instead. 0xAARRGGBB format
		 */
		public function createImageBar(empty:Class = null, fill:Class = null, emptyBackground:uint = 0xff000000, fillBackground:uint = 0xff00ff00):void
		{
			barType = BAR_IMAGE;
			
			if (empty == null && fill == null)
			{
				return;
			}
			
			if (empty && fill == null)
			{
				//	If empty is set, but fill is not ...

				emptyBar = Bitmap(new empty).bitmapData.clone();
				emptyBarRect = new Rectangle(0, 0, emptyBar.width, emptyBar.height);
				
				barWidth = emptyBarRect.width;
				barHeight = emptyBarRect.height;
				
				filledBar = new BitmapData(barWidth, barHeight, true, fillBackground);
				filledBarRect = new Rectangle(0, 0, barWidth, barHeight);
			}
			else if (empty == null && fill)
			{
				//	If fill is set, but empty is not ...
		
				filledBar = Bitmap(new fill).bitmapData.clone();
				filledBarRect = new Rectangle(0, 0, filledBar.width, filledBar.height);
				
				barWidth = filledBarRect.width;
				barHeight = filledBarRect.height;
				
				emptyBar = new BitmapData(barWidth, barHeight, true, emptyBackground);
				emptyBarRect = new Rectangle(0, 0, barWidth, barHeight);
			}
			else if (empty && fill)
			{
				//	If both are set
				
				emptyBar = Bitmap(new empty).bitmapData.clone();
				emptyBarRect = new Rectangle(0, 0, emptyBar.width, emptyBar.height);
				
				filledBar = Bitmap(new fill).bitmapData.clone();
				filledBarRect = new Rectangle(0, 0, filledBar.width, filledBar.height);
				
				barWidth = emptyBarRect.width;
				barHeight = emptyBarRect.height;
			}
			
			canvas = new BitmapData(barWidth, barHeight, true, 0x0);
			
			if (fillHorizontal)
			{
				pxPerPercent = barWidth / 100;
			}
			else
			{
				pxPerPercent = barHeight / 100;
			}
		}
		
		/**
		 * Set the direction from which the health bar will fill-up. Default is from left to right. Change takes effect immediately.
		 * 
		 * @param	direction 			One of the FlxBar.FILL_ constants (such as FILL_LEFT_TO_RIGHT, FILL_TOP_TO_BOTTOM etc)
		 */
		public function setFillDirection(direction:uint):void
		{
			switch (direction)
			{
				case FILL_LEFT_TO_RIGHT:
				case FILL_RIGHT_TO_LEFT:
				case FILL_HORIZONTAL_INSIDE_OUT:
				case FILL_HORIZONTAL_OUTSIDE_IN:
					fillDirection = direction;
					fillHorizontal = true;
					break;
					
				case FILL_TOP_TO_BOTTOM:
				case FILL_BOTTOM_TO_TOP:
				case FILL_VERTICAL_INSIDE_OUT:
				case FILL_VERTICAL_OUTSIDE_IN:
					fillDirection = direction;
					fillHorizontal = false;
					break;
			}
		}
		
		private function updateValueFromParent():void
		{
			updateValue(parent[parentVariable]);
		}
		
		private function updateValue(newValue:Number):void
		{
			if (newValue > max)
			{
				newValue = max;
			}
			
			if (newValue < min)
			{
				newValue = min;
			}
			
			value = newValue;
			
			if (value == min && emptyCallback is Function)
			{
				emptyCallback.call();
			}
			
			if (value == max && filledCallback is Function)
			{
				filledCallback.call();
			}
			
			if (value == min && emptyKill)
			{
				kill();
			}
		}
		
		/**
		 * Internal
		 * Called when the health bar detects a change in the health of the parent.
		 */
		private function updateBar():void
		{
			if (fillHorizontal)
			{
				filledBarRect.width = int(percent * pxPerPercent);
			}
			else
			{
				filledBarRect.height = int(percent * pxPerPercent);
			}
			
			canvas.copyPixels(emptyBar, emptyBarRect, zeroOffset);
			
			if (percent > 0)
			{
				switch (fillDirection)
				{
					case FILL_LEFT_TO_RIGHT:
					case FILL_TOP_TO_BOTTOM:
						//	Already handled above
						break;
						
					case FILL_BOTTOM_TO_TOP:
						filledBarRect.y = barHeight - filledBarRect.height;
						filledBarPoint.y = barHeight - filledBarRect.height;
						break;
						
					case FILL_RIGHT_TO_LEFT:
						filledBarRect.x = barWidth - filledBarRect.width;
						filledBarPoint.x = barWidth - filledBarRect.width;
						break;
						
					case FILL_HORIZONTAL_INSIDE_OUT:
						filledBarRect.x = int((barWidth / 2) - (filledBarRect.width / 2));
						filledBarPoint.x = int((barWidth / 2) - (filledBarRect.width / 2));
						break;
						
					case FILL_HORIZONTAL_OUTSIDE_IN:
						filledBarRect.width = int(100 - percent * pxPerPercent);
						filledBarPoint.x = int((barWidth - filledBarRect.width) / 2);
						break;
						
					case FILL_VERTICAL_INSIDE_OUT:
						filledBarRect.y = int((barHeight / 2) - (filledBarRect.height / 2));
						filledBarPoint.y = int((barHeight / 2) - (filledBarRect.height / 2));
						break;
						
					case FILL_VERTICAL_OUTSIDE_IN:
						filledBarRect.height = int(100 - percent * pxPerPercent);
						filledBarPoint.y = int((barHeight- filledBarRect.height) / 2);
						break;
				}
				
				canvas.copyPixels(filledBar, filledBarRect, filledBarPoint);
				
			}
			
			pixels = canvas;
		}
		
		override public function update():void
		{
			if (parent)
			{
				if (parent[parentVariable] != value)
				{
					updateValueFromParent();
					updateBar();
				}
				
				if (fixedPosition == false)
				{
					x = parent.x + positionOffset.x;
					y = parent.y + positionOffset.y;
				}
			}
		}
		
		/**
		 * The percentage of how full the bar is (a value between 0 and 100)
		 */
		public function get percent():Number
		{
			if (value > max)
			{
				return 100;
			}
			
			return Math.floor((value / range) * 100);
		}
		
		/**
		 * Sets the percentage of how full the bar is (a value between 0 and 100). This changes FlxBar.currentValue
		 */
		public function set percent(newPct:Number):void
		{
			if (newPct >= 0 && newPct <= 100)
			{
				updateValue(pct * newPct);
				
				updateBar();
			}
		}
		
		/**
		 * Set the current value of the bar (must be between min and max range)
		 */
		public function set currentValue(newValue:Number):void
		{
			updateValue(newValue);
			
			updateBar();
		}
		
		/**
		 * The current actual value of the bar
		 */
		public function get currentValue():Number
		{
			return value;
		}
		
	}

}

================================================
FILE: src/org/flixel/plugin/photonstorm/FlxBitmapFont.as
================================================
/**
 * FlxBitmapFont
 * -- Part of the Flixel Power Tools set
 * 
 * v1.4 Changed width/height to characterWidth/Height to avoid confusion and added setFixedWidth
 * v1.3 Exposed character width / height values
 * v1.2 Updated for the Flixel 2.5 Plugin system
 * 
 * @version 1.4 - June 21st 2011
 * @link http://www.photonstorm.com
 * @author Richard Davey / Photon Storm
 * @see Requires FlxMath
*/

package org.flixel.plugin.photonstorm 
{
	import org.flixel.*;
	
	import flash.display.BitmapData;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	public class FlxBitmapFont extends FlxSprite
	{
		/**
		 * Alignment of the text when multiLine = true or a fixedWidth is set. Set to FlxBitmapFont.ALIGN_LEFT (default), FlxBitmapFont.ALIGN_RIGHT or FlxBitmapFont.ALIGN_CENTER.
		 */
		public var align:String = "left";
		
		/**
		 * If set to true all carriage-returns in text will form new lines (see align). If false the font will only contain one single line of text (the default)
		 */
		public var multiLine:Boolean = false;
		
		/**
		 * Automatically convert any text to upper case. Lots of old bitmap fonts only contain upper-case characters, so the default is true.
		 */
		public var autoUpperCase:Boolean = true;
		
		/**
		 * Adds horizontal spacing between each character of the font, in pixels. Default is 0.
		 */
		public var customSpacingX:Number = 0;
		
		/**
		 * Adds vertical spacing between each line of multi-line text, set in pixels. Default is 0.
		 */
		public var customSpacingY:uint = 0;
		
		private var _text:String;
		
		/**
		 * Align each line of multi-line text to the left.
		 */
		public static const ALIGN_LEFT:String = "left";
		
		/**
		 * Align each line of multi-line text to the right.
		 */
		public static const ALIGN_RIGHT:String = "right";
		
		/**
		 * Align each line of multi-line text in the center.
		 */
		public static const ALIGN_CENTER:String = "center";
		
		/**
		 * Text Set 1 = !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
		 */
		public static const TEXT_SET1:String = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
		
		/**
		 * Text Set 2 =  !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ
		 */
		public static const TEXT_SET2:String = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		
		/**
		 * Text Set 3 = ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 
		 */
		public static const TEXT_SET3:String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ";
		
		/**
		 * Text Set 4 = ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789
		 */
		public static const TEXT_SET4:String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789";
		
		/**
		 * Text Set 5 = ABCDEFGHIJKLMNOPQRSTUVWXYZ.,/() '!?-*:0123456789
		 */
		public static const TEXT_SET5:String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ.,/() '!?-*:0123456789";
		
		/**
		 * Text Set 6 = ABCDEFGHIJKLMNOPQRSTUVWXYZ!?:;0123456789\"(),-.' 
		 */
		public static const TEXT_SET6:String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ!?:;0123456789\"(),-.' ";
		
		/**
		 * Text Set 7 = AGMSY+:4BHNTZ!;5CIOU.?06DJPV,(17EKQW\")28FLRX-'39
		 */
		public static const TEXT_SET7:String = "AGMSY+:4BHNTZ!;5CIOU.?06DJPV,(17EKQW\")28FLRX-'39";
		
		/**
		 * Text Set 8 = 0123456789 .ABCDEFGHIJKLMNOPQRSTUVWXYZ
		 */
		public static const TEXT_SET8:String = "0123456789 .ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		
		/**
		 * Text Set 9 = ABCDEFGHIJKLMNOPQRSTUVWXYZ()-0123456789.:,'\"?!
		 */
		public static const TEXT_SET9:String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ()-0123456789.:,'\"?!";
		
		/**
		 * Text Set 10 = ABCDEFGHIJKLMNOPQRSTUVWXYZ
		 */
		public static const TEXT_SET10:String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		
		/**
		 * Text Set 11 = ABCDEFGHIJKLMNOPQRSTUVWXYZ.,\"-+!?()':;0123456789
		 */
		public static const TEXT_SET11:String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ.,\"-+!?()':;0123456789";
		
		/**
		 * Internval values. All set in the constructor. They should not be changed after that point.
		 */
		private var fontSet:BitmapData;
		private var offsetX:uint;
		private var offsetY:uint;
		public var characterWidth:uint;
		public var characterHeight:uint;
		private var characterSpacingX:uint;
		private var characterSpacingY:uint;
		private var characterPerRow:uint;
		private var grabData:Array
		private var fixedWidth:uint = 0;
		
		/**
		 * Loads 'font' and prepares it for use by future calls to .text
		 * 
		 * @param	font			The font set graphic class (as defined by your embed)
		 * @param	characterWidth	The width of each character in the font set.
		 * @param	characterHeight	The height of each character in the font set.
		 * @param	chars			The characters used in the font set, in display order. You can use the TEXT_SET consts for common font set arrangements.
		 * @param	charsPerRow		The number of characters per row in the font set.
		 * @param	xSpacing		If the characters in the font set have horizontal spacing between them set the required amount here.
		 * @param	ySpacing		If the characters in the font set have vertical spacing between them set the required amount here
		 * @param	xOffset			If the font set doesn't start at the top left of the given image, specify the X coordinate offset here.
		 * @param	yOffset			If the font set doesn't start at the top left of the given image, specify the Y coordinate offset here.
		 */
        public function FlxBitmapFont(font:Class, characterWidth:uint, characterHeight:uint, chars:String, charsPerRow:uint, xSpacing:uint = 0, ySpacing:uint = 0, xOffset:uint = 0, yOffset:uint = 0):void
        {
			//	Take a copy of the font for internal use
			fontSet = (new font).bitmapData;
			
			this.characterWidth = characterWidth;
			this.characterHeight = characterHeight;
			characterSpacingX = xSpacing;
			characterSpacingY = ySpacing;
			characterPerRow = charsPerRow;
			offsetX = xOffset;
			offsetY = yOffset;
			
			grabData = new Array();
			
			//	Now generate our rects for faster copyPixels later on
			var currentX:uint = offsetX;
			var currentY:uint = offsetY;
			var r:uint = 0;
			
			for (var c:uint = 0; c < chars.length; c++)
			{
				//	The rect is hooked to the ASCII value of the character
				grabData[chars.charCodeAt(c)] = new Rectangle(currentX, currentY, characterWidth, characterHeight);
				
				r++;
				
				if (r == characterPerRow)
				{
					r = 0;
					currentX = offsetX;
					currentY += characterHeight + characterSpacingY;
				}
				else
				{
					currentX += characterWidth + characterSpacingX;
				}
			}
        }
		
		/**
		 * Set this value to update the text in this sprite. Carriage returns are automatically stripped out if multiLine is false. Text is converted to upper case if autoUpperCase is true.
		 * 
		 * @return	void
		 */ 
		public function set text(content:String):void
		{
			var newText:String;
			
			if (autoUpperCase)
			{
				newText = content.toUpperCase();
			}
			else
			{
				newText = content;
			}
			
			// Smart update: Only change the bitmap data if the string has changed
			if (newText != _text)
			{
				_text = newText;
				
				removeUnsupportedCharacters(multiLine);
				
				buildBitmapFontText();
			}
		}
		
		/**
		 * If you need this FlxSprite to have a fixed width and custom alignment you can set the width here.<br>
		 * If text is wider than the width specified it will be cropped off.
		 * 
		 * @param	width			Width in pixels of this FlxBitmapFont. Set to zero to disable and re-enable automatic resizing.
		 * @param	lineAlignment	Align the text within this width. Set to FlxBitmapFont.ALIGN_LEFT (default), FlxBitmapFont.ALIGN_RIGHT or FlxBitmapFont.ALIGN_CENTER.
		 */
		public function setFixedWidth(width:int, lineAlignment:String = "left"):void
		{
			fixedWidth = width;
			align = lineAlignment;
		}
		
		public function get text():String
		{
			return _text;
		}
		
		/**
		 * A helper function that quickly sets lots of variables at once, and then updates the text.
		 * 
		 * @param	content				The text of this sprite
		 * @param	multiLines			Set to true if you want to support carriage-returns in the text and create a multi-line sprite instead of a single line (default is false).
		 * @param	characterSpacing	To add horizontal spacing between each character specify the amount in pixels (default 0).
		 * @param	lineSpacing			To add vertical spacing between each line of text, set the amount in pixels (default 0).
		 * @param	lineAlignment		Align each line of multi-line text. Set to FlxBitmapFont.ALIGN_LEFT (default), FlxBitmapFont.ALIGN_RIGHT or FlxBitmapFont.ALIGN_CENTER.
		 * @param	allowLowerCase		Lots of bitmap font sets only include upper-case characters, if yours needs to support lower case then set this to true.
		 */
		public function setText(content:String, multiLines:Boolean = false, characterSpacing:Number = 0, lineSpacing:uint = 0, lineAlignment:String = "left", allowLowerCase:Boolean = false):void
		{
			customSpacingX = characterSpacing;
			customSpacingY = lineSpacing;
			align = lineAlignment;
			multiLine = multiLines;
			
			if (allowLowerCase)
			{
				autoUpperCase = false;
			}
			else
			{
				autoUpperCase = true;
			}
			
			if (content.length > 0)
			{
				text = content;
			}
		}
		
		/**
		 * Updates the BitmapData of the Sprite with the text
		 * 
		 * @return	void
		 */
		private function buildBitmapFontText():void
		{
			var temp:BitmapData;
			var cx:int = 0;
			var cy:int = 0;
			
			if (multiLine)
			{
				var lines:Array = _text.split("\n");
			
				if (fixedWidth > 0)
				{
					temp = new BitmapData(fixedWidth, (lines.length * (characterHeight + customSpacingY)) - customSpacingY, true, 0xf);
				}
				else if(customSpacingX>0)
				{
					temp = new BitmapData(getLongestLine() * (characterWidth + customSpacingX), (lines.length * (characterHeight + customSpacingY)) - customSpacingY, true, 0xf);
				}else 
				{
					temp = new BitmapData(getLongestLine() * (characterWidth), (lines.length * (characterHeight + customSpacingY)) - customSpacingY, true, 0xf);
				}
				
				//	Loop through each line of text
				for (var i:uint = 0; i < lines.length; i++)
				{
					//	This line of text is held in lines[i] - need to work out the alignment
					switch (align)
					{
						case ALIGN_LEFT:
							cx = 0;
							break;
							
						case ALIGN_RIGHT:
							cx = temp.width - (lines[i].length * (characterWidth + customSpacingX));
							break;
							
						case ALIGN_CENTER:
							cx = (temp.width / 2) - ((lines[i].length * (characterWidth + customSpacingX)) / 2);
							cx += customSpacingX / 2;
							break;
					}
					
					//	Sanity checks
					if (cx < 0)
					{
						cx = 0;
					}
					
					pasteLine(temp, lines[i], cx, cy, customSpacingX);
					
					cy += characterHeight + customSpacingY;
				}
			}
			else
			{
				if (fixedWidth > 0)
				{
					temp = new BitmapData(fixedWidth, characterHeight, true, 0xf);
				}
				else if (customSpacingX>0)
				{
					temp = new BitmapData(_text.length * (characterWidth + customSpacingX), characterHeight, true, 0xf);
				}
				else 
				{
					temp = new BitmapData(_text.length * (characterWidth), characterHeight, true, 0xf);
				}
				
				switch (align)
				{
					case ALIGN_LEFT:
						cx = 0;
						break;
						
					case ALIGN_RIGHT:
						cx = temp.width - (_text.length * (characterWidth + customSpacingX));
						break;
						
					case ALIGN_CENTER:
						cx = (temp.width / 2) - ((_text.length * (characterWidth + customSpacingX)) / 2);
						cx += customSpacingX / 2;
						break;
				}
			
				pasteLine(temp, _text, cx, 0, customSpacingX);
			}
			
			pixels = temp;
		}
		
		/**
		 * Returns a single character from the font set as an FlxSprite.
		 * 
		 * @param	char	The character you wish to have returned.
		 * 
		 * @return	An <code>FlxSprite</code> containing a single character from the font set.
		 */
		public function getCharacter(char:String):FlxSprite
		{
			var output:FlxSprite = new FlxSprite();
			
			var temp:BitmapData = new BitmapData(characterWidth, characterHeight, true, 0xf);

			if (grabData[char.charCodeAt(0)] is Rectangle && char.charCodeAt(0) != 32)
			{
				temp.copyPixels(fontSet, grabData[char.charCodeAt(0)], new Point(0, 0));
			}
			
			output.pixels = temp;
			
			return output;
		}
		
		/**
		 * Returns a single character from the font set as bitmapData
		 * 
		 * @param	char	The character you wish to have returned.
		 * 
		 * @return	<code>bitmapData</code> containing a single character from the font set.
		 */
		public function getCharacterAsBitmapData(char:String):BitmapData
		{
			var temp:BitmapData = new BitmapData(characterWidth, characterHeight, true, 0xf);

			//if (grabData[char.charCodeAt(0)] is Rectangle && char.charCodeAt(0) != 32)
			if (grabData[char.charCodeAt(0)] is Rectangle)
			{
				temp.copyPixels(fontSet, grabData[char.charCodeAt(0)], new Point(0, 0));
			}
			
			return temp;
		}
		
		/**
		 * Internal function that takes a single line of text (2nd parameter) and pastes it into the BitmapData at the given coordinates.
		 * Used by getLine and getMultiLine
		 * 
		 * @param	output			The BitmapData that the text will be drawn onto
		 * @param	line			The single line of text to paste
		 * @param	x				The x coordinate
		 * @param	y
		 * @param	customSpacingX
		 */
		private function pasteLine(output:BitmapData, line:String, x:uint = 0, y:uint = 0, customSpacingX:uint = 0):void
		{
			for (var c:uint = 0; c < line.length; c++)
			{
				//	If it's a space then there is no point copying, so leave a blank space
				if (line.charAt(c) == " ")
				{
					x += characterWidth + customSpacingX;
				}
				else
				{
					//	If the character doesn't exist in the font then we don't want a blank space, we just want to skip it
					if (grabData[line.charCodeAt(c)] is Rectangle)
					{
						output.copyPixels(fontSet, grabData[line.charCodeAt(c)], new Point(x, y),null,null,true);
						
						x += characterWidth + customSpacingX;
						
						if (x > output.width)
						{
							break;
						}
					}
				}
			}
		}
		
		/**
		 * Works out the longest line of text in _text and returns its length
		 * 
		 * @return	A value
		 */
		private function getLongestLine():uint
		{
			var longestLine:uint = 0;
			
			if (_text.length > 0)
			{
				var lines:Array = _text.split("\n");
				
				for (var i:uint = 0; i < lines.length; i++)
				{
					if (lines[i].length > longestLine)
					{
						longestLine = lines[i].length;
					}
				}
			}
			
			return longestLine;
		}
		
		/**
		 * Internal helper function that removes all unsupported characters from the _text String, leaving only characters contained in the font set.
		 * 
		 * @param	stripCR		Should it strip carriage returns as well? (default = true)
		 * 
		 * @return	A clean version of the string
		 */
		private function removeUnsupportedCharacters(stripCR:Boolean = true):String
		{
			var newString:String = "";
			
			for (var c:uint = 0; c < _text.length; c++)
			{
				if (grabData[_text.charCodeAt(c)] is Rectangle || _text.charCodeAt(c) == 32 || (stripCR == false && _text.charAt(c) == "\n"))
				{
					newString = newString.concat(_text.charAt(c));
				}
			}
			
			return newString;
		}
		
	}

}

================================================
FILE: src/org/flixel/plugin/photonstorm/FlxButtonPlus.as
================================================
/**
 * FlxButtonPlus
 * -- Part of the Flixel Power Tools set
 * 
 * v1.5 Added setOnClickCallback
 * v1.4 Added scrollFactor to button and swapped to using mouseInFlxRect so buttons in scrolling worlds work
 * v1.3 Updated gradient colour values to include alpha
 * v1.2 Updated for the Flixel 2.5 Plugin system
 * 
 * @version 1.5 - August 3rd 2011
 * @link http://www.photonstorm.com
 * @author Richard Davey / Photon Storm
*/

package org.flixel.plugin.photonstorm
{
	import flash.events.MouseEvent;
	
	import org.flixel.*;
	
	/**
	 * A simple button class that calls a function when clicked by the mouse.
	 */
	public class FlxButtonPlus extends FlxGroup
	{
		static public var NORMAL:uint = 0;
		static public var HIGHLIGHT:uint = 1;
		static public var PRESSED:uint = 2;
		
		/**
		 * Set this to true if you want this button to function even while the game is paused.
		 */
		public var pauseProof:Boolean;
		/**
		 * Shows the current state of the button.
		 */
		protected var _status:uint;
		/**
		 * This function is called when the button is clicked.
		 */
		protected var _onClick:Function;
		/**
		 * Tracks whether or not the button is currently pressed.
		 */
		protected var _pressed:Boolean;
		/**
		 * Whether or not the button has initialized itself yet.
		 */
		protected var _initialized:Boolean;
		
		
		
		//	Flixel Power Tools Modification from here down
		
		public var buttonNormal:FlxExtendedSprite;
		public var buttonHighlight:FlxExtendedSprite;
		
		public var textNormal:FlxText;
		public var textHighlight:FlxText;
		
		/**
		 * The parameters passed to the _onClick function when the button is clicked
		 */
		private var onClickParams:Array;
		
		/**
		 * This function is called when the button is hovered over
		 */
		private var enterCallback:Function;
		
		/**
		 * The parameters passed to the enterCallback function when the button is hovered over
		 */
		private var enterCallbackParams:Array;
		
		/**
		 * This function is called when the mouse leaves a hovered button (but didn't click)
		 */
		private var leaveCallback:Function;
		
		/**
		 * The parameters passed to the leaveCallback function when the hovered button is left
		 */
		private var leaveCallbackParams:Array;
		
		/**
		 * The 1px thick border color that is drawn around this button
		 */
		public var borderColor:uint = 0xffffffff;
		
		/**
		 * The color gradient of the button in its in-active (not hovered over) state
		 */
		public var offColor:Array = [0xff008000, 0xff00FF00];
		
		/**
		 * The color gradient of the button in its hovered state
		 */
		public var onColor:Array = [0xff800000, 0xffff0000];
		
		private var _x:int;
		private var _y:int;
		public var width:int;
		public var height:int;
		
		/**
		 * Creates a new <code>FlxButton</code> object with a gray background
		 * and a callback function on the UI thread.
		 * 
		 * @param	X			The X position of the button.
		 * @param	Y			The Y position of the button.
		 * @param	Callback	The function to call whenever the button is clicked.
		 * @param	Params		An optional array of parameters that will be passed to the Callback function
		 * @param	Label		Text to display on the button
		 * @param	Width		The width of the button.
		 * @param	Height		The height of the button.
		 */
		public function FlxButtonPlus(X:int, Y:int, Callback:Function, Params:Array = null, Label:String = null, Width:int = 100, Height:int = 20):void
		{
			super(4);
			
			_x = X;
			_y = Y;
			width = Width;
			height = Height;
			_onClick = Callback;
			
			buttonNormal = new FlxExtendedSprite(X, Y);
			buttonNormal.makeGraphic(Width, Height, borderColor);
			buttonNormal.stamp(FlxGradient.createGradientFlxSprite(Width - 2, Height - 2, offColor), 1, 1);
			buttonNormal.solid = false;
			buttonNormal.scrollFactor.x = 0;
			buttonNormal.scrollFactor.y = 0;
			
			buttonHighlight = new FlxExtendedSprite(X, Y);
			buttonHighlight.makeGraphic(Width, Height, borderColor);
			buttonHighlight.stamp(FlxGradient.createGradientFlxSprite(Width - 2, Height - 2, onColor), 1, 1);
			buttonHighlight.solid = false;
			buttonHighlight.visible = false;
			buttonHighlight.scrollFactor.x = 0;
			buttonHighlight.scrollFactor.y = 0;
			
			
			add(buttonNormal);
			add(buttonHighlight);
			
			if (Label != null)
			{
				textNormal = new FlxText(X, Y + 3, Width, Label);
				textNormal.setFormat(null, 8, 0xffffffff, "center", 0xff000000);
				
				textHighlight = new FlxText(X, Y + 3, Width, Label);
				textHighlight.setFormat(null, 8, 0xffffffff, "center", 0xff000000);
				
				add(textNormal);
				add(textHighlight);
			}

			_status = NORMAL;
			_pressed = false;
			_initialized = false;
			pauseProof = false;
			
			if (Params)
			{
				onClickParams = Params;
			}
		}
		
		public function set x(newX:int):void
		{
			_x = newX;
			
			buttonNormal.x = _x;
			buttonHighlight.x = _x;
			
			if (textNormal)
			{
				textNormal.x = _x;
				textHighlight.x = _x;
			}
		}
		
		public function get x():int
		{
			return _x;
		}
		
		public function set y(newY:int):void
		{
			_y = newY;
			
			buttonNormal.y = _y;
			buttonHighlight.y = _y;
			
			if (textNormal)
			{
				textNormal.y = _y;
				textHighlight.y = _y;
			}
		}
		
		public function get y():int
		{
			return _y;
		}
		
		//public function set scrollFactor(value:Number):void
		//{
			//buttonNormal;
			//buttonHighlight;
			//textNormal;
			//textHighlight;
		//}
		
		override public function preUpdate():void
		{
			super.preUpdate();
			
			if (!_initialized)
			{
				if(FlxG.stage != null)
				{
					FlxG.stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
					_initialized = true;
				}
			}
		}
		
		/**
		 * If you wish to replace the two buttons (normal and hovered-over) with FlxSprites, then pass them here.<br />
		 * Note: The pixel data is extract from the passed FlxSprites and assigned locally, it doesn't actually use the sprites<br />
		 * or keep a reference to them.
		 * 
		 * @param	normal		The FlxSprite to use when the button is in-active (not hovered over)
		 * @param	highlight	The FlxSprite to use when the button is hovered-over by the mouse
		 */
		public function loadGraphic(normal:FlxSprite, highlight:FlxSprite):void
		{
			buttonNormal.pixels = normal.framePixels;
			buttonHighlight.pixels = highlight.framePixels;
			
			width = buttonNormal.width;
			height = buttonNormal.height;

			if (_pressed)
			{
				buttonNormal.visible = false;
			}
			else
			{
				buttonHighlight.visible = false;
			}
		}
		
		/**
		 * Called by the game loop automatically, handles mouseover and click detection.
		 */
		override public function update():void
		{
			updateButton(); //Basic button logic
		}
		
		/**
		 * Basic button update logic
		 */
		protected function updateButton():void
		{
			var prevStatus:uint = _status;
			
			if (FlxG.mouse.visible)
			{
				if (buttonNormal.cameras == null)
				{
					buttonNormal.cameras = FlxG.cameras;
				}
				
				var c:FlxCamera;
				var i:uint = 0;
				var l:uint = buttonNormal.cameras.length;
				var offAll:Boolean = true;
				
				while(i < l)
				{
					c = buttonNormal.cameras[i++] as FlxCamera;
					
					if (FlxMath.mouseInFlxRect(false, buttonNormal.rect))
					{
						offAll = false;
						
						if (FlxG.mouse.justPressed())
						{
							_status = PRESSED;
						}
						
						if (_status == NORMAL)
						{
							_status = HIGHLIGHT;
						}
					}
				}
				
				if (offAll)
				{
					_status = NORMAL;
				}
			}
			
			if (_status != prevStatus)
			{
				if (_status == NORMAL)
				{
					buttonNormal.visible = true;
					buttonHighlight.visible = false;
					
					if (textNormal)
					{
						textNormal.visible = true;
						textHighlight.visible = false;
					}
					
					if (leaveCallback is Function)
					{
						leaveCallback.apply(null, leaveCallbackParams);
					}
				}
				else if (_status == HIGHLIGHT)
				{
					buttonNormal.visible = false;
					buttonHighlight.visible = true;
					
					if (textNormal)
					{
						textNormal.visible = false;
						textHighlight.visible = true;
					}
					
					if (enterCallback is Function)
					{
						enterCallback.apply(null, enterCallbackParams);
					}
				}
			}
		}
		
		override public function draw():void
		{
			super.draw();
		}
		
		/**
		 * Called by the game state when state is changed (if this object belongs to the state)
		 */
		override public function destroy():void
		{
			if (FlxG.stage != null)
			{
				FlxG.stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
			}
			
			if (buttonNormal != null)
			{
				buttonNormal.destroy();
				buttonNormal = null;
			}
			
			if (buttonHighlight != null)
			{
				buttonHighlight.destroy();
				buttonHighlight = null;
			}
			
			if (textNormal != null)
			{
				textNormal.destroy();
				textNormal = null;
			}
			
			if (textHighlight != null)
			{
				textHighlight.destroy();
				textHighlight = null;
			}
			
			_onClick = null;
			enterCallback = null;
			leaveCallback = null;
			
			super.destroy();
		}
		
		/**
		 * Internal function for handling the actual callback call (for UI thread dependent calls like <code>FlxU.openURL()</code>).
		 */
		protected function onMouseUp(event:MouseEvent):void
		{
			if (exists && visible && active && (_status == PRESSED) && (_onClick != null) && (pauseProof || !FlxG.paused))
			{
				_onClick.apply(null, onClickParams);
			}
		}
		
		/**
		 * If you want to change the color of this button in its in-active (not hovered over) state, then pass a new array of color values
		 * 
		 * @param	colors
		 */
		public function updateInactiveButtonColors(colors:Array):void
		{
			offColor = colors;
			
			buttonNormal.stamp(FlxGradient.createGradientFlxSprite(width - 2, height - 2, offColor), 1, 1);
		}
		
		/**
		 * If you want to change the color of this button in its active (hovered over) state, then pass a new array of color values
		 * 
		 * @param	colors
		 */
		public function updateActiveButtonColors(colors:Array):void
		{
			onColor = colors;
			
			buttonHighlight.stamp(FlxGradient.createGradientFlxSprite(width - 2, height - 2, onColor), 1, 1);
		}
		
		/**
		 * If this button has text, set this to change the value
		 */
		public function set text(value:String):void
		{
			if (textNormal && textNormal.text != value)
			{
				textNormal.text = value;
				textHighlight.text = value;
			}
		}
		
		/**
		 * Center this button (on the X axis) Uses FlxG.width / 2 - button width / 2 to achieve this.<br />
		 * Doesn't take into consideration scrolling
		 */
		public function screenCenter():void
		{
			buttonNormal.x = (FlxG.width / 2) - (width / 2);
			buttonHighlight.x = (FlxG.width / 2) - (width / 2);
			
			if (textNormal)
			{
				textNormal.x = buttonNormal.x;
				textHighlight.x = buttonHighlight.x;
			}
		}
		
		/**
		 * Sets a callback function for when this button is rolled-over with the mouse
		 * 
		 * @param	callback	The function to call, will be called once when the mouse enters
		 * @param	params		An optional array of parameters to pass to the function
		 */
		public function setMouseOverCallback(callback:Function, params:Array = null):void
		{
			enterCallback = callback;
			
			enterCallbackParams = params;
		}
		
		/**
		 * Sets a callback function for when the mouse rolls-out of this button
		 * 
		 * @param	callback	The function to call, will be called once when the mouse leaves the button
		 * @param	params		An optional array of parameters to pass to the function
		 */
		public function setMouseOutCallback(callback:Function, params:Array = null):void
		{
			leaveCallback = callback;
			
			leaveCallbackParams = params;
		}
		
		/**
		 * Sets a callback function for when the mouse clicks on this button
		 * 
		 * @param	callback	The function to call whenever the button is clicked.
		 * @param	params		An optional array of parameters that will be passed to the Callback function
		 */
		public function setOnClickCallback(callback:Function, params:Array = null):void
		{
			_onClick = callback;
			
			if (params)
			{
				onClickParams = params;
			}
		}
		
	}
}


================================================
FILE: src/org/flixel/plugin/photonstorm/FlxCollision.as
================================================
/**
 * FlxCollision
 * -- Part of the Flixel Power Tools set
 * 
 * v1.6 Fixed bug in pixelPerfectCheck that stopped non-square rotated objects from colliding properly (thanks to joon on the flixel forums for spotting)
 * v1.5 Added createCameraWall
 * v1.4 Added pixelPerfectPointCheck()
 * v1.3 Update fixes bug where it wouldn't accurately perform collision on AutoBuffered rotated sprites, or sprites with offsets
 * v1.2 Updated for the Flixel 2.5 Plugin system
 * 
 * @version 1.6 - October 8th 2011
 * @link http://www.photonstorm.com
 * @author Richard Davey / Photon Storm
*/

package org.flixel.plugin.photonstorm 
{
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.display.BlendMode;
	
	import org.flixel.*;
	
	public class FlxCollision 
	{
		public static var debug:BitmapData = new BitmapData(1, 1, false);
		
		public static var CAMERA_WALL_OUTSIDE:uint = 0;
		public static var CAMERA_WALL_INSIDE:uint = 1;
		
		public function FlxCollision() 
		{
		}
		
		/**
		 * A Pixel Perfect Collision check between two FlxSprites.
		 * It will do a bounds check first, and if that passes it will run a pixel perfect match on the intersecting area.
		 * Works with rotated, scaled and animated sprites.
		 * 
		 * @param	contact			The first FlxSprite to test against
		 * @param	target			The second FlxSprite to test again, sprite order is irrelevant
		 * @param	alphaTolerance	The tolerance value above which alpha pixels are included. Default to 255 (must be fully opaque for collision).
		 * @param	camera			If the collision is taking place in a camera other than FlxG.camera (the default/current) then pass it here
		 * 
		 * @return	Boolean True if the sprites collide, false if not
		 */
		public static function pixelPerfectCheck(contact:FlxSprite, target:FlxSprite, alphaTolerance:int = 255, camera:FlxCamera = null):Boolean
		{
			var pointA:Point = new Point;
			var pointB:Point = new Point;
			
			if (camera)
			{
				pointA.x = contact.x - int(camera.scroll.x * contact.scrollFactor.x) - contact.offset.x;
				pointA.y = contact.y - int(camera.scroll.y * contact.scrollFactor.y) - contact.offset.y;
				
				pointB.x = target.x - int(camera.scroll.x * target.scrollFactor.x) - target.offset.x;
				pointB.y = target.y - int(camera.scroll.y * target.scrollFactor.y) - target.offset.y;
			}
			else
			{
				pointA.x = contact.x - int(FlxG.camera.scroll.x * contact.scrollFactor.x) - contact.offset.x;
				pointA.y = contact.y - int(FlxG.camera.scroll.y * contact.scrollFactor.y) - contact.offset.y;
				
				pointB.x = target.x - int(FlxG.camera.scroll.x * target.scrollFactor.x) - target.offset.x;
				pointB.y = target.y - int(FlxG.camera.scroll.y * target.scrollFactor.y) - target.offset.y;
			}
			
			var boundsA:Rectangle = new Rectangle(pointA.x, pointA.y, contact.framePixels.width, contact.framePixels.height);
			var boundsB:Rectangle = new Rectangle(pointB.x, pointB.y, target.framePixels.width, target.framePixels.height);
			
			var intersect:Rectangle = boundsA.intersection(boundsB);
			
			if (intersect.isEmpty() || intersect.width == 0 || intersect.height == 0)
			{
				return false;
			}
			
			//	Normalise the values or it'll break the BitmapData creation below
			intersect.x = Math.floor(intersect.x);
			intersect.y = Math.floor(intersect.y);
			intersect.width = Math.ceil(intersect.width);
			intersect.height = Math.ceil(intersect.height);
			
			if (intersect.isEmpty())
			{
				return false;
			}
			
			//	Thanks to Chris Underwood for helping with the translate logic :)
			
			var matrixA:Matrix = new Matrix;
			matrixA.translate(-(intersect.x - boundsA.x), -(intersect.y - boundsA.y));
			
			var matrixB:Matrix = new Matrix;
			matrixB.translate(-(intersect.x - boundsB.x), -(intersect.y - boundsB.y));
			
			var testA:BitmapData = contact.framePixels;
			var testB:BitmapData = target.framePixels;
			var overlapArea:BitmapData = new BitmapData(intersect.width, intersect.height, false);
			
			overlapArea.draw(testA, matrixA, new ColorTransform(1, 1, 1, 1, 255, -255, -255, alphaTolerance), BlendMode.NORMAL);
			overlapArea.draw(testB, matrixB, new ColorTransform(1, 1, 1, 1, 255, 255, 255, alphaTolerance), BlendMode.DIFFERENCE);
			
			//	Developers: If you'd like to see how this works, display it in your game somewhere. Or you can comment it out to save a tiny bit of performance
			debug = overlapArea;
			
			var overlap:Rectangle = overlapArea.getColorBoundsRect(0xffffffff, 0xff00ffff);
			overlap.offset(intersect.x, intersect.y);
			
			if (overlap.isEmpty())
			{
				return false;
			}
			else
			{
				return true;
			}
		}
		
		/**
		 * A Pixel Perfect Collision check between a given x/y coordinate and an FlxSprite<br>
		 * 
		 * @param	pointX			The x coordinate of the point given in local space (relative to the FlxSprite, not game world coordinates)
		 * @param	pointY			The y coordinate of the point given in local space (relative to the FlxSprite, not game world coordinates)
		 * @param	target			The FlxSprite to check the point against
		 * @param	alphaTolerance	The alpha tolerance level above which pixels are counted as colliding. Default to 255 (must be fully transparent for collision)
		 * 
		 * @return	Boolean True if the x/y point collides with the FlxSprite, false if not
		 */
		public static function pixelPerfectPointCheck(pointX:uint, pointY:uint, target:FlxSprite, alphaTolerance:int = 255):Boolean
		{
			//	Intersect check
			if (FlxMath.pointInCoordinates(pointX, pointY, target.x, target.y, target.framePixels.width, target.framePixels.height) == false)
			{
				return false;
			}
			
			//	How deep is pointX/Y within the rect?
			var test:BitmapData = target.framePixels;
			
			if (FlxColor.getAlpha(test.getPixel32(pointX - target.x, pointY - target.y)) >= alphaTolerance)
			{
				return true;
			}
			else
			{
				return false;
			}
		}
		
		/**
		 * Creates a "wall" around the given camera which can be used for FlxSprite collision
		 * 
		 * @param	camera				The FlxCamera to use for the wall bounds (can be FlxG.camera for the current one)
		 * @param	placement			CAMERA_WALL_OUTSIDE or CAMERA_WALL_INSIDE
		 * @param	thickness			The thickness of the wall in pixels
		 * @param	adjustWorldBounds	Adjust the FlxG.worldBounds based on the wall (true) or leave alone (false)
		 * 
		 * @return	FlxGroup The 4 FlxTileblocks that are created are placed into this FlxGroup which should be added to your State
		 */
		public static function createCameraWall(camera:FlxCamera, placement:uint, thickness:uint, adjustWorldBounds:Boolean = false):FlxGroup
		{
			var left:FlxTileblock;
			var right:FlxTileblock;
			var top:FlxTileblock;
			var bottom:FlxTileblock;
			
			switch (placement)
			{
				case CAMERA_WALL_OUTSIDE:
					left = new FlxTileblock(camera.x - thickness, camera.y + thickness, thickness, camera.height - (thickness * 2));
					right = new FlxTileblock(camera.x + camera.width, camera.y + thickness, thickness, camera.height - (thickness * 2));
					top = new FlxTileblock(camera.x - thickness, camera.y - thickness, camera.width + thickness * 2, thickness);
					bottom = new FlxTileblock(camera.x - thickness, camera.height, camera.width + thickness * 2, thickness);
					
					if (adjustWorldBounds)
					{
						FlxG.worldBounds = new FlxRect(camera.x - thickness, camera.y - thickness, camera.width + thickness * 2, camera.height + thickness * 2);
					}
					break;
					
				case CAMERA_WALL_INSIDE:
					left = new FlxTileblock(camera.x, camera.y + thickness, thickness, camera.height - (thickness * 2));
					right = new FlxTileblock(camera.x + camera.width - thickness, camera.y + thickness, thickness, camera.height - (thickness * 2));
					top = new FlxTileblock(camera.x, camera.y, camera.width, thickness);
					bottom = new FlxTileblock(camera.x, camera.height - thickness, camera.width, thickness);
					
					if (adjustWorldBounds)
					{
						FlxG.worldBounds = new FlxRect(camera.x, camera.y, camera.width, camera.height);
					}
					break;
			}
			
			var result:FlxGroup = new FlxGroup(4);
			
			result.add(left);
			result.add(right);
			result.add(top);
			result.add(bottom);
			
			return result;
		}
		
	}

}

================================================
FILE: src/org/flixel/plugin/photonstorm/FlxColor.as
================================================
/**
 * FlxColor
 * -- Part of the Flixel Power Tools set
 * 
 * v1.5 Added RGBtoWebString
 * v1.4 getHSVColorWheel now supports an alpha value per color
 * v1.3 Added getAlphaFloat
 * v1.2 Updated for the Flixel 2.5 Plugin system
 * 
 * @version 1.5 - August 4th 2011
 * @link http://www.photonstorm.com
 * @author Richard Davey / Photon Storm
 * @see Depends upon FlxMath
*/

package org.flixel.plugin.photonstorm
{
	import org.flixel.*;
	
	/**
	 * <code>FlxColor</code> is a set of fast color manipulation and color harmony methods.<br />
	 * Can be used for creating gradient maps or general color translation / conversion.
	 */
	public class FlxColor
	{
		public function FlxColor()
		{
		}
		
		/**
		 * Get HSV color wheel values in an array which will be 360 elements in size
		 * 
		 * @param	alpha	Alpha value for each color of the color wheel, between 0 (transparent) and 255 (opaque)
		 * 
		 * @return	Array
		 */
		public static function getHSVColorWheel(alpha:uint = 255):Array
		{
			var colors:Array = new Array();
			
			for (var c:int = 0; c <= 359; c++)
			{
				colors[c] = HSVtoRGB(c, 1.0, 1.0, alpha);
			}
			
			return colors;
		}
		
		/**
		 * Returns a Complementary Color Harmony for the given color.
		 * <p>A complementary hue is one directly opposite the color given on the color wheel</p>
		 * <p>Value returned in 0xAARRGGBB format with Alpha set to 255.</p>
		 * 
		 * @param	color The color to base the harmony on
		 * 
		 * @return 0xAARRGGBB format color value
		 */
		public static function getComplementHarmony(color:uint):uint
		{
			var hsv:Object = RGBtoHSV(color);
			
			var opposite:int = FlxMath.wrapValue(hsv.hue, 180, 359);
			
			return HSVtoRGB(opposite, 1.0, 1.0);
		}
		
		/**
		 * Returns an Analogous Color Harmony for the given color.
		 * <p>An Analogous harmony are hues adjacent to each other on the color wheel</p>
		 * <p>Values returned in 0xAARRGGBB format with Alpha set to 255.</p>
		 * 
		 * @param	color The color to base the harmony on
		 * @param	threshold Control how adjacent the colors will be (default +- 30 degrees)
		 * 
		 * @return 	Object containing 3 properties: color1 (the original color), color2 (the warmer analogous color) and color3 (the colder analogous color)
		 */
		public static function getAnalogousHarmony(color:uint, threshold:int = 30):Object
		{
			var hsv:Object = RGBtoHSV(color);
			
			if (threshold > 359 || threshold < 0)
			{
				throw Error("FlxColor Warning: Invalid threshold given to getAnalogousHarmony()");
			}
			
			var warmer:int = FlxMath.wrapValue(hsv.hue, 359 - threshold, 359);
			var colder:int = FlxMath.wrapValue(hsv.hue, threshold, 359);
			
			return { color1: color, color2: HSVtoRGB(warmer, 1.0, 1.0), color3: HSVtoRGB(colder, 1.0, 1.0), hue1: hsv.hue, hue2: warmer, hue3: colder }
		}
		
		/**
		 * Returns an Split Complement Color Harmony for the given color.
		 * <p>A Split Complement harmony are the two hues on either side of the color's Complement</p>
		 * <p>Values returned in 0xAARRGGBB format with Alpha set to 255.</p>
		 * 
		 * @param	color The color to base the harmony on
		 * @param	threshold Control how adjacent the colors will be to the Complement (default +- 30 degrees)
		 * 
		 * @return 	Object containing 3 properties: color1 (the original color), color2 (the warmer analogous color) and color3 (the colder analogous color)
		 */
		public static function getSplitComplementHarmony(color:uint, threshold:int = 30):Object
		{
			var hsv:Object = RGBtoHSV(color);
			
			if (threshold >= 359 || threshold <= 0)
			{
				throw Error("FlxColor Warning: Invalid threshold given to getSplitComplementHarmony()");
			}
			
			var opposite:int = FlxMath.wrapValue(hsv.hue, 180, 359);
			
			var warmer:int = FlxMath.wrapValue(hsv.hue, opposite - threshold, 359);
			var colder:int = FlxMath.wrapValue(hsv.hue, opposite + threshold, 359);
			
			FlxG.log("hue: " + hsv.hue + " opposite: " + opposite + " warmer: " + warmer + " colder: " + colder);
			
			//return { color1: color, color2: HSVtoRGB(warmer, 1.0, 1.0), color3: HSVtoRGB(colder, 1.0, 1.0), hue1: hsv.hue, hue2: warmer, hue3: colder }
			
			return { color1: color, color2: HSVtoRGB(warmer, hsv.saturation, hsv.value), color3: HSVtoRGB(colder, hsv.saturation, hsv.value), hue1: hsv.hue, hue2: warmer, hue3: colder }
		}
		
		/**
		 * Returns a Triadic Color Harmony for the given color.
		 * <p>A Triadic harmony are 3 hues equidistant from each other on the color wheel</p>
		 * <p>Values returned in 0xAARRGGBB format with Alpha set to 255.</p>
		 * 
		 * @param	color The color to base the harmony on
		 * 
		 * @return 	Object containing 3 properties: color1 (the original color), color2 and color3 (the equidistant colors)
		 */
		public static function getTriadicHarmony(color:uint):Object
		{
			var hsv:Object = RGBtoHSV(color);
			
			var triadic1:int = FlxMath.wrapValue(hsv.hue, 120, 359);
			var triadic2:int = FlxMath.wrapValue(triadic1, 120, 359);
			
			return { color1: color, color2: HSVtoRGB(triadic1, 1.0, 1.0), color3: HSVtoRGB(triadic2, 1.0, 1.0) }
		}
		
		/**
		 * Returns a String containing handy information about the given color including String hex value,
		 * RGB format information and HSL information. Each section starts on a newline, 3 lines in total.
		 * 
		 * @param	color A color value in the format 0xAARRGGBB
		 * 
		 * @return	String containing the 3 lines of information
		 */
		public static function getColorInfo(color:uint):String
		{
			var argb:Object = getRGB(color);
			var hsl:Object = RGBtoHSV(color);
			
			//	Hex format
			var result:String = RGBtoHexString(color) + "\n";
			
			//	RGB format
			result = result.concat("Alpha: " + argb.alpha + " Red: " + argb.red + " Green: " + argb.green + " Blue: " + argb.blue) + "\n";
			
			//	HSL info
			result = result.concat("Hue: " + hsl.hue + " Saturation: " + hsl.saturation + " Lightnes: " + hsl.lightness);
			
			return result;
		}
		
		/**
		 * Return a String representation of the color in the format 0xAARRGGBB
		 * 
		 * @param	color The color to get the String representation for
		 * 
		 * @return	A string of length 10 characters in the format 0xAARRGGBB
		 */
		public static function RGBtoHexString(color:uint):String
		{
			var argb:Object = getRGB(color);
			
			return "0x" + colorToHexString(argb.alpha) + colorToHexString(argb.red) + colorToHexString(argb.green) + colorToHexString(argb.blue);
		}
		
		/**
		 * Return a String representation of the color in the format #RRGGBB
		 * 
		 * @param	color The color to get the String representation for
		 * 
		 * @return	A string of length 10 characters in the format 0xAARRGGBB
		 */
		public static function RGBtoWebString(color:uint):String
		{
			var argb:Object = getRGB(color);
			
			return "#" + colorToHexString(argb.red) + colorToHexString(argb.green) + colorToHexString(argb.blue);
		}

		/**
		 * Return a String containing a hex representation of the given color
		 * 
		 * @param	color The color channel to get the hex value for, must be a value between 0 and 255)
		 * 
		 * @return	A string of length 2 characters, i.e. 255 = FF, 0 = 00
		 */
		public static function colorToHexString(color:uint):String
		{
			var digits:String = "0123456789ABCDEF";
			
			var lsd:Number = color % 16;
			var msd:Number = (color - lsd) / 16;
			
			var hexified:String = digits.charAt(msd) + digits.charAt(lsd);
			
			return hexified;
		}
		
		/**
		 * Convert a HSV (hue, saturation, lightness) color space value to an RGB color
		 * 
		 * @param	h 		Hue degree, between 0 and 359
		 * @param	s 		Saturation, between 0.0 (grey) and 1.0
		 * @param	v 		Value, between 0.0 (black) and 1.0
		 * @param	alpha	Alpha value to set per color (between 0 and 255)
		 * 
		 * @return 32-bit ARGB color value (0xAARRGGBB)
		 */
		public static function HSVtoRGB(h:Number, s:Number, v:Number, alpha:uint = 255):uint
		{
			var result:uint;
			
			if (s == 0.0)
			{
				result = getColor32(alpha, v * 255, v * 255, v * 255);
			}
			else
			{
				h = h / 60.0;
				var f:Number = h - int(h);
				var p:Number = v * (1.0 - s);
				var q:Number = v * (1.0 - s * f);
				var t:Number = v * (1.0 - s * (1.0 - f));
				
				switch (int(h))
				{
					case 0:
						result = getColor32(alpha, v * 255, t * 255, p * 255);
						break;
						
					case 1:
						result = getColor32(alpha, q * 255, v * 255, p * 255);
						break;
						
					case 2:
						result = getColor32(alpha, p * 255, v * 255, t * 255);
						break;
						
					case 3:
						result = getColor32(alpha, p * 255, q * 255, v * 255);
						break;
						
					case 4:
						result = getColor32(alpha, t * 255, p * 255, v * 255);
						break;
						
					case 5:
						result = getColor32(alpha, v * 255, p * 255, q * 255);
						break;
						
					default:
						FlxG.log("FlxColor Error: HSVtoRGB : Unknown color");
				}
			}
			
			return result;
		}
		
		/**
		 * Convert an RGB color value to an object containing the HSV color space values: Hue, Saturation and Lightness
		 * 
		 * @param	color In format 0xRRGGBB
		 * 
		 * @return 	Object with the properties hue (from 0 to 360), saturation (from 0 to 1.0) and lightness (from 0 to 1.0, also available under .value)
		 */
		public static function RGBtoHSV(color:uint):Object
		{
			var rgb:Object = getRGB(color);
			
			var red:Number = rgb.red / 255;
			var green:Number = rgb.green / 255;
			var blue:Number = rgb.blue / 255;
			
			var min:Number = Math.min(red, green, blue);
            var max:Number = Math.max(red, green, blue);
            var delta:Number = max - min;
            var lightness:Number = (max + min) / 2;
			var hue:Number;
			var saturation:Number;
			
            //  Grey color, no chroma
            if (delta == 0)
            {
                hue = 0;
                saturation = 0;
            }
            else
            {
                if (lightness < 0.5)
                {
                    saturation = delta / (max + min);
                }
                else
                {
                    saturation = delta / (2 - max - min);
                }
                
                var delta_r:Number = (((max - red) / 6) + (delta / 2)) / delta;
                var delta_g:Number = (((max - green) / 6) + (delta / 2)) / delta;
                var delta_b:Number = (((max - blue) / 6) + (delta / 2)) / delta;
                
                if (red == max)
                {
                    hue = delta_b - delta_g;
                }
                else if (green == max)
                {
                    hue = (1 / 3) + delta_r - delta_b;
                }
                else if (blue == max)
                {
                    hue = (2 / 3) + delta_g - delta_r;
                }
                
                if (hue < 0)
                {
                    hue += 1;
                }
                
                if (hue > 1)
                {
                    hue -= 1;
                }
            }
            
			//	Keep the value with 0 to 359
			hue *= 360;
			hue = Math.round(hue);
			
			//	Testing
			//saturation *= 100;
			//lightness *= 100;
			
            return { hue: hue, saturation: saturation, lightness: lightness, value: lightness };
		}
		
        
		
		
		
		
		
		
		public static function interpolateColor(color1:uint, color2:uint, steps:uint, currentStep:uint, alpha:uint = 255):uint
        {
			var src1:Object = getRGB(color1);
			var src2:Object = getRGB(color2);
			
            var r:uint = (((src2.red - src1.red) * currentStep) / steps) + src1.red;
            var g:uint = (((src2.green - src1.green) * currentStep) / steps) + src1.green;
            var b:uint = (((src2.blue - src1.blue) * currentStep) / steps) + src1.blue;

			return getColor32(alpha, r, g, b);
        }
		
        public static function interpolateColorWithRGB(color:uint, r2:uint, g2:uint, b2:uint, steps:uint, currentStep:uint):uint
        {
			var src:Object = getRGB(color);
			
            var r:uint = (((r2 - src.red) * currentStep) / steps) + src.red;
            var g:uint = (((g2 - src.green) * currentStep) / steps) + src.green;
            var b:uint = (((b2 - src.blue) * currentStep) / steps) + src.blue;
        
			return getColor24(r, g, b);
        }
		
        public static function interpolateRGB(r1:uint, g1:uint, b1:uint, r2:uint, g2:uint, b2:uint, steps:uint, currentStep:uint):uint
        {
            var r:uint = (((r2 - r1) * currentStep) / steps) + r1;
            var g:uint = (((g2 - g1) * currentStep) / steps) + g1;
            var b:uint = (((b2 - b1) * currentStep) / steps) + b1;
        
			return getColor24(r, g, b);
        }
		
		/**
		 * Returns a random color value between black and white
		 * <p>Set the min value to start each channel from the given offset.</p>
		 * <p>Set the max value to restrict the maximum color used per channel</p>
		 * 
		 * @param	min		The lowest value to use for the color
		 * @param	max 	The highest value to use for the color
		 * @param	alpha	The alpha value of the returning color (default 255 = fully opaque)
		 * 
		 * @return 32-bit color value with alpha
		 */
		public static function getRandomColor(min:uint = 0, max:uint = 255, alpha:uint = 255):uint
		{
			//	Sanity checks
			if (max > 255)
			{
				FlxG.log("FlxColor Warning: getRandomColor - max value too high");
				return getColor24(255, 255, 255);
			}
			
			if (min > max)
			{
				FlxG.log("FlxColor Warning: getRandomColor - min value higher than max");
				return getColor24(255, 255, 255);
			}
			
			var red:uint = min + int(Math.random() * (max - min));
			var green:uint = min + int(Math.random() * (max - min));
			var blue:uint = min + int(Math.random() * (max - min));
			
			return getColor32(alpha, red, green, blue);
		}
		
		/**
		 * Given an alpha and 3 color values this will return an integer representation of it
		 * 
		 * @param	alpha	The Alpha value (between 0 and 255)
		 * @param	red		The Red channel value (between 0 and 255)
		 * @param	green	The Green channel value (between 0 and 255)
		 * @param	blue	The Blue channel value (between 0 and 255)
		 * 
		 * @return	A native color value integer (format: 0xAARRGGBB)
		 */
		public static function getColor32(alpha:uint, red:uint, green:uint, blue:uint):uint
		{
			return alpha << 24 | red << 16 | green << 8 | blue;
		}
		
		/**
		 * Given 3 color values this will return an integer representation of it
		 * 
		 * @param	red		The Red channel value (between 0 and 255)
		 * @param	green	The Green channel value (between 0 and 255)
		 * @param	blue	The Blue channel value (between 0 and 255)
		 * 
		 * @return	A native color value integer (format: 0xRRGGBB)
		 */
		public static function getColor24(red:uint, green:uint, blue:uint):uint
		{
			return red << 16 | green << 8 | blue;
		}
		
		/**
		 * Return the component parts of a color as an Object with the properties alpha, red, green, blue
		 * 
		 * <p>Alpha will only be set if it exist in the given color (0xAARRGGBB)</p>
		 * 
		 * @param	color in RGB (0xRRGGBB) or ARGB format (0xAARRGGBB)
		 * 
		 * @return Object with properties: alpha, red, green, blue
		 */
		public static function getRGB(color:uint):Object
		{
			var alpha:uint = color >>> 24;
			var red:uint = color >> 16 & 0xFF;
			var green:uint = color >> 8 & 0xFF;
			var blue:uint = color & 0xFF;
			
			return { alpha: alpha, red: red, green: green, blue: blue };
		}
		
		/**
		 * Given a native color value (in the format 0xAARRGGBB) this will return the Alpha component, as a value between 0 and 255
		 * 
		 * @param	color	In the format 0xAARRGGBB
		 * 
		 * @return	The Alpha component of the color, will be between 0 and 255 (0 being no Alpha, 255 full Alpha)
		 */
		public static function getAlpha(color:uint):uint
		{
			return color >>> 24;
		}
		
		/**
		 * Given a native color value (in the format 0xAARRGGBB) this will return the Alpha component as a value between 0 and 1
		 * 
		 * @param	color	In the format 0xAARRGGBB
		 * 
		 * @return	The Alpha component of the color, will be between 0 and 1 (0 being no Alpha (opaque), 1 full Alpha (transparent))
		 */
		public static function getAlphaFloat(color:uint):Number
		{
			var f:uint = color >>> 24;
			
			return f / 255;
		}
		
		/**
		 * Given a native color value (in the format 0xAARRGGBB) this will return the Red component, as a value between 0 and 255
		 * 
		 * @param	color	In the format 0xAARRGGBB
		 * 
		 * @return	The Red component of the color, will be between 0 and 255 (0 being no color, 255 full Red)
		 */
		public static function getRed(color:uint):uint
		{
			return color >> 16 & 0xFF;
		}
		
		/**
		 * Given a native color value (in the format 0xAARRGGBB) this will return the Green component, as a value between 0 and 255
		 * 
		 * @param	color	In the format 0xAARRGGBB
		 * 
		 * @return	The Green component of the color, will be between 0 and 255 (0 being no color, 255 full Green)
		 */
		public static function getGreen(color:uint):uint
		{
			return color >> 8 & 0xFF;
		}
		
		/**
		 * Given a native color value (in the format 0xAARRGGBB) this will return the Blue component, as a value between 0 and 255
		 * 
		 * @param	color	In the format 0xAARRGGBB
		 * 
		 * @return	The Blue component of the color, will be between 0 and 255 (0 being no color, 255 full Blue)
		 */
		public static function getBlue(color:uint):uint
		{
			return color & 0xFF;
		}
		
	}

}

================================================
FILE: src/org/flixel/plugin/photonstorm/FlxControl.as
================================================
/**
 * FlxControl
 * -- Part of the Flixel Power Tools set
 * 
 * v1.1 Fixed and added documentation
 * v1.0 First release
 * 
 * @version 1.1 - July 21st 2011
 * @link http://www.photonstorm.com
 * @author Richard Davey / Photon Storm
*/

package org.flixel.plugin.photonstorm 
{
	import flash.utils.Dictionary;
	import org.flixel.*;

	public class FlxControl extends FlxBasic
	{
		//	Quick references
		public static var player1:FlxControlHandler;
		public static var player2:FlxControlHandler;
		public static var player3:FlxControlHandler;
		public static var player4:FlxControlHandler;
		
		//	Additional control handlers
		private static var members:Dictionary = new Dictionary(true);
		
		public function FlxControl() 
		{
		}
		
		/**
		 * Creates a new FlxControlHandler. You can have as many FlxControlHandlers as you like, but you usually only have one per player. The first handler you make
		 * will be assigned to the FlxControl.player1 var. The 2nd to FlxControl.player2 and so on for player3 and player4. Beyond this you need to keep a reference to the
		 * handler yourself.
		 * 
		 * @param	source			The FlxSprite you want this class to control. It can only control one FlxSprite at once.
		 * @param	movementType	Set to either MOVEMENT_INSTANT or MOVEMENT_ACCELERATES
		 * @param	stoppingType	Set to STOPPING_INSTANT, STOPPING_DECELERATES or STOPPING_NEVER
		 * @param	updateFacing	If true it sets the FlxSprite.facing value to the direction pressed (default false)
		 * @param	enableArrowKeys	If true it will enable all arrow keys (default) - see setCursorControl for more fine-grained control
		 * 
		 * @return	The new FlxControlHandler
		 */
		public static function create(source:FlxSprite, movementType:int, stoppingType:int, player:int = 1, updateFacing:Boolean = false, enableArrowKeys:Boolean = true):FlxControlHandler
		{
			var result:FlxControlHandler;
			
			if (player == 1)
			{
				player1 = new FlxControlHandler(source, movementType, stoppingType, updateFacing, enableArrowKeys);
				members[player1] = player1;
				result = player1;
			}
			else if (player == 2)
			{
				player2 = new FlxControlHandler(source, movementType, stoppingType, updateFacing, enableArrowKeys);
				members[player2] = player2;
				result = player2;
			}
			else if (player == 3)
			{
				player3 = new FlxControlHandler(source, movementType, stoppingType, updateFacing, enableArrowKeys);
				members[player3] = player3;
				result = player3;
			}
			else if (player == 4)
			{
				player4 = new FlxControlHandler(source, movementType, stoppingType, updateFacing, enableArrowKeys);
				members[player4] = player4;
				result = player4;
			}
			else
			{
				var newControlHandler:FlxControlHandler = new FlxControlHandler(source, movementType, stoppingType, updateFacing, enableArrowKeys);
				members[newControlHandler] = newControlHandler;
				result = newControlHandler;
			}
			
			return result;
		}
		
		/**
		 * Removes an FlxControlHandler 
		 * 
		 * @param	source	The FlxControlHandler to delete
		 * @return	Boolean	true if the FlxControlHandler was removed, otherwise false.
		 */
		public static function remove(source:FlxControlHandler):Boolean
		{
			if (members[source])
			{
				delete members[source];
				
				return true;
			}
			
			return false;
		}
		
		/**
		 * Removes all FlxControlHandlers.<br />
		 * This is called automatically if this plugin is ever destroyed.
		 */
		public static function clear():void
		{
			for each (var handler:FlxControlHandler in members)
			{
				delete members[handler];
			}
		}
		
		/**
		 * Starts updating the given FlxControlHandler, enabling keyboard actions for it. If no FlxControlHandler is given it starts updating all FlxControlHandlers currently added.<br />
		 * Updating is enabled by default, but this can be used to re-start it if you have stopped it via stop().<br />
		 * 
		 * @param	source	The FlxControlHandler to start updating on. If left as null it will start updating all handlers.
		 */
		public static function start(source:FlxControlHandler = null):void
		{
			if (source)
			{
				members[source].enabled = true;
			}
			else
			{
				for each (var handler:FlxControlHandler in members)
				{
					handler.enabled = true;
				}
			}
		}
		
		/**
		 * Stops updating the given FlxControlHandler. If no FlxControlHandler is given it stops updating all FlxControlHandlers currently added.<br />
		 * Updating is enabled by default, but this can be used to stop it, for example if you paused your game (see start() to restart it again).<br />
		 * 
		 * @param	source	The FlxControlHandler to stop updating. If left as null it will stop updating all handlers.
		 */
		public static function stop(source:FlxControlHandler = null):void
		{
			if (source)
			{
				members[source].enabled = false;
			}
			else
			{
				for each (var handler:FlxControlHandler in members)
				{
					handler.enabled = false;
				}
			}
		}
		
		/**
		 * Runs update on all currently active FlxControlHandlers
		 */
		override public function update():void
		{
			for each (var handler:FlxControlHandler in members)
			{
				if (handler.enabled == true)
				{
					handler.update();
				}
			}
		}
		
		/**
		 * Runs when this plugin is destroyed
		 */
		override public function destroy():void
		{
			clear();
		}
		
	}

}


================================================
FILE: src/org/flixel/plugin/photonstorm/FlxControlHandler.as
================================================
/**
 * FlxControlHandler
 * -- Part of the Flixel Power Tools set
 * 
 * v1.8 Added isPressedUp/Down/Left/Right handlers
 * v1.7 Modified update function so gravity is applied constantly
 * v1.6 Thrust and Reverse complete, final few rotation bugs solved. Sounds hooked in for fire, jump, walk and thrust
 * v1.5 Full support for rotation with min/max angle limits
 * v1.4 Fixed bug in runFire causing fireRate to be ignored
 * v1.3 Major refactoring and lots of new enhancements
 * v1.2 First real version deployed to dev
 * v1.1 Updated for the Flixel 2.5 Plugin system
 * 
 * @version 1.8 - August 16th 2011
 * @link http://www.photonstorm.com
 * @author Richard Davey / Photon Storm
*/

package org.flixel.plugin.photonstorm 
{
	import flash.geom.Rectangle;
	import org.flixel.*;
	import flash.utils.getTimer;
	
	/**
	 * Makes controlling an FlxSprite with the keyboard a LOT easier and quicker to set-up!<br>
	 * Sometimes it's hard to know what values to set, especially if you want gravity, jumping, sliding, etc.<br>
	 * This class helps sort that - and adds some cool extra functionality too :)
	 * 
	 * TODO
	 * ----
	 * Allow to bind Fire Button to FlxWeapon
	 * Allow to enable multiple key sets. So cursors and WASD together
	 * Hot Keys
	 * Binding of sound effects to keys (seperate from setSounds? as those are event based)
	 * If moving diagonally compensate speed parameter (times x,y velocities by 0.707 or cos/sin(45))
	 * Specify animation frames to play based on velocity
	 * Variable gravity (based on height, the higher the stronger the effect)
	 */
	public class FlxControlHandler
	{
		//	Used by the FlxControl plugin
		public var enabled:Boolean = false;
		
		private var entity:FlxSprite = null;
		
		private var bounds:Rectangle;
		
		private var up:Boolean;
		private var down:Boolean;
		private var left:Boolean;
		private var right:Boolean;
		private var fire:Boolean;
		private var altFire:Boolean;
		private var jump:Boolean;
		private var altJump:Boolean;
		private var xFacing:Boolean;
		private var yFacing:Boolean;
		private var rotateAntiClockwise:Boolean;
		private var rotateClockwise:Boolean;
		
		private var upMoveSpeed:int;
		private var downMoveSpeed:int;
		private var leftMoveSpeed:int;
		private var rightMoveSpeed:int;
		private var thrustSpeed:int;
		private var reverseSpeed:int;
		
		//	Rotation
		private var thrustEnabled:Boolean;
		private var reverseEnabled:Boolean;
		private var isRotating:Boolean;
		private var antiClockwiseRotationSpeed:Number;
		private var clockwiseRotationSpeed:Number;
		private var enforceAngleLimits:Boolean;
		private var minAngle:int;
		private var maxAngle:int;
		private var capAngularVelocity:Boolean;
		
		private var xSpeedAdjust:Number = 0;
		private var ySpeedAdjust:Number = 0;
		
		private var gravityX:int = 0;
		private var gravityY:int = 0;
		
		private var fireRate:int; 			// The ms delay between firing when the key is held down
		private var nextFireTime:int; 		// The internal time when they can next fire
		private var lastFiredTime:int; 		// The internal time of when when they last fired
		private var fireKeyMode:uint;		// The fire key mode
		private var fireCallback:Function;	// A function to call every time they fire
		
		private var jumpHeight:int; 		// The pixel height amount they jump (drag and gravity also both influence this)
		private var jumpRate:int; 			// The ms delay between jumping when the key is held down
		private var jumpKeyMode:uint;		// The jump key mode
		private var nextJumpTime:int; 		// The internal time when they can next jump
		private var lastJumpTime:int; 		// The internal time of when when they last jumped
		private var jumpFromFallTime:int; 	// A short window of opportunity for them to jump having just fallen off the edge of a surface
		private var extraSurfaceTime:int; 	// Internal time of when they last collided with a valid jumpSurface
		private var jumpSurface:uint; 		// The surfaces from FlxObject they can jump from (i.e. FlxObject.FLOOR)
		private var jumpCallback:Function;	// A function to call every time they jump
		
		private var movement:int;
		private var stopping:int;
		private var rotation:int;
		private var rotationStopping:int;
		private var capVelocity:Boolean;
		
		private var hotkeys:Array;			// TODO
		
		private var upKey:String;
		private var downKey:String;
		private var leftKey:String;
		private var rightKey:String;
		private var fireKey:String;
		private var altFireKey:String;		// TODO
		private var jumpKey:String;
		private var altJumpKey:String;		// TODO
		private var antiClockwiseKey:String;
		private var clockwiseKey:String;
		private var thrustKey:String;
		private var reverseKey:String;
		
		//	Sounds
		private var jumpSound:FlxSound = null;
		private var fireSound:FlxSound = null;
		private var walkSound:FlxSound = null;
		private var thrustSound:FlxSound = null;
		
		//	Helpers
		public var isPressedUp:Boolean = false;
		public var isPressedDown:Boolean = false;
		public var isPressedLeft:Boolean = false;
		public var isPressedRight:Boolean = false;
		
		/**
		 * The "Instant" Movement Type means the sprite will move at maximum speed instantly, and will not "accelerate" (or speed-up) before reaching that speed.
		 */
		public static const MOVEMENT_INSTANT:int = 0;
		/**
		 * The "Accelerates" Movement Type means the sprite will accelerate until it reaches maximum speed.
		 */
		public static const MOVEMENT_ACCELERATES:int = 1;
		/**
		 * The "Instant" Stopping Type means the sprite will stop immediately when no direction keys are being pressed, there will be no deceleration.
		 */
		public static const STOPPING_INSTANT:int = 0;
		/**
		 * The "Decelerates" Stopping Type means the sprite will start decelerating when no direction keys are being pressed. Deceleration continues until the speed reaches zero.
		 */
		public static const STOPPING_DECELERATES:int = 1;
		/**
		 * The "Never" Stopping Type means the sprite will never decelerate, any speed built up will be carried on and never reduce.
		 */
		public static const STOPPING_NEVER:int = 2;
		
		/**
		 * The "Instant" Movement Type means the sprite will rotate at maximum speed instantly, and will not "accelerate" (or speed-up) before reaching that speed.
		 */
		public static const ROTATION_INSTANT:int = 0;
		/**
		 * The "Accelerates" Rotaton Type means the sprite will accelerate until it reaches maximum rotation speed.
		 */
		public static const ROTATION_ACCELERATES:int = 1;
		/**
		 * The "Instant" Stopping Type means the sprite will stop rotating immediately when no rotation keys are being pressed, there will be no deceleration.
		 */
		public static const ROTATION_STOPPING_INSTANT:int = 0;
		/**
		 * The "Decelerates" Stopping Type means the sprite will start decelerating when no rotation keys are being pressed. Deceleration continues until rotation speed reaches zero.
		 */
		public static const ROTATION_STOPPING_DECELERATES:int = 1;
		/**
		 * The "Never" Stopping Type means the sprite will never decelerate, any speed built up will be carried on and never reduce.
		 */
		public static const ROTATION_STOPPING_NEVER:int = 2;
		
		/**
		 * This keymode fires for as long as the key is held down
		 */
		public static const KEYMODE_PRESSED:int = 0;
		
		/**
		 * This keyboard fires when the key has just been pressed down, and not again until it is released and re-pressed
		 */
		public static const KEYMODE_JUST_DOWN:int = 1;
		
		/**
		 * This keyboard fires only when the key has been pressed and then released again
		 */
		public static const KEYMODE_RELEASED:int = 2;
		
		/**
		 * Sets the FlxSprite to be controlled by this class, and defines the initial movement and stopping types.<br>
		 * After creating an instance of this class you should call setMovementSpeed, and one of the enableXControl functions if you need more than basic cursors.
		 * 
		 * @param	source			The FlxSprite you want this class to control. It can only control one FlxSprite at once.
		 * @param	movementType	Set to either MOVEMENT_INSTANT or MOVEMENT_ACCELERATES
		 * @param	stoppingType	Set to STOPPING_INSTANT, STOPPING_DECELERATES or STOPPING_NEVER
		 * @param	updateFacing	If true it sets the FlxSprite.facing value to the direction pressed (default false)
		 * @param	enableArrowKeys	If true it will enable all arrow keys (default) - see setCursorControl for more fine-grained control
		 * 
		 * @see		setMovementSpeed
		 */
		public function FlxControlHandler(source:FlxSprite, movementType:int, stoppingType:int, updateFacing:Boolean = false, enableArrowKeys:Boolean = true)
		{
			entity = source;
			
			movement = movementType;
			stopping = stoppingType;
			
			xFacing = updateFacing;
			yFacing = updateFacing;
			
			up = false;
			down = false;
			left = false;
			right = false;
			
			thrustEnabled = false;
			isRotating = false;
			enforceAngleLimits = false;
			rotation = ROTATION_INSTANT;
			rotationStopping = ROTATION_STOPPING_INSTANT;
			
			if (enableArrowKeys)
			{
				setCursorControl();
			}
			
			enabled = true;
		}
		
		/**
		 * Set the speed at which the sprite will move when a direction key is pressed.<br>
		 * All values are given in pixels per second. So an xSpeed of 100 would move the sprite 100 pixels in 1 second (1000ms)<br>
		 * Due to the nature of the internal Flash timer this amount is not 100% accurate and will vary above/below the desired distance by a few pixels.<br>
		 * 
		 * If you need different speed values for left/right or up/down then use setAdvancedMovementSpeed
		 * 
		 * @param	xSpeed			The speed in pixels per second in which the sprite will move/accelerate horizontally
		 * @param	ySpeed			The speed in pixels per second in which the sprite will move/accelerate vertically
		 * @param	xSpeedMax		The maximum speed in pixels per second in which the sprite can move horizontally
		 * @param	ySpeedMax		The maximum speed in pixels per second in which the sprite can move vertically
		 * @param	xDeceleration	A deceleration speed in pixels per second to apply to the sprites horizontal movement (default 0)
		 * @param	yDeceleration	A deceleration speed in pixels per second to apply to the sprites vertical movement (default 0)
		 */
		public function setMovementSpeed(xSpeed:uint, ySpeed:uint, xSpeedMax:uint, ySpeedMax:uint, xDeceleration:uint = 0, yDeceleration:uint = 0):void
		{
			leftMoveSpeed = -xSpeed;
			rightMoveSpeed = xSpeed;
			upMoveSpeed = -ySpeed;
			downMoveSpeed = ySpeed;
			
			setMaximumSpeed(xSpeedMax, ySpeedMax);
			setDeceleration(xDeceleration, yDeceleration);
		}
		
		/**
		 * If you know you need the same value for the acceleration, maximum speeds and (optionally) deceleration then this is a quick way to set them.
		 * 
		 * @param	speed			The speed in pixels per second in which the sprite will move/accelerate/decelerate
		 * @param	acceleration	If true it will set the speed value as the deceleration value (default) false will leave deceleration disabled
		 */
		public function setStandardSpeed(speed:uint, acceleration:Boolean = true):void
		{
			if (acceleration)
			{
				setMovementSpeed(speed, speed, speed, speed, speed, speed);
			}
			else
			{
				setMovementSpeed(speed, speed, speed, speed);
			}
		}
		
		/**
		 * Set the speed at which the sprite will move when a direction key is pressed.<br>
		 * All values are given in pixels per second. So an xSpeed of 100 would move the sprite 100 pixels in 1 second (1000ms)<br>
		 * Due to the nature of the internal Flash timer this amount is not 100% accurate and will vary above/below the desired distance by a few pixels.<br>
		 * 
		 * If you don't need different speed values for every direction on its own then use setMovementSpeed
		 * 
		 * @param	leftSpeed		The speed in pixels per second in which the sprite will move/accelerate to the left
		 * @param	rightSpeed		The speed in pixels per second in which the sprite will move/accelerate to the right
		 * @param	upSpeed			The speed in pixels per second in which the sprite will move/accelerate up
		 * @param	downSpeed		The speed in pixels per second in which the sprite will move/accelerate down
		 * @param	xSpeedMax		The maximum speed in pixels per second in which the sprite can move horizontally
		 * @param	ySpeedMax		The maximum speed in pixels per second in which the sprite can move vertically
		 * @param	xDeceleration	Deceleration speed in pixels per second to apply to the sprites horizontal movement (default 0)
		 * @param	yDeceleration	Deceleration speed in pixels per second to apply to the sprites vertical movement (default 0)
		 */
		public function setAdvancedMovementSpeed(leftSpeed:uint, rightSpeed:uint, upSpeed:uint, downSpeed:uint, xSpeedMax:uint, ySpeedMax:uint, xDeceleration:uint = 0, yDeceleration:uint = 0):void
		{
			leftMoveSpeed = -leftSpeed;
			rightMoveSpeed = rightSpeed;
			upMoveSpeed = -upSpeed;
			downMoveSpeed = downSpeed;
			
			setMaximumSpeed(xSpeedMax, ySpeedMax);
			setDeceleration(xDeceleration, yDeceleration);
		}
		
		/**
		 * Set the speed at which the sprite will rotate when a direction key is pressed.<br>
		 * Use this in combination with setMovementSpeed to create a Thrust like movement system.<br>
		 * All values are given in pixels per second. So an xSpeed of 100 would rotate the sprite 100 pixels in 1 second (1000ms)<br>
		 * Due to the nature of the internal Flash timer this amount is not 100% accurate and will vary above/below the desired distance by a few pixels.<br>
		 */
		public function setRotationSpeed(antiClockwiseSpeed:Number, clockwiseSpeed:Number, speedMax:Number, deceleration:Number):void
		{
			antiClockwiseRotationSpeed = -antiClockwiseSpeed;
			clockwiseRotationSpeed = clockwiseSpeed;
			
			setRotationKeys();
			setMaximumRotationSpeed(speedMax);
			setRotationDeceleration(deceleration);
		}
		
		/**
		 * 
		 * 
		 * @param	rotationType
		 * @param	stoppingType
		 */
		public function setRotationType(rotationType:int, stoppingType:int):void
		{
			rotation = rotationType;
			rotationStopping = stoppingType;
		}
		
		/**
		 * Sets the maximum speed (in pixels per second) that the FlxSprite can rotate.<br>
		 * When the FlxSprite is accelerating (movement type MOVEMENT_ACCELERATES) its speed won't increase above this value.<br>
		 * However Flixel allows the velocity of an FlxSprite to be set to anything. So if you'd like to check the value and restrain it, then enable "limitVelocity".
		 * 
		 * @param	speed			The maximum speed in pixels per second in which the sprite can rotate
		 * @param	limitVelocity	If true the angular velocity of the FlxSprite will be checked and kept within the limit. If false it can be set to anything.
		 */
		public function setMaximumRotationSpeed(speed:Number, limitVelocity:Boolean = true):void
		{
			entity.maxAngular = speed;
			
			capAngularVelocity = limitVelocity;
		}
		
		/**
		 * Deceleration is a speed (in pixels per second) that is applied to the sprite if stopping type is "DECELERATES" and if no rotation is taking place.<br>
		 * The velocity of the sprite will be reduced until it reaches zero.
		 * 
		 * @param	speed		The speed in pixels per second at which the sprite will have its angular rotation speed decreased
		 */
		public function setRotationDeceleration(speed:Number):void
		{
			entity.angularDrag = speed;
		}
		
		/**
		 * Set minimum and maximum angle limits that the Sprite won't be able to rotate beyond.<br>
		 * Values must be between -180 and +180. 0 is pointing right, 90 down, 180 left, -90 up.
		 * 
		 * @param	minimumAngle	Minimum angle below which the sprite cannot rotate (must be -180 or above)
		 * @param	maximumAngle	Maximum angle above which the sprite cannot rotate (must be 180 or below)
		 */
		public function setRotationLimits(minimumAngle:int, maximumAngle:int):void
		{
			if (minimumAngle > maximumAngle || minimumAngle < -180 || maximumAngle > 180)
			{
				throw new Error("FlxControlHandler setRotationLimits: Invalid Minimum / Maximum angle");
			}
			else
			{
				enforceAngleLimits = true;
				minAngle = minimumAngle;
				maxAngle = maximumAngle;
			}
		}
		
		/**
		 * Disables rotation limits set in place by setRotationLimits()
		 */
		public function disableRotationLimits():void
		{
			enforceAngleLimits = false;
		}
		
		/**
		 * Set which keys will rotate the sprite. The speed of rotation is set in setRotationSpeed.
		 * 
		 * @param	leftRight				Use the LEFT and RIGHT arrow keys for anti-clockwise and clockwise rotation respectively.
		 * @param	upDown					Use the UP and DOWN arrow keys for anti-clockwise and clockwise rotation respectively.
		 * @param	customAntiClockwise		The String value of your own key to use for anti-clockwise rotation (as taken from org.flixel.system.input.Keyboard)
		 * @param	customClockwise			The String value of your own key to use for clockwise rotation (as taken from org.flixel.system.input.Keyboard)
		 */
		public function setRotationKeys(leftRight:Boolean = true, upDown:Boolean = false, customAntiClockwise:String = "", customClockwise:String = ""):void
		{
			isRotating = true;
			rotateAntiClockwise = true;
			rotateClockwise = true;
			antiClockwiseKey = "LEFT";
			clockwiseKey = "RIGHT";

			if (upDown == true)
			{
				antiClockwiseKey = "UP";
				clockwiseKey = "DOWN";
			}
			
			if (customAntiClockwise != "" && customClockwise != "")
			{
				antiClockwiseKey = customAntiClockwise;
				clockwiseKey = customClockwise;
			}
		}
		
		/**
		 * If you want to enable a Thrust like motion for your sprite use this to set the speed and keys.<br>
		 * This is usually used in conjunction with Rotation and it will over-ride anything already defined in setMovementSpeed.
		 * 
		 * @param	thrustKey		Specify the key String (as taken from org.flixel.system.input.Keyboard) to use for the Thrust action
		 * @param	thrustSpeed		The speed in pixels per second which the sprite will move. Acceleration or Instant movement is determined by the Movement Type.
		 * @param	reverseKey		If you want to be able to reverse, set the key string as taken from org.flixel.system.input.Keyboard (defaults to null).
		 * @param	reverseSpeed	The speed in pixels per second which the sprite will reverse. Acceleration or Instant movement is determined by the Movement Type.
		 */
		public function setThrust(thrustKey:String, thrustSpeed:Number, reverseKey:String = null, reverseSpeed:Number = 0):void
		{
			thrustEnabled = false;
			reverseEnabled = false;
			
			if (thrustKey)
			{
				this.thrustKey = thrustKey;
				this.thrustSpeed = thrustSpeed;
				thrustEnabled = true;
			}
			
			if (reverseKey)
			{
				this.reverseKey = reverseKey;
				this.reverseSpeed = reverseSpeed;
				reverseEnabled = true;
			}
		}
		
		/**
		 * Sets the maximum speed (in pixels per second) that the FlxSprite can move. You can set the horizontal and vertical speeds independantly.<br>
		 * When the FlxSprite is accelerating (movement type MOVEMENT_ACCELERATES) its speed won't increase above this value.<br>
		 * However Flixel allows the velocity of an FlxSprite to be set to anything. So if you'd like to check the value and restrain it, then enable "limitVelocity".
		 * 
		 * @param	xSpeed			The maximum speed in pixels per second in which the sprite can move horizontally
		 * @param	ySpeed			The maximum speed in pixels per second in which the sprite can move vertically
		 * @param	limitVelocity	If true the velocity of the FlxSprite will be checked and kept within the limit. If false it can be set to anything.
		 */
		public function setMaximumSpeed(xSpeed:uint, ySpeed:uint, limitVelocity:Boolean = true):void
		{
			entity.maxVelocity.x = xSpeed;
			entity.maxVelocity.y = ySpeed;
			
			capVelocity = limitVelocity;
		}
		
		/**
		 * Deceleration is a speed (in pixels per second) that is applied to the sprite if stopping type is "DECELERATES" and if no acceleration is taking place.<br>
		 * The velocity of the sprite will be reduced until it reaches zero, and can be configured separately per axis.
		 * 
		 * @param	xSpeed		The speed in pixels per second at which the sprite will have its horizontal speed decreased
		 * @param	ySpeed		The speed in pixels per second at which the sprite will have its vertical speed decreased
		 */
		public function setDeceleration(xSpeed:uint, ySpeed:uint):void
		{
			entity.drag.x = xSpeed;
			entity.drag.y = ySpeed;
		}
		
		/**
		 * Gravity can be applied to the sprite, pulling it in any direction.<br>
		 * Gravity is given in pixels per second and is applied as acceleration. The speed the sprite reaches under gravity will never exceed the Maximum Movement Speeds set.<br>
		 * If you don't want gravity for a specific direction pass a value of zero.
		 * 
		 * @param	xForce	A positive value applies gravity dragging the sprite to the right. A negative value drags the sprite to the left. Zero disables horizontal gravity.
		 * @param	yForce	A positive value applies gravity dragging the sprite down. A negative value drags the sprite up. Zero disables vertical gravity.
		 */
		public function setGravity(xForce:int, yForce:int):void
		{
			gravityX = xForce;
			gravityY = yForce;
			
			entity.acceleration.x = gravityX;
			entity.acceleration.y = gravityY;
		}
		
		/**
		 * Switches the gravity applied to the sprite. If gravity was +400 Y (pulling them down) this will swap it to -400 Y (pulling them up)<br>
		 * To reset call flipGravity again
		 */
		public function flipGravity():void
		{
			if (gravityX && gravityX != 0)
			{
				gravityX = -gravityX;
				entity.acceleration.x = gravityX;
			}
			
			if (gravityY && gravityY != 0)
			{
				gravityY = -gravityY;
				entity.acceleration.y = gravityY;
			}
		}
		
		/**
		 * TODO
		 * 
		 * @param	xFactor
		 * @param	yFactor
		 */
		public function speedUp(xFactor:Number, yFactor:Number):void
		{
		}
		
		/**
		 * TODO
		 * 
		 * @param	xFactor
		 * @param	yFactor
		 */
		public function slowDown(xFactor:Number, yFactor:Number):void
		{
		}
		
		/**
		 * TODO
		 * 
		 * @param	xFactor
		 * @param	yFactor
		 */
		public function resetSpeeds(resetX:Boolean = true, resetY:Boolean = true):void
		{
			if (resetX)
			{
				xSpeedAdjust = 0;
			}
			
			if (resetY)
			{
				ySpeedAdjust = 0;
			}
		}
		
		/**
		 * Creates a new Hot Key, which can be bound to any function you specify (such as "swap weapon", "quit", etc)
		 * 
		 * @param	key			The key to use as the hot key (String from org.flixel.system.input.Keyboard, i.e. "SPACE", "CONTROL", "Q", etc)
		 * @param	callback	The function to call when the key is pressed
		 * @param	keymode		The keymode that will trigger the callback, either KEYMODE_PRESSED, KEYMODE_JUST_DOWN or KEYMODE_RELEASED
		 */
		public function addHotKey(key:String, callback:Function, keymode:int):void
		{
			
		}
		
		/**
		 * Removes a previously defined hot key
		 * 
		 * @param	key		The key to use as the hot key (String from org.flixel.system.input.Keyboard, i.e. "SPACE", "CONTROL", "Q", etc)
		 * @return	true if the key was found and removed, false if the key couldn't be found
		 */
		public function removeHotKey(key:String):Boolean
		{
			return true;
		}
		
		/**
		 * Set sound effects for the movement events jumping, firing, walking and thrust.
		 * 
		 * @param	jump	The FlxSound to play when the user jumps
		 * @param	fire	The FlxSound to play when the user fires
		 * @param	walk	The FlxSound to play when the user walks
		 * @param	thrust	The FlxSound to play when the user thrusts
		 */
		public function setSounds(jump:FlxSound = null, fire:FlxSound = null, walk:FlxSound = null, thrust:FlxSound = null):void
		{
			if (jump)
			{
				jumpSound = jump;
			}
			
			if (fire)
			{
				fireSound = fire;
			}
			
			if (walk)
			{
				walkSound = walk;
			}
			
			if (thrust)
			{
				thrustSound = thrust;
			}
		}
		
		/**
		 * Enable a fire button
		 * 
		 * @param	key				The key to use as the fire button (String from org.flixel.system.input.Keyboard, i.e. "SPACE", "CONTROL")
		 * @param	keymode			The FlxControlHandler KEYMODE value (KEYMODE_PRESSED, KEYMODE_JUST_DOWN, KEYMODE_RELEASED)
		 * @param	repeatDelay		Time delay in ms between which the fire action can repeat (0 means instant, 250 would allow it to fire approx. 4 times per second)
		 * @param	callback		A user defined function to call when it fires
		 * @param	altKey			Specify an alternative fire key that works AS WELL AS the primary fire key (TODO)
		 */
		public function setFireButton(key:String, keymode:uint, repeatDelay:uint, callback:Function, altKey:String = ""):void
		{
			fireKey = key;
			fireKeyMode = keymode;
			fireRate = repeatDelay;
			fireCallback = callback;
			
			if (altKey != "")
			{
				altFireKey = altKey;
			}
			
			fire = true;
		}
		
		/**
		 * Enable a jump button
		 * 
		 * @param	key				The key to use as the jump button (String from org.flixel.system.input.Keyboard, i.e. "SPACE", "CONTROL")
		 * @param	keymode			The FlxControlHandler KEYMODE value (KEYMODE_PRESSED, KEYMODE_JUST_DOWN, KEYMODE_RELEASED)
		 * @param	height			The height in pixels/sec that the Sprite will attempt to jump (gravity and acceleration can influence this actual height obtained)
		 * @param	surface			A bitwise combination of all valid surfaces the Sprite can jump off (from FlxObject, such as FlxObject.FLOOR)
		 * @param	repeatDelay		Time delay in ms between which the jumping can repeat (250 would be 4 times per second)
		 * @param	jumpFromFall	A time in ms that allows the Sprite to still jump even if it's just fallen off a platform, if still within ths time limit
		 * @param	callback		A user defined function to call when the Sprite jumps
		 * @param	altKey			Specify an alternative jump key that works AS WELL AS the primary jump key (TODO)
		 */
		public function setJumpButton(key:String, keymode:uint, height:int, surface:int, repeatDelay:uint = 250, jumpFromFall:int = 0, callback:Function = null, altKey:String = ""):void
		{
			jumpKey = key;
			jumpKeyMode = keymode;
			jumpHeight = height;
			jumpSurface = surface;
			jumpRate = repeatDelay;
			jumpFromFallTime = jumpFromFall;
			jumpCallback = callback;
			
			if (altKey != "")
			{
				altJumpKey = altKey;
			}
			
			jump = true;
		}
		
		/**
		 * Limits the sprite to only be allowed within this rectangle. If its x/y coordinates go outside it will be repositioned back inside.<br>
		 * Coordinates should be given in GAME WORLD pixel values (not screen value, although often they are the two same things)
		 * 
		 * @param	x		The x coordinate of the top left corner of the area (in game world pixels)
		 * @param	y		The y coordinate of the top left corner of the area (in game world pixels)
		 * @param	width	The width of the area (in pixels)
		 * @param	height	The height of the area (in pixels)
		 */
		public function setBounds(x:int, y:int, width:uint, height:uint):void
		{
			bounds = new Rectangle(x, y, width, height);
		}
		
		/**
		 * Clears any previously set sprite bounds
		 */
		public function removeBounds():void
		{
			bounds = null;
		}
		
		private function moveUp():Boolean
		{
			var move:Boolean = false;
			
			if (FlxG.keys.pressed(upKey))
			{
				move = true;
				isPressedUp = true;
				
				if (yFacing)
				{
					entity.facing = FlxObject.UP;
				}
				
				if (movement == MOVEMENT_INSTANT)
				{
					entity.velocity.y = upMoveSpeed;
				}
				else if (movement == MOVEMENT_ACCELERATES)
				{
					entity.acceleration.y = upMoveSpeed;
				}
				
				if (bounds && entity.y < bounds.top)
				{
					entity.y = bounds.top;
				}
			}
			
			return move;
		}
		
		private function moveDown():Boolean
		{
			var move:Boolean = false;
			
			if (FlxG.keys.pressed(downKey))
			{
				move = true;
				isPressedDown = true;
				
				if (yFacing)
				{
					entity.facing = FlxObject.DOWN;
				}
				
				if (movement == MOVEMENT_INSTANT)
				{
					entity.velocity.y = downMoveSpeed;
				}
				else if (movement == MOVEMENT_ACCELERATES)
				{
					entity.acceleration.y = downMoveSpeed;
				}
				
				if (bounds && entity.y > bounds.bottom)
				{
					entity.y = bounds.bottom;
				}
				
			}
			
			return move;
		}
		
		private function moveLeft():Boolean
		{
			var move:Boolean = false;
			
			if (FlxG.keys.pressed(leftKey))
			{
				move = true;
				isPressedLeft = true;
				
				if (xFacing)
				{
					entity.facing = FlxObject.LEFT;
				}
				
				if (movement == MOVEMENT_INSTANT)
				{
					entity.velocity.x = leftMoveSpeed;
				}
				else if (movement == MOVEMENT_ACCELERATES)
				{
					entity.acceleration.x = leftMoveSpeed;
				}
				
				if (bounds && entity.x < bounds.x)
				{
					entity.x = bounds.x;
				}
			}
			
			return move;
		}
		
		private function moveRight():Boolean
		{
			var move:Boolean = false;
			
			if (FlxG.keys.pressed(rightKey))
			{
				move = true;
				isPressedRight = true;
				
				if (xFacing)
				{
					entity.facing = FlxObject.RIGHT;
				}
				
				if (movement == MOVEMENT_INSTANT)
				{
					entity.velocity.x = rightMoveSpeed;
				}
				else if (movement == MOVEMENT_ACCELERATES)
				{
					entity.acceleration.x = rightMoveSpeed;
				}
				
				if (bounds && entity.x > bounds.right)
				{
					entity.x = bounds.right;
				}
			}
			
			return move;
		}
		
		private function moveAntiClockwise():Boolean
		{
			var move:Boolean = false;
			
			if (FlxG.keys.pressed(antiClockwiseKey))
			{
				move = true;
				
				if (rotation == ROTATION_INSTANT)
				{
					entity.angularVelocity = antiClockwiseRotationSpeed;
				}
				else if (rotation == ROTATION_ACCELERATES)
				{
					entity.angularAcceleration = antiClockwiseRotationSpeed;
				}
				
				// TODO - Not qu
Download .txt
gitextract_y9trc_t2/

├── .gitignore
├── CHANGELOG.md
├── LICENSE.md
├── README.md
├── lib/
│   ├── flixel-v2.55.swc
│   ├── neoart-flectrum-v1.0.swc
│   └── neoart-flod-v2.0.swc
└── src/
    └── org/
        └── flixel/
            └── plugin/
                └── photonstorm/
                    ├── API/
                    │   └── FlxKongregate.as
                    ├── BaseTypes/
                    │   ├── Bullet.as
                    │   └── MouseSpring.as
                    ├── FX/
                    │   ├── BaseFX.as
                    │   ├── BlurFX.as
                    │   ├── CenterSlideFX.as
                    │   ├── FloodFillFX.as
                    │   ├── GlitchFX.as
                    │   ├── PlasmaFX.as
                    │   ├── RainbowLineFX.as
                    │   ├── RevealFX.as
                    │   ├── SineWaveFX.as
                    │   ├── StarfieldFX.as
                    │   └── WowCopperFX.as
                    ├── FlxBar.as
                    ├── FlxBitmapFont.as
                    ├── FlxButtonPlus.as
                    ├── FlxCollision.as
                    ├── FlxColor.as
                    ├── FlxControl.as
                    ├── FlxControlHandler.as
                    ├── FlxCoreUtils.as
                    ├── FlxDelay.as
                    ├── FlxDisplay.as
                    ├── FlxExplode.as
                    ├── FlxExtendedSprite.as
                    ├── FlxFlectrum.as
                    ├── FlxFlod.as
                    ├── FlxGradient.as
                    ├── FlxGridOverlay.as
                    ├── FlxLinkedGroup.as
                    ├── FlxMath.as
                    ├── FlxMouseControl.as
                    ├── FlxPowerTools.as
                    ├── FlxScreenGrab.as
                    ├── FlxScrollZone.as
                    ├── FlxScrollingText.as
                    ├── FlxSpecialFX.as
                    ├── FlxVelocity.as
                    ├── FlxWeapon.as
                    └── PNGEncoder.as
Condensed preview — 48 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (436K chars).
[
  {
    "path": ".gitignore",
    "chars": 362,
    "preview": "\n### ACTIONSCRIPT ###\n\n# Build and Release Folders\nbin/\nbin-debug/\nbin-release/\n\n# Project property files\n.actionScriptP"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 2142,
    "preview": "## v1.9 Released ##\n\n#### 10th October 2011\n\nFlxBar - v1.6 Lots of bug fixes, more documentation, 2 new test cases, abil"
  },
  {
    "path": "LICENSE.md",
    "chars": 1581,
    "preview": "Simplified BSD License\n======================\n\nCopyright &copy; 2011, Richard Davey  \nAll rights reserved.\n\nRedistributi"
  },
  {
    "path": "README.md",
    "chars": 4209,
    "preview": "Flixel Power Tools\n==================\n\nVersion 1.9 (final release)\n\nNovember 28th 2013\n\nBy Richard Davey, [Photon Storm]"
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/API/FlxKongregate.as",
    "chars": 11167,
    "preview": "/**\n * FlxKongregate\n * -- Part of the Flixel Power Tools set\n * \n * v1.0 First release\n * \n * @version 1.0 - August 1st"
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/BaseTypes/Bullet.as",
    "chars": 6328,
    "preview": "/**\n * Bullet\n * -- Part of the Flixel Power Tools set\n * \n * v1.2 Removed \"id\" and used the FlxSprite ID value instead\n"
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/BaseTypes/MouseSpring.as",
    "chars": 2301,
    "preview": "package org.flixel.plugin.photonstorm.BaseTypes \n{\n\timport org.flixel.*;\n\timport org.flixel.plugin.photonstorm.FlxExtend"
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FX/BaseFX.as",
    "chars": 2458,
    "preview": "/**\n * BaseFX - Special FX Plugin\n * -- Part of the Flixel Power Tools set\n * \n * v1.1 Fixed some documentation\n * v1.0 "
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FX/BlurFX.as",
    "chars": 3474,
    "preview": "/**\n * BlurFX - Special FX Plugin\n * -- Part of the Flixel Power Tools set\n * \n * v1.0 First release\n * \n * @version 1.0"
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FX/CenterSlideFX.as",
    "chars": 8139,
    "preview": "/**\n * CenterSlideFX - Special FX Plugin\n * -- Part of the Flixel Power Tools set\n * \n * v1.1 Refactored main loop a lit"
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FX/FloodFillFX.as",
    "chars": 3546,
    "preview": "/**\n * FloodFillFX - Special FX Plugin\n * -- Part of the Flixel Power Tools set\n * \n * v1.1 Renamed - was \"DropDown\", bu"
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FX/GlitchFX.as",
    "chars": 2670,
    "preview": "/**\n * GlitchFX - Special FX Plugin\n * -- Part of the Flixel Power Tools set\n * \n * v1.2 Fixed updateFromSource github i"
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FX/PlasmaFX.as",
    "chars": 3716,
    "preview": "/**\n * PlasmaFX - Special FX Plugin\n * -- Part of the Flixel Power Tools set\n * \n * v1.4 Moved to the new Special FX Plu"
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FX/RainbowLineFX.as",
    "chars": 7637,
    "preview": "/**\n * RainbowLineFX - A Special FX Plugin\n * -- Part of the Flixel Power Tools set\n * \n * v1.0 Built into the new FlxSp"
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FX/RevealFX.as",
    "chars": 2537,
    "preview": "/**\n * RevealFX - Special FX Plugin\n * -- Part of the Flixel Power Tools set\n * \n * v1.1 Added changeGlitchValues suppor"
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FX/SineWaveFX.as",
    "chars": 13730,
    "preview": "/**\n * SineWaveFX - Special FX Plugin\n * -- Part of the Flixel Power Tools set\n * \n * v1.0 First release\n * \n * @version"
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FX/StarfieldFX.as",
    "chars": 7564,
    "preview": "/**\n * StarfieldFX - Special FX Plugin\n * -- Part of the Flixel Power Tools set\n * \n * v1.1 StarField moved to the FX Pl"
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FX/WowCopperFX.as",
    "chars": 5108,
    "preview": "/**\n * WowCopperFX - Special FX Plugin\n * -- Part of the Flixel Power Tools set\n * \n * v1.0 First release\n * \n * @versio"
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FlxBar.as",
    "chars": 19837,
    "preview": "/**\n * FlxBar\n * -- Part of the Flixel Power Tools set\n * \n * v1.6 Lots of bug fixes, more documentation, 2 new test cas"
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FlxBitmapFont.as",
    "chars": 15138,
    "preview": "/**\n * FlxBitmapFont\n * -- Part of the Flixel Power Tools set\n * \n * v1.4 Changed width/height to characterWidth/Height "
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FlxButtonPlus.as",
    "chars": 12048,
    "preview": "/**\n * FlxButtonPlus\n * -- Part of the Flixel Power Tools set\n * \n * v1.5 Added setOnClickCallback\n * v1.4 Added scrollF"
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FlxCollision.as",
    "chars": 8310,
    "preview": "/**\n * FlxCollision\n * -- Part of the Flixel Power Tools set\n * \n * v1.6 Fixed bug in pixelPerfectCheck that stopped non"
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FlxColor.as",
    "chars": 17391,
    "preview": "/**\n * FlxColor\n * -- Part of the Flixel Power Tools set\n * \n * v1.5 Added RGBtoWebString\n * v1.4 getHSVColorWheel now "
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FlxControl.as",
    "chars": 5301,
    "preview": "/**\n * FlxControl\n * -- Part of the Flixel Power Tools set\n * \n * v1.1 Fixed and added documentation\n * v1.0 First relea"
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FlxControlHandler.as",
    "chars": 44419,
    "preview": "/**\n * FlxControlHandler\n * -- Part of the Flixel Power Tools set\n * \n * v1.8 Added isPressedUp/Down/Left/Right handlers"
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FlxCoreUtils.as",
    "chars": 1423,
    "preview": "/**\n * FlxCoreUtils\n * -- Part of the Flixel Power Tools set\n * \n * v1.1 Added get mouseIndex and gameContainer\n * v1.0 "
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FlxDelay.as",
    "chars": 3711,
    "preview": "/**\n * FlxDelay\n * -- Part of the Flixel Power Tools set\n * \n * v1.4 Modified abort so it no longer runs the stop callba"
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FlxDisplay.as",
    "chars": 6472,
    "preview": "/**\n * FlxDisplay\n * -- Part of the Flixel Power Tools set\n * \n * v1.3 Added \"screenWrap\", \"alphaMask\" and \"alphaMaskFlx"
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FlxExplode.as",
    "chars": 169,
    "preview": "package org.flixel.plugin.photonstorm \n{\n\t/**\n\t * ...\n\t * @author Richard Davey\n\t */\n\tpublic class FlxExplode \n\t{\n\t\t\n\t\tp"
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FlxExtendedSprite.as",
    "chars": 24626,
    "preview": "/**\n * FlxExtendedSprite\n * -- Part of the Flixel Power Tools set\n * \n * v1.4 Added MouseSpring, plugin checks and all t"
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FlxFlectrum.as",
    "chars": 15716,
    "preview": "/**\n * Flectrum version 1.0 by Christian Corti - Jiggled around a bit to work with Flixel by Richard Davey, 29th July 20"
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FlxFlod.as",
    "chars": 6890,
    "preview": "/**\n * FlxFlod\n * -- Part of the Flixel Power Tools set\n * \n * v1.3 Added full FlxFlectrum support\n * v1.2 Updated for t"
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FlxGradient.as",
    "chars": 8250,
    "preview": "/**\n * FlxGradient\n * -- Part of the Flixel Power Tools set\n * \n * v1.6 Fixed bug where gradients with chunk sizes > 1 w"
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FlxGridOverlay.as",
    "chars": 6073,
    "preview": "/**\n * FlxGridOverlay\n * -- Part of the Flixel Power Tools set\n * \n * v1.1 Updated for the Flixel 2.5 Plugin system\n * \n"
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FlxLinkedGroup.as",
    "chars": 533,
    "preview": "package org.flixel.plugin.photonstorm \n{\n\timport org.flixel.FlxGroup;\n\timport org.flixel.FlxSprite;\n\timport flash.utils."
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FlxMath.as",
    "chars": 15799,
    "preview": "/**\n * FlxMath\n * -- Part of the Flixel Power Tools set\n * \n * v1.7 Added mouseInFlxRect\n * v1.6 Added wrapAngle, angleL"
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FlxMouseControl.as",
    "chars": 6969,
    "preview": "/**\n * FlxMouseControl\n * -- Part of the Flixel Power Tools set\n * \n * v1.2 Added Mouse Zone, Mouse Speed and refactored"
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FlxPowerTools.as",
    "chars": 514,
    "preview": "/**\n * Flixel Power Tools\n * \n * Version information and constants the other classes in this package can reference\n * \n "
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FlxScreenGrab.as",
    "chars": 5206,
    "preview": "/**\n * FlxScreenGrab\n * -- Part of the Flixel Power Tools set\n * \n * v1.0 Updated for the Flixel 2.5 Plugin system\n * \n "
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FlxScrollZone.as",
    "chars": 9439,
    "preview": "/**\n * FlxScrollZone\n * -- Part of the Flixel Power Tools set\n * \n * v1.4 Added \"clearRegion\" support for when you use S"
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FlxScrollingText.as",
    "chars": 9294,
    "preview": "/**\n * FlxScrollingText\n * -- Part of the Flixel Power Tools set\n * \n * v1.0 First version released\n * \n * @version 1.0 "
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FlxSpecialFX.as",
    "chars": 6066,
    "preview": "/**\n * FlxSpecialFX\n * -- Part of the Flixel Power Tools set\n * \n * v1.6 Added WowCopperFX\n * v1.5 Added RevealFX\n * v1."
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FlxVelocity.as",
    "chars": 14355,
    "preview": "/**\n * FlxVelocity\n * -- Part of the Flixel Power Tools set\n * \n * v1.6 New method: velocityFromFacing\n * v1.5 New metho"
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/FlxWeapon.as",
    "chars": 26436,
    "preview": "/**\n * FlxWeapon\n * -- Part of the Flixel Power Tools set\n * \n * v1.3 Added bullet elasticity and bulletsFired counter\n "
  },
  {
    "path": "src/org/flixel/plugin/photonstorm/PNGEncoder.as",
    "chars": 5053,
    "preview": "/*\n  Copyright (c) 2008, Adobe Systems Incorporated\n  All rights reserved.\n\n  Redistribution and use in source and binar"
  }
]

// ... and 3 more files (download for full content)

About this extraction

This page contains the full source code of the photonstorm/Flixel-Power-Tools GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 48 files (375.1 KB), approximately 107.7k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!