AS3 quick movieclip manager class

I think one of the most important things making the difference between a programmer and a PROgrammer is the ability to write code you can’t use again and again.

Building reusable code speeds up projects and does not need that much test, since you already know what to expect from your snippets.

This is the story of Wojtek from mmankt and his AS3 quick movieclip manager class.

Wojtek gave me the permission to share it with you.

« While making my game I got to a point when I needed to add many MovieClips that should play their animation/just appear for 1 frame and get removed. But it was a boring process to write new functions and manage them without any major control. I also got many bugs that I had to workaround.

For example, when adding muzzle flash I had to manually add, specify how long should it be on screen and then remove it from stage. It all had to happen inside the enemy class. But when the enemy was killed when animation was still displaying I got an error and a static muzzle flash image on the screen. It was pretty painful managing many animations for one little thing and even with workarounds I was still getting occasional errors.

This week I decided that I needed a better way to do this. I created two classes: mcobjMang and mcobj.

The aim of this ‘manager’ is to speed up and streamline the creation process of my game/games. It’s great for beginners and basically anyone who’ll find this useful. It’s a perfect solution for use I described earlier.

You have total control of the content you add to the screen. You can dynamically manipulate MovieClips and add them quickly to the stage without worrying about what will happen with them later. You can let them update themselves, update in your own game/app loop, pause and remove all at once.

The mcobjMang class adds mcobj objects, updates them, stores and basically does everything with them. mcobj are stored in Vector and are easily manipulated, they control all movieclip behaviour and looks. »

Here it is the deeply commented code:

package {

	import flash.display.MovieClip;

	public class main extends MovieClip {
		//Welcome to this quick tutorial. using this class is very easy. let's setup in 2 easy steps:

		internal static var _main;
		/*
		 * necessary to add movieclips from any other class! 
		 * if your main class's name isn't 'main' change this variables in mcobj class 
		 * _yourmainclassname (don't know any better method - if you do, please share!)
		 */

		public var quickMC:mcobjMang = new mcobjMang();
		/*
		* initial setup. parameters: 
		* auto_update:Boolean -whether you want the manager to update all objects by itself
		* (true by default, set to false if you want to update in your main app/game loop )
		* (if not in the same folder as your main class, import this properly!)
		*/

		public function main() {
			main._main=this;//yourmainclassname._yourmainclassname = this 
			/*
			 * Ok! let's get started using the class.
			 * first we need a movieclip from our library (gfx sponsored by Intruder series)
			 */

			var my_movieclip:samplemc;
			/*
			 *Awesome! now let's create a new instance of my_movieclip,
			 * pass it to the mcobjMang, add to the stage and manipulate it to our liking.
			 * how? very easliy, we use the create function
			 */

			my_movieclip=new samplemc  ;//you have to do this everytime you want to add a new movieclip 
			quickMC.create(my_movieclip, 275, 200);

			//easy, huh? now run the code to see the outcome. 
			//you think well, i can do this manually. true, but let's take a look at all parameters:
			/*
			 * mc - the movieclip we created
			 * x (integer) - the x cooridinate on the stage
			 * y (integer) - the y cooridinate on the stage
			 * frame (integer) - on which frame you want to place the movieclip at spawn,
			 * set to 0 for random, don't know exact number of frames?
			 * no worries, it will place it on the last frame if you put in too much 
			 * animated (integer) - in what way the clip should be animated
			 * 0 - will be stopped
			 * 1 - will play and loop
			 * 2 - will go to the last frame and stop there
			 * 3 - will be removed as soon as it's on the last frame
			 * life (integer) - the time of life IN FRAMES! if you use your own time based update mutiply accordingly;
			 * set to 0 for infinite life (will be removed with everything on remove_all())
			 * rotation (integer) -  rotation of the movieclip in degrees seto to 360 for random rotation
			 * if you calculate the rotation dynamically and u get 360(like muzzle flash angle accordingly to the gun's angle),
			 * just change 360 to 0.
			 * alpha (number) - transparency of the movie clip from  0 (100% opaque) to 1 (100% visible) 
			 * sizeX (integer) - custom size on x axis in pixels, if set to 0, nothing changes (default size will remain) 
			 * sizeY (integer) - custom size on y axis in pixels, if set to 0, nothing changes (default size will remain)
			 * (both are assigned before rotation so you can calculate exact vector length and put it here(example - smoke trails strached between 2 points) )
			 * scalex (number) - custom scale on x axis, 1 = 100%, .5 = 50%, 2 = 200% etc
			 * scaley (number) - custom scale on y axis, 1 = 100%, .5 = 50%, 2 = 200% etc
			 */

			// looks complicated? no fear, it's super easy and fast to use.

			//uncomment next sections to see the class in full use

			//same mc, different aniamtion states:
			/*
			my_movieclip = new samplemc; 
			quickMC.create(my_movieclip, 105, 200, 1);
			my_movieclip = new samplemc; 
			quickMC.create(my_movieclip, 275, 200, 5);
			my_movieclip = new samplemc; 
			quickMC.create(my_movieclip, 405, 200,11);
			*/

			//same mc, different animation patterns:
			/*
			my_movieclip = new samplemc; 
			quickMC.create(my_movieclip, 105, 200, 0,0);
			my_movieclip = new samplemc; 
			quickMC.create(my_movieclip, 275, 200, 0,1);
			my_movieclip = new samplemc; 
			quickMC.create(my_movieclip, 405, 200, 1, 2);
			my_movieclip = new samplemc; 
			quickMC.create(my_movieclip, 405, 300,1,3);
			*/

			//same mc, different everything:
			/*
			my_movieclip = new samplemc; 
			quickMC.create(my_movieclip, 105, 200, 0,1,60,10);
			my_movieclip = new samplemc; 
			quickMC.create(my_movieclip, 275, 200, 0,1,90,360,.3);
			my_movieclip = new samplemc; 
			quickMC.create(my_movieclip, 405, 200, 1, 1,120,45,.7,25);
			my_movieclip = new samplemc; 
			quickMC.create(my_movieclip, 405, 300,1,1,150,0,1,0,0,.5,.5);
			*/

			//have fun and experiment with different parameters! 
			/*
			  * let's look at other functions u can use:
			  * remove_all() - remove all movie clips that u have on the stage
			  * manual_update_all() - updates all elements once, use this in your own game loop
			  * pause() - pause all elements (pauses movie clips too)
			  * unpause() - unpause all elements (unpauses movie clips too)
			  */



		}

	}//class end
}

As you can see creating, scaling, placing and animating movieclips is very easy with mcobjMang class, here listed:

package {
	import flash.display.MovieClip;
	import flash.display.DisplayObject;
	import flash.events.Event;
	/**
	 * MovieClip quick manager for use with Flash IDE (could be modified though)
	 *  simplifies some annoying operations on movieclips that should appear on the screen for a short time
	 *  great for me and begginner actionscripters 
	 *  -use, distribute, change this as you wish
	 * -if u add some new functionalities or improve some aspects of the code please let me know!
	 * -giving me credit is highly appreciated! 
	 *  -if u found this useful - please let me know!
	 *  -if u found this shitty - please let me know(or don't)!
	 * 
	 * :)
	 *  
	 * @author m_man
	 * http://mmankt.boo.pl
	 * mmankt.gmail.com
	 * ask any related questions you want
	 * note: i'm a beginner so all strange, unusual or stupid design choices may be casued by that :)
	 */
	public class mcobjMang extends MovieClip {
		internal static var _mcobjMang;
		public var nmc:mcobj;

		//public var all_mcs:Array = new Array;
		public var all_mcs:Vector. = new Vector.();

		private var paused:Boolean=false;
		private var autoupdating:Boolean;

		public function mcobjMang(auto_update:Boolean = true) {
			if (auto_update) {
				addEventListener(Event.ENTER_FRAME, update_all);
				autoupdating=true;
			}
			mcobjMang._mcobjMang=this;
		}

		public function create(mc,x:int,y:int,frame:int=1,animated:int=1,life:int=0,rotation:int=0,alpha:Number=1,sizeX:int=0,sizeY:int=0,scalex:Number=1,scaley:Number=1) {
			nmc=new mcobj  ;

			all_mcs.push(nmc);

			nmc.create(mc, x, y, frame, animated, life, rotation, alpha, sizeX, sizeY, scalex, scaley);

		}

		public function remove(mc:mcobj) {

			for (var i in all_mcs) {

				if (all_mcs[i]==mc) {
					all_mcs.splice(i, 1);
					break;

				}
			}

		}

		public function remove_all() {
			for (var i:int=all_mcs.length-1; i>=0; i--) {
				all_mcs[i].remove();
			}

		}

		private function update_all(event:Event) {
			for (var i:int=all_mcs.length-1; i>=0; i--) {
				all_mcs[i].update();
			}
		}

		public function manual_update_all() {
			for (var i:int=all_mcs.length-1; i>=0; i--) {
				all_mcs[i].update();
			}
		}

		public function pause() {
			if (autoupdating) {
				removeEventListener(Event.ENTER_FRAME, update_all);
			}
			for (var i:int=all_mcs.length-1; i>=0; i--) {
				all_mcs[i].pause();
			}
		}

		public function unpause() {
			if (autoupdating) {
				addEventListener(Event.ENTER_FRAME, update_all);
			}
			for (var i:int=all_mcs.length-1; i>=0; i--) {
				all_mcs[i].unpause();
			}
		}
	}
}

while mcobj does the dirty work:

package {
	import flash.display.MovieClip;
	import flash.events.Event;

	/**
	 * MovieClip quick manager
	 *  simplifies some annoying operations on movieclips that should appear on the screen for a short time
	 * 
	 *  -use, distribute, change this as you wish
	 * -if u add some new functionalities or improve some aspects of the code please let me know!
	 * -giving me credit is highly appreciated! 
	 *  -if u found this useful - please let me know!
	 *  -if u found this shitty - please let me know(or don't)!
	 * 
	 * :)
	 *  
	 * @author m_man
	 * http://mmankt.boo.pl
	 * mmankt.gmail.com
	 * ask any related questions you want
	 * note: i'm a beginner so all strange, unusual or stupid design choices may be casued by that :)
	 */

	public class mcobj extends MovieClip {
		private var maxlifetime:int=0;
		private var lifetime:int=0;
		private var stoplastframe:Boolean;
		private var theclip;
		private var immortal:Boolean=false;
		private var removeatlastframe:Boolean=false;
		private var anim_type:int;

		public function create(mc,x:int,y:int,frame:int,animated:int,life:int,rotation:int,alpha:Number,sizeX:int,sizeY:int,scalex:Number,scaley:Number) {
			theclip=mc;

			mc.x=x;
			mc.y=y;

			maxlifetime=life;

			if (frame==0) {
				mc.gotoAndStop(Math.round(Math.random() * mc.totalFrames));
			} else if (frame > mc.totalFrames) {
				mc.gotoAndStop(mc.totalFrames);
			} else {
				mc.gotoAndStop(frame);
			}

			if (Math.abs(sizeX)>0) {
				mc.width=sizeX;
			}
			if (Math.abs(sizeY)>0) {
				mc.height=sizeY;
			}

			mc.scaleX=scalex;
			mc.scaleY=scaley;

			if (rotation==360) {
				mc.rotation=Math.random()*360;
			} else {
				mc.rotation=rotation;
			}

			mc.alpha=alpha;

			if (animated>=1) {
				mc.play();
			}
			if (animated==2) {
				stoplastframe=true;
			}
			if (animated==3) {
				removeatlastframe=true;
				maxlifetime=0;
			}
			anim_type=animated;


			main._main.addChild(mc);

			//addEventListener(Event.ENTER_FRAME, update);
		}

		public function update() {
			if (stoplastframe) {
				if (theclip.currentFrame==theclip.totalFrames) {
					theclip.stop();
				}
			}

			if (removeatlastframe) {
				if (theclip.currentFrame==theclip.totalFrames) {
					remove();
				}
			}

			if (lifetime>=maxlifetime&&maxlifetime>0) {
				remove();
			}

			lifetime++;
		}

		public function remove() {
			main._main.removeChild(theclip);

			//main._main.quickMC.remove(this);
			mcobjMang._mcobjMang.remove(this);

			//removeEventListener(Event.ENTER_FRAME, update);
		}

		public function pause() {
			theclip.stop();
		}

		public function unpause() {
			if (anim_type!=0) {
				theclip.play();
			}
		}



	}
}

Download the source code and experiment

Get the most popular Phaser 3 book

Through 202 pages, 32 source code examples and an Android Studio project you will learn how to build cross platform HTML5 games and create a complete game along the way.

Get the book

214 GAME PROTOTYPES EXPLAINED WITH SOURCE CODE
// 1+2=3
// 100 rounds
// 10000000
// 2 Cars
// 2048
// A Blocky Christmas
// A Jumping Block
// A Life of Logic
// Angry Birds
// Angry Birds Space
// Artillery
// Astro-PANIC!
// Avoider
// Back to Square One
// Ball Game
// Ball vs Ball
// Ball: Revamped
// Balloon Invasion
// BallPusher
// Ballz
// Bar Balance
// Bejeweled
// Biggification
// Block it
// Blockage
// Bloons
// Boids
// Bombuzal
// Boom Dots
// Bouncing Ball
// Bouncing Ball 2
// Bouncy Light
// BoxHead
// Breakout
// Bricks
// Bubble Chaos
// Bubbles 2
// Card Game
// Castle Ramble
// Chronotron
// Circle Chain
// Circle Path
// Circle Race
// Circular endless runner
// Cirplosion
// CLOCKS - The Game
// Color Hit
// Color Jump
// ColorFill
// Columns
// Concentration
// Crossy Road
// Crush the Castle
// Cube Jump
// CubesOut
// Dash N Blast
// Dashy Panda
// Deflection
// Diamond Digger Saga
// Don't touch the spikes
// Dots
// Down The Mountain
// Drag and Match
// Draw Game
// Drop Wizard
// DROP'd
// Dudeski
// Dungeon Raid
// Educational Game
// Elasticity
// Endless Runner
// Erase Box
// Eskiv
// Farm Heroes Saga
// Filler
// Flappy Bird
// Fling
// Flipping Legend
// Floaty Light
// Fuse Ballz
// GearTaker
// Gem Sweeper
// Globe
// Goat Rider
// Gold Miner
// Grindstone
// GuessNext
// Helicopter
// Hero Emblems
// Hero Slide
// Hexagonal Tiles
// HookPod
// Hop Hop Hop Underwater
// Horizontal Endless Runner
// Hundreds
// Hungry Hero
// Hurry it's Christmas
// InkTd
// Iromeku
// Jet Set Willy
// Jigsaw Game
// Knife Hit
// Knightfall
// Legends of Runeterra
// Lep's World
// Line Rider
// Lumines
// Magick
// MagOrMin
// Mass Attack
// Math Game
// Maze
// Meeblings
// Memdot
// Metro Siberia Underground
// Mike Dangers
// Mikey Hooks
// Nano War
// Nodes
// o:anquan
// One Button Game
// One Tap RPG
// Ononmin
// Pacco
// Perfect Square!
// Perfectionism
// Phyballs
// Pixel Purge
// PixelField
// Planet Revenge
// Plants Vs Zombies
// Platform
// Platform game
// Plus+Plus
// Pocket Snap
// Poker
// Pool
// Pop the Lock
// Pop to Save
// Poux
// Pudi
// Pumpkin Story
// Puppet Bird
// Pyramids of Ra
// qomp
// Quick Switch
// Racing
// Radical
// Rebuild Chile
// Renju
// Rise Above
// Risky Road
// Roguelike
// Roly Poly
// Run Around
// Rush Hour
// SameGame
// SamePhysics
// Save the Totem
// Security
// Serious Scramblers
// Shrink it
// Sling
// Slingy
// Snowflakes
// Sokoban
// Space Checkers
// Space is Key
// Spellfall
// Spinny Gun
// Splitter
// Spring Ninja
// Sproing
// Stabilize!
// Stack
// Stick Hero
// String Avoider
// Stringy
// Sudoku
// Super Mario Bros
// Surfingers
// Survival Horror
// Talesworth Adventure
// Tetris
// The Impossible Line
// The Moops - Combos of Joy
// The Next Arrow
// Threes
// Tic Tac Toe
// Timberman
// Tiny Wings
// Tipsy Tower
// Toony
// Totem Destroyer
// Tower Defense
// Trick Shot
// Tunnelball
// Turn
// Turnellio
// TwinSpin
// vvvvvv
// Warp Shift
// Way of an Idea
// Whack a Creep
// Wheel of Fortune
// Where's my Water
// Wish Upon a Star
// Word Game
// Wordle
// Worms
// Yanga
// Yeah Bunny
// Zhed
// zNumbers