Quantumwave Interactive Inc.
  Interactive media development . Programming . Design . Consulting

Virtual Movieclip Class (aka MovieClip Inheritance or MovieClip SubClass)

A common question many Flash developers ask is: How to associate a movieclip with a class in Flash 5?

Back in June 2001, I encountered this question and looked into implementing a solution. After various versions and refinements, the result is Virtual Movieclip Class (VMC). A VMC is just like a regular class, except it is also an extension of movieclip instances.

The benefit of using Virtual Movieclip Class is to simplify movieclip behavior programming, by encapsulating the properties and methods in reusable classes.

A VMC can be thought of as the movieclip itself, as the two become one through the change in the prototype chain. It can inherit from other VMCs like regular classes; however, one does not need to instantiate from a VMC. The class properties and methods become the movieclip's properties and methods.

The mechanism behind Virtual Movieclip Class is in the function mcExtends(). By rearranging the prototype chain of a movieclip instance, a class (or classes) becomes part of the movieclip prototype chain. Instead of linking a movieclip instance to the MovieClip class, this technique links it to the VMC(s), before it is linked back to the MovieClip class. See this diagram for the states of the classes before and after applying mcExtends():

VMC class diagram

In Flash MX, Object.registerClass() is used to associate a symbol in the library to a class. This new method affects all instances of the associated symbol; unlike VMC, which affects per movieclip instance.

If you need to associate a symbol (movieclip with graphics) with more than one class, or need to dynamically associate (on-stage) movieclip instances to different classes, or wish to separate the graphics from external reusable class files, VMC is a possible solution (even in Flash MX). By reusing the same symbol graphics, one can save on file size and also bind different class behaviors to the same symbol.

Below is the source code for a simple demo in Flash 5, and then in Flash MX. The Flash 5 version uses two external library source files for providing event handling and inheritance code. A ball symbol with a linkage identifier "Ball" is in the library.

// Demo of Virtual Movieclip Class (VMC) for Flash 5
//
// Last revised: August 31, 2002
//
// Copyright 2001-2002 by Dave Yang / Quantumwave Interactive Inc.
// http://www.quantumwave.com/
//
// The magic behind VMC is mcExtends() in "daveExtends.as". It associates
// movieclip instances with a class. The original release in June 2001
// called this technique MovieClip Inheritance, and the method was called
// setClass().
//===========================================================================

#include "dave.as"
#include "daveExtends.as"

//===========================================================================

// Class Ball - basic class with two methods and an event handler
Ball = function(o) {
   // the argument object o is used for simplicity and performance;
   // it is expected as an object with the following properties:
   // x, y, r, c for x and y locations, radius, and color
   this.init(o);
};

// initialize the ball's properties: x, y locations, size, and color
Ball.prototype.init = function(o) {
   this._x = o.x;
   this._y = o.y;
   this._width = this._height = o.r*2;
   this._c = new Color(this);
   this.setColor(o.c);
};

// change the ball color
Ball.prototype.setColor = function(c) {
   this._c.setRGB(c);
};

// animate the ball by moving it to the right and wrapping around the screen
Ball.prototype.onEnterFrame = function() {
   this._x += random(15)+15;
   if (this._x > 550) {
      this._x = 0;
      this.setColor(random(16777216));
   }
};

//===========================================================================

// Class VBall - generalized vertically-moving ball
VBall = function(o) {
   // the argument object o expects the same properties of Ball
   // with an extra property v for a vertical random range
   //Object.inherits(this, Ball, o);
   this.init(o);
};

// VBall extends (inherits from) Ball
Object.extends(VBall, Ball);

// initialize the ball's properties with the superclass's init() method,
// and also initialize the VBall vertical range properties
VBall.prototype.init = function(o) {
   Object.super(this, "init", o);
   this.v = o.v;
};

// move to the right and down
VBall.prototype.onEnterFrame = function() {
   Object.super(this, "onEnterFrame");
   this._y += random(this.v)+5;
   if (this._y > 400) {
      this._y = 0;
   }
};

//===========================================================================

// Main program starts: place the balls on the stage
for (var i=1; i<=5; i++) {
   // Attach a ball and associate it with the Ball class
   var b = "ball"+i;
   this.attachMovie("Ball", b, i+100);
   this[b].mcExtends(Ball, {x:i*30, y:i*50, r:i*5, c:random(16777215)});
   // Enable onEnterFrame
   MovieClip.register(this[b]);

   // Attach a ball and associate it with the VBall class
   var b = "ball"+(i+100);
   this.attachMovie("Ball", b, i+200);
   this[b].mcExtends(VBall, {x:i*5, y:i*6, r:i*7, c:random(16777215), v:i*2});
   // Enable onEnterFrame
   MovieClip.register(this[b]);
}


Here is the MX version:

// Demo of Virtual Movieclip Class (VMC) for Flash MX
//
// Uses for VMC in Flash MX (in addition to Object.registerClass):
// - Reuse of symbols (a single symbol can be associated with different classes)
// - Dynamic binding of (on-stage) symbols to different classes
// - Separate graphics from external source code (ease of version control)
//
// Last revised: August 31, 2002
//
// Copyright 2001-2002 by Dave Yang / Quantumwave Interactive Inc.
// http://www.quantumwave.com/
//
// The magic behind VMC is mcExtends(). It associates movieclip instances
// with a class. The function extend() is used for inheritance so that
// super() works inside a constructor when using __proto__.
//===========================================================================

// To inherit the current class from a superclass
// e.g. SubClass.extend(SuperClass);
Function.prototype.extend = function(superClass) {
   this.prototype.__proto__ = superClass.prototype;
   this.prototype.__constructor__ = superClass;
   ASSetPropFlags(this.prototype, ["__constructor__"], 1);
};

// hide from for..in loops
ASSetPropFlags(Function.prototype, ["extend"], 1);

//===========================================================================

/**
 * Movieclip mcExtends (inherits from) a virtual movieclip class (VMC)
 * This is for inheriting a *movieclip* from a VMC in Flash MX
 *
 * @param superclass [function] reference of the superclass
 *
 * Usage:
 *    this.mcExtends(superClass, arg1, arg2, argN);
*/
MovieClip.prototype.mcExtends = function(superClass) {
   if (typeof superClass == "function") {
      this.__proto__ = superClass.prototype;

      if (typeof this.attachMovie == "undefined") {
         // If not a movieclip, reconstruct the link from the class to
         // MovieClip.prototype starting from the immediate inherited class
         var o = this.__proto__;

         // Check for multi-level inheritance
         var p = o.__proto__.__proto__;
         while (p != null) {
            p = p.__proto__;
            o = o.__proto__;
         }

         // Complete the prototype chain by linking back to MovieClip.prototype
         o.__proto__ = MovieClip.prototype;
      }
      // remove the superclass from arguments and pass only the parameters
      arguments.splice(0,1);
      superClass.apply(this, arguments);
   } else {
      trace("mcExtends: Incorrect superClass type or path - "+ typeof superClass);
   }
};

// hide from for..in loops
ASSetPropFlags(MovieClip.prototype, ["mcExtends"], 1);

//===========================================================================

// Class Ball - basic class with two methods and an event handler
Ball = function(x,y,r,c) {
   // x, y, r, c for x and y locations, radius, and color
   this.init(x,y,r,c);
};

// initialize the ball's properties: x, y locations, size, and color
Ball.prototype.init = function(x,y,r,c) {
   this._x = x;
   this._y = y;
   this._width = this._height = r*2;
   this._c = new Color(this);
   this.setColor(c);
};

// change the ball color
Ball.prototype.setColor = function(c) {
   this._c.setRGB(c);
};

// animate the ball by moving it to the right and wrapping around the screen
Ball.prototype.onEnterFrame = function() {
   this._x += random(15)+15;
   if (this._x > 550) {
      this._x = 0;
      this.setColor(random(16777216));
   }
};

//===========================================================================

// Class VBall - generalized vertically-moving ball
VBall = function(x,y,r,c,v) {
   this.init(x,y,r,c,v);
};

// VBall extends (inherits from) Ball
VBall.extend(Ball);

// initialize the ball's properties with the superclass's init() method,
// and also initialize the VBall vertical range property
VBall.prototype.init = function(x,y,r,c,v) {
   super.init(x,y,r,c);
   this.v = v;
};

// move to the right and down
VBall.prototype.onEnterFrame = function() {
   // invoke the superclass's onEnterFrame method
   super.onEnterFrame();
   this._y += random(this.v)+5;
   if (this._y > 400) {
      this._y = 0;
   }
};

//===========================================================================

// Main program starts: place the balls on the stage
for (var i=1; i<=5; i++) {
   // Attach a ball and associate it with the Ball class
   attachMovie("Ball", "ball"+i, i+100).mcExtends(Ball, i*30, i*50, i*5, random(16777215));
   // Attach a ball and associate it with the VBall class
   attachMovie("Ball", "ball"+(i+100), i+200).mcExtends(VBall, i*5, i*6, i*7, random(16777215), i*2);
}

Download source file: vmc_demo.zip

This zip file includes both Flash 5 and MX versions of VMC. There is also an extra 'vmc_demo_args' version supporting multiple arguments instead of an argument object. The MX version uses some of the new MX ActionScript to support multiple arguments and uses the standard 'super' keyword.

See also: Object Inheritance, Different ways to inherit & DAVE


Last updated on: Sept 1, 2002 - Copyright © 2001-2002 Dave Yang / Quantumwave Interactive Inc.

home | about | news | flash | director | shockwave | download | dave | résumé | contact

Copyright © 1995-2009 Quantumwave Interactive Inc.