■サンプルファイル: ActionScript2Advanced.zip(Zip圧縮/約20KB)
1 定義済みクラスを拡張する − Stringクラスの例
1-1 String.replace()メソッドを追加する − ActionScript 1.0の場合
// フレームアクション
String.prototype.replace = function(from_str, to_str) {
return this.split(from_str).join(to_str);
};
trace("Microsoft".replace("s", "$"));
1-2 ダイナミックなクラス
ダイナミックなクラスでないと未宣言のメソッド/プロパティが設定できません。ActionScript 2.0ではコンパイルエラーになります。
1-3 サブクラスの作成 − ActionScript 2.0の場合(MyString.as)
// ActionScript 2.0クラス定義ファイル: MyString.as
class MyString extends String {
function MyString(_str:String) {
super(_str); // スーパークラスを初期化
}
function replace(from_str:String, to_str:String):String {
return this.split(from_str).join(to_str);
}
}
1-4 型チェックを回避する裏技
1-4-1 配列アクセス演算子[]の使用
// フレームアクション(変更部分)
trace("Microsoft"["replace"]("s", "$"));
1-4-2 intrinsicクラスに宣言追加
// intrinsic class定義ファイル: String.as
intrinsic class String
{
// [中略]
function replace(from_str:String, to_str:String):String; // 追加
static function fromCharCode():String;
var length:Number;
}
2 定義済みクラスを拡張する − Mathクラスの例
2-1 staticメソッド/プロパティ主体のクラスは別途拡張
2-1-1 staticメンバ
staticメンバはクラスに対して定義され、クラスを直接ターゲットにしてアクセスします。
2-1-2 独自に追加したクラス(MyMath.as)
// ActionScript 2.0クラス定義ファイル: MyMath.as
class MyMath {
static function randomInt(minNumber:Number, maxNumber:Number):Number {
if (maxNumber == undefined) {
maxNumber = 0;
}
if (minNumber>maxNumber) {
var temp:Number = minNumber;
minNumber = maxNumber;
maxNumber = temp;
}
return Math.floor(Math.random()*(maxNumber-minNumber+1))+minNumber;
}
}
2-2 staticメンバの継承
2-2-1 Mathクラスを継承する(MyMath.as)
// ActionScript 2.0クラス定義ファイル: MyMath.as
class MyMath extends Math {
private function MyMath() {
}
static function randomInt(minNumber:Number, maxNumber:Number):Number {
if (maxNumber == undefined) {
maxNumber = 0;
}
if (minNumber>maxNumber) {
var temp:Number = minNumber;
minNumber = maxNumber;
maxNumber = temp;
}
return Math.floor(Math.random()*(maxNumber-minNumber+1))+minNumber;
}
static function radiansToDegrees(radian:Number):Number {
return radian/PI*180; // Math.PIプロパティを継承
}
}
2-2-2 タイムラインからstaticメンバの参照が切れる
// フレームアクション
// Math; // スーパークラスへのアクセスが必要: コメントを外すと参照可能
trace(MyMath.PI); // undefined
trace(MyMath.radiansToDegrees(MyMath.PI)); // NaN
2-2-3 クラスからstaticメンバを参照することは可能(Rotation.as/Math.fla)
// ActionScript 2.0クラス定義ファイル: Rotation.as
class Rotation extends MovieClip {
var deceleration:Number = 0.2;
function onEnterFrame() {
var radian:Number = MyMath.atan2(_ymouse, _xmouse);
_rotation += MyMath.radiansToDegrees(radian)*deceleration;
}
}
3 MovieClipにリスナーを設定する − クラスパスの使用
3-1 BroadcasterMXクラス(mx.transitions.BroadcasterMX)
リスナー用の3メソッド/1プロパティを追加
・addListener()
・removeListener()
・broadcastMessage()
・_listeners
3-2 MovieClipにリスナーを設定(OnEnterFrameBeacon.as/参考: mx.transitions.OnEnterFrameBeaacon.as)
// ActionScript 2.0クラス定義ファイル: OnEnterFrameBeacon.as
import mx.transitions.BroadcasterMX;
class OnEnterFrameBeacon {
static function initialize() {
if (!_root._OnEnterFrameBeacon) {
BroadcasterMX.initialize(MovieClip);
var _mc = _root.createEmptyMovieClip("_OnEnterFrameBeacon", 9999);
_mc.onEnterFrame = function() {
MovieClip.broadcastMessage("onEnterFrame");
};
}
}
}
// テスト用(EnterFrameListener.fla)
// フレームアクション
OnEnterFrameBeacon.initialize();
var myListener:Object = new Object();
var count:Number = 0;
myListener.onEnterFrame = function() {
trace(++count);
};
MovieClip.addListener(myListener);
this.onMouseUp = function() {
MovieClip.removeListener(myListener);
};
追記■OnEnterFrameBeaconクラスにMovieClipを削除するメソッド追加(2004.6.20)
import mx.transitions.BroadcasterMX;
class OnEnterFrameBeacon {
static var initialized:Boolean = false;
static var _mc:MovieClip;
static function initialize() {
if (!initialized) {
BroadcasterMX.initialize(MovieClip);
initialized = true;
}
if (!_root._OnEnterFrameBeacon) {
_mc = _root.createEmptyMovieClip("_OnEnterFrameBeacon", 9999);
_mc.onEnterFrame = function() {
MovieClip.broadcastMessage("onEnterFrame");
};
}
}
static function clearMovieClip() {
if (initialized && !MovieClip._listeners.length && _mc) {
_mc.removeMovieClip();
return (delete _mc);
}
return false;
}
}
|
4 インタフェース
4-1 インタフェースの定義: 守るべきルール(RandomReceiver.as)
// ActionScript 2.0インタフェース定義ファイル: RandomReceiver.as
interface RandomReceiver {
function updateRandom(randomInt:Number):Void;
}
4-2 インタフェースで型指定されたオブジェクトを使用するクラス: ルールが守られることを信頼して行動する人(RandomGenerator.as)
// ActionScript 2.0クラス定義ファイル: RandomGenerator.as
class RandomGenerator {
var myTarget:RandomReceiver; // ルールを守る人
var myInteger:Number;
function RandomGenerator(integer:Number, target:RandomReceiver) {
myTarget = target;
myInteger = integer;
OnEnterFrameBeacon.initialize();
}
function startRandom() {
MovieClip.addListener(this);
}
function onEnterFrame():Void {
var randomInt:Number = MyMath.randomInt(myInteger);
myTarget.updateRandom(randomInt); // 信頼して行動
}
function stopRandom():Number {
MovieClip.removeListener(this);
return MyMath.randomInt(myInteger);
}
}
4-3 インタフェースを実装するクラス定義: ルールを守る約束をした人(NumberSlot.as/ColorChange.as)
4-3-1 数字のランダム表示
// ActionScript 2.0クラス定義ファイル: NumberSlot.as
class NumberSlot extends MovieClip implements RandomReceiver { // 約束
var my_txt:TextField;
var myRandomGenerator:RandomGenerator;
function NumberSlot() {
myRandomGenerator = new RandomGenerator(9, this);
}
function startSlot():Void {
myRandomGenerator.generateRandom();
}
function updateRandom(randomInt:Number):Void { // ルール遵守
my_txt.text = String(randomInt);
}
function stopSlot():Void {
my_txt.text = String(myRandomGenerator.stopGenerate());
}
}
4-3-2 カラーのランダム変更
// ActionScript 2.0クラス定義ファイル: ColorChange.as
class ColorChange extends MovieClip implements RandomReceiver { // 約束
var myRandomGenerator:RandomGenerator;
var my_color:Color;
function ColorChange() {
myRandomGenerator = new RandomGenerator(0xFFFFFF, this);
my_color = new Color(this);
}
function startChange() {
myRandomGenerator.generateRandom();
}
function stopChange() {
my_color.setRGB(myRandomGenerator.stopGenerate());
}
function updateRandom(randomInt:Number):Void { // ルール遵守
my_color.setRGB(randomInt);
}
}
4-4 テストサンプル(interface.fla)
// flaファイル
// MovieClip: ボタン用
// ランダム数字用slot_mcとランダム背景用background_mcを配置
// MovieClipアクション
on (release) {
if (bToggle=!bToggle) {
_root.background_mc.startChange();
_root.slot_mc.startSlot();
} else {
_root.background_mc.stopChange();
_root.slot_mc.stopSlot();
}
}