レイヤークラス

それぞれのオブジェクトの重なり順を管理するために、
事前に大雑把にステージ用スプライトのようなものを作ってまとめておけるクラスがあったら
それなりに便利かもしれないと思いまして考えてみました。

/**
 * ・レイヤークラス
 */
package
{
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.Sprite;
	
	public class Layer
	{
// --------------------------------------------------------------------------------------
// --プロパティ	-----------------------------------------------------------------------------
		private var _stageObj:DisplayObjectContainer;	// ステージディスプレイオブジェクトコンテナ
		private var _layer:Object;						// レイヤー格納オブジェクト
// --------------------------------------------------------------------------------------
// --初期処理	-----------------------------------------------------------------------------
		/**
		 * ■コンストラクタ
		 * 
		 * @param stageObj ステージとするディスプレイオブジェクトコンテナ
		 */
		public function Layer(stageObj:DisplayObjectContainer)
		{
			_stageObj	= stageObj;
			_layer		= new Object();
		}
// --------------------------------------------------------------------------------------
// --通常メソッド	-------------------------------------------------------------------------
		/**
		 * ■最前面レイヤー追加メソッド
		 * 
		 * @param name	レイヤー名
		 * @param layer	追加するレイヤー
		 * 
		 * @return 追加したレイヤー
		 */
		public function addLayer(name:String,
							layer:DisplayObjectContainer = null):DisplayObjectContainer
		{
			if (layer == null)
			{
				_layer[name] = new Sprite();
			}
			else
			{
				_layer[name] = layer;
			}
			
			return DisplayObjectContainer(_stageObj.addChild(_layer[name]));
		}
		
		/**
		 * ■インデックス指定型レイヤー追加メソッド
		 * 
		 * @param name	レイヤー名
		 * @param index	レイヤー重なり順(0が最低値)
		 * @param layer	追加するレイヤー
		 * 
		 * @return 追加したレイヤー
		 */
		public function addLayerAt(name:String, index:int,
							layer:DisplayObjectContainer = null):DisplayObjectContainer
		{
			if (layer == null)
			{
				_layer[name] = new Sprite();
			}
			else
			{
				_layer[name] = layer;
			}
			
			return DisplayObjectContainer(_stageObj.addChildAt(_layer[name], index));
		}
		
		/**
		 * ■レイヤー取得メソッド
		 * 
		 * @param name 取得するレイヤー名
		 * 
		 * @return レイヤー
		 */
		public function getLayer(name:String):DisplayObjectContainer
		{
			return _layer[name];
		}
		
		/**
		 * ■レイヤー除去メソッド
		 * 
		 * @param name 除去するレイヤー名
		 * 
		 * @return 除去したレイヤー(失敗したならnull)
		 */
		public function removeLayer(name:String):DisplayObjectContainer
		{
			var obj:DisplayObjectContainer = _layer[name];
			
			if (obj != null)
			{
				if (obj.parent != null)
				{
					return DisplayObjectContainer(_stageObj.removeChild(obj));
				}
			}
			
			return null;
		}
		
		/**
		 * ■指定インデックスレイヤー除去メソッド
		 * 
		 * @param index 除去するレイヤーのインデックス
		 * 
		 * @return 除去したレイヤー(失敗したならnull)
		 */
		public function removeLayerAt(index:int):DisplayObjectContainer
		{
			return DisplayObjectContainer(_stageObj.removeChildAt(index));
		}
// --------------------------------------------------------------------------------------
// --プロパティの設定取得メソッド	-------------------------------------------------------------
		// ■ステージディスプレイオブジェクトコンテナ
		public function getStageObj():DisplayObjectContainer { return _stageObj; }
	}
}



こんな感じで使えそうです。

public class Screen
{
	private var _stageSp:Sprite;
	private static var _layer:Layer;

	public function Screen()
	{
		_stageSp = new Sprite();
		_layer = new Layer(_stageSp);

		_layer.addLayer("backgroundStage");			// 背景ステージ
		_layer.addLayer("objectStage");			// キャラクターなどのオブジェクトステージ
		_layer.addLayer("screenEffectStage");	// 画面特殊効果ステージ
		_layer.addLayer("systemObjectStage");	// スコアなどのシステムオブジェクトステージ
		_layer.addLayer("sceneEffectStage");		// シーン切り替え効果ステージ
	}

	public static function getLayer():Layer { return _layer; }
}
public class Player
{
	public function Player()
	{
		var stageSp:Sprite = Sprite(Screen.getLayer().getLayer("objectStage"));
		var playerSp:Sprite = <プレイヤー画像>;
		stageSp.addChild(playerSp);
	}
}

あれ?これだと

Sprite(Screen.getLayer().getLayer("objectStage"));

これのようにいちいちキャストしなければエラーが出ますね。
何だかめんどくさいです。
メソッドの戻り値は「Sprite」とかに統一しておいた方がいいのかもしれません。
でも「addChild()」も戻り値は「DisplayObject」なので、
キャストしなければ戻り値を「Sprite」型の変数に代入できませんよね。
どちらがいいのやら。


このクラスが実際に役に立つのかたたないのかは分かりませんが、
これを作っている最中、「DisplayObject」と「DisplayObjectContainer」の違いを
より明確に理解できたような気がします。




# この記事を投稿した当初のソースにバグがありました。25:00、修正しておきました。