[AS3]sortOn()を使って複数条件で配列をソート

Posted 2012年2月24日 | Auther dada | Category PC・デジタル | Tag タグ: ,
Twitterにツイートする Facebookでシェアする はてなブックマーク

ActionScript3でオブジェクトを複数条件ソートする時のメモ。
sortOn() を使うと一発でできるのでラクチンです。

しかし条件の指定をちょっと変えると結果が全然違ってくるので注意です。
下の例では全て「y」「x」の順にソートしています。

var list:Array = [ 
  new Point(5, 5),
  new Point(0, 10),
  new Point(10, 10),
  new Point(10, 0)
];

list.sortOn( ["y", "x"] );
// 文字列比較で小さい順に並べている。文字列だから「10<5」になる。
// (x=10, y=0),(x=0, y=10),(x=10, y=10),(x=5, y=5)

list.sortOn( ["y", "x"], Array.DESCENDING );
// 降順ソート。こちらも文字列だから「10<5」になる。
// (x=5, y=5),(x=10, y=10),(x=0, y=10),(x=10, y=0)

list.sortOn( ["y", "x"], [Array.NUMERIC, Array.NUMERIC] );
// どちらも数値としてソート
// (x=10, y=0),(x=5, y=5),(x=0, y=10),(x=10, y=10)

list.sortOn( ["y", "x"], [Array.DESCENDING | Array.NUMERIC, Array.NUMERIC] );
// 「y」は「数値で降順」、「x」は「数値で昇順」
// (x=0, y=10),(x=10, y=10),(x=5, y=5),(x=10, y=0)

list.sortOn( ["y", "x"], [Array.DESCENDING|Array.NUMERIC, Array.DESCENDING|Array.NUMERIC] );
// どちらも「数値で降順」
// (x=10, y=10),(x=0, y=10),(x=5, y=5),(x=10, y=0)			
Array.CASEINSENSITIVE 大文字と小文字を区別しないソート
Array.DESCENDING 降順のソート順
Array.UNIQUESORT 一意性ソート要件
Array.RETURNINDEXEDARRAY sort() メソッドまたは sortOn() メソッドの呼び出し結果としてインデックス付き配列を返す
Array.NUMERIC 数値によるソート

Array.UNIQUESORT はちょっと特殊で、ソート対象に同じ値が混ざっていないかチェックします。
同じ値が混ざっている場合は並び替えをせず「0」を返します。

正規表現の「先読み」

Posted 2010年4月16日 | Auther dada | Category PC・デジタル | Tag タグ: , ,
Twitterにツイートする Facebookでシェアする はてなブックマーク

数値を3桁ごとに「,(カンマ)」で区切るのを調べていたら
WadadanetさんのAS3で数字を3桁毎にコンマ区切りにするが見付かり
目的を達することは出来たのですが、構文の中に「?=」や「?:」など意味のわからないものが。

Twitterで質問してみたら正規表現の「先読み」らしいことがわかりました。

大ざっぱに言うと、
マッチングはするけど、カーソルは先読み部分の前で止めちゃうよ
ということなのですね。

そんなわけで自分向けメモ。
javascriptで書くとこんなん。

var maho = "マホは咲の真似してリンシャンあがった";

document.write(
	maho.replace( /(マホは(?=.+あがった)咲の真似して)/, "$1カンして" )
);
// 先読みを使った結果
// マホは咲の真似してカンしてリンシャンあがった

document.write(
	maho.replace( /(マホは咲の真似して).+あがった/, "$1カンして" )
);
// 先読みを使わない結果
// マホは咲の真似してカンして

先読みを使うと「あがった」の部分までマッチングするけど、
その直前までしか「$1」で取得してません。

従来の方法だと「あがった」まで取得してしまうので、
同じように置換すると後半部分が消えてます。

従来方法で同じ結果を出すならこんな感じでしょうか。

document.write(
	maho.replace( /(マホは咲の真似して)(.+あがった)/, "$1カンして$2" )
);
// マホは咲の真似してカンしてリンシャンあがった

これでもいいですが、「リンシャンあがった」の部分になんらかの処理を加えたい時、
カーソルは通り過ぎているのでちょっと面倒なことになります。

咲-Saki- ラブじゃん マホちゃんの必殺技完成! 咲-Saki- ラブじゃん マホちゃんの必殺技完成!
スクウェア・エニックス

スクウェア・エニックス 2010-01-29
売り上げランキング :
おすすめ平均

Amazonで詳しく見る by G-Tools

Progressionのコマンドで分岐

Posted 2010年3月6日 | Auther dada | Category PC・デジタル | Tag タグ: , ,
Twitterにツイートする Facebookでシェアする はてなブックマーク

コマンドリストを実行している時、
途中のコマンドの結果によって分岐させたい時の方法。

var hogeCommand:HogeCommand = new HogeCommand();
var serial:SerialList = new SerialList();

serial.addCommand( hogeCommand );

serial.addCommand( new Func( function():void {
	// コマンドの結果で分岐
	if ( hogeCommand.value ) {
		serial.insertCommand( new Trace("コマンドを挟む"));
	}
}));

serial.execute();

HogeCommandクラスの実行結果を受け取りたいので
インスタンスを先に作っておきます。

var hogeCommand:HogeCommand = new HogeCommand();

今回のキモ「insertCommand」です。
これにより動的にコマンドを挿入させることができます。

	// コマンドの結果で分岐
	if ( hogeCommand.value ) {
		serial.insertCommand( new Trace("コマンドを挟む"));
	}

このやり方についてはIs It So Easy?さんが詳しく書かれています。
this.parentで挿入することも出来るんですねー。

[改訂版]ActionScript3.0プログラミング入門 for Adobe Flash CS4/CS3 [改訂版]ActionScript3.0プログラミング入門 for Adobe Flash CS4/CS3

ビー・エヌ・エヌ新社 2009-07-23
売り上げランキング : 79902

Amazonで詳しく見る by G-Tools

Progression4のリソース系で謎のエラー

Posted 2010年3月2日 | Auther dada | Category PC・デジタル | Tag タグ: , ,
Twitterにツイートする Facebookでシェアする はてなブックマーク

いったい何がキッカケだったのかまったくわからないけど、ある日突然出てきたエラー。

Resource.as、行 44
1004: 名前空間が見つからないか、コンパイル時定数ではありません。
progression_internal static const $collection:IdGroupCollection = new IdGroupCollection();

いろいろ試して、音声ファイルがリンケージされていると発生することがわかりました。
下記のようにごく一般的なファイルを普通にリンケージしただけえす。

ファイル:testse.wav
クラス:testse
基本クラス:flash.media.Sound

「最初のフレームに書き出し」のチェックを外すとエラーは出ません。

しかし上記チェックを外すわけにもいかず色々試していたら、
Index.asに下記の行を追加したらエラーが出なくなりました。

function hogehoge():void {
	getResourceById("hoge").data;
}

この関数はどこからも呼ばれませんが、記述しておくだけで良いようです。

バグなのか仕様なのかはわかりませんが、公式のフォーラムに報告しておきました。

ActionScript 3.0 エラーアーカイブス コンパイルエラー・コンパイラ警告・ランタイムエラーの解法 ActionScript 3.0 エラーアーカイブス コンパイルエラー・コンパイラ警告・ランタイムエラーの解法
大重美幸

ソシム 2009-09-09
売り上げランキング : 83197
おすすめ平均

Amazonで詳しく見る by G-Tools

Progressionで複数ファイルをまとめて読む

Posted 2010年2月21日 | Auther dada | Category PC・デジタル | Tag タグ: , ,
Twitterにツイートする Facebookでシェアする はてなブックマーク

Progressionのリソースキャッシュと、複数ファイル読み込みの組み合わせが
便利すぎて思わず漏らしてしまいそうです(チョロリ)。あっ。

外部画像を読み込んで一覧表示させるものを作ってまして、
各サムネイル内で読み込むようにしてたんですが、
最初にまとめて読むように変更しました。

というのも、リソースキャッシュのおかげで
画像の流用がすごく簡単に行えるようになったからです。

Progression4で外部ファイルの使い回しを簡単に 》 RuputerFan

リソースキャッシュについては以前かいたこの日記を参照。

続きを読む

ProgressionのURLアンカー遷移を無効にする

Posted 2010年2月20日 | Auther dada | Category PC・デジタル | Tag タグ: , ,
Twitterにツイートする Facebookでシェアする はてなブックマーク

Progressionが備えているURLアンカー(URLの後の「#~」)によるページ遷移は
フルFlashサイトを作る際にはとても便利で素晴らしいのですが、
ブログパーツやメニューのみFlashにしている場合は誤動作の原因になる場合もあります。

今日まさにそれでハマっていたので対処法をメモっておきます。

ドキュメントクラス「Index.as」内の下記の箇所を書き換えれば
無効にすることができます。

protected override function atReady():void {
//	manager.sync = true;
	manager.sync = false;

//	manager.goto( manager.syncedSceneId );
	manager.goto( new SceneId('/index') );
}

manager.syncというプロパティが関係するらしいので「false」にします。

manager.syncedSceneIdもURLアンカーによる場所が格納されているぽいので、
移動先も強制的に「/index」にしてしまいます。

もっとエレガントな方法もありそうですが、とりあえずこれで対処できました。

リトルアンカー(限定版) リトルアンカー(限定版)

D3PUBLISHER 2009-04-23
売り上げランキング : 7802
おすすめ平均

Amazonで詳しく見る by G-Tools

Progression4で外部ファイルの使い回しを簡単に

Posted 2010年2月13日 | Auther dada | Category PC・デジタル | Tag タグ: , ,
Twitterにツイートする Facebookでシェアする はてなブックマーク

Progression4から搭載されたResource関連がとても便利なのでメモ。

これまでも外部ファイル(swf、画像、mp3など)を読み込んで使い回す
ということは出来ましたが、それなりに手間がかかりました。

Progression4からはそれらを管理するResource系のクラスが登場し、
かなりシンプルになったようです。

michinoko blogさんで書かれていたことを参考に書いてみました。

続きを読む

Progression:カスタムコマンドを使おう(2)

Posted 2010年2月3日 | Auther dada | Category PC・デジタル | Tag タグ: , ,
Twitterにツイートする Facebookでシェアする はてなブックマーク

今回は簡単なカスタムコマンドを作ってみます。

カスタムコマンドのテンプレートをコピーする

プロジェクトを作成すると「templates」フォルダに様々なテンプレートが作成されます。
「src」フォルダに「MyCommand.as」を複製し、名前を「HokutoCommand.as」に変更します。

※本当は「classes」などのフォルダを作ってまとめたほうが良いのですが割愛します。

package {
	import jp.progression.casts.*;
	import jp.progression.commands.display.*;
	import jp.progression.commands.lists.*;
	import jp.progression.commands.net.*;
	import jp.progression.commands.tweens.*;
	import jp.progression.commands.*;
	import jp.progression.data.*;
	import jp.progression.events.*;
	import jp.progression.scenes.*;

	public class MyCommand extends Command {

		public function MyCommand( initObject:Object = null ) {
			super( _execute, _interrupt, initObject );
		}

		private function _execute():void {
			executeComplete();
		}

		private function _interrupt():void {
		}

		public override function clone():Command {
			return new MyCommand( this );
		}
	}
}

カスタムコマンドを記述する

それでは北斗百烈拳ならぬ、北斗十烈拳を繰り出すコマンドに書き換えます。
「MyCommand」になっている箇所を「HokutoCommand」に書き換えたり、いろいろ。

package {
	import flash.display.DisplayObjectContainer;
	import flash.display.MovieClip;
	import jp.progression.commands.*;
	import jp.progression.commands.lists.SerialList;

	public class HokutoCommand extends Command {

		private var $myStage:DisplayObjectContainer;

		/*******************************
		 * コンストラクタ
		 * @param	myStage		「あた!」の配置先
		 */
		public function HokutoCommand( myStage:DisplayObjectContainer, initObject:Object = null ) {
			super( _execute, _interrupt, initObject );
			$myStage = myStage;
		}

		/*******************************
		 * 処理実行
		 */
		private function _execute():void {

			// 直列実行コマンド
			var serialList:SerialList = new SerialList();

			// 「あた!」を配置して 0.2秒待つをくり返す
			serialList.addCommand( new Func( addAta ));
			serialList.addCommand( new Wait( 0.2 ));
			~略~
			serialList.addCommand( new Func( addAta ));
			serialList.addCommand( new Wait( 0.2 ));

			// カスタムコマンド終了関数
			serialList.addCommand( new Func( executeComplete ));

			// 終了処理
			serialList.addCommand( new Func( _endExec ));

			// 直列処理開始
			serialList.execute();
		}

		/*******************************
		 * 「あた!」を配置する関数
		 */
		private function addAta():void {

			// ata_mcをランダム位置に貼りつける
			var mc:MovieClip = new ata_mc();
			mc.x = (Math.random() * 300) + 50;
			mc.y = (Math.random() * 200) + 50;

			$myStage.addChild( mc );
		}

		/*******************************
		 * 終了処理
		 */
		private _endExec():void {
			$myStage = null;
		}

		/*******************************
		 * 処理中断
		 */
		private function _interrupt():void {
			// 中断時は終了と同じことをさせる
			_endExec();
		}

		/*******************************
		 * 複製
		 */
		public override function clone():Command {
			return new HokutoCommand( $myStage, this );
		}
	}
}

ポイントの説明

長く見えるかもしれませんがやってることはいたって単純。

		/*******************************
		 * コンストラクタ
		 * @param	myStage		「あた!」の配置先
		 */
		public function HokutoCommand( myStage:DisplayObjectContainer, initObject:Object = null ) {
			super( _execute, _interrupt, initObject );
			$myStage = myStage;
		}

コンストラクタでは「あた!」を配置させる場所を保存しているだけです。
initObjectと、super()は定型文と思ってそのままにしてください。

			// 「あた!」を配置して 0.2秒待つをくり返す
			serialList.addCommand( new Func( addAta ));
			serialList.addCommand( new Wait( 0.2 ));

SerialListは直列処理を実現してくれるクラスです。
Funcクラスは関数を実行するためだけのものです。Commandクラスを継承しています。
addAta()内で「あた!」を配置し、Waitクラスで0.2秒待機させています。

			// カスタムコマンド終了関数
			serialList.addCommand( new Func( executeComplete ));

executeComplete()はとても大切な関数で、
カスタムコマンドの処理が完了したことを上位オブジェクトに通知します。
これを実行しないと上位オブジェクトは次の処理に移りません。

			// 終了処理
			serialList.addCommand( new Func( _endExec ));
		/*******************************
		 * 終了処理
		 */
		private _endExec():void {
			$myStage = null;
		}

executeComplete()で終了の通知は行きますが、
その後は自分でキレイに掃除しなくてはいけません。
やらなくても構いませんがメモリリークの原因になります。

_endExec()(名前は任意)は中断処理でも呼ばれます。
コマンドが中断された際も掃除をしておかないとメモリリークの原因になります。

		/*******************************
		 * 処理中断
		 */
		private function _interrupt():void {
			// 中断時は終了と同じことをさせる
			_endExec();
		}

clone()は同じパラメータを与えられたコマンドを複製しますが、
まぁほとんど使うことはないと思います。
コンストラクタと同じ関数名、引数を与えればよいです。

		/*******************************
		 * 複製
		 */
		public override function clone():Command {
			return new HokutoCommand( $myStage, this );
		}

カスタムコマンドで守るべきこと

実際の処理を書く_execute()と、終了処理を書く_endExec()以外は
ほとんどテンプレートのままで、クラス名にあわせてコンストラクタ名や
引数が変わるくらいです。
(上記2つの関数名は任意)

大切なことは、処理が終わったらexecuteComplete()を実行すること。

その後に終了処理をするということです。
executeComplete()は終了を通知するだけの、いわばdispatchEvent()のようなものです。

カスタムコマンドの呼び出しかた

それでは実際にカスタムコマンドを使ってみましょう。
「IndexScene.as」から呼び出します。

~略~
		/*********************************
		 * ボタン押した
		 */
		private function _onClick( e:MouseEvent ):void {

			// 北斗十烈拳を実行した後、「終わった」を表示
			var serialList:SerialList = new SerialList();
			serialList.addCommand(
				new HokutoCommand( this.container ),
				new Func( _owatta )
			);
			serialList.execute();
		}

		/*********************************
		 * 終わったァ!
		 */
		private function _owatta():void {
			var owatta:MovieClip = new owatta_mc();
			owatta.x = 200;
			owatta.y = 150;

			this.container.addChild( owatta );
		}
~略~

めちゃくちゃシンプルです。
カスタムコマンドを実行しているのはこの行だけ。
「あた!」を配置する場所を指定しています。
initObjectは不要です。

				new HokutoCommand( this.container ),

コンパイルしてみよう

「北斗十烈拳」をクリックすると始まります。

今回のソースファイルをアップしましたので、試してみたい方はどうぞ。
※他の環境で動作するかはテストしてません。

Adobe Flash CS4 詳細!ActionScript3.0入門ノート[完全改訂版](CD-ROM付) Adobe Flash CS4 詳細!ActionScript3.0入門ノート[完全改訂版](CD-ROM付)

ソーテック社 2009-08-01
売り上げランキング : 15546
おすすめ平均

Amazonで詳しく見る by G-Tools

Y座標で重ね順を入れ替える

Posted 2010年1月20日 | Auther dada | Category PC・デジタル | Tag タグ: ,
Twitterにツイートする Facebookでシェアする はてなブックマーク

ActionScript3の重ね順は setChildIndex()のおかげでだいぶラクになりましたね。

ゲームとかいろんなとこで必要になる、Y座標による重ね順の変更です。
だいぶ以前 mixiに書いてたのを掘り起こしてリプレースしました。

続きを読む

カテゴリー