書き物

技術とか作った物の話とか愚痴文句感想など

アニメーション機能が付きました。「フレームクラス」

前のフレームクラスの時に、

これ、上手いことしたらアニメーションとかもできるかもしれません。

と書きましたが、そろそろアニメーションも使いそうなので考えてみました。

前フレームクラスを改良しています。

/**
* ・フレームクラス
*/
package lib.utils
{
import flash.display.DisplayObjectContainer;
import flash.display.DisplayObject;
import flash.display.Shape;
public class Frame
{
// --------------------------------------------------------------------------------------
// --プロパティ    -----------------------------------------------------------------------------
private var _objDOC         :DisplayObjectContainer;    // オブジェクト格納用オブジェクト
private var _labelList      :Array;                     // ラベルリスト
private var _objList        :Object;                    // オブジェクトリスト
private var _currentObj     :DisplayObject;             // 現在のディスプレイオブジェクト
private var _currentFrame   :uint;                      // 現在のフレーム番号
private var _currentLabel   :String;                    // 現在のラベル
private var _playFlg        :Boolean;                   // 再生中ならtrue
private var _labelNum       :uint;                      // 一意のラベル名設定用番号
// --------------------------------------------------------------------------------------
// --初期処理   -----------------------------------------------------------------------------
/**
* ■コンストラクタ
*
* @param objDOC オブジェクト格納用オブジェクト
*/
public function Frame(objDOC:DisplayObjectContainer)
{
_labelList      = new Array();  // フレームラベルリスト
_objList        = new Object(); // オブジェクトスプライトリストを生成
_objDOC         = objDOC;       // オブジェクト格納用オブジェクト
_currentFrame   = 0;            // 現在のフレーム番号はとりあえず0
_currentLabel   = "";           // 現在のラベルはとりあえず空
_playFlg        = false;        // アニメーション停止としておく
// とりあえずシェイプを登録しておく
_currentObj     = new Shape();
objDOC.addChild(_currentObj);
_labelNum       = 0;            // ラベル名設定用番号
}
// --------------------------------------------------------------------------------------
// --通常メソッド -------------------------------------------------------------------------
/**
* ■ディスプレイオブジェクト登録メソッド
*
* @param obj    登録するディスプレイオブジェクト
* @param label  登録するディスプレイオブジェクトを指すフレームラベル
*/
public function setFrame(obj:DisplayObject, label:String = ""):DisplayObject
{
// ラベルが指定されていないなら
if (label == "")
{
label = "noName0000" + _labelNum;   // 一意のラベルを生成
++_labelNum;                        // ラベル生成用番号をアップ
}
_labelList.push(label);                 // ラベルを登録
_objList[label] = obj;                  // オブジェクトを登録
return obj;     // 登録したオブジェクトを返す
}
/**
* ■ディスプレイオブジェクトフレーム番号指定登録メソッド
*
* @param obj    登録するディスプレイオブジェクト
* @param num    登録するディスプレイオブジェクトのフレーム番号
* @param label  登録するディスプレイオブジェクトを指すフレームラベル
*/
public function setFrameAt(obj:DisplayObject, num:uint, label:String = ""):DisplayObject
{
// ラベルが指定されていないなら
if (label == "")
{
label = "noName0000" + _labelNum;   // 一意のラベルを生成
++_labelNum;                        // ラベル生成用番号をアップ
}
_labelList.splice(num - 1, 0, label);   // ラベルを登録
_objList[label] = obj;                  // オブジェクトを登録
return obj;     // 登録したオブジェクトを返す
}
/**
* ■フレーム移動共通メソッド
*
* @param frame 移動するフレーム
*/
private function gotoAndAction(frame:*):void
{
var label:String = "";  // ラベル
// 指定されたフレームの型がuintなら
if (frame is uint)
{
label           = _labelList[frame - 1];    // ラベルリストからラベルを取得
_currentFrame   = frame;                    // 現在のフレームを設定
}
// 指定されたフレームが文字列なら
else if (frame is String)
{
label           = frame;                // ラベルとして使う
_currentFrame   = getFrameNum(frame);   // 現在のフレームを設定
}
// それ以外の型なら
else
{
return; // 終了
}
// 対象フレームのディスプレイオブジェクト
var obj:DisplayObject = _objList[label];
// 現在のフレームが指定したラベルのフレームと同じでないなら
if (_currentLabel != label)
{
// 対象フレームのディスプレイオブジェクトが存在するなら
if (obj != null)
{
// 表示切替
_objDOC.addChild(obj);
_objDOC.removeChild(_currentObj);
_currentObj = obj;
_currentLabel = label;
}
}
}
/**
* ■フレーム番号取得メソッド
*
* @param label 対象のラベル
*/
private function getFrameNum(label:String):uint
{
var list:Array  = _labelList;       // ラベルリスト
var l:uint      = list.length;      // ラベルリストの長さ
// ラベルリストの探索
for (var i:uint = 0; i < l; ++i)
{
// 指定したラベルが登録されているラベルと同じなら
if (label == list[i])
{
return i + 1;   // 番号を返す
}
}
return null;    // 登録されていないラベルを指定したならnullを返す
}
// ■再生開始メソッド
public function play():void
{
_playFlg = true;    // 再生
}
// ■再生停止メソッド
public function stop():void
{
_playFlg = false;   // 停止
}
/**
* ■フレーム移動&停止メソッド
*
* @param frame 移動するフレーム
*/
public function gotoAndStop(frame:*):void
{
gotoAndAction(frame);   // フレーム移動
stop();                 // 再生停止
}
/**
* ■フレーム移動&再生メソッド
*
* @param frame 移動するフレーム
*/
public function gotoAndPlay(frame:*):void
{
gotoAndAction(frame);   // フレーム移動
play();                 // 再生開始
}
// ■アニメーションメソッド
public function animate():void
{
// 再生中なら
if (_playFlg)
{
var f:uint = _currentFrame; // 現在のフレーム
gotoAndAction(f);           // フレーム移動
++f;                        // 次のフレームへ
// 最後のフレームなら
if (f > _labelList.length)
{
f = 1;  // 最初のフレームへ戻る
}
_currentFrame = f;  // 現在のフレームを設定
}
}
// --------------------------------------------------------------------------------------
// --プロパティ関連メソッド  ---------------------------------------------------------------------
// ■フレーム数
public function get length():uint                   { return _labelList.length; }
// ■現在のディスプレイオブジェクト
public function get currentObject():DisplayObject   { return _currentObj;       }
// ■現在のフレーム番号
public function get currentFrame():uint             { return _currentFrame;     }
// ■現在のディスプレイオブジェクトのラベル
public function get currentLabel():String           { return _currentLabel;     }
}
}

ちょっとこれまで使ってきた「MovieClip」クラスっぽくしてみましたが中途半端です。


使い方の例です。

初期化部分です。

var stageSp:Sprite = new Sprite();    // ステージとするスプライト
var objSp:Sprite = new Sprite();    // フレームを持たせるスプライト
stageSp.addChild(objSp);
var frame:Frame = new Frame(objSp);    // フレームを持たせるスプライトを登録しオブジェクトを作成
// フレームに登録するディスプレイオブジェクトを作成
var sh:Shape = new Shape();
var shAt:Shape = new Shape();
var sp:Sprite = new Sprite();
var spAt:Sprite = new Sprite();
// フレームに登録
frame.setFrame(sh, "shape");    // ラベルを指定して登録
frame.setFrame(sp);    // ラベルを指定せずに登録
frame.setFrameAt(shAt, 2, "shapeAt");    // 登録するフレームの番号を指定して登録
frame.setFrameAt(spAt, 3);    // これもラベルを指定せずに登録できる
// この段階でのフレームの登録状況は「sh, shAt, spAt, sp」となっている。
// 実際に表示するためにとりあえずフレームを移動しておく。
frame.gotoAndStop(1);

フレームの移動は「MovieClip」クラスっぽく「gotoAndStop()」と「gotoAndPlay()」があります。

どちらラベルもしくはフレーム番号でフレームを移動できます。

フレーム番号の最低値は「MovieClip」クラスっぽく1です。


ここからが新しい部分です。

「gotoAndPlay()」もしくは「play()」を実行した後、

「animate()」をループ実行することでアニメーションします。

つまりこれまでの「onEnterFrame」内で「animate()」を実行すれば

1回実行するごとに1フレームずつ表示が切り替わります。

(上の例の場合、sh -> shAt -> spAt -> sp -> sh ->・・・と表示され続けます。)

再生を止める方法は、お分かりのとおり「gotoAndStop()」もしくは「stop()」を実行します。



これでFlexでゲームを作る基本的な準備が整った・・・はずです。

あとはネタ待ちです。


何か不具合などありましたらご報告いただけますと助かります。