AIRでウィンドウを最前面にするメモ
Mac特有の現象かもしれませんが、AIRアプリでウィンドウを強制的に最前面に移動させるメソッド、
NativeWindow::orderToFront();
がちゃんと動いてくれません。
なので、代替え方法として、
NativeWindow::alwaysInFront=true;
NativeWindow::alwaysInFront=false;
としてやると一応最前面に来てくれます。
Mac特有の現象かもしれませんが、AIRアプリでウィンドウを強制的に最前面に移動させるメソッド、
NativeWindow::orderToFront();
がちゃんと動いてくれません。
なので、代替え方法として、
NativeWindow::alwaysInFront=true;
NativeWindow::alwaysInFront=false;
としてやると一応最前面に来てくれます。
先日Sparkの特別版でちょいと発表してきたよ。
発表とか初めてなのでキンチョーしました。
内容はFP10.1でマイクの生データを取得出来るので録音したり、エフェクトかけたり、音声認識(グダグダな精度)したり、という感じです。緊張トークと微妙すぎる解析精度に会場が大きく笑いに包まれていた気がします。(所謂失笑ですね。はい。)
マイクのエフェクト処理はもう少しFlashプレイヤーのパワーが上がって、音響処理が出来るレベルのレイテンシを得られると、結構誰でも使えるんじゃないかと。音声認識に関しては既存のライブラリを誰かがFlashに移植してくれる日を待ちましょう。(javaにそれ系ライブラリがあるはず)
そんな訳でとりあえずサンプルです
(*Macだとマイクの取得が怪しいかもです)
他の人の発表はどれも面白くて多いに刺激を受けた中、やはり個人的にはモバイル関連とAIR2.0の話が興味深かった。興味だけじゃなく、いいかげんモバイルをキャッチアップせねば、という焦燥感も感じつつ。
当日の様子はgihyoさんのレポートにまとめられてます。
最近CS5の虎の子であるTLF周りを触っているので軽くメモ。
1.flashX
TLFの実体は flashx.textLayout というパッケージである。ここで気になるのは"flashx"という見慣れないパッケージ。そう、"flash"では無いのだ。これがflash+FP10(X)によるものなのか、flash+mxによるものなのか、 あるいは両方なのか、それとも全く違う理由なのかよくわからないがちょっぴり不思議な感じ。
2.TextFieldとは全くの別物。
TextFieldの流れが
3.TextFieldライクに使うならTLFTextFieldがおすすめ
fl.text.TLFTextFieldというコンポーネントが存在する。IDE上でTLFを生成すると自動的にこのクラスを使う事になる。TextFieldと親和性の高いAPIを持つ。ひょっとするとflパッケージの中で今後最も使われるクラスになるかもしれない。キラークラス(?)だ!
4.コードの比較
TLF
import flashx.textLayout.elements.*; import flashx.textLayout.container.ContainerController; import flashx.textLayout.edit.EditManager import flash.display.Sprite; var tfw:TextFlow = new TextFlow(); tfw.interactionManager = new EditManager(); tfw.fontSize = 18; var p:ParagraphElement = new ParagraphElement(); tfw.addChild(p) var span:SpanElement = new SpanElement() span.text = "hello world TLF"; p.addChild(span) var sp:Sprite = addChild(new Sprite) as Sprite sp.x = 10 sp.y = 10; tfw.flowComposer.addController(new ContainerController(sp,200,20)) tfw.flowComposer.updateAllControllers();flash.text.TextField;
import flash.text.TextField; import flash.text.TextFormat; import flash.text.TextFieldType; var tf:TextField = addChild(new TextField) as TextField; tf.defaultTextFormat = new TextFormat(null,18) tf.type = TextFieldType.INPUT; tf.text= "hello world TextField" tf.width = 200 tf.x = 10 tf.y = 40;fl.text.TLFTextField;
import fl.text.TLFTextField; var tlf:TLFTextField = addChild(new TLFTextField) as TLFTextField; tlf.textFlow.fontSize = 18 tlf.type = TextFieldType.INPUT; tlf.text= "hello world TLFTextField" tlf.width = 200 tlf.x = 10 tlf.y = 80;
個人的にすきなところ
縦書きは待望の機能だったが、同じくらい嬉しいのが「複数のContainerControllerでもセレクションが途切れない」という超々地味な仕様。さらにhtmlのマークアップも途切れずに表現してくれるのだ。
TextFieldに置き換えて言えば「複数のTextFieldでもセレクションが途切れない、htmlのマークアップも途切れない」と言う事だ。これが如何に重大な事件か、マルチカラムレイアウトをTextFieldを使い力技で実装した事のあるFlasherなら大いに賛同してくれるはずだ。 だが、如何にマークアップを補完したとしても、セレクションに関しては涙をのまざるを得なかった。
しかし、そう、我々はついに手に入れたのだ!途切れる事泣きセレクションを!
という訳で長くなったのでここまで。次回は主要なクラスの紹介です(時間があれば)
先月はPythonでのコーディングをたしなんだので、AS3と比較しながらPythonメモ。
def hoge():
print "hoge"
AS3
function hoge():void{
trace("hoge");
}
Pythonと言えばインデント。コードブロックはインデントで表現する。コーディングの一貫性を狙っての事だと思うけど、Pythonみたいなシンプルな文法だから可能なんだろう。AS3なんてコンストラクタ書く時点でインデントが二つも付いて、あれよあれよとコードが右へ寄ってくからね。
myname = "kappalab"AS3
var myname:String = "kappalab";
"var"や型指定がいらない。AS1みたいな感じかな。
def hoge(value="hoge",*arg):
for i in arg:
print i
print "hoge"
AS3
function hoge(value:String="hoge",...arg):void{
for each(var i:* in arg){
trace(i);
}
trace("hoge");
}
Pythonだと宣言は"def"を使う。こちらも型指定いらず。引数のデフォルト値の指定は同様。
class Hoge (object):
def __init__(self):
self.name = "kappalab"
print self.foo()
def foo(self):
return "Hoge:foo"
AS3
package{
public class Hoge extends SuperHoge{
public var name:String;
public function Hoge():void{
name = "kappalab";
trace(foo());
}
public function foo():String{
return "Hoge:foo";
}
}
}
Pythonだとコンストラクタは"__init__"で定義する。でもって第一引数に"self"を渡す。また、インスタンスメソッドの第一引数にも必ず"self"を渡す。さらにインスタンス変数(プロパティと言うとAS3とちょっと意味合いが異なるみたい)及びインスタンスメソッドを参照するときも"self.name"とする。AS3の"this.name"とよく似ているが、AS3が"this"を省略可能なのに対してPythonは必須。
そして、変数は全てコンストラクタ内で定義。AS3みたいにあらかじめ定義は出来ない。
その他、カプセル化まわりで色々と特徴があるけどそれはまた今度。
for i in [0,1,2,3]:
print i*2
AS3
for (var i:int = 0 ; i < 4; i++){
trace(i*2);
}
とりあえず配列とセットで使う。
list = ["a","b","c"]
for i in list:
print i
AS3
var array:Array = ["a","b","c"];
for each(var p:* in array){
trace(p);
}
AS3のfor eachとほぼ同様。ループ処理その1よりこっちの方が比較としては的確かも。
list = [i*2 for i in range(0,10)]AS3
var array:Array = [];
for (var i:int = 0 ; i<10;i++){
array.push(i*2);
}
リスト内包処理。何かしらの処理結果を配列に格納するときにとても便利。ここら辺の機能がPythonって流石と思わせる。というか、こうしたループで文字列などのデータをゴニョゴニョ処理するのはPython、Perl、phpは基本的に得意なんだろうと思う。そしてAS3はつくづくその対局にいるのではないかと思ったりする。
ここに紹介した事以上にPythonは紹介すべき事が沢山あると思うけどとりあえず今のところは以上で。もし反響が良ければクラス周り、OOPとしての性質の違いに付いて比較したいと思います。
最後の最後にところでなぜPythonなのかというと、関西方面に引っ越ししたFlasherさんが、「Pythonいいよ!めちゃかわいいんですわ!yes!yes!!」と別れの間際に言ってた事と、AS3という言語を別の角度から見つめ直すにはPythonの様なシンプルなOOP言語が良いんじゃないかと思った事。
そして最終的にPythonをどこで使うかというと、http://onsight.la/のバックエンド。そんなわけでこれからはASerとPythonianのハイブリットを目指して頑張ります。あ、でもoFとかもやりたいなあ。
Progression書籍が今日から本屋さんの店頭に並びます。
http://twitpic.com/1j08e1(via fumix)
是非お手に取ってご覧ください。
それとサンプルファイルや正誤表などが下記サポートページで公開されています。
http://book.mycom.co.jp/support/pc/prog/
既に、誤表記が数カ所訂正されておりますので、お手数ですが併せてご確認いただければと思います。
それでは enjoy Progression !
ついにProgression"だけ"をあつかったFlash専門書が出ます。最近若手のFlasher間でも俄然注目度の高いProgressionですが、まだまだ敷居を高く感じる方も多く、(ほんとはそんな事無いんだけどね!)今回の書籍で一気に敷居が下がること間違いなし、な内容です。
とくに「Progressionってはやってるけどフレームワークとかよくわかんないよ」とか、「そもそもタイムライン/コンポーネントでしか制作しないよ」とか、「コマンドをもっと美しく使いたいなあ」とか、「SceneObjectってDisplayObjectと名前かぶってるやん」とか思ってる人におすすめです。是非ご高覧ください。
ProgressionによるFlashコンテンツ開発ガイドブック
著者:阿部貴弘(nium), 池田泰延(clockmaker), 楢山哲弘(northprint), 松竹 誠(Mk-10:cellfusion), 山上健一(kappalab)
税抜価格:2,800円
ISBN:978-4-8399-3179-7
総頁数:312ページ
出版社:毎日コミュニケーションズ
新規プロジェクトがスタートしました。世間はエイプリルフール真っ盛りですが、いろいろと空気が読めない感じでお知らせ。

ON SIGHT
新規プロジェクトの概要をざっくり言うと、「山に登って帰ってきた後に撮影した写真を使って地図を書いちゃうよ」という内容です。ON SIGHTと言うのはコードネームであり正式な名称じゃありません。一応、発想の起点が登山だったのでクライミング用語から引用しています。ただ開発しているうちにGPS ・ Geotag ・ Mobile ・ Web は想像以上に可能性がある事に気づいたので、何かとやる事が変わって行くかもしれないです。
今のところ可能なのはGPXデータか、Geotag付きjpegから3D地図と地図上へのルートの生成、画像の配置、ってところです。サンプルは富士山(GPX画像なし)と谷川岳(Geotag画像あり)があるので是非見てやってください。
今後の展開は、短期的にはAPI公開してGPXデータを扱うwebサイトから利用出来るようにするのが目標です。中期的にはモバイルデバイスでGPS、GPXのビジュアライズってところでしょうか。
まあそんな訳で季節も良くなってきたので皆で山でも登りましょう。
FP10案件に向けて自分用メモ
Vectorクラスを複数SWF環境で使用する場合、特定の場合でTypeErrorが発生する。
子SWF内でVecotr.<Hoge>のインスタンスがあり、
かつ親SWF内にHogeクラスへの参照が無い場合。

親SWFが子SWFを2回以上読み込む場合、2回目でTypeErrorが発生する。(上の図だとload2)。
解決するには初回読み込み時にApplicationDomainを明示的に指定する
loader = new Loader()
loader.load(
new URLRequest("sub.swf"),
new LoaderContext(false,
loaderInfo.applicationDomain
)
)
結論から言うと、Index.asのコンストラクタに
「Locale.language = Locale.JAPANESE;」
と記述するだけ。
あまり需要が無さそうだけど、MacユーザーでiPhone開発の為にOSの言語を英語に設定している場合に使えますよ。
クロスドメイン環境でProgression4を使う際は数カ所でクロスドメインに対応する必要があります。一般的なケースでは無いけど、webサービスとかにProgressionをインクルードした場合に必要になるかと思うのでメモ。
例えば下記の様なサイト構造

http://tmp1/index.htmlがhttp://tmp2にあるProgressionファイル一式(preloader.swfとかindex.swf)を読み込んで表示する場合、こんな感じでクロスドメイン処理をします。
step1. index.swfでtmp1をSecurity.allowDomain()で許可(*1)
step2. tmp2サーバー上にcrossdomain.xmlを設置、tmp1を許可
どうしてまた二カ所で指定するのかと言うと、
phase1. index.htmlがpreloader.swfを読み込む
phase2. preloader.swfがindex.swfを読み込む
phase3. index.swfがindex.htmlを読み込む
という読み込みシーケンスをProgression4では行うので
phase2. Security.allowDomain()でtmp1の許可が必要
phase3. crossdomain.xmlでtmp1を許可の許可が必要
となります。
このphase3.でindex.swfがindex.htrmlを読み込むのはProgression4から搭載されたWebDataHolderの動作によるものです。WebDataHolderはProgressionのシーン構造をindex.htmlが構築してやるぜ!という野心的なClassですがこれについてはそのうち詳しく説明するかもです。
ちなみにここで紹介したのはFlashPlayer10を対象にしてるので、今後のバージョンアップでCrossDomainのポリシーが変更された場合は、異なる処理が必要になるかもしれません。
とりあえずサンプルファイル(*2)
*1 Security.allowDomain()はIndexクラス(Index.asファイル)のコンストラクタで実行します。
*2 実際の動作を確認するためにはtmp1,tmp2をネットワーク上に配置する必要があります。
WEB+DB PRESS vol.54 に「ActionScript 3.0ライブラリ大集合」って記事書いたよ。
Unknow Qualityのll_koba_llさんと共著。
サンキュー!コバッチ!遅筆な僕を最後までサポートしていただいてホントに感謝しきりです。共著者のはずが編集者みたい(っていうか僕がダメすぎでそうなった感じ)な役目も担われて本当に頭が上がりません!なんかこのエントリーもコピペの様な内容だぜ!
23日発売日です。Amazonで予約できるよ。
第1章 ActionScript 3.0ライブラリの基本
第2章 表現・演出ライブラリ [基本編]
・3D : Papervision3D
・物理エンジン : Box2dFlashAS3
・アニメーション : Tweener
第3章 表現・演出ライブラリ [個性派編]
・グラフィック : Frocessing
・拡張現実 : FLARToolkit
・サウンド : SiON
第4章 制作支援ライブラリ
・非同期処理 : Thread Libray
・フレームワーク : Progression
・デバッグ : Monster Debuger
・プロファイラ : SWFProfiler
・Flash IDEの拡張 : JSFL
第5章 その他ライブラリ
・地図 : Google Maps API
・バイナリ操作 : as3corelib(jpg/png encoder)
・外部デバイス連携
webの人間ですが、印刷媒体への寄稿は一つの到達点と思っていました。まあ古い人間なので。
で、ようやくオレもその高みなのか!?と意気揚々と書いてみたものの、これが実に書けない。誤字脱字に始まり、意味の通らない解説、ソースコードの掲載ズレ、などなど。自分がまったく到達してない事が分かりました。
つまりBlogと比較した際の両者のメディアの特性を改めて感じたって事です。もちろんそれは優劣をつけるものではなく、あくまでも特性の差異って文脈で。
ずいぶんご無沙汰エントリーですが嬉しいお知らせです。ASoundが案件デビューしました !
スタンダード通信社&LOWE TOKYO
http://www.standard.co.jp/

Art Director: 築地 Roy 良
Design: チェ ヨヌク
Flash: 塚本 一真
制作:BIRDMAN
作った本人としてはどう使われたのかとてもソースが気になるところです。塚本さんほんとにありがとうございます!
ちなみこちらのサイトはProgressionのshowcaseからもご覧になれます。
昨日、Scaleformのセミナーにいった話は既にしましたが、全然本題に関係ないところですごい気になった事があった。
セミナー恒例のアンケートにFlashDevelopがあったのだ。一瞬我が目を疑いましたよ。ひょっとして誤植か? とすら思った。 未だに見間違いだったのではないかと思うんだけど、多分間違いではない。(もしかして間違いだったらすいません)
具体的には、「お使いの製品はなんですか?」という旨の質問があって、FlashCS4,FlexBuilder,Photoshop,,,と選択肢が続く。その中にあるんですよ「FlashDevelop」の名前が。
いままでこんな事は無かったはずだ。
これはですね、キョーレツにAdobeがFlashDevelopを意識しているのではないかと。いや、そうに違いない。FlashDevelop3.0のRCがとれてリリースされるときはAdobeの名前を冠してるかもしれないなあ。
やはり作るべきはツルハシかジーパンなのだろうか。
ScaleformGFxに行ってきたよ。Flashの人とゲームの人の参加割合はよくわからなかったけど、勝手な印象だと半々ってところなのかな?とりあえず普段なじみの無いゲーム業界の実情とかも垣間見れて、技術的な話よりそっちに興味が向いた感じでした。
おそらく参加したFlasher達も興味があったのはゲーム業界への参入とか市場拡大への関心ではなかったかと。そういう意味で3Dがどうとか、マッピングがどう、っていう話はあまり重要では無かったかもしれない。逆にゲーム業界の人に取ってはこの部分が重要だったのかも。ま、あくまでも個人的な感想にすぎないけどね。
質疑応答で
FlashやってるクリエイターがFlash技術でゲーム業界の案件に参加できるのか?またそういった前例とか、体制はあるのか?
という問いに対して、Scaleformの社長さんは
Flasherがゲーム業界に転職するというのはあり得るけど、すぐにScaleformの案件があるかどうかは分らない
或はゲームパブリッシャーやゲームデベロッパーなどの企業に企画を持ち込む、というのもありかも
見たいな回答でした。
僕の印象では質問の意図がうまく伝わっていない感じだったけど(そもそもScaleformという企業が考える問題ではなく、どちかっていうとAdobeの課題だと思う)、少なくとも
僕が今やってるブログパーツやバナー、Flashサイトなどの受注・制作をやりつつ、スクエア・エニックスから某格ゲーのライフインジケーターとか、某RPGのマップを作る、みたいなのはなさそう。(ScaleformならFlashでここら辺のモジュールが作れるみたいです)そもそも現時点では想定すらされていない感じだった。
そんなわけでFlasherがwebの仕事と平行してゲームの仕事をするってのはまだまだ先の話だ。
それともう一つ。ScaleformによってゲームをFlashだけで作る事も可能ですが(実事例でみたゲームはまさにこれ)本格的な格ゲーの3D処理とかはC++でやるみたい。今のところFlashの出番はちょっとした小物パーツとか設定画面みたいなところがメインって感じ。
いろいろ可能性は感じられたけど、色々と難しいな〜って感じた夜でした。
ExternalInterface.call("lightBoxInit",image,title);
LIghtBoxからのcallbackはendメソッドの中に"closeLightBox"とか適当な関数を書いて、ExternalInterfaceに渡していますにしています。直接ExternalInterfaceにendメソッドを渡せる方がLightBox.jsを修正しないで済むしエレガントだと思うんだけど、
ExternalInterface.addCallback("Lightbox.prototype.end", closeLightBox);
だと動かなかったので断念。おしえてエロいひと。Today, I add a few files which is ASound samples.
ASound is Actionscript sound library, using dynamic sound generation.
Simple Sine Oscillator .
ASound/branches/gamiken/src/example/example.fla
Lesson | .as file
Simple Delay Effects .
ASound/branches/gamiken/src/example/example2.fla
Lesson | .as file
Effects, Envelop, and mult-Oscillator .
ASound/branches/gamiken/src/example/example3.fla
Lesson | .as file
please check out repository.
http://www.libspark.org/svn/as3/ASound
usage
I would like to talk about ASound APIs. but I want to rebuild, and will change some APIs.
so, I can not talk that.
ASound is unripe library. But, be sure to make complete.
Please wait for a while.

FlashCS4のタブ切り替えが遂に判明したので発表します。
おそらくこの事実に気づいているのはFlash屋の中でも極一部のはずだが、オープンソースマインドに従って公開する事にしました。
ってわけでショートカット。
「Cmd + @」
及び
「Cmd + Shift + @」
前者だと「左→右」後者だと「右→左」と切り替わります。チョー便利。windowsだとCmdをCtrlにすれば良いんじゃないかとおもいます。
Windowsだとプラグインスイッチャーという便利ツールがあったけどMacだとよくわかんなかったので手動でやってみたメモ。本来ならAdobeのアンインストーラーを使うのが適当なんだろうけどなぜか失敗。一応手動でもなんとかなったよ。
(MacOSX Leopardでの作業です)
Step1.ブラウザのプラグインを削除
/Library/Internet Plug-Ins/Flash Player Enabler.plugin
/Library/Internet Plug-Ins/Flash Player.plugin
/Library/Internet Plug-Ins/flashplayer.xpt
Step2.FlashPlayerをDL
http://www.adobe.com/jp/support/kb/ts/228/ts_228683_ja-jp.html
Step3.インストール
任意のプレイヤーを選択し、ダイアログに従えば完了。
と思いきやここで大きな罠が。
FP9r159以降では、以前に入っていたプレイヤーをどっかで取得しているらしく、「既に新しいプレイヤーが入ってるよ」的なことを言って、インストールさせてくれない。とりあえずFP9r45とかならインストールできた。
オマケ。
おそらくstep1のファイルを差し替えるだけでplayerのバージョンを変更できるんじゃないかと思う。そういうアプリがあれば便利かも。
なんだかえらく間が開いちゃったけど、ASoundのプロパティの続きを書くことにした。
前回、Envelop、Filter、Effects、そしてMasterについて言及しますと宣言していたけど、Max/MSPのベンキョを進めているうちに、設計変更したくなったのでペンディング。今回はMasterについてのみ言及します。
masterプロパティがASoundの目玉なのは前回でも触れたが、まさしくマスターピース。これに関しては基本的に設計変更はない予定。ではいったいどういった設計かと言うとDisplayObjectにおけるstageプロパティを思い浮かべてもらうと分りやすい。
var ins:Instrument = new Instrument(); ins.master; ins.master.volume = 1; var sprite:Sprite = new Sprite(); sprite.stage; sprite.stage.scaleX = 1;
という感じで、stage.scaleX
を変更すると全体の横幅が変更されるように、master.volume を変更すると全体の音量(つまりマスターボリューム)が変更される。
さらにstageがswf上、完全に単一の存在であるようにmasterも単一の存在。外部からswfをロードした場合も同一のmasterを参照する。所謂シングルトンクラスというわけ。
で、ここからがポイント。
ASoundではMasterクラスのみが、Soundインスタンスを保持し、実際にバイナリデータをSoundインスタンスに書き込む。Instrumentクラスや、SinOSCなどのオシレーター系クラスはサンプリングデータを保持するだけで直接Soundインスタンスを扱いはしない。実質的に、MasterクラスはDAC(デジタルアナログコンバーター)として機能している。
POPFORGEでは、バッファー毎にnew Sound()をおこなうSoundFactory方式が採用されていたが(これはFP9をハックする上でそうせざるを得なかった訳だけど)、ASoundではmasterが生成され、swfが終了するまで、単一のSoundインスタンスにバッファを書き込んでゆく。どちらの方式が優れているかは一概に言えないが、個人的には前者はSEやシーケンサー等に向いていて、後者はDSPとかインスタレーションに向いているんじゃないかと思う。
また、ASoundの単一Sound方式だと、アタックのタイミング(音が成るタイミング)をバッファーベースで設定できるので遅延がほぼ発生しない。これをEnterFrameやTimerEventで行うと、フレーム落ちやらで遅延が生じる。fpsに依存しない時間管理ができるので、個人的にはとてもうれしい。(ひょっとすると音響以外の部分でもなにかしらの役に立つんじゃないかな)
気になるメモリ効率だけど、これはSampleDataEvent毎に解放される。なので、メモリリークの心配はない。また、n個のサイン波を鳴らす場合をSoundFactory方式と単一Sound方式で比較してみたところ20個が分水領となり、20以下だと前者が有利で、20以上は後者が有利となった。(CPUの負荷を観測)
とまあ、そんな感じ。
そしてオマケ。
masterがstageと同じく単一の存在なので、ロードしたサブswfからもmasterは同一になる。という事は元swfとロードswfでタイミングの同期が簡単にとれる。つまり任意のタイミングでswfをロードしても、必ず意図したタイミングで鳴らすことができる。ここら辺をうまくやってライブコーディングが面白くなればな〜と思う。
Progressionを開発してるCLOQUE.のティザーサイトがアップされてます。皆さんどうぞご覧ください。
中央でCLOQUE.の文字がモーフィングなのかパスが狂ったのか、キモかわいい動きをしています。
これはSVGデータをパースして得た数値をもとに、キモかわい目に弄くってモーションさせています。
当初はSVGじゃなくてFIVE3Dから出ているフォントをAS3クラスにコンバートしてくれる拡張機能を使う予定だったのですが、「SVGくらいパースできなきゃASerは名乗れないぜ?」とCLOQUE.の最高意志決定権者が言ったため、急遽パースする事に成りました。
でまあ、どうしてそんな台所事情をこのブログで書いているかというと、他でもなくその最高意志決定権者がこのブログの著者だからです。
というのはもちろん嘘で、本当はCLOQUE.の雑用係としてアサインされました。これからはkappa-lab研究者兼任CLOQUE.使い走りとして邁進してゆきますのでどうぞお見知り置きを。
ディスプレイオブジェクトライクなAPIを目指してるASoundですが、今回は実際にどの部分が"ディスプレイオブジェクトライク"なのか、具体例を挙げて説明していきます。
var ins:Instrument = new Instrument(); ins.listen = true; ins.volume = 1; ins.signals.push(new SinOSC(220)); ins.play();
var mc:MovieClip = new MovieClip(); mc.visible = true; mc.alpha = 1; mc.graphics.beginFill(0xFF0000); mc.graphics.drawRect(0,0,10,10); mc.graphics.endFill() mc.play();
いきなりコードを書いてしまいましたが、これは"Instrumentクラス"が"MovieClipクラス"をモデルとしている事を示しています。Flashをスクリプトベースで制作するようになるとMvieClipより圧倒的にSpriteを使うようになり、なんとなくMovieClipを生成する事自体躊躇する事があります。が、あくまでもここはMovieClipです。
これは両者ともplay()メソッドを実装するという共通点とともに、さらに本質的な共通項、"時間軸を持つオブジェクト"である事を示唆しています。
ま、そんな改まって言及するほどの事ではないですが、続いて上から順にプロパティを見てゆきます。
ins.listen
mc.visible
これは直感的に分かると思いますが、listen = falseで消音します。まったく聞こえません。visible = falseで見えないのと一緒。若干異なるのは表示オブジェクトの場合、visible = falseをしただけではremoveChild()は実行されず、多少なりともリソースを食います。しかしInstumentの場合、内部的にremoveChild()の様な処理が施され、リソースの回収が(ある程度)可能です。
ins.volume
mc.alpha
これも直感的に分かると思いますが、alpha = 0で完全透明になるようにvolume = 0で消音します。ここでも若干差異があり、volumeの値を1以上にした場合、そのまま波形が増幅され、場合によって音が割れます。(ディストーションとか?)
ins.signals
mc.graphics
ちょっとここら辺になってくるとこじつけっぽいですが、MovieClipが実際に線や面を描画するにはgraphicsに委譲させるように、Instrumentクラスも波形の生成はsignalsを用います。
しかし、signalsが特定のクラスではなく配列であったり、複数の波形を持つ事ができたりで、やっている事が、なんとなくaddChild()みたいだったりします。
いっそ、この部分は表示ツリーの様にツリー構造にすべきかとも考えましたが、音響におけるツリー構造は不自然だと考えてやめました。
ins.play()
mc.play()
そして、プレイ。いまのところstop()はありません。あまりstop()を使用する場面を思い浮かばなかったので忘れていたペンディングしたのですが、そのうち実装します。
と言うところで今日は以上です。
次回は
filters,effects,generateEnvelop, そして目玉であるmasterについて話したいと思います。
3/29日に渋谷で行われたCloque.(クロック)のランチパーティーでAS3を使ったサウンドプログラミングのデモンストレーションをしたんですが、そのときの成果物を「ASound(ア・サウンド)」と改め、libsparkにコミットしました。
視聴→http://memo.kappa-lab.com/samples/Exsample4.swf
今回を含めて数回にわたって、ASoundの概要を書いて行きたいと思ってます。
今日は手始めってことで簡単にご紹介。
var ins:Instrument = new Instrument(); ins.signals.push(new SinOSC(220)); ins.play();
220Hzのサイン波と880Hzのサイン波と900Hzのサイン波とノイズを音響合成し、レゾナントフィルター(sazameki謹製)をかけ、音圧0からスタートし、1秒後に音圧1まで増加してさらに1秒後消音す。
ソース | 視聴var ins:Instrument = new Instrument(); ins.signals.push(new SinOSC(220)); ins.signals.push(new SinOSC(800)); ins.signals.push(new SawOSC(900)); ins.signals.push(new NoiseOSC()); ins.generateEnvelop(0, [1, 1000, 0, 1000]); ins.filters.push(new ResonatFilter(ins)) ins.play();
AS3ではインターフェイスを定義できるもののアブストラクトクラス(抽象クラス)できない。この問題に関してはビンタ先生も「PHPが羨ましいのは抽象クラスをてきぎできるところ(だけ)」とtwitterで言ってた気がする。(間違ってたらごめんね。)
ところが、DisplayObjectなんかは間違いなく抽象クラスだし、ASDocを読んでも「このクラスは基本抽象クラスだからnewすんなyo!」とか書いてあります。
ビルトインクラスで可能なんだから、カスタムクラスでもできるんじゃないかと思って、少し考えてみたところ、泥臭いながら定義できるようになりました。
さらに泥臭いながらも抽象メソッドも定義してみました。
具体的には
1.抽象クラスのコンストラクタでgetQualifiedClassName()を使って完全修飾名から抽象クラスかサブクラスかを判断。抽象クラスならエラーを吐く。
2.抽象メソッド内にArgumentErrorを生成。抽象クラスのコンストラクタ内で実行。サブクラス内でオーバーライドしておかないとエラーを吐く。
という方法でやってます。
以下、サンプルです。
抽象クラス
package abstractClassTest
{
import flash.utils.getQualifiedClassName;
public class AbstractClass
{
public function AbstractClass()
{
//直接newされるとエラーをはく
if (getQualifiedClassName(this) == "abstractClassTest::AbstractClass"){
throw new ArgumentError( "abstractClassTest::AbstractClass is abstruct Class"); }
//オーバーライドされていないとエラーをはく //ただし無駄にメソッドがコールされるので、駄目か。
hoo() ; }
/*abstact method*/
public function hoo():void
{
//オーバーライドされていないとエラーをはく
throw new ArgumentError("hoo() is abstruct method. you must implement! ");
}
}
}
具象クラス
package abstractClassTest
{
public class ConcreteClass extends AbstractClass
{
public function ConcreteClass()
{
}
override public function hoo():void
{
trace("実装しました")
}
}
}
実装忘れクラス
package abstractClassTest
{
public class WarningConcreteClass extends AbstractClass
{ //抽象メソッドを実装し忘れてみる
public function WarningConcreteClass()
{
}
}
}
クライアントプログラム
package abstractClassTest
{
import flash.display.Sprite;
public class Main extends Sprite
{
public function Main()
{ //OK
var c:AbstractClass = new ConcreteClass();
c.hoo();//"実装しました
//Error
new WarningConcreteClass();
//Error
new AbstractClass()
}
}
}
ダイナミックサウンドを用いた作品を作る時、ほとんどの場合複数の音を操る事になると思います。単純なところで言えばサイン波と三角波とノイズを同時に鳴らす、とか。
で、このとき、三つのシグナルに対して、それぞれ三つのSoundインスタンスを生成してゴニョゴニョやるのか、単一のSoundインスタンスに対して、三つの信号を合算してゴニョゴニョするのか、二つの選択肢が生まれます。
一応テストしてみたところ、後者の方がパフォーマンスが良いと思うのですがどうでしょう?
手持ちのMBPで20個のサイン波を処理してみたところ前者81%、後者66%とかでした。
上記の仮説が正しい場合、マスターとなるSoundインスタンスをシングルトン化し、シグナルを生成するクラスのプロパティとして持たせれば良いんじゃないでしょうか。ちょうど、DisplayObjectにstageプロパティがあるように、masterプロパティを持たせるって感じ。
さらにvisibleプロパティよろしくmuteプロパティかlistenプロパティを持たせてtrue/falseでmasterへシグナルを書き込むか否かをコントロールすると、何となくFlashの表示オブジェクト系と似たような流れで処理が可能になると思うんだけど。
個人的にはダイナミックサウンド系のライブラリ設計は如何に表示オブジェクトライクに設計するかがキモなんじゃないかと思いますが、果たしてどうでしょう。春にはSFWSoundがお目見えするって話なのでとても楽しみ。
Progression in MTLに行ってきたよ。
いつになくディープな話であっという間の二時間でした。
個人的にはCommand周りの話が面白かった。ほとんどの場合サーバー連携の非同期通信の部分でカスタムコマンドを作ったりするんだけど、その他にも色々と可能性を感じたり。Tween系のカスタムコマンドとかを量産しておくとエフェクトとかトランジョンのプリセットととしてストック可能だよな、と。あるいはSOAPCommandとかを作って公開すると結構便利なんじゃないでしょうか。
Progresion案件じゃなくても非同期処理はCommandを使いたい感じなのでいっそのこと、CommandパッケージはProgressionからスピンオフしてもいいんじゃないかと思ったり。あ、でもそうすっとCastオブジェクトとの連携が逆にややこしくなるかな?
stop();
var myServer:String = "rtmp://hoge.fms.heteml.jp/var";
//myServer = "rtmp://nottinghill.llc.msu.edu/recordYourself/video"
var myRecording:String = "test001";
var myClip:String = myRecording
var myNS:NetStream
var myCam:Camera
var myMic:Microphone
var myVid:Video = _video
var myNC:NetConnection = new NetConnection();
tooltip_mc.visible = false;
function setStatus(msg){
log(msg)
status_txt.text = msg;
}
recBtn.addEventListener(MouseEvent.CLICK,recClip)
playBtn.addEventListener(MouseEvent.CLICK,playClip)
stopBtn.addEventListener(MouseEvent.CLICK,stopClip)
myNC.objectEncoding = ObjectEncoding.AMF0
myNC.addEventListener(NetStatusEvent.NET_STATUS,
function(e:NetStatusEvent):void{
setStatus("Connecting to server...");
if(e.info.code == "NetConnection.Connect.Success")
initStream();
log(e.info.code)
}
)
initCamera()
myNC.connect(myServer);
function initStream()
{
setStatus("initStream");
myNS = new NetStream(myNC);
/**/
myNS.bufferTime = 2;
myNS.addEventListener(AsyncErrorEvent.ASYNC_ERROR,log)
myNS.addEventListener(NetStatusEvent.NET_STATUS,
function(e:NetStatusEvent):void{
trace("nsm :",e.info.code);
switch(e.info.code)
{
case "NetStream.Play.Complete":
setStatus("stopped.");
myVid.attachCamera(myCam);
break;
default:
break;
}
}
)
/**/
}
function initCamera():void
{
setStatus("initCamera");
// init camera
myCam = Camera.getCamera()
myCam.setMode(240, 180, 15);
myCam.setQuality(0, 90);
myCam.setKeyFrameInterval(5);
//myCam.setLoopback(true);
myMic = Microphone.getMicrophone()
myMic.setSilenceLevel(0)
//myMic.setRate(22);
myVid.attachCamera(myCam);
}
function recClip(e:MouseEvent = null)
{
myVid.attachCamera(myCam)
myNS.attachAudio(myMic);
myNS.attachCamera(myCam);
myNS.publish(myClip, "record");
setStatus("recording.");
}
function playClip(e:MouseEvent = null)
{
myNS.play(myClip);
myVid.attachNetStream(myNS);
setStatus("playing.");
}
function stopClip(e:MouseEvent = null)
{
//myNS.publish(myClip,"stop")
myNS.close()
setStatus("stopped.");
myVid.attachCamera(myCam);
}
import flash.external.ExternalInterface;
import flash.utils.getQualifiedClassName;
function log(... args):void {
var inspect:Function = function(arg:*, bracket:Boolean = true):String {
var className:String = getQualifiedClassName(arg);
var str:String;
switch(getQualifiedClassName(arg)) {
case 'Array':
var results:Array = [];
for (var i:uint = 0; i < arg.length; i++) {
results.push(inspect(arg[i]));
}
if (bracket) {
str = '[' + results.join(', ') + ']';
} else {
str = results.join(', ');
}
break;
case 'int':
case 'uint':
case 'Number':
str = arg.toString();
break;
case 'String':
str = arg;
break;
default:
str = '[' + className + ':' + String(arg) + ']';
}
return str;
}
var r:String = inspect(args, false);
trace(r)
try
{
ExternalInterface.call('console.log', r);
} catch (error:Error)
{
}
}
ADOBE MAX 2009に行ってきたよ!
前回(一昨年)も行ったけど、今年も楽しかった。この1年間で知り合いのFlasherが増えたから、色々と情報交換ができたのが良かったです。
コミュニティーの形成が技術の発展と拡大をどれだけ後押しするかは今更言うまでもないけど、今回再確認しました。
見てきたセッションはこんな感じ。
1/29
D-1 WEBとタイポグラフィー
B-2 Flash Catalyst
C-3 プロフェッショナルのピクセルコントロール
C-4 Beyond the Knowledge
1/30
L-4 失敗に学ぶFlexプロジェクト
A-5 映像とプログラミング
D-6 Flashと外部デバイスであれを作りました
D-7 コンテンツ制作の決め手Progression
D-8 コミッタ全員集合 Spark Project
ADOBE MAX以外のデベロッパーカンファレンスって行ったことがないんだけど、エンタープライズ向けの内容から、コンシューマー向け、果てはメディアアートまでを一カ所で扱えるカンファレンスってあんまり無いんじゃないでしょうか。
今更ですが新年あけましておめでとうございます。今年もどうぞよろしくお願い致します。
地元には元旦から5日まで帰省してたんだけど、新年会やらそれの仕込みやらで忙しかった〜。あんまり正月を休んだ実感なし。
正月中、wonderflしたり、Max/MSP(円高に便乗して購入)をいじくり倒したりしたかったけど、結局2日の夜中までPV3Dで新年会用のスライドショーを作ってました。バージョン1.7のSampleに同梱されているPaperCloudをごにょごにょいじっただけでそんな大層なものでもなく、写真自体がプライベートな感じだったので正直不発。まあいい。次だ次。
こういう極普通の新年会とか結婚式だと、インタラクティブ作品は鑑賞が難しいな〜と改めて実感した。特に、操作を2〜3人以下に限定されてしまうと残りの人たちが置いてけぼりな感じになっちゃって、間延びしてしまう。改善するにはコンテンツの完成度は必須だけど、それに加えてMCというかプレゼン能力が重要な感じ。早い話が喋りを鍛えろ、と。
中途半端にインタラクションを加えるくらいならノンインタラクティブな動画作品の方が遥かに受けるなあ。ProductionPremium買った事だし、AEとPrをがんばろう。未だにVカムもって無いけど。
そうそう、VCamで思い出したけど、新年会当日に来場者を動画撮影して上記スライドショーで再生してみた。しかしこれまた不発気味だった。
具体的には受付を終わった来場者から順路に流れてもらい、定点でメッセージを撮影したが、どうにも盛り上がらない。おそらく三脚にカメラを据え置きにせず、手持ちでスナップショット気分で撮影していたらもうちょっと違う画がとれたと思うが、後の祭りだ。そういえばハーモニー・コリンも三脚を使わない映像集団を作ってた気がするなあ。
新年早々、プライベートワークの独り反省会ってなんかキモイけど、今年が飛躍の年でありますように!(なんだこりゃ)
ちょっと時間が経っちゃけど、先週「ごはんとFlash暴年会」に行ってきた。スタッフの皆さんおつかれさまでした。
この時期にkayacさんのスタッフが沢山集まるんだから、「wonderfl凄いっすね!」と言うしかないだろうと思っていたら、幸運にもwonderflの発案者の方とお話が出来た。
曰く、
「公開初日にd氏が呟いただけで●万PVに達した」とか
「開発はたった●人でやってる」とか
「企画は合宿で捻りだした」とか
色々面白い話が聞けました。
(伏せ字の所は一応大人の配慮で...)
なんかコーフンして(酔ってた?)たので自分が何をしゃべったのかいまいち覚えてないんだけど、
「いや〜ニコ動とかリードオンリーだったけど、ようやく投稿側の面白さが理解できました」と言ったのは為らざる意見。そろそろ違うプラットホームで制作してみたいな、と考えていたけどwonderflの出現でFlash制作のモチベーションが急上昇してしまった。
個人サイトが表現の場として衰退し、それらのリソースが何かしらのwebサービスに集約・吸収されて久しいが、同じ現象がFlash制作の現場でもおこったんだろうな。しかも「今更」というプリフィックスを携えて。
更に、Flashという技術が先に挙げた集約・吸収のシステム上で重要な役割を担っていた。にも関わらず、それ自身の集約・吸収がこのタイミングって、なんか感じさせますね。歴史のイロニーを。
インターネットはその発端っからクラウド指向だったと思うのですが、ここ2、3年くらいを見てるとかなり中央集権型になってきていると思う。SNSからAppStoreまでそういう文脈でみていいんじゃ無いかと。この傾向はモバイルwebが主流になると更に加速するんだろうな。
と、まあそんな事を考えながら前回のノイズメーカーから少し進歩したドラムンベース(っぽいもの)をリリースしました!
*Forkされた作品のほうが完成度高いです。イカす。
いや〜wanderflがあっちこっちのブログで喝采を浴びてますね。ほんとにすごいよ。前回「wonderflスゲエ」と書いてみたのはいいけど自分の作品がかなりショボイので、ちょっとDynamicSoundGenerationなやつを投下してみた。
ほんとはイカにも!なブレイクビーツがやりたかったけど、出来上がったのはなんだか体に悪そうなノイズ系。一応音のタイミングだけランダムになってます。その他のパラメータは決めうち。
コードの最後のほうに、正弦波、のこぎり波、三角波、矩形波の処理があります。ここら辺って難しそうだから今までコードに書き起こした事無かったけど、実際に書いてみると案外簡単。もっとも間違って無い保証も無ければ、もっと美しいコードもあり得ると思いますが。
*きんくまデザインさんを参にしました。
http://www.kuma-de.com/blog/?p=80
けどブログパーツの表示のされ方がちょっと予想外だった。
Macに環境を移行してから一ヶ月少々たちますが、その間、Flex、Textmate、mi、XCode等々いくつかのエディタ/IDEでFlashの開発を試みた。で、その結果は「やっぱFlashDevelopだよな」ということ。
ただやはり仮想環境ではなくOSX上でFlashDevelopを動作させたかった。だからwineやらmonoを試してみたけど、まだまだ時期尚早なようで、結局VMwareに戻ってきました。
そんなわけでそれなりに調子良くFlashDevelopを使ってるんだけど、やはり仮想環境なので若干気になる所がある。メモリリークや起動の遅さは言うまでものないが、特に気になるのが各種ショートカット。
例えばcmd+Tabで次のドキュメントへ移動するが、Macからこれを実行すると「アプリケーションの切り替え」が開くし、cmd+Qでコメントアウトだけど、「アプケーションの終了」だったりする。まあ、ここら辺はVMwareの環境設定でキーボードショートカットやキーボードマッピングを変えてやれば解決可能なんだけど、悩んだのはFlashIDEでのコンパイル。
通常、F6、或はcmd+Enterでファイルを保存してFlashIDEからTestMovieしてくれるんだけど、VMware上にはFlashIDEはないし(インストールしてない)、VMwareからMac上のFlashIDEをコールできない。ここは妥協かなあ〜と思った矢先、AppleScript(AS!)とQuickSilverで解決できる事に気がついた(力技っぽいけど)
具体的にはAppleScriptでFlashIDEをアクティブにしてcmd+Enterを押下するスクリプトを書く。そしてQuickSilverのTriggerに登録してショートカットを「cmd+Enter」とする。さらにscopeを「VMware Fusion」に設定する。これでOK!
*AppleScriptはよくわからないのでAutomatorを使ってコピペ&類推でごまかす。
**QuickSilverは最新版じゃないとscopeが機能しない。
そしてもう一工夫。FlashDevelopはコンパイル前にファイルを自動保存してくれるのでそれにも対応。FlashDevelopの「Save All」はデフォルトでショートカットが割り振られていないのでApplication Files の 「MainMenu.xml」に記載されていSaveAllを探して修正。適当にcontrol+Alt+Sとかを割り当てる。書式は他のコードを見ればわかるはず。
とまあこんな感じでVMware上のFlashDevelopからcmd+Enter一発でコンパイル可能になりました!応用すればFlexSDKでも出来るんじゃないかな。
今日の「AS(AppleScript)」
まあ、全然動かないんだけど、Mac上でFlashDevelopのネイティブ起動に成功した。
既にubuntuではこの件に成功しているという話なので、なんとかMacでも出来ないものかと、色々試してようやくここにたどり着いたが、残念ながら起動までで実用できるレベルには至らなかった。
もうちょっと粘ればそれなりに動くと期待したいけど、とりあえず成果報告。
大まかな手順は以下
1.wine インストール
(cf http://www001.upp.so-net.ne.jp/ito-hi/stat/winbugs.html)
2.fink インストール
3.cabexstra インストール
4.winetrick 実行
(cf http://blog.livedoor.jp/highfrontier/archives/51562797.html)
5.wineからflashdevelopインストール
6.wineからflashdevelop起動
7.数分後、落ちる
MIKUInstaller とか CrossOverMacもためしてみたけど、.NET Framewokのインストールがうまく行かずいろいろ試した結果、本家のwineHQをコンパイルしてインストール。
FlashDevelopは動かなかったけど、notepadとかその辺は動作を確認できた。なんとなくだけど、wine環境で.NETは鬼門なんじゃないかと思う。純然たる.NETアプリならmono上での動作が望ましいのかもなあ。
そんなわけで、まだまだVMWareから離れられそうにないなあ。トホホ
function crlf2lf(str:String):String {
str = str.replace(/\r\n/g, '\n');
return str;
}
AS2
function crlf2lf(str:String) {
var ary:Array = str.split("\r\n")
return ary.join("\n");
}
var loader:Loader = tf.getImageReference("img") as Loader ;
loader.load(new URLRequest("img.jpg"))
function comp(e:Event):void {
var loaderInfo:LoaderInfo = e.target as LoaderInfo
trace(loaderInfo.content.parent.parent);
//[object TextField]
trace(loader.parent);
//[object TextField]
}
と言うかんじでTextFieldが帰ってくるが、コレが解せない。だって、DisplayObject.parentと言うプロパティはDiplayObjectContainerの筈だ。そしてTextFieldはDisplayObjectContainerは継承していない。
DisplayObjectContainer(textField)と書くとコンパイルエラーが帰ってくる。
ちょっと前のエントリーで、「TextField内にロードした画像ってロード状況を監視出来なくて困ったもんだ」という旨の発言をしてしまったけど、実は間違いでした。スミマセン。
なんと、TextField内でもロードを監視できるようです。
大まかな流れは、Textfieldインスタンスから「getImageReference()」を使って<img src="foo.jpg" id="foge" />によって指定した表示オブジェクトを取得。更にLoaderクラスにキャストし、後は普通のLoaderと同じ。
具体的にはこんな塩梅です。var tf:TextField = new TextField()
tf.htmlText = '<img src="img.jpg" id="img" />';
addChild(tf);
var loader:Loader = tf.getImageReference("img") as Loader
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,comp)
function comp(e:Event):void {
var loaderInfo:LoaderInfo = e.target as LoaderInfo
trace(loaderInfo.content.parent.parent)
//[object TextField]
trace("complete")
}
いや~とうとう出るね!Progression 3!
実は個人的にはbetaが出る前くらいから実戦投入して使っています。ロクな検証もしないで、「ん、どうなってんだ?教えてnium先生!」とtwitter上で焦ってたのはボクです。ホント申し訳ありません。
他にも無理難題な追加機能を提案してみたり穴があったら入りたいですね。
そんなわけで今月下旬にリリース予定のProgression 3 のラウンチパーティーが9月4日に銀座アップルストアで行われるそうです。
詳しくはこちらhttp://event.progression.jp/
ちなみにどうでも良いけどその日はボクの誕生日です(...言っちゃた)
行きたいけど言ったら流石に家族のヒンシュクを買いそう。
最近、デザインパターンとかUMLとか、ウオーターホール的に言えば「上流」に近い事柄に対して感心が大きい。
ごりごりにコーディングとかも楽しいんだけど、ノート上にクラス図みたいなのを書いてるときも結構楽しい。ちなみに自分のスタイルは、初めは深く考えずコーディングしてみてラピッドプロトみたいなものができあがって来たところで「設計」みたいな事をする。
今のところ、UMLツールとかは使わずにマインドマップで書き起こしてみたり、ポストイットで家の襖にべたべた貼って、おお!Googleみたいだ!とか一人で喜んでいます。
ウオーターホールの教義に則れば設計から入るのが筋かもしれないが、いきなり設計から入るには設計力不足だし、第一楽しくない。正直プロジェクトの一番楽しい時期ってのは初期の気楽なコーディングとラピッドプロトまでが最高潮かもしれないと思う。ただ、この段階は「本当にうまくいくのかなあ~」みたいな不安も常に付きまとうので疲れるのも確か。
ついでに言うとラピッドプロトが上がってきた段階でデザインをアタッチするのも楽しい。ただこれはあくまでもデザインを発注されていればの話。
で、そこからはコードを見やすくしたり、可能な限りカプセル化したり、継承可能なクラスをまとめてスーパークラス作ったりする。パッケージなんかも一貫性を保つために整える。displayパッケージだったけど、これどう考えてもdataパッケージだよな~とか。他にSingletonクラスを作ったり、ミディエイタクラスを作るのもこの辺のフェーズ。ここら辺のデザインパターンの利用は、既に「それ」として機能しているものをより一層明確化するためにFogeMannagerとかHoo.singletonとか命名してやる。名前変更はトータスSVNでやって、うっかりsvn上での家系図が途切れないように留意、といいつつお家断絶しちゃったまま気付かず進めてしまう事多し。
みたいな感じで個人的には進めています。世の中のFlasherないしはASerもこんな感じなんだろうか。書いてみて思ったのは、つくづく自分はAS1、AS2、AS3と遷移してきたんだなと言うこと。もっと言えば「クリップアクション」→「タイムラインアクション」→「クラススタイルコーディング」と遷移してきたんだな~と感じた。ま、あくまでも個人的な感想だけど。でも、もし「その気持ちわからんでもないな~」という人がいればウレシイ。
おそらくJavaの人とかPHPの人とかRubyの人とかCの人とかはこういうスタイルは取らないんじゃないだろうか。ひょっとするとFlasherの中でも自分だけかもしれないけど。
2008/08/26 追記
このエントリーの後、よりスマートな方法でTextField内の画像を監視できる方法に気がついたので
コチラを是非ご覧ください。
textField.htmlText でhtml文書をFlash内で表示させるわけですが、html文書中にimgタグが含まれている場合、この画像のロードを監視することは困難です。(多分不可能だと思うけどどうかな?)
場合によっては完全にtextFieldが整形されてから表示させたかったりするのでこれは結構やっかいな問題です。しかも画像がロードされたあと若干レンダリングにズレが生じたりするので更に大変。
で、どうしようかと悩んだ末に「Event.CHANGE」をaddEventListenerすることにしました。
ここでの懸念は、そもそもhtmlText自体は何も変更されておらず、果たしてトリッガされるのか、という点でしたが、なんとばっちりトリガリング!(←こんな英語は多分ない)
多分文字組が変更されるから「Event.CHANGE」がdispatchされるのでしょう。
ソースはこんな感じです。 それでは。
tf.addEventListener(Event.CHANGE,changeHandler)
private function changeHandler(e:Event):void {
trace("-----------[changeHandler]")
}
こないだポストした「AS3的デザインパターンについての独り言」について、色々な方々からTwitterとかBlog上でコメントをいただきました。ありがとうございます。
で、大方の意見は
「Singleton.getInstance()をSingleton.instanceにするのは賛成だけどIterrator.next()をIterrator.nextにするのはどうかな...? あ、もちろんIterrator.hasNextはいいと思うよ!」
と言う感じでした。
なぜIterrator.nextが推奨されないのかというと、「next()は内包する配列のポインタを進めるという重要な操作を担っているので明示的にメソッドにしたほうがいい」という理由です。
ここら辺は自分でも迷ってたところなので、色々な方々のご意見を聞くことが出来て良かったです。
で、ここからは個人的な話で、なぜnextに、プロパティにしようと思ったのかについて。
そもそもはAdobeのコーディングガイドラインにプロパティベースのAPIの方がmxmlと親和性が高いと書かれている点です。mxmlを書いたことはほとんど無いですが、xml形式で開発するなら多分間違いなくその通りでしょう。
もう一つはTextFieldクラスなどで、" myTextfield.text = "helloworld"; " と書けばきちんと表示される点です。これは額面取りに「text」という「String型プロパティ」に値を格納しているだけではなく、内部的にゴニョゴニョと表示関係を操作しています。禁則処理もかけたり、自分で実装するのは絶対に避けたいような処理を行ってくれていると推測できます。
これはTextFieldクラスに限ったことではなく、Spriteクラス、これも同様です。たとえば" mySprite.x=100; " が額面通り「Number型のxプロパティ」に100を代入しているだけではないことは明らかです。実際には100という数値を受け取り、mySpriteをx軸の100ピクセルの位置へ配置し、描画しています。
もしASのgetter、setterの仕様が「プロパティ」として振る舞えないものであったなら、myTextfield.setText("helloworld") や mySprite.setX(100) と記述しなければならなかったかもしれません。
そう考えるととたんにgetter、setterの恩恵を実感出来て何でもかんでもプロパティとして実装したくなります。解っていただけたでしょうか??
さらに " myTextfield.text+="helloworld"; " が推奨されず " myTextfield.appendText("helloworld"); " が推奨されてる辺りも示唆に富んでいますね。
多分。
ActionScriptのコーディングで三角関数とか三平方の定理とかを使ってる時ってややこしいんだけど、これぞAS!な感じがして個人的には好きです。
ここら辺のコーディングにはプリミティブ値だけで計算してしまう場合と、Mathクラスを使う場合、Pointクラスを使う場合、と色々なやり方が考えられます。条件次第では、Math.sin()などが必須になる場合もありますが、何を使っても良い場合、そのパフォーマンスはどうなんでしょうか?
と言うわけでベンチマークを取ってみました。
処理内容は下図の三角形から線分cの長さを求める。

これを上記三種のコーディングで記述するとこうなる↓
これを1000万回くらいループしてやります。
すると、結果はこう↓
細かい実装方法は置いておいて、とりあえずプリミティブ値を計算しするのが一番早いことが解りました。Pointクラスはハッキリ言って戦力外。まあループ毎にnewしているので当然の結果だけど、newをループの外で実行してループ内で.lengthを参照する形にしても5,000msec以上かかっていたのでやっぱり遅い。
と言うわけでプリミティブ及びMathクラスが実行速度的には良さそう。ただココでも注意が必要。下記は計算結果で見て貰えば解るがb / Math.cos(θ);の計算結果だけ値が異なる。
とりあえずそんな感じで。以上、報告おわり。
ごはんとFlash(二杯目)に行ってきたよ。
当日は朝から鎌倉よりもう少し南端に近い、「油壺」という入り江で磯遊びをして現地入り。水着を持って行かなかったので全く泳げなかったのが悔やまれるが(だって泳いだらへとへとになってイベントで腑抜けになりそうだったから)磯遊びだけでもかなり楽しかった。そしてモーレツに日焼けしてしまって未だ肩から背中にかけて痛い。シャワーのお湯が痛い。いつまで続くんだろうか。
そんなこんだで現地には6時くらいに到着するも全然誰もいなかった(あたりまえか)。どうしようかと思案していると Saqoosha さんがいたのでご挨拶をしてお名刺頂戴。
そのあと適当に散歩してビール買って砂浜でボンヤリしていると最高に気持ちよくて気がつけば開演時刻になってて振り返れば人がいっぱい。とりあえず受付をすませる。ドリンクチケットでビールを貰うとSaqoosha さんとmurakenさんのセッションが始まる。
個人的にはmurakenさんの「Flashって初めはVJツールだと思ってた」という話が印象的だった。自分も当初、Flashに対するイメージは、「webサイトを作るツール」というより、「インスタレーションやメディアアート的なアプローチをするツール」だと思ってたからだろうか。
その後、呑みながら色んな人とお名刺を交換させていただく。ここら辺から結構呑んでたので所々記憶が危うい。しかもトイレにいって帰ってくると、拙作「黒藤院」が作例紹介されて、「このサイトの制作者様いらっしゃいませんか」と呼ばれているのであわてて前へ行く。なんかゴニョゴニョっと喋ったけどキンチョーしちゃって質問にそぐわない回答してたかもしれない。恥ずかしい。
余談だけど、司会をしていらした女性の方はてっきり喋り手さんだと思っていたらそうではないらしい。ちょっとびっくり。上手すぎです。
イベントも終盤になってからzkさんとかfeb19さんとお名刺を交換して、「いや~もっとサウンドプログラミング盛り上げていかないとダメですな」とか「DynamicSoundに期待大っす!」とか「sazamekiの勉強会しましょう!」とか「フーリエ変換とかって...」などなど、自分的には一番したかった話をした。
とまあ、そんな感じでした。
RadioHeadの新譜がGoogleCode上で公開されている。
GoogleCode上で、もちろん" ソースコード "付で。
いつの日か、この手のプロモーションを仕掛けてくれるアーティストが出てくるだろうと期待をしていたが、それがRadioHeadだったとはなんともおあつらえ向き。
トム・ヨークがやらないとすればビョークなんかもやってくれそうだけど、99年の彼の格言「world wide web は無意味な底引き網になってしまった」を思い起こすと凄くドラマチックだ。
兎に角、こうして、プログラミングがその他の表現フォーマットとチャンプルーされ、作品として堂々と立っているのが素晴らし。すごく嬉しい。
この嬉しさを名著、
「Foundation ActionScript3.0 Animation -Making Things Move!-」からの引用(もちろん超々意訳)で締めよう。
デベロッパー、とか デザイナーとかなんか色々呼び名はあるけどさ、
もういいんじゃないの?そろそろ言ってしまえよ! 「アーティスト」だって。
デザインパターンって読み囓っただけであんまりエラソーなことは言えないんだけど、素朴な疑問を書いておきたいと思います。未来の自分がアンサーしてくれることを祈って。
この分野では「Javaで学ぶデザインパターン」といったタイトルの書籍が多く見受けられ、自分もその手の書籍を読んだ。するとまあ、当然だけどjavaで書かれていて、変数や関数の定義は下記の如くだ。
String getName();
int myNumber;
これをAS3で書き換えるともちろん
function getName():String ;
myNumber:int;
という感じになる。戻り値が関数・変数名の前につくのか後に付くのかが異なり、初めは何か気持ちが悪いけどすぐ慣れるし大した問題じゃあない。
では、何が問題なのか。
それはgetter、setterにまつわる実装方法だ(あくまで、個人的に)
たとえばイテレータパターン。通常、javaでは「next()」「hasNext()」というメソッドを実装し、「next()」を実行するとシーケンシャルにデータを受け取る事を可能にしている。
「next()」はカプセル化された配列から、次のデータを順番に返すように実装され、「hasNext()」は最後に「next()」を実行した配列のインデックスが最後で無いかを真偽値で返す。つまり、次のデータがあるのか無いのかを教えてくれる。
「next()」と「hasNext()」は両者とも「戻り値を持つ」そして「引数を取らない」という共通点がある。これは外から見た場合、読み取り専用値と言えるのではないかと思う。とすればAS3で実装する場合は「get」アクセサを使って、「next」「hasNext」とプロパティ化してしまうべきなのでは無いかと思う。
実際のコードを書けばこうだ。
public function get hasNext():Boolean{
return (index < str_ary.length)
}
public function get next():*{
return str_ary[index++]
}
そして、使用する場合は
if(iteratot.hasNext){
var data:* = iterator.next
}
とすればすっきりしていいんじゃないかと思う。同じ理由でsingletonモデルなんかでも「Singleton.getInstance()」ではなく「Singleton.getInstance」にするとか、プロパティなのに動詞がダメというなら「Singleton.uniqInstance」にするとか、いっそ「Singleton.singleton」にすればいいんじゃないかと思う。
もちろん、こうして従来の命名を多少なりとも変更することはあまりいいことではないと思う。特に「getInstance()」と書かれていれば一目瞭然でSingletonモデルであることが解る。これはすごく重要な事だ。でも「Singleton.singleton」とか手が無いわけでもない。
そして、もう一つ重要なことに「AdobeがプロパティベースのAPIを推奨していると言うことだ。」ココを読んでみるとどうやらそれっぽい事が書いてある。
Property-based APIsFavor property-based APIs rather than method-based APIs, because these are more suitable for declarative-style MXML programming.
プロパティベースのAPIのほうがメソッドべースよりオススメさ!だって、MXMLで開発するときそっちの方がいいんだもん。
そろそろ、「JavaとかC++から載せ替えただけのデザインパターン」ではなく「AS3、というかECMAScriptの利点を引き出したデザインパターン」が必要な時期ではないかと、思う。
おわり。
7/20に鎌倉で開催されるごはんとFlashに行きます!
前回は偶然にも他のイベント(ミーティング?)とバッティングした為不参加となってしまったが、今回は万全を期してエントリーに挑んだ。
いや、万全はウソかも。
エントリー当日は「本日のタスク」に項目を立ててまでエントリーに望んだけど、何か色々やってるウチに気がつけばエントリー開始の10分前。あわててサイトをチェックするがまだ告知は出ていない。twitterを眺めると「まだ告知でないね」みたいな発言がチラホラあってしばし安心。
で、漸く告知が出てエントリーフォームに進むが予想以上のビジー状態でフォームが表示されず。そうこうしてるうちにtwitter上で「オレ一番乗り~」みたいな発言が出始めいよいよ焦る。その後も表示されず、更にtwitterで「2番手かな~」とか「このタイミングで漏れたら泣ける」みたいな発言が出始めた時点でPowerBookを立ち上げてsafariにてアクセス。
何か知らないけどsafariだとスル~と辿り着いて、そのまま登録。
しかし、あまりに焦っていたため「備考欄」が空白のまんま。
まあでも無事に申し込み完了メールが届いて良かった。なんでも開始から30分で満席になったそうだから、これは凄い人気だ。safariに乗り換えなかったらやばかったかも。
そんなわけで当日はどうぞ宜しくお願い申し上げます
早くもFP10b2が出ましたね!やるじゃんAdobe! イイペースだね!
で、さらりとリリースとかを読んでみたところ、Linuxがどうした~、とかGraphicカードが~、とかフルスクリーンが~云々と書いてあります。
なんかSound周りもなんか追加されたみたいです。いまいち解らないけど「Speexコーデック」とやらが追加されたみたいで、なんでもオープンソースの声圧縮エンコーダーだそう。具体的な使用例があんまり思い浮かばないけど、多分マイクロフォンの音声圧縮に使うんでしょう。
何にせよ楽しみ。
長らく、正規表現とかデータベース周りの作業は「サーバサイド技術者に任せてFlasherはやらなくてもいいんじゃないの?」 というアティテュードを貫いてきた訳ですが、ちょっと用事が出来たのでURLを抜き出してリンクを貼り付けるスクリプトを書きました。
mixiなんかでhttp://~を入力して日記を書くと、自動的にリンクを張ってくれるアレです
var pattern:RegExp = /https?:\/\/[-_.!~*'()\w;\/?:@&=+$,%#]+/gi;
とりあえずURLにマッチする正規表現はこれでいいはず。
コチラを参考に、AS3でちょこっと書き直しただけなので多分間違ってないと思う。
これを元に静的メソッドを持つクラスを作る(クラス名は適当)↓
package {
public class URLMarkUp {
public static const BLANK_WINDOW:String = "_blank"
public static const SELF_WINDOW:String = "_self"
/**
* @param source URLを含む文章
* @param window LINKを開くときのウィンドウ
* @return URL部分をマークアップした文章全体
*/
public static function markUpURL(source:String,
window:String = SELF_WINDOW):String {
var pattern:RegExp = /https?:\/\/[-_.!~*'()\w;\/?:@&=+$,%#]+/gi;
var markup:String = "<a href=\"$&\" target=\""+window+"\">$&</a>"
var htmlStr:String = source.replace(pattern, markup)
return htmlStr;
}
}
}markUpURL()にURLを含むソース文章を第一引数に渡し、第二引数にはターゲットウィンドウを渡します。するとaタグをくっつけた文章全文を返してくれます。
実際に使うときはこんな感じで。 ↓
package{
import flash.display.Sprite;
import flash.text.TextField;
public class Main extends flash.display.Sprite {
public function Main():void {
var textField:TextField = new TextField();
addChild(textField)
textField.width = 500
textField.height = 500
textField.wordWrap = true
var str:String = "my weisite is http://abc.com and secure https://secure.bar.com/asaこれがワタシのwebですHTTP://www.foge.netついでにクエリーもhttp://secure.bar.com/?p=(2)_34!$5&"
textField.htmlText = URLMarkUp.markUpURL(str, URLMarkUp.BLANK_WINDOW);
}
}
};
アーカイブはコチラ
*イマイチ正規表現って自信が無いのでもうちょっと勉強します。ご使用はあくまでも自己責任でお願いいたします。
If a class overrides a method and wants to continue to expose the base method, it should do so by implementing a method whose name is the base name with a $ prepended. This method should be marked final and should do nothing more than call the supermethod.
mx_internal final function $addChild(child:DisplayObject):DisplayObject
{
return super.addChild(child);
}
だそうです。
あの伝説的ライブ「ChaccaManShow」が大成功を収めて早一週間。あの熱狂も漸く落ち着きを取り戻したようなので、少し映像にまとめてみた。
実際のライブ映像は撮影していないので、これはライブ後にChaccaManShowをスタンドアロンで演奏し、スクリーンキャストしたものを、更に編集している。
見ていただければなんとな~く解ってもらえるかもしれないけど、炎の位置によって音の高低が変化している。技術的には動体検知ではなくハイライトだけを拾う光センサーに近い仕様。なんとなく画像とサウンドが同期が怪しく、「え?インチキくせえな..」と思われるかもしれないが、決してインチキではありません。
オーディエンスの反応は前々回辺りのエントリーにも書いたが、それなりに上々だったみたい。アンビエントとかメディアアート的な解釈をしてくれたみたいでこちらとしてはひと安心。
個人的にはやっぱり線香花火っていいな~、と。
今後の展開としては、やっぱり自分一人だけ自宅にいるのはどうにも面白くないので、会場に行きたい。けどそうしちゃうと「ネット」という属性からはずれてしまうので、二カ所同時ライブがいいのではないかと思う。
つまり、東京と京都で同時にライブを開催して、相互通信でインプロビゼーションするとか。きっとすごく面白いと思う。
いづれ必ず!
netStream = new NetStream(netConection)
netStream.send("hogeFunc","foo")
前回告知した、Flash Web ライブ「Chacca Man Show」は無事に終了することができました。
スタッフの皆さん、手伝ってくれた友達、イベントオーガナイザー、お店の店長さん、皆さんどうもありがとう。

パフォーマンスの内容はというと「Chacca Man Show」の名前が示すとおり、炎を使った演奏。そしてもちろんストリーミングによるインターネットライブ。
東京からビデオ配信、京都で受信、動画を解析、音声合成という流れをFlashとFlashMediaServerで構築。Astroを使ったネットライブとしては一番乗りなんじゃ無いかと思うけどどうなんだろ。
で、肝心のお客の盛り上がりなんだけど、全く不明。自分的には若干メリハリが悪い部分もあったが、それなり盛り上がったのではないかと思う。というかそうであって欲しい。自己評価としては79点ってところ。
オーガナイザーのカイト氏曰く、「なんかさ~サプライズみたいな感じで良かったね!」とのこと。
自らも出展しかつ設置に協力してくれた50R氏は、「Tenori-onの動きっぽかった、そうとう研究したね!?」とのこと。Tenori-onの音じゃなくて動きってどういう事なんだ?Tenori-onは甲斐性さえあれば今すぐにでも欲しいナンバーワン・アイテムで何度も動画を視聴したけど、動きって言われても...
そんな感じで、そこそこの評価を得たと思って問題はなさそうだが、やはり自分が現場の空気を感じていないのでなんとも不安。そしてなんとなくライブをやったという実感に乏しい。これがリモートライブの宿命と言えばその通りなんだけど、次回があるならそこら辺をもうちょっと違う形で解決したい。
と、言うわけで今週末6月22日(日)、ライブに出ます。
京都にあるライブハウス、nano(map)にて行われるLiving Special Destiny (lsd) というイベントのちょっとした枠でパフォーマンスします。
お近くにお住まいの方は是非お越しください!インスタレーション、ペインティング、映像、ファッションデザイン、その他盛りだくさんのコンテンツでおもてなしいたします。間違いなく楽しいです。たぶん。
ただし当日、河童研究員はいません。
video.attachNetStream( null ); //ここ、試験に出るかも bmd.draw(video); video.attachNetStream(ns);
Tweener.addTween(oto,
{frequency:OTO.RE, time:0, delay:.5,transition:"linear"});
Tweener.addTween(oto,
{frequency:OTO.MI, time:0, delay:1,transition:"linear"});
Tweener.addTween(oto,
{frequency:OTO.RE, time:0, delay:2,transition:"linear"});
Tweener.addTween(oto,
{frequency:OTO.DO, time:0, delay:2.5, transition:"linear"});
Tweener.addTween(oto,
{frequency:OTO.MUTE, time:0, delay:3,transition:"linear"});
Tweener.addTween(oto,
{frequency:OTO.DO, time:0, delay:3.5, transition:"linear"});
Tweener.addTween(oto,
{frequency:OTO.RE, time:0, delay:4,transition:"linear"});
Tweener.addTween(oto,
{frequency:OTO.MI, time:0, delay:4.5,transition:"linear"});
Tweener.addTween(oto,
{frequency:OTO.RE, time:0, delay:5,transition:"linear"});
Tweener.addTween(oto,
{frequency:OTO.DO, time:0, delay:5.5, transition:"linear"});
Tweener.addTween(oto,
{frequency:OTO.RE, time:0, delay:6,transition:"linear"});
Tweener.addTween(oto,
{frequency:OTO.MI, time:0, delay:7.5,transition:"linear"});
Tweener.addTween(oto,
{frequency:OTO.RE, time:0, delay:7.7,transition:"linear"});
Tweener.addTween(oto,
{frequency:OTO.DO, time:0, delay:7.9, transition:"linear"});
Tweener.addTween(oto,
{frequency:OTO.MUTE, time:0, delay:8.3, transition:"linear"});
package {
import flash.media.Sound;
import flash.events.SamplesCallbackEvent;
import flash.media.SoundChannel;
import flash.media.SoundTransform;
public class OTO extends Sound{
static public const TWELEVE_TONE_SCALE:Array =[220,
233.08,
246.94,
261.63,
277.18,
293.67,
311.13,
329.63,
349.23,
369.99,
392,
415.31,
]
static public const MUTE:Number = 0;
static public const DO:Number = TWELEVE_TONE_SCALE[0];
static public const DOs:Number = TWELEVE_TONE_SCALE[1];
static public const RE:Number = TWELEVE_TONE_SCALE[2];
static public const REs:Number = TWELEVE_TONE_SCALE[3];
static public const MI:Number = TWELEVE_TONE_SCALE[4];
static public const FA:Number = TWELEVE_TONE_SCALE[5];
static public const FAs:Number = TWELEVE_TONE_SCALE[6];
static public const SO:Number = TWELEVE_TONE_SCALE[7];
static public const SOs:Number = TWELEVE_TONE_SCALE[8];
static public const RA:Number = TWELEVE_TONE_SCALE[9];
static public const RAs:Number = TWELEVE_TONE_SCALE[10];
static public const SI:Number = TWELEVE_TONE_SCALE[11];
static public const A:Number = TWELEVE_TONE_SCALE[0];
static public const B:Number = TWELEVE_TONE_SCALE[1];
static public const H:Number = TWELEVE_TONE_SCALE[2];
static public const C:Number = TWELEVE_TONE_SCALE[3];
static public const Cs:Number = TWELEVE_TONE_SCALE[4];
static public const D:Number = TWELEVE_TONE_SCALE[5];
static public const Ds:Number = TWELEVE_TONE_SCALE[6];
static public const E:Number = TWELEVE_TONE_SCALE[7];
static public const F:Number = TWELEVE_TONE_SCALE[8];
static public const Fs:Number = TWELEVE_TONE_SCALE[9];
static public const G:Number = TWELEVE_TONE_SCALE[10];
static public const Gs:Number = TWELEVE_TONE_SCALE[11];
private const SAMPLEING_RATE:Number = 44100
private var refreshRate:uint = 4410
private var herts:Number = 220
private var _frequency:Number = 220
private var _volume:Number = .5
private var ampEnd:Number =0
public function OTO() {
init()
}
private function init():void{
this.addEventListener("samplesCallback",sineWavGenerator);
}
public function start(toneScale:Number = 220):SoundChannel{
this.frequency = toneScale
return this.play()
}
private function sineWavGenerator(event:SamplesCallbackEvent):void {
var rate:Number = SAMPLEING_RATE
var refreshRate:Number = this.refreshRate
var amp:Number
var freq:Number = (Math.PI * 2) * frequency / 44100;
var volume:Number = this.volume
for ( var c:int=1; c <= refreshRate; c++ ) {
amp = (c * freq) + ampEnd
var sample:Number = Math.sin(amp) * volume
this.samplesCallbackData.writeFloat(sample);
this.samplesCallbackData.writeFloat(sample);
}
ampEnd = amp
}
public function get frequency():Number { return _frequency; }
public function set frequency(value:Number):void {
_frequency = value;
}
public function get volume():Number { return _volume; }
public function set volume(value:Number):void {
_volume = value;
}
}
}
for ( var c:int=0; c<512; c++ ) {
amp = (event.position + c) * freq
var sample:Number = Math.sin( amp ) * 0.5
sound.samplesCallbackData.writeFloat(sample);
sound.samplesCallbackData.writeFloat(sample);
}
for ( var c:int=1; c <= 512; c++ ) {
//前回のサンプル末尾に加算
amp = (c * freq) + ampEnd
var sample:Number = Math.sin(amp) * 0.5
this.samplesCallbackData.writeFloat(sample);
this.samplesCallbackData.writeFloat(sample);
}
//サンプルの末尾を保持
ampEnd = amp
最近、カメラマンの友達に「Flashが遂に縦書き出来るようになったんだよ!!すげーよ。革命とはこのことに違いない!」と大興奮で話したら、「え?何それ。Flashってそんなことも出来ないの。サッブー」と言われてしまった(誇張アリ)。
まあ世間の反応としてはこれが平均値だろう。確かにランタイム上でサウンドの生成やバイナリレベルの処理に加え動体検知なんて事が出来るようになったこのご時世に「縦書き」が実装されるって言うのは何となくアンビバレントな感じがしないでもない。一般的に「縦書き」なんて「出来て当たり前 」だからだ。この話を聴いた彼はひょっとすると、「今まで何の開発してたんだ?」と思ったのかもしれない。
だけど、もう一度考えてみよう。このテキストエンジンの名前は「EastAsianJustifier」、つまり東アジア向けってことなんだ。僕たちが「アタリマエ」と思っている「縦書き」を使う文化圏は必ずしも多数派ではない。むしろ少数派なのだ。Adobeにしてみれば「何でアジアの一部だけの為にこんな実装しなきゃなんねえんだよ」と思ってるかもしれない。
というわけでAstroのflash.text.engine.EastAsianJustifierで縦書きを作ってみた。
http://memo.kappa-lab.com/swf/eastAsianJustifierExample.swf
(要 FlashPlayer10)
公式リファレンスのソースに少し手を加えただけですが、リファレンスを見る限りだと、かなり力業で縦書きにしている様子です。まず、テキストを保持するコンテナ(TextBox)を用意してそこにテキストを格納、そこから一行づつ文章を生成(TextLine)してaddChildeする。行間はTextLineのx座標でコントロール。
う~ん。なんか力業すぎるんじゃないの?
行間がx座標って!
それと、現時点でテキストの選択が出来ないみたい。TextFieldのselectableに相等するプロパティが見つからない。でもって、カギ括弧あたりの字詰めが怪しい。というか崩れている。
当然beta版なのでこれから色々と改良されていくと思いますが、とりあえずFlashの縦書き元年を祝って、乾杯。
今月中頃にリモートライブを企画しておりまして、その為の準備として、手始めにhetemlのFMS(FlashMediaServer)でビデオキャストしてみた。そしたら案の定躓いたのでメモ。
hetemlさんの「WEBカメラからの映像配信マニュアル」には親切なことにflaファイルまで含めたサンプルがおいてあるんだけど、残念ながらAS2でコーディングされている。これじゃあ「samplesCallback」とか使えないのでAS3で作ってみた。
ポイントは2カ所。
nc.objectEncoding = ObjectEncoding.AMF0;AS2の時は上記の指定は必要なかったけど、AS3だと必須みたいで、明示的に指定しないと接続できない。
Video.attachNetStream();こちらはAS2のときは「attachVideo()」でよかったんだけど、AS3では「ストリーミングですよ!」って感じのメソッドに変更されている。
とりあえずはビデオ配信の為だけど、今後色々とFMSを使った企画を考えてみたいと思います。了
参考サイト Flash Media Server 2メモ
ソースはこちら *Sender.asが配信側で Receiver.asが受信側
Sender.as
package {
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.*;
import flash.media.Camera;
import flash.media.Video;
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.net.ObjectEncoding
import flash.text.TextField;
public class Sender extends Sprite {
//rtmp://サーバー名/アプリ名/{任意}インスタンス名
private var PATH_FMS:String = "rtmp://foo.fms.heteml.jp/watch"
private var camera:Camera
private var video:Video;
private var nc:NetConnection;
private var ns:NetStream
private var textField:TextField
public function Sender() {
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
init();
}
private function init():void{
//debug用にテキストフィールド生成
textField=new TextField();
textField.text="FMSConnectEx";
addChild(textField);
textField.y = 300
textField.width = 400
//カメラのセットアップ
setCamera();
//ネットワーク接続
connectFMS();
}
//カメラのセットアップ
private function setCamera():void{
camera = Camera.getCamera();
if (camera != null) {
video = new Video(camera.width, camera.height);
video.attachCamera(camera);
addChild(video);
}
}
//ネットワーク接続
private function connectFMS():void{
nc = new NetConnection();
//AMF設定!
nc.objectEncoding = ObjectEncoding.AMF0;
nc.addEventListener(NetStatusEvent.NET_STATUS,onNetStatus);
nc.connect(PATH_FMS);
}
//ネットワーク接続イベント
private function onNetStatus(e:NetStatusEvent):void {
textField.text = "" + e.info.code;
if (e.info.code == "NetConnection.Connect.Success"){
//ストリーム送信
sendStream();
}
}
//ストリーム送信
private function sendStream():void{
ns = new NetStream(nc)
ns.attachCamera(camera)
ns.publish("video")
ns.addEventListener(NetStatusEvent.NET_STATUS,
function(e:NetStatusEvent):void{
textField.appendText(e.info.code)
})
}
}
}
package {
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.*;
import flash.media.Camera;
import flash.media.Video;
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.net.ObjectEncoding
import flash.text.TextField;
public class Receiver extends Sprite {
//rtmp://サーバー名/アプリ名/{任意}インスタンス名
private var PATH_FMS:String = "rtmp://foo.fms.heteml.jp/watch"
private var camera:Camera
private var video:Video;
private var nc:NetConnection;
private var ns:NetStream
private var textField:TextField
public function Receiver() {
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
init();
}
private function init():void {
textField=new TextField();
textField.text="FMSConnectEx";
addChild(textField);
textField.y = 300
textField.width = 400
video = new Video()
addChild(video)
//ネットワーク接続
connectFMS();
}
//video受信
private function receiveVideo():void{
ns = new NetStream(nc)
ns.play("video");
//videoに直接ストリームをattach
video.attachNetStream(ns)
ns.addEventListener(NetStatusEvent.NET_STATUS,
function(e:NetStatusEvent):void{
textField.appendText(e.info.code)
})
}
//ネットワーク接続
private function connectFMS():void{
nc = new NetConnection();
nc.objectEncoding = ObjectEncoding.AMF0;
nc.addEventListener(NetStatusEvent.NET_STATUS,onNetStatus);
nc.connect(PATH_FMS);
}
//ネットワーク接続イベント
private function onNetStatus(evt:NetStatusEvent):void {
textField.text = "" + evt.info.code;
if (evt.info.code == "NetConnection.Connect.Success"){
//video受信
receiveVideo();
}
}
}
}
powerd by as2html
FlashDevelopでAstro環境を作った。しかもFlashPlayer10betaのインストール無しで。「Astro環境作りたいけど本番環境にbetaプレイヤー入れんのヤダな」というあなた、おすすめです。
[構築フロー]
[1] ダウンロード
Adobeの公式サイトからDL
現時点での最新版「3.0.1.1991」をDLし、任意のディレクトリに展開(ここではC:\flex_sdk_301とする)
[2] FlexSDKのコンフィグ修正
Flash Player 10 + FlashDevelop で遊ぶ (from 馬鹿全 ) こちらを参考にconfigを修正。
Adobe公式はこちら
[3] FlashDevelopのAstroパッチ適用
FlashDevelopの公式サイトからFD3_Debug_rev2297.rarをDL、解凍しFlashDevelopのファイルを上書きする(XPならC:\Program Files\FlashDevelop 直下のファイルすべて)この際、SettingsやらSnippetsが初期化されるので、バックアップを取っておく。復元するはC:\Program Files\FlashDevelop\FirstRun以下のファイルを上書きする
[4] swfファイルのデフォルトアプリをAstroにする
任意のswfファイルを選択してコンテクストメニューを出す
プログラムから開く>プログラムの選択>参照>
と進んで、「C:\flex_sdk_301\runtimes\player\10\win\FlashPlayer.exe」を選択する。これで常にswfファイルがFlashplayer10betaで実行される。
[5] FlashDevelopでAS3プロジェクトを作る
FlashDevelopでAS3プロジェクトを作る。ここでは「Default Project」を選ぶ。

Project>Propaties>CompilerOpetions から
「Custom Path to FlexSDK」 に 「C:\flex_sdk_301」、
「External Libraries」 に 「C:\flex_sdk_3.0.1\frameworks\libs\player\10\playerglobal.swc」
最後に
Output >Pratform > target を 「FlashPlayer10」、
Output >Test Movie を 「Play in external player」
package {
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.events.SamplesCallbackEvent;
import flash.media.Sound;
import flash.text.TextField;
import flash.utils.getTimer;
use namespace astro;
[SWF ( frameRate="40")]
public class Astrotest extends Sprite{
private const RATE:Number = 44100
private var frequency:Number = 220
private var textField:TextField = new TextField()
public function Astrotest(){
for(var i:int = 0; i < 8; i++){
createKey(i)
}
createDebuger();
var sound:Sound = new Sound();
function sineWavGenerator(event:SamplesCallbackEvent):void {
var rate:Number = RATE
var amp:Number
var freq:Number = (Math.PI * 2) * frequency / 44100;
for ( var c:int=0; c<512; c++ ) {
amp = (event.position + c) * freq
var sample:Number = Math.sin( amp ) * 0.5
sound.samplesCallbackData.writeFloat(sample);
sound.samplesCallbackData.writeFloat(sample);
}
}
sound.addEventListener("samplesCallback",sineWavGenerator);
sound.play();
}
private function createKey(index:int = 0):void{
var ary:Array = [220, //ド
246.942, //レ
277.183, //ミ
293.655, //ファ
329.628, //ソ
369.994, //ラ
415.305, //シ
440] //ド
var key:Sprite = new Sprite()
key.buttonMode = true;
key.graphics.beginFill(0xff0000)
key.graphics.drawRect(0,0,50,50)
key.graphics.endFill();
key.addEventListener(MouseEvent.MOUSE_DOWN,
function ():void{
frequency = ary[index]
textField.appendText(frequency.toString() + ", ");
})
addChild(key)
key.x = index * 70;
}
private function createDebuger():void{
addChild(textField)
textField.text ="debuger"
textField.wordWrap = true
textField.width = 800;
textField.height = 800;
textField.y = 200
}
}
}
今日はsmalltalkなどを少々たしなんでみた。
いや、「たしなんだ」と言えるほど理解できたわけじゃ無いけど、とりあえずweb上のリソースのリサーチと、開発環境のinstall、「Hallo World」までやってみました。工数は夕飯喰ってからビール呑みつつ4時間ってとこかな?
一応環境はこんな感じで進めています。
開発環境:VisualWorks7.6
http://www.nextindex.net/pgm/smalltalk.html
教科書:Smalltalk Textbook (in Japanese)
http://www.sra.co.jp/people/aoki/SmalltalkTextbookJ/index.html
そのた:
http://smalltalk.cincom.jp/scripts/smalltalk.dll/
tutorials/vw7.4/tutorial2/weblogstatstoc2.ssp
なぜここに来てsmalltalkなのかと言うと、聡明期のOOPに触れてデザインパターンとかMVCとかMMVCとかをさらっと語れるようになったら、30代を目前にモテ期が訪れのではなかろうかというスケベ心からだ。従って、smalltalkでコンテンツを作るつもりはなく、あくまでもプロトタイプ制作や、概念理解のためなのだ。そして最終的にはActionScript上で成果を結実させれたらいいな~と思う。
そして、もう一つ。smalltalkで学ぶMVCとかプラガブルMVCをActionScriptに移植して公開したら結構なモテコンテンツになるんじゃ無いかと思うけど、どうでしょうか?勝ち組になるでしょうか??
まあこの手の「次回コンテンツ予告」は果たせられなかった前科があるので、あまり大きな事は言わないでおこう。あ、ちなみに「前科」と書いてしまったが、一応「5歳から始めるActionScript3」の草稿はあるのだ。ただ、ひっぱったわりに貧弱な内容なので公開するのが憚れる、というのが本音。
今年の春はたくさん写真を撮った。
この手の写真は好きなんだけど、飽きやすくもあり、ちょうどフンイキの良いcafeでかかっている、これまたフンイキのよいエレクトロニカに似ているのではないかと思う。
出張の時に「ひょっとして聴きたくなるかもしれないからiPodに入れておくけど結局聴かない楽曲」とかにもよく似ている。
なんというか、そこにあれば安心する、安心さえ与えてくれればそれで十分。な存在とでも言えばいいのだろうか。
ただそれと同時に、「雲とか空の写真って、むかつくねん」と言った友達の言葉を思い出してなんとなく同意したりもする。
個人的にそんな感じのニュアンスの写真をコンパイルしてギャラリーにしてみました。BGMとか効果音は、今話題の5月12日に発売される「TENORI-ON」から。
それでは「聴いて」ください。
Twitterでごにょごにょ呟きながらLivedoor LISLOGのアンケートを2.3個作ってみたので、まとめました。
皆さんも是非、お声をお聞かせください。
「いつからFlasher?アンケート」
初めてFlashに触れたのはどのバージョンでしたか?というアンケート。もちろんfuture Splashもお答えいただけます。
「ActionScriptコーディングに使用しているエディタについてのランキング」
AS書くのにつかってるエディターないしは開発環境についての質問です。Lislogの仕様がよく分かっていないので後付でFDTを加えてしまいました。すんません。
「ActionScriptの変数名で「$」って使いますか?」
仕様上、$マークを変数名に含めることが出来ますが、皆さんお使いでしょうか?
「"{"の前に改行するか、後でしますか?」
はじめてLislogでつくった記念すべき(?)第一作目アンケートです。ちょっとややこしい聞き方なのでこちらもご参考に
血相が若干かわるほど少し焦ったのでメモ。
FlashIDE(CS3) で以下のコードはコンパイルされるのですが、
addEventListener(Event.ENTER_FRAME,function(){trace("ok");})
FlashDevelop(mxmlc) だとこんなコンパイルエラーをはきます。
警告: return value for function 'anonymous' に型宣言がありません。
addEventListener(Event.ENTER_FRAME,function(){trace("ok");})
一瞬、匿名関数に型宣言「Function」を付けろって事なのかと思い、
addEventListener(Event.ENTER_FRAME,function:Function(){trace("ok");})とかあり得ないコードを書いてみたけど、やっぱりダメ。
実は何のことはなく戻り値を指定してやれば良かったようです。つまりこう。
addEventListener(Event.ENTER_FRAME,function():void{trace("ok");})
「:void」が必要だった訳です。
「'anonymous' に型宣言がありません。」じゃなくて
「'anonymous' の戻り値に型宣言がありません。」
って言ってくれればいいのに。
「超絶英才教育!5歳から始めるActionScript3.0」を開催しました。(開催ってほどのモノではない)
英才教育と言えば英会話が王道だけど、前衛的超絶英才教育って事でなんと5歳児にActionScriptを教えてみることにした。
「子どもは大人のモルモットじゃねえぞ!」と突っ込まれそうだけど、そういう性質のものでは無く、ワークショップ的な雰囲気で家庭教師をしてみました。
講師:不肖、河童研究員
生徒:A君、5歳
教材:FlashCS3
時間:45分
まずA君について紹介。A君は今年の4月で5歳になった健康優良男児。日常会話はOK。ひらがな、カタカナは8割くらい読める。書くのは5割くらい。濁音で点々の数を間違えたりする。英語はもちろん知らない。しかしアルファベットをみると「英語だな」とそれなりに認識可能。
数は224まで数えられる(なぜ半端なのかよく分からない)。足し算は1+1とか2+2はOK。繰り上がるとダメ。引き算はまだわからない。
「地下鉄の線路にはどうして石がないの?」的な疑問を抱く、至って子どもらしい男の子。
「おいおい、これで一体何を教えるつもりなんだよ」と思われるかもしれないが、これだけのスペックがあれば十分。それでは本題に移りたい。
まずは早速、今回書いたコードを大公開!
ball.x = 100;
ball.y= 100;
そう、たったの2行だけ!
しかし、たった2行に広大な宇宙が詰め込まれているのだ。
次回は実際のやりとりをふまえつつ全容を公開。乞御期待!
毎度お世話になってます。FlashDevelop Beta7を入れてみました。
全体的な印象は、「GUIベースでカスタマイズ出来るところが増えた」ってな感じ。
「Program Setting」からカスタマイズ出来る項目が増えた様子。ただ、コードフォーマットとかは相変わらずXMLベースみたい。ちなみにBeta4の時から使っている「Settings」フォルダ以下のファイルをそのまま使ってみて何の問題も無かった。
で、個人的にとても困ったことが発生したのでそれの解決方法をメモ。
function foo():void{
var hoge:int = 2;
}
上記コードが示すように、個人的には「{」の後に前に改行したくない派なんですが、beta7はデフォルトで改行してくれます。
つまりこう↓↓↓
function foo():void
{
var hoge:int = 2;
}
どうやったら、解除できるのか色々調べた結果、
「Program Setting >> ASCompletion >> Charactors Requiring WhiteSpace」から「{}」を削除してやれば良いことが分かりました。いや~ここにたどり着くのに2時間くらいかかったかも。
半年ほど前
に制作した「DRMdeUtaho」というものっすごいシンプルなシーケンサーアプリのブログパーツが出来たのでリリースしてみた。このアプリがどれくらいシンプルかというとその名が示すとおり、「ド、レ、ミ」の三音しか使えないという点。もちろんシーケンサーとしてはなんの役にも立たないのだけど、それなりに喜んでくれる人はいたみたい。多分。
で、今回はそのブログパーツをリリース。「なんで半年も経ってからなのよ」とはごもっともな意見なんだけど、実はもうすぐブログパーツの案件があるかもしれないのでその手習い用に作ってみた次第。
MySQL+PHP+ActionScript3.0+JavaScript というインフラなんだけど、だいたいのイメージは掴めたと思う。おそらく世の中に出回っているFlashブログパーツとインフラ的には大差無いだろうからこれで十分じゃないかと思う。
で、能書きが長くなったけどブログパーツ貼り付け用コードはこちら。
<script type="text/javascript" >var drmSoungID = 21; </script>
<script src="http://memo.kappa-lab.com/catapio_test/DRMblogparts.js" language="javascript" type="text/javascript" ></script>
一行目の「drmSoungID」の値に自分の聞きたい音源のIDを打ち込めばOK。音源のIDはプレイリストをマウスオーバーすることで表示。(山吹色の9ptぐらいで表示される)
とりあえずwebアプリ、ないしはwebサービスとインフラとしてのブログパーツが出来たので、もうちょっと楽しい音ゲー的Flashコンテンツを作ってみたいなぁ。
AS2時代のFlashvarsは_level0.fogeで参照出来たけど、AS3で仕様が変わったので、今更ながらのメモ。
for (var i:String in loaderInfo.parameters) {
とまあこんな感じ。
上記コードではテキストフィールドにflashvarで渡した値を全て列挙。
textField.appendText(i + ":" + vars[i] + "\n");
}
テキストフィールド生成を含めたコード全体は下記。
var textField:TextField = new TextField()
addChild(textField)
textField.width =400
for (var i:String in loaderInfo.parameters) {
textField.appendText(i + ":" + vars[i] + "\n");
}
HTML側の記述はAS2時代と同様
<param name="flashvars" value="username=Thomas&userid=10" />
<embed src="parameters.swf" flashvars="username=Thomas&userid=10" name="flashvars".....
AC_RunActiveContent.jsを使っている場合は
AC_FL_RunContent(
------
'FlashVars', 'username=Thomas&userid=11',
------
);
でいいかな。
兎に角良く忘れるからメモ。
SoundMixer.soundTransform = new SoundTransform(1);
Adobeのドキュメントには「グローバルボリューム」と書かれていて、
「マスターボリューム」で検索しても引っかからないのがなんとももどかしい。
「グローバルボリューム」なんて言い方するかね?フツー。
調べてたら、これもよさそうだな~と思った。
AS3で音のボリュームやパンを操作する
珠玉のASライブラリプロジェクト、「Spark Project」のこの記事「Spark project ソースコード貼付けブログパーツのサンプル」を読んでおそらく1万人くらいがこの表現を頭に浮かべた事だろうと思う。
そして、浮かんだと同時にあまりにも手垢にまみれた手法故に、脳内で即ボツになったはずだ。
そんな低い山を登って見ました。
ただ、八割がた書いたところで、クロスドメインポリシーの事を思い出して、「SparkProjectのasコードに直接手が届かないじゃ...」と思ったら、案の定、「セキュリティサンドボックス侵害」に見舞われてしまった。
間にPHPとか咬ませれば何とかなるだろうけど、今はとりあえずこのFlashのソースコードでも表示しておきます。ちなみに「SVN」はダミー。「DL」は「Main.txt」が開きます。hetemlサーバーは「.as」ファイルをロードすると、FMSが作動するからだと思うけど、DL出来ない。
PhoshopExpress使ってみたよ。
少し使ってみた感じはPhotoshopElementsみたいなもんかな。
まだベータ版なので動作が遅く感じることもあるけど、概ね良好。「ブログ始めたけど掲載する写真の編集したい」とか「画像処理したいけどPhotoshopみたいな高機能いらないよ」って人にはこれで十分だと思う。
この層のニーズって、完全な個人というよりは社員10数人の中小企業や自営業でwebを運営している法人に多いと思う。
もし彼らがクライアントでCMSなりBlogの更新なりの補助をする場合、こういうオンライン画像編集ツールを紹介するって言うのはアリだと思うな。
画像処理はサムネイル式で選ぶ
ちょっとしたフィルターも可能。
ああそう!一つ見落とし。画像ファイルがjpgしか使えない。只これは間違いなくベータ版故だろうから、最終版はpngとかtiffもOKになると思う。PSDは...どうなんだろ?
「貧弱、貧弱ゥ」なドップラー効果もどきのサンプルを作りました。
背景有り(重い!)*音が鳴ります
前回もちょこっと書いたけど、AS2コーディングされているflaファイルをAS3に再コーディングした。
タスクはだいたいこんな感じ。
idMap["foo"]を使っていたので、全部descendants().(attribute("id") == "foo")に書き換え。trace(Global.instance.rootPath); // http://exsample.com/Global.instance.dataXMLとして参照可能にする。以前に紹介した新鋭舞踏集団、「黒藤院」の公式webサイトをProgression Frameworkでリビルドしてみた。

グローバルナビが5項目だけなので、いまいちディープリンクのありがたみを感じられないのが残念だけど、学習量としてはちょうど良かった。
実際に記述したProgression用のソースコードはグローバルナビへのCastButtonの追加と、各SceneObjectのイベント処理くらい。後はそれによって生じるコンテンツ遷移処理の調整。ものの数時間の工程。
ただ、そこに至る前にAS2をAS3に再コーディング。これが半日くらい。なんかようわからんBugをポツポツつぶす。ちょっとはまったのが、AS2のflaを途中でAS3に変換した際、コンパイルオプションが変更されなかったこと。StrictとかWarningにチェックが入っていなかったので、コンパイル時に検出されずにランタイムでエラーが多発。(flaがvr8だったことも関係があるかも)
その他、SWFObjectを使ったことが無かったので、FullScreenでFlashを表示させる方法が分からずちょっと悩む。色々調べてCSSを下記に改め、解決。
#flashcontent {
top:0;
left:0;
height:100%;
margin:0;
background:#FFF;
}
そんな訳で、全体の工数からするとProgressionに費やした工数はあんまり多くないが、逆に言えば簡単な修正でProgressionが利用可能とも言える。既存のflaに対して比較的容易にディープリンクを貼れるという事は強力なアドバンテージだとつくづく感心。
使用頻度が特に高いわけでもないが、結構重要な割にすぐ忘れるし、GGってもすぐにヒットしないので自分用メモ。
[SWF(backgroundColor="#ffffff", frameRate="25",width="600",height="200" )]
こんな感じのカンマ区切り。
記述場所はclass宣言の直上。
package {
import flash.display.Sprite;
[SWF(backgroundColor="#ffffff", frameRate=25)]
/*
[SWF(backgroundColor="#000000", frameRate=25)]
commentOutも出来る
*/
public class Main extends Sprite {
public function Main(){
}
}
}
背景色、fps、幅、高さ、以外のタグもあるみたいなのでそのうち追記しよう。
昨日ポストしたProgression Framework のエントリーに作者ご本人taka:nium.jpさんからコメントを頂戴した。
おかげさまで問題はあっけなく解決。一応自分的留意点をまとめると以下3点。
Flasherの悲願とも言うべき、ブラウザの「戻る」「進む」ボタンを意図もたやすく解決するProgression Framework をちょっと弄ってみた。
オフィシャルサイトのチュートリアルを見ながら少し遊んだだけだけど、これはかなりよさげだ。でもディープリンクの発行やらURL同期に関する処理が分からん。まだドキュメント化されていないだけだろうか。
それともルートのタイムラインにアンカーを埋め込む方法みたいな感じなんだろうか....
あるいはSWFADDRESSを咬ませるとか
一刻も早く答えが知りたい。
ところで過去に一度、クライアントから「戻る」「進む」ボタンが使えない、と言われて大幅&大赤字な修正をしたことがあったなあ。あの時ほど自分の説明不足を呪った事は無かった。そして結局、FullFlashサイトなのに静的HTMLにFlash をぺたぺた貼り付けただけのサイトになってしまった。当然、コンテンツ間の遷移に使っていたシームレスなモーションスクリプトは全部破棄。あんな思いはもうごめんだ。
ジョブズ氏が語る「iPhoneがFlashをサポートしない理由」
iPhoneへのFlash搭載の可能性については悲観的なので、この話が出てきてもあまり驚かなかった。
jobsの言によると、iPhoneのスペック的にFlashは厳しいという話だけど本当にそれだけなんだろうか?確かにそれもあるが、実際には今後のモバイルRIA市場での優位性を確保したいと考えている、これが本心なんじゃあ無いだろうか。
うわさではAppleが独自プラグインの開発を進めているという話まであるけど、それがデマカセであれ、その分野でAdobeにおいしいところを持って行かれるのは絶対に許せないだろう。
iPhoneSDKがプライマリ、Flashは良くてもセカンダリ、というのがAppleの絶対条件なんじゃあないだろうか。でもってこのヒエラルキーをモバイルRIA市場全域に行き渡らせようと考えてたりして。
まあ、なんにせよこの分だとしばらくはiPhoneでFlashは走らないだろうな。つまんね。
http://www.flashdevelop.org/community/viewtopic.php?t=2574
FlashDevelop3 beta5beta6が出てる。
いや、2週間以上前の話だけど全然気がつかなかった。早速入れてみようと思うけど、正直Flex3のリリースよりウレシイかも。
詳細はまた後で。
(只、コードフォーマットとか環境を再現するのが面倒くさいんだよな)
前回のマウスストーカをやや修正。
前回のロジックは実際にはxy平面上のオブジェクトに対しカメラアングルとポジションから遠近感をつけていたが、今回はyz平面上にオブジェクトを配置し、yz軸を使って動作させている。z軸という3D特有のプロパティに漸く触れることが出来た感じ。
あえて2つパターンを作ってみた。
MOUSE_DOWNで動き出すパターン
http://memo.kappa-lab.com/samples/Mouse3D_Arrow_Z.html
ENTER_FRAMEで動き続ける2パターン
http://memo.kappa-lab.com/samples/Mouse3D_Arrow_Z2.html
ソースはこちら。
http://memo.kappa-lab.com/samples/Mouse3D_Z_1_2.zip
![]()
Flex3をインストールしてみた。当然トライアル。トライアルだけど、各種CS3と違って60日間も使えるってところがウレシイ。
まだあんまり触ってないけど、正直FlashDevelopの入力補完のほうが素晴らしい。Flex3はpublicとかfunctionとかまで補完してくれないし。ColinMoockも言ってた行単位でのコピペは便利だけど、それもFlashDevelopが既に備えている機能なので感動せず。あとはリファクタリングの際、パラメータの名前を一カ所書き換えるとその他の部分でも一括変換してくれるという話だけど、これはまだ試してない。
ヘルプやリファレンスを見ると「flash.data」とか「flash.desktop」パッケージがあって、ちょっとわくわくするかも。
とりあえず一番大きな印象はロゴが変わったことくらいかな。
先日25日、遂にAIR1.0がリリースされたらしい。akihiro kamijoさんのブログで知った。
Adobeのサイトでもリリースを出している。
なのに、周囲の静けさはなんだ?今のところニュースサイトとかブログで大々的に取り上げている記事なりエントリーなりに遭遇したことが無いんだけど、このままスルーされていまうのかしら。
AS3の時も基本的な仕様は正式リリースの前にブロガーに書き尽くされてしまったけど、今回も同じなのかな?そうするとベータ版の段階で、既にtipsやら導入方法なんかを特集してしまったので、ニュースにするネタに乏しいのかもしれない。
ただ、個人的にはmixiのFlash関連コミュとかで質問やトピックを見かけなくなって久しい。
やっぱFlashって落ち目なんじゃないかと心配だ。
HalloWorldと同じくらいプログラミング初心者が頻繁に実装する定石、「マウスストーカー」をPV3Dでやってみた。
http://memo.kappa-lab.com/samples/Mouse3D_Arrow.html
相変わらず、原点より上部(見た目は遠方)に移動すると背面にマウスストーカーが移動してしまうが、あんまり気にせずに作ってみた。(この件はPV3D1.7のバグかもね)
作ってみた感想は、、「非常にヨイ!!」
なんかヒラヒラと魚が泳いでるみたいで、これはいいなあ~。2Dのマウスストーカーよりプリミティブな感動を味わうことが出来るんじゃないかと思う。
静かなる死を迎えようとしていた"SOUND_COMPLETE"イベントが復活しようとしているらしい。
andré michelle のエントリーに書き込みがあったのは2月の14日。
どういう事かというと、
http://bugs.adobe.com/jira/browse/ASC-3111と言うページの、SOUND_COMPLETEイベントのBugFixステータスが"Resolved"になったと言うこと。あいかわらずプライオリティは低いままだけど、少なくともやる気にはなったみたい。
ただ、いつまでに修正されるのか、どの程度安定するのかはサッパリ。
とりあえずPapervision3Dを触ってみた。
3次元空間内の平面上でマウスストーカーみたいな実装をしたくて色々試してみたところ2つほどひっかかったのでメモ。
サンプルはこちら
今のところ1番目は解決できた。2番目はまだ。
一番目に関してはPlaneインスタンスを生成するときのsegmentsW,segmentsHパラメータの数値を大きくすれば解決出来る。ちゃんとドキュメントを読んでいないけど、レンダリングするときの元画像のサンプリングレートみたいな扱いなのかな?
plane = new Plane(material, 1000, 1000,8)
/*第四引数に4以上の数値を与えておくと良さそう
*segmentsHを省略した場合は自動的にsegmentsWと同数になる
*/
修正後はこちら
ちなみにデフォルトは1で、その場合は初めのサンプルどおり。
2番目はワールド座標でY座標の値が原点より大きくなると、グリッドの背面にマウスストーカーが移動してしまう状態。このサンプルでは、グリッドとストーカーはXY平面上に存在していて、カメラの位置とアングルでそれらを水平に見せかけているだけ。だからZ軸上の移動は発生していないはずなので、ストーカーがグリッドの背面に移動してしまう理由が不明。多分自分がとんでもない勘違いをしている可能性が高い。
3Dって頭の体操をしてる感じでやっぱり面白いな。
や、あくまで Making music is cool! Much cooler than 3D だけどね。
10年スパンで考えると新しいプログラミング言語を学習するより英語を学習した方が良いのかな、と思う今日この頃。そしたら一層その思いを強くさせる出来事が起きた。
事の発端はAS”スーパー”コーダのandré michelleの"The silent death of onSoundComplete event - a petition"というエントリ。もうふた月以上も前のエントリにもかかわらず、あまりの長文ぶりに尻込んでスルーしていたら、実は結構重大な内容で、「onSoundCompleteが使えなくなってしまってるぜ!」とのこと。
しかも始末の悪いことにその内容(の一部)を知ったのが、原典からでなく他のサイト(trick7さん)からと言うところ。そのエントリを読んだ瞬間大いに焦ってしまった。「Adobeの公式見解なの?」とか「原典どこだ?」とか焦ってるとコメント覧に自分がスルーしていたエントリのリンクが。
そんな訳で漸く原典を読むに至った。andré michelle氏はドイツ人なのでこんな一昔前のアメリカ人ロックミュージシャンみたいな口調じゃ無いと思うけどだいたいこんな感じ。
個人的には、「音造りの方が3Dなんかよりサイコーにクールだぜ!」っていうandré michelle氏のはっちゃけぶりに目頭を熱くせずにはいられない。皆さんも是非コメント覧にAdobeへの署名を書き込んで欲しい。今年の1月15日に日本で開催されたColin Moock のActionScript3 Tour が2月20日にドイツで開催される。
とandré michelleさんのBlogに書かれていた。
ざっくり意訳すると「Colin MoockがAS3とAIRの話をしにくるぜ!しかも無料で!絶対見逃すなよ!!」みたいな感じ。でもandré michelleと言えばPOPFORGEを開発したスーパーコーダな訳で、参加する意義はあんまりないんじゃないかと思う。あり得るとしたら招待者としてかな。
フリークとしてはCollinMoockの講演をandré michelleがどう思ったのかをBlogに書いてくれたら凄く面白いけど、まあないだろうな。
あまりハマらずに、ほどよい距離感でつきあっていきたいPV3Dだけど、そんな事を言っていると知らない間にvr2.0が出ていたみたいだ。
2007年12月5日に初めてSVNにコミットしたみたいで、その後もかなり精力的にupdateしている様子。
そんなことも全然知らずにテキトーにvr1.7をチェックアウトしていた自分がなんだか情けない。もちろんvr2.0はAlphaでvr1.7の方が安定しているのだから、vr1.7環境を使うことに問題はないんだけど、何も気がつかなかったって事がトホホ。
PV3Dの公式ブログを読んでいれば動向に気がつくのかもしれないけど、それ以上にgoogleCodeのSVNリポジトリが無秩序なんじゃないかと思う。brancheとかtagとかフォルダがあるにもかかわらず、誰も使ってないのだよ。もちろん使わなければならない規則はないんだけど、trunkの中にbrancheがあったりしてわけわかんねえよ!
っと思うんだけど他の人はどうなんだろ。
とりあえず、PapervisionもPOPFORGEもTweenerも、そしてAdobeCorelibまでもそんな感じ。
(Adobeに関してはしょうがないか?)
ま、でも無償でこんな凄いことをやっていただいていただいてるんだから文句を言ったら罰が当たるぜ。
ひょんなことから、AIR以前にFlashデスクトップアプリを構築するツールがリリースされていたことを知った。(これは本当)
その名は「SWF Studio」
現在、vr3。プロダクトなので、$299。一応トライアルもあって、APIや機能はフルスペックで使えるけど、何かしらの制限つき。動作環境はwindowsのみ(コンパイルした.exeもwindowsでのみ動作)。
で、何ができるかというと下記のような感じ。
という感じでいろいろできるみたいです。この中でも特筆すべきはAS2で開発可能ってことで、これはAIRと同等のFlashデスクトップアプリをAS2で構築できるってこと。
開発の流れは下記のような感じ。
AIRが正式リリースされようとしている中で、どこまで必要とされるかは疑問だけど、FlashデスクトップアプリやりたいけどAS3勉強したくない、とかAS3を使わせてくれない環境で役に立つのかも。
2年前くらいに自作の3Dクラスでちょこっと3Dを作ってみた。
Javaの3D入門書みたいなのを読んで、Javaの3DライブラリをAS2に移植しようかと考えていたが、結局は4,5個の行列計算をするクラスを作っただけで3Dから遠ざかってしまった。
で、最近になって漸くPV3Dをちょこっと触ってみたところ、なかなかイイカンジ。シンプルで割と理解しやすい。少なくともPOPFORGEよりは取っつきやすい。POPFORGEはある程度音楽プログラミングの基礎がいるが、その基礎を学習する教材があまり豊富ではない。一方、3Dとなるとわんさか教材があるのがステキだ。
ただ、個人的にはあまり3Dライブラリにハマりたくはない。
fladdictさんも言ってたけど、「どんなけ3Dですっごいことやっても、PS3とかXbox360には敵わない」というのが大方の理由。
そして、もう一つ。次期Flash、vr10にはZ軸がサポートされるという話がある。AdobeMAX2007でもアナウンスされていたけど、そうなるとAdobe謹製の3Dライブラリがリリースされちまうかもしれないわけで、PV3Dの学習コストが全くの無駄になる可能性も高い。as3corelibやAdobeのブログを追っかけているとある程度未来の予測も立つかもしれないので、慎重に時間投資をしたほうが吉。と思う。
ちなみに3Dの基礎、ワールド座標やスクリーン座標なんかを勉強するのにこの本はなかなか良かった。
巷では久々にPHPが話題をかっさらっているみたい。
自分でPHPを書いたのは、小規模な掲示板の様なシステムとか、ActionScriptから投げたバイナリーデータの処理だったので、これくらいの規模だとちょうど良かった。プライベートワーク以外に結構大規模な開発でPHPのなんちゃってメンテナーをしたこともあったが、コードをフルスクラッチしたデベロッパーが有能だったおかげで、ほとんど問題はなかった。
けどそろそろサーバサイドの処理はRubyにしようかしらと考え中。
何となくRubyだとPHPを書く上で悩んでいた細々したところが解決されそうなきがしているからだ(まだ勉強はじめなのでよく分からないが)。
やっぱりPHPって「お手軽に書けるけど、ぐちゃぐちゃで読めない」という印象が強い。
PHPの功罪を要約すると「お手軽に書けるけど、ぐちゃぐちゃで読めない」という事に行き着くと思うんだけど、ActionScript(主に1.2)をフレームアクションの中でぐだぐだに書き殴っていた頃を思い起こすとかわいいもんではないかと思えて、不思議。
また、PHPの功罪というかPHPユーザーの特性として「他の言語から積極的に学んでいない」という言葉が出ていたが、これまた耳が痛い台詞だ。自分の言語スキルは「なんちゃってActionScript」と「読み囓ったPHP」と「盗み聞きしたJava」くらいしかないからだ。
AS1、AS2、AS3で3言語出来ます!って言うのはだめかな?だめだよな。
前回に引き続いてPOPFORGEを使ってwavファイルのループ再生してみた。
http://memo.kappa-lab.com/samples/sirenAStream_REF.html

*ご注意:いきなり音が鳴ります
例によってFlashCS3を使えば何の造作も無い事だけど、今後のサウンドエフェクトの可能性を切り開くためにもPOPFORGEのbufferクラスを使って再生。何故かAudioBufferクラスに音源データを渡すとき、そのままではなく一つおきにデータを渡す。結果的にデータが圧縮されていることなって音質が下がって居るんじゃ無いかと思うが、詳しい解析をしたわけではないのでよく分からない。訳は神のみぞ知るってところかな。
フローは以下の形。
1.バイナリーとしてwavを読み込んだSirenクラスからサンプリング配列を取得
2.AudioBufferインスタンスを生成してサンプリング配列を参照
3.AudioBufferサンプリング配列にSirenクラスのサンプリング配列を渡す
4.3の時に配列の終端で折り返す
5.再生
と言う感じ。前回は一つしかクラスが無かったけど、今回は音源データを別クラス(Sirenクラス)にしてある。ついでに波形をモニタリングするクラスもくっついているのでややウザイコードになったかもしれない。
サンプルコード
http://memo.kappa-lab.com/samples/SirenASound_REF.zip
FlashIDE(FlashCS3)だとライブラリにwavファイルを追加してリンケージすることによって、Embed可能だけど、Flex環境というか.asファイルにwavファイルのEmbedは不可能。(だと思うけど違っていたら教えてください)
そこでバイナリーとして読み込んでPOPFORGEで復元、再生することにした。
派生物として、サウンドの生データが取得できるのでそれにフィルターをかけてやるとエフェクトをかけることも可能。やる気出せばサウンドへのリアルタイムエフェクトの可能性が見えるかも。
もともとはPOPFORGEでオリジナルの音源を使って、ストリームを生成させることが目的だったんだけど、Voiceクラスを解析するのがかなり大変そうなので、泥臭いがシンプルな方法を模索しているウチに上記の様な事になった。いつの日かドップラー効果やリバーブ、ディストーションをグリグリかけられるようになるかも。
フローは以下の形。
1.バイナリーとしてwavを読み込み、Class化
2.バイトコードを取得
3.fromByteArrayにバイトコードを渡す
4.再生
*エフェクトのサンプルとして1オクターブ高くなるeffect()が付随
package
{
import de.popforge.audio.output.Audio;
import de.popforge.audio.output.SoundFactory;
import flash.display.Sprite;
import flash.media.Sound;
import flash.utils.ByteArray
import flash.utils.Endian
public class SirenASound_REF extends Sprite
{
//バイナリーとしてwavを読み込み、Class化
[Embed(source="wav/siren_short.wav", mimeType="application/octet-stream")]
public static const Song:Class;
//wavファイルヘッダー部分のoffset
public static const WAV_HEADER_END:uint = 44
public function SirenASound_REF(){
init();
}
private function init(): void {
//バイトコードを取得
var bytes:ByteArray = getByteArray()
var array:Array = byteArray2Array(bytes)
//effectの有無 1オクターブ高くなる
//array = effect(array)
//var bytes2:ByteArray = array2ByteArray(array)
//fromByteArrayにバイトコードを渡す
SoundFactory.fromByteArray(bytes,Audio.STEREO, Audio.BIT16, Audio.RATE44100, onSoundGenerated );
}
private function onSoundGenerated( sound: Sound ): void {
//再生
sound.play();
}
private function getByteArray():ByteArray {
var bytes:ByteArray = new ByteArray()
bytes.endian = Endian.LITTLE_ENDIAN
var wavData:ByteArray = new Song() as ByteArray
bytes.writeBytes(wavData, WAV_HEADER_END)
bytes.position = 0
return bytes;
}
private function byteArray2Array(bytes:ByteArray):Array {
var array:Array = new Array()
while(bytes.position < bytes.length-1){array.push(bytes.readShort())}
return array;
}
private function array2ByteArray(array:Array):ByteArray {
var bytes:ByteArray = new ByteArray()
bytes.endian = Endian.LITTLE_ENDIAN
for each(var index:int in array){bytes.writeShort(index)}
bytes.position = 0
return bytes;
}
private function effect(sample:Array):Array {
var array:Array = new Array()
for (var i:int = 0; i < sample.length;i+=2){
array.push(sample[i])
}
return array
}
}
}
* http://qurage.net/labo/as2html/ でコードフォーマットさせていただきました
trace(1.90-1.0)
trace(1.9-0.9)
上記コードを実行して期待される値はもちろん、「0.9」「1」なんだけど、残念ながら事実は違うようだ。実際の数値は以下の様になる。
0.8999999999999999
0.9999999999999999
なんだよこれ!
AS3でNumber、int、uintが導入されて数の扱いは改善されたはずじゃなかったのか!?
更に腹立たしいことにこれをAS2で実行すると、
0.9
1
と期待通りの値が帰ってくれる。もちろんAS1でもAS2と同様なのだ。どうすりゃいいんだ!?既出の問題の可能性が高いし、仕様としてそうなってるのかもしれないけど困った。
久しぶりにPOPFORGEを弄った。
とりあえず音階表現をある程度理解しないことには先に進めそうにないので、簡単なキーボードを押すことでドレミファソラシド(#、♭なし)がなるようなサンプルを作ってみた。
http://memo.kappa-lab.com/samples/createASound_Key.html

音が終端で「ぶちっ」とちぎれるのはAudioBufferクラスではなく、単純なSamplesクラスを使っているから。(だと思う)
AudioBufferを使ってストリームを生成すれば解決するはずだけど、やや難しいのでペンディング。
音階に関してはこちらのサイトを参考にさせて貰いました。
http://www.dai3gen.net/onkai11.htm
図表を見れば分かるように1オクターブごとに220Hzずつ周波数が増加するって事を初めて知った。いろいろ勉強になるなあ。
ソースはこちら
http://memo.kappa-lab.com/samples/createASound_Key.zip
Colin MoockのAS3セミナーに参加してきたよ。
詳しい内容とかは他のブログでレポートされると思うので(Adobe自身ブログレポーターを募集していた)かなりどうでも良い個人的な感想を書いておこうかと...
1.MacもWindowsも好きじゃ無いんだ!
質疑応答の時、「開発環境はMacですかWindowsですか?」との質問にColin氏の解答は「Macははっきり言って嫌い。でもwindowsも良くない」とばっさり。更に「どうしても使いたいソフトがwindowsにしかないからwindowsを使っているだけ。iTuneとかは好きだけどMacのファイルシステム、あれはだめだね」って感じのことを言っていた。個人的には一番印象に残った場面かも。そう、世の中にアホとバカしか居なかったとしていったいどうして選べと言うんだ。
2.Flexの環境設定がやりにくいんだ!
コードアシストや行単位の操作に関してはべた褒めしていたColin氏だったが、フォントサイズを変えるのに煩雑なコントロールパネルの操作を強いるFlex(おそらくvr3)についつい不満を漏らす。「まあ開発者向けだしね。でもAdobeサン頑張ってね」って感じのことを言ってた。ここら辺はFlexっていうよりEclipseが原因なんだろうか?悪いのはSunIBMだっ(言い過ぎ?)
3.コードアシストなしですらすら
プレゼンの半分以上はFlexなどIDEを全く使わず、Macのエディタ(多分シンプルテキスト)でコーディング。ミスタイプしそうな関数やらクラスをサクサクと手打ちしていた。これくらいは普通に出来なきゃだめかもしれないけど、やっぱスゴイ。
4.オブジェクト、関数、引数の関係は英語の文法そのまま
" pet.eat(apple) ; "
ってのは英語の文法での他動詞SVOそのまんまなのでプログラムに通じていなくとも直感的に理解できる。と言っていた。英語圏はトクだね。
今から3ヶ月ほど前、漸くAS3を勉強し始めた頃にこんなエントリーを書いた。
「parentの扱い」
内容は「AS3ではparent.gotoAndPlay()が出来ない、なぜならparentはMovieClipではなくDisplayObjectContainerだから」という具合で、その解決策とかを載せていた。そして最後に「でもなぜparentがDisplayObjectContainerなのか今の理解じゃあわからんなあ~」と締めくくっていた。
そして、3ヶ月。なんとなくわかってきた!(気がする)
要するにOOP的なものがいまいち理解できてなかったのだ(今でも怪しいが)。なんとなく概念は読み囓ったものの、実際のクラス設計で継承やインターフェイスの使い方を知らなかった(今でもインターフェイスは全然使ってなかったりだけど)。ポリフォーリズムなんて本当にうわべだけだったと思う。
いまなら、なぜparentがDisplayObjectContainerなのかは表示リストの概念からそれなりに理解できる(でも神髄を掴んでいるかと言えばそうではない)。SpriteにaddChilde()したらparent.gotoAndPlay()はどう考えても無茶しすぎだろうと肌で感じる事が出来る。
そんなわけで、この仕様が至極まっとうな物であることに漸く気づくに至った。
ここら辺のOOPに対する理解の難しさや、誤解を含んだ理解はAS1→AS2→AS3とプログラミングの極北の様な道を純粋に突き進んできたからかもしれない。そろそろ別の道を覗いてみようと思う。
けどAS3で抽象基本クラスってどうやって定義してるんだろう。ビルトインクラスだけか?
既に前のエントリーの末尾で書いてしまったネタだけど、なんかハマりやすいみたいなので、敢えて別のエントリを立ててみた。アルバムからのシングルカット、の感じで。
SWFの起動時のウィンドウモードを「Documment」から「External」に変更してやればOK。
>Project >Properties >Output >TestMovie>Open SWF in から。
ちなみにAIR開発のtrace()を受け取るにはここをどうぞ。
それと、Beta5を日本語SDKでコンパイルさせると、swfを終了させた後Outputパネルが終了イベントをキャッチできずに延々とループしてしまいますが、そいつはここをご参考に
なんかのエントリーに「○○のための△△個の方法」っていうタイトルを着けるとトラフィックが伸びる!と真しやかに書いてあったので早速実践。
Flash制作で使えるフリーソフト4点です。
その他にも色々あるけど個人的に気に入ってるところから。
1.FlashDevelop
もうこれなしではやっていけません。聞けばMacユーザの中にはパラレルにwindowsをインストールしてでもFlashDevelopを使ってるとか。英語版しかないけどシンプルなのですぐなれます。これになれるとFlashIDEのアクションパネルなんざタダのテキストエディタです。比較にならない。とにかく一押し!
http://www.flashdevelop.org/community/
2.TortoiseSVN
これも最早離れらないバージョン管理ソフト。svnなんてコマンド叩けよ!と言われても知りません。リビジョングラフやらログ一覧やら(ログからダブルクリックで該当バージョンのファイルが開ける)とにかく便利。httpsとかsshも使えるので最高。
http://www.gside.org/Gentoo/subversion/subversion_client.html
3.PluginSwitcher
FlashPlayerのバージョンを切り替えるやつ。そういえば最近あんまり使ってないけど、無いとかなり困る。縁の下の力持ちってやつでしょうか。
http://www.pluginswitcher.de/
4.FlashTracer
これはもう本当に「かゆいところに手が届く」って表現がぴったりなんじゃないかと思うFirefoxのアドオン。ブラウザ上で動作するFlashからのtraceを表示してくれます。
とまあこんなところで。
FlashDevelop Beta4+FlashIDE環境でAIR開発しているとき、コードアシスト出来ないのかと思っていたら、実は可能だって事に気がついた。とりあえずflash.data.*はちゃんと補完してくれるぜ。さっすが。
以下やり方
Project > Properties > Compiler Option >SWC Libraries
に
C:\Program Files\Adobe\Adobe Flash CS3\ja\Configuration\ActionScript 3.0 AIR 1.0\Classes\playerglobal.swc
を追加するとOK。
Flexつかっているとこんな回りくどいやり方しなくてもアシストされるのかもしれないけど、ちょっとFlex買うのを躊躇ってるもんで。あんまりきちっと調べていないから、ひょっとしてバイナリ(swc)だけじゃなくてソースコードも何処かに格納されているかもしれないけどとりあえず動くしいいだろう。
今年、sshでのみアクセスを行うサーバを使ってサイト制作をしていたら、クライアントからftpにできないの?みたいな質問が出た。個人情報やら重要な情報があるので、ftpは止めましょう、と説明するとすんなり納得してくれたものの、そっからFileZillaがクライアントのマシンにのるまで一週間がかかった。
なんでもアプリケーションをインストールするには管理者に申請を出して管理者によってインストールしてもらわねばならないらしい。
どこでもそうだけど、これが企業のIT管理の現状というか弊害。
そんなわけで、よっぽどずさんな企業か規模の小さな企業以外、スタッフの勝手な判断でインストールはできない。もちろんマシンは会社のものだから、スタッフの好きなようにいじくっていい道理はないわけだが、これにFlashPlayerのアップデートも含まれていたりする。うっかり担当者のマシンがvr6だったりするとサイトを確認するまでに上記の工程が必要になる。
そう、企業はやすやすとインストールをさせてくれないのだ。下手するとインストールするくらいなら新しいマシン買え!ってくらい、こっちから見ているとインストール過敏症な管理をしている。(インストールだけじゃなくて閲覧できるwebとかもやたらに制限されてたりする)
で、この企業のインストール過敏症を見ているとAIRとかFlash技術って、今後のポストoffice製品に参入するときにかなりの障壁になるんじゃないかと感じた。ポストofficeと書いたのは、現在のMicrosoftに牛耳られているoffice製品が、その束縛から解放された状態をそう呼びたい、という願望で、そう遠くないうちにそれは現実のものになるだろうと個人的には思っている。これに異論を唱える人はそんなに多くないはずだ。GoogleDocsは言うに及ばず、AdobeもBuzzword等がんばっている。
googleとadobeはポストoffice世代を牽引する有力株で、前者はAjax,後者はFlashと言う陣営。現状ではgoogleがダントツだけど、基本的にインストールやシステムの変更が不要なAjaxに対して、Adobeがインストールと言うハンデを背負い続ける以上、苦戦は必至かと思う。Adobeが管理者や権限に縛られない家庭内マシンのシェアだけで満足なら、このままでいいかもしれないが、企業内でのシェアを獲得するためにはこのインストールという障壁を何とかしないといけないんじゃないかな?
ものすっごい初歩的なエントリだけど、メモ。
FlashIDE(もちろんFlashCS3)でAIRの制作をしている場合の"trace()"からの出力は「ムービープレビュー(ctrl+Enter)」ではなく「ムービーのデバック(ctrl+shift+Enter)」でなければ表示できない!
ついついctrl+Enterしがちで、AIR初心者としては「trace()が出ないけどそういう仕様なんだろうな」と勝手に諦めているとそんなわけだった。ちゃんとココ(zipファイル)の23pageに記載されてある。
ほんとに初歩的な話だけど、このいブログがそもそも初歩的な話を更に不十分に殴り書きしているわけで、今更何誰に恥じる事もないかと、居直るエントリ。こういうtipsとも呼べないtipsを今後とも誰かに届けたい。(←だれに?)
AdobeAIRのSQLite関連APIは"flash.data"パッケージ以下にSQLCnnectionやら、SQLResult等々15個くらいのクラスからなっている様子で、ともあれDBを生成してテーブル作ってデータの流し込みをそこら辺で公開されているチュートリアルを見ながらやってみることにした。
と、そうすると流石beta版だけあって微妙にメソッド名が変わっていたりする。もちろんそのままでは動かない。たとえば、DBへのパスを指定する
File.desktopDirectory.resolve("hoge.db");
*AIR beta1で使用
が、
File.desktopDirectory.resolvePath("hoge.db");
*AIR beta2.beta3で使用
に変わっていたり。
流石のFlashDevelopもbeta版のコードアシストは完全ではないみたいで、FlashIDEのアクションパネルに戻ったような感じで書かねばならない。まぁ先物買いしてる以上は文句言えない部分だ。
漸くAIRで「Hallo World」をしてみた。Flexではなく、Flashからの書き出がしたかったので、Flash周りの環境を整えてみたが、以前のバージョンのアンインストールやら、なんやかんやでやや煩雑な作業だった。
リソースはここら辺を参照にしました。
環境さえ整えればあっさり「Hallo World」は出来る。フツーにAS3を書けば良いだけ。
var hw_txt:TextField = new TextField();
addChild(hw_txt)
hw_txt.text = "hello world"
で、commandメニューから「AIR - Create AIR File」すると、証明書の生成を問われるので、SSLの自己証明みたいな感じでテキトーに入力、そしてインストーラが書き出される。拡張子は「.air」 こいつをダブルクリックして任意のディレクトリにインストール、そして同名のexeファイルを叩けば「HalloWorld」完了。文章に起こしてみるとタスクが多い気がするけど、実際は簡単(多分文章が下手なせいだな)。
で、AIRでなにをしようかな、という話ですが、凄く地味なアプリを作ろうと思っている。
ずばり「受注・請求アプリ」。
webでなければweb2.0でもない、かなり地味なアプリ。「弥○会計」とか「■生販売管理」みたいなやつだ。何故、今”それ”なのかと言うと、もうMSAccessの受注テンプレートとはおさらばしたいから。これに尽きる。基本的にDBの設計やら運営がメインの作業になると思われるので、脱DB素人も達成したい。まあ、来年の肥やしになるかもしれないので頑張ろうと思う。できあがっても自分以外誰も喜ばないと思うけど。
前々回の続きで、AS3用FPSメータのコンポーネントを作ってみました。何故FPSメーター(FPSモニターと呼ぶべきかな?)かというと、それは前々々回を読んでもらえたら分かるかな。最近、精力的にエントリしまくっている。
とりあえず今のところベータって事でこちらにUP。
http://memo.kappa-lab.com/samples/ASTachoMeter.zip
コンポーネントインスペクタで
1.interval :: 何フレームごとに集計結果を表示するか
2.digit :: フレームレートの小数点以下の表示桁数
の2つの変数が変更できます。
1.の値を小さくすればするほど、リアルタイム集計になっていくが、その分だけマシンの負担も増える。
FPSを計測するという主旨は、ちょっとしたベンチマーク的な意味合いもあるので、FPSメータ自身がパフォーマンスに影響を与えてしまうと本末転倒なのだ。今のところ、interval=20でCPU使用率は2,3%に抑えられているので合格圏内だと思う。
ここに書かれているように、iPhone 上で Flash は動作しない。将来的にプラグインが提供される可能性はあるけど、多分かなり先になるだろうという観測だ。他にもアナリストやらMacウォッチャーが同様に、iPhoneでFlashが動くようになるとしてもかなり先になるだろうと言ってる。
更にAppleのwebサイトは Flash でつくっても良いような部分まで非Flash で構築されている。この状況から、JobsがFlashを遠ざける戦略を取っていると考えてもそんなに不自然ではない。
今後のiPhone の普及拡大は安泰だろうし、iPod も同様だ。そlこで重要なインターフェイス部分にFlashを組み込んだ場合、Adobe への依存度が極端に高くなるわけで、Jobs がその状況を喜ぶはずは無いと思う。
1999年前後、初めてiMacを手に入れたときは、AppleとAdobeは今よりもっと親密な関係に見えた。Apple、そしてMac と言えばPhotoshopを走らせるためのマシンだと認識していたくらいに。一方、Macromedia と言えばFlashやDremwaever とともにFireworksやFreeHandなどPhotoshop、illustratorと同様のグラフィックツールをリリースしながらもwindowsとの親和性が高いように見え、少なくともApple一辺倒、という体制では無かったと思う。ひょっとして Jobs がFlashを許さない原因がこのころにあったりして(多分ないけど)。
なんにせよ、Flash/FlexコミュニティとしてはiPhone向けのコンテンツが制作出来ないわけで、これは今後、重大な足かせになるんじゃないかと思う。ただでさえモバイル向けのFlashコンテンツって何となく腰が重くなるのに、唯一魅力的なデバイス/プラットフォームであるiPhoneにそっぽを向かれてはモチベーションが上がるはずがない。
GoogleのAndroidが先月リリースされて、iPhone用のSDKは来年2月にリリースされるらしい。FlashLiteもFlashLite2の普及が微妙なままもうFlashLite3になる。今度はモバイルプラットフォームが乱立するのか。
"Write once, run anywhere"なんて結局やってこないのだ。
AS3でカスタムコンポーネントを作って、SWC書き出しする際のメモ3点。
1.SWCを格納するディレクトリ(winXPの場合)
C:\Documents and Settings\user\Local Settings\Application Data\Adobe\Flash CS3\ja\Configuration\Components
2.ビルトインコンポーネントのソースファイル(勉強になる)
C:\Program Files\Adobe\Adobe Flash CS3\ja\Configuration\Component Source\ActionScript 3.0\User Interface
3.コンポーネントインスペクタで変数を扱えるようにするには(これを書きたかった)
追加したいプロパティのsetterメソッドの上にメタタグを入れる。
[Inspectable(defaultValue=1)]
これで有効化。この場合はデフォルトが1になる。
ちなみにコンストラクタにtrace()を入れるとFlashIDEでステージに追加したときにメッセージが出る。ひょっとして、ENTER_FRAMEも出力されるのかと、試してみると一回だけ実行された。ちょっと焦るなあ。
ど忘れして無駄にハマッてしまったので、自戒の念も込めてメモ。
Flashオーサリング中にムービープレビューをすると、もちろんスタンドアロンSWFプレイヤーが動作して、ムービーが再生される。順調に制作が進行して、終盤でhtmlを含めたファイルを「パブリッシュ」する。するとどういうわけだかスタンドアロンの時よりパフォーマンスが低下していて狼狽。目に見えて動作が遅いので、かなり焦る。目の前真っ暗。
で何が原因かと言うと、下記赤線部の設定。

「ウィンドウモード」の設定がデフォルトでは「標準」になっているが、ここを「不透明表示」にしてやらないとかなりのパフォーマンス低下、20%前後の低下を被る。はっきり言って納品できない。
まあ、解決策は「不透明表示」にすれば良いだけで至って簡単な話だけど、どうしてまた、「標準」がデフォルトに収まっているのかがナゾ。ナゾというか、迷惑。
不透明表示にしたらしたで、マウスホイールを拾えなかったり日本語入力に問題あったりするので根治療法にはならない
あ、ちなみにウィンドウのスキンがヘンテコなのは、これを使ってるからです。
ActionScriptを書くならこれなしじゃあ無理との誉れ高いFlashDevelopのBeta5がリリースされている!
とりあえずインストールしてみると、あんまり見た目には変化がないものの、AIRがサポートされていたり、Flex3でプロジェクトが作れたり、プロジェクトのオープンが早くなっていたり、色々と更新が見て取れる。そろそろ正式版のリリースも近いのかもしれない。
ちなみにBeta4からUpdateしたら、コードフォーマットやらカスタマイズ情報が完全に上書きされてデフォルトに戻ってしまった。前のエントリーにコンフィグファイルを掲載していたので何とか復元できた。焦るよ。
ここでも紹介されているけど、AS3でバイナリーデータをサーバに保存する方法を極力単純化してメモ。
AS3の抜粋。
req.contentType = 'application/octet-stream';
が大切
private function sendObjectPHP():void{
var obj:Object ={val1:123,val2:"test"}
var byteArr:ByteArray = new ByteArray
byteArr.writeObject(obj)
byteArr.position = 0;
var req:URLRequest = new URLRequest();
var loader:URLLoader = new URLLoader();
req.url = 'saveBinary.php';
req.contentType = 'application/octet-stream';
req.method = URLRequestMethod.POST;
req.data = byteArr;
loader.addEventListener(Event.COMPLETE,loadComplete)
loader.load(req)
function loadComplete(e:Event):void{
trace("complete")
}
}
phpソース
$bin = file_get_contents("php://input");
$path = dirname(__FILE__);
$tmpfname = tempnam($path,'dat_');
unlink($tmpfname);
$tmpfname = $tmpfname . '.bin';
$fp = fopen($tmpfname, 'wb');
fwrite($fp, $bin);
fclose($fp);
これで「dat_hogehoge.bin」ファイルが生成。バイナリエディタで見ると
val1:123
val2:"test"
が確認できる。
zipファイルはコチラhttp://memo.kappa-lab.com/samples/sendBinaryToPHP.zip
FlashDevelopでswfからネットワークに接続するコーディング作業をしているとき、
「Error #2044: ハンドルされていない securityError : text=Error #2048: セキュリティサンドボックス侵害 」が発生したので、その対処をメモ。
ここで、任意のフォルダを許可する。
FlashIDEでムービープレビュ(ctrl+Enter)をした場合はこの設定なしでもエラーは発生しない。パブリッシュの場合はエラーが発生するが、上記リンクへと案内してくれる。初歩的な話だけど、OSリインストしたり作業環境を再構築するときに見落としがちだからメモ。
バグってほどのことでもないかもしれないけど、FlashCS3をデュアルモニターで使っていると、再起動時にパネルの位置が前回終了時と違っていることが多い。
具体的にはサブモニターに配置していたパネルがメインモニター上に移動している。しかも妙なことにすべてのパネルでそうなるわけではなく、ライブラリパネルやプロパティパネル、タイムラインパネルでよく起こっている様子。不思議だ。
起動時にワケ分からん場所にパネルがあると誰かが散らかしていったみたいで無性にムッとする。やっぱバグだな。
ところで最近はワイドモニターが当たり前に使われるようになってきてるので、デュアルモニターはあんまり使われていないのかな?
たまにmixiなんかでflaファイルの納品どうしてますか?という質問を目にするけど、最近の自分の傾向としては仕様書の明記の有無にかかわらず、「くれ!」と言われたら「あんまり嬉しくないけどまあいいよ」とあげている(というか提出)。念のため付け加えるとそこに別途見積もりやら予算は発生していない。
理由は3つほどあって、
1.オープンソース的(?)な理想
2.渡しても多分先方が適切に使用できない
3.2より著作権を侵害するような事態は発生しずらい
flaファイルの提出を渋る一番の理由は「ノウハウの流出と転用の危険性」だとおもうけど、実際のところ、クライアントにそれだけの技術はあんまりない。そもそもバージョンがMXでファイル自体が開けなかったり、フォントが存在していなかったり、win/macで文字組が崩れたりしてまともにコンパイルすら出来ない。更に単一のflaだけで完結している作品だったら良いけどこれからのAS3普及が順調に進めば膨大なクラスファイルが存在するだろうし、色々な汎用フレームワークで内部処理をしている場合、絶対に環境を再現できないと思う。たとえば3DエンジンにPapervision3Dを導入してコンテンツを制作した場合、当然だけどflaファイルだけで完結するはずがない。ここでクライアントに対してPapervision3Dの導入まで面倒を見てやることはないし、仮に導入となったら流石に予算が必要だ。
じゃあなんで「嬉しくないけどまあいいよ」という態度になってしまうのかというと、上記の諸々をクライアントが理解していない(まあ全然理解しなくて良いんだけど)点と、出費したんだからソースファイルもウチのもんでしょ?という誤解があるからだ。
まあ、技術的に理解していないのはしょうがないし、基本的にクライアントにそんな義務はない。ただ、理解してくれてたらこちらも嬉しいし気持ちよく仕事できる。問題はその次の誤解だ。現行の著作権法から言えばソースファイルは当然、アウトプットした物も著作権は制作者に帰属するわけで、「ソースファイルもウチのもんでしょ?」は根本的に誤解だ。では、それにも関わらずどうしてソースファイルを提出するのかというと、上記理由の1番かな、と思う。もちろんクライアントとの関係に波風を立てたくない気持ちを否定はしないが、最たる理由はオープン化によって誰かの役に立てばいいな、という願いだ。
と、言うわけでソース提出の主旨は「クライアントに諸々の権利をすべて差し出す」行為ではなくて「オープンソースとして閲覧、改変、再配布、の自由」を認める事にしよう思う。つまり「ソースファイルはクライアントが独占する物ではなく、公共のものだ」と言うことだ。
と、ここまで書いたところで、そもそも自分の権利関係の知識が乏しいことを今更ながらに実感した。もうちょっとGNUとかBSD、CreativeCommonsとかの勉強をしないと、、と強引にまとめる。
AS3がかなりまじめなOOP言語になったので、デザインパターンとか勉強したら凄く有益かもしれない!と変な誤解をしたままデザインパターンの本を読んでみた。
この本を選んだ理由は、ズバリ薄いから。実際にデザインパターンは23個しかないので、一日1パターンづつ読み進めても一月でコンプリートできるという計算で読んでみた。
これを読み終える頃には○×のフレームワークはイテレーターとコンポジットを混ぜて構築してるのか~なんて具合にソースの読解力が格段にレベルアップしていることを期待していざ読んでみた。
で、案の定AS3でコンテンツ作るのにこんなご大層な物はいらないんじゃ無いかという結論に達したけど、実際にJAVAなりASなりRubyなりで、明確に何かのデザインパターンをターゲットにしたプログラムとかフレームワークって存在するんだろうか。いや、当然この考え方はデザインパターンを語る上で陥りやすい誤解だというのは上記の書籍でも繰り返し述べられている事だけど、ケーススタディとして「googleの××はビルダパターンだ」とか「Amazonの○○はブリッジパターンだ」と言った具合でサンプルを知ればもう少し見方が変わる気がする。
もう一つ、副次的な効果だったけど、インターフェイスの概念や使い方について参考になった。でも広告系のFlashコンテンツでインターフェイスとか実装させる場合ってどれくらいあるんだろうか?Flexとかで大規模システムとか構築する場合は十分考えられるけど、そっちのニーズって今後本当に伸びて行くんだろうか。首尾良く成長を遂げたならもう一度デザインパターンをちゃんと勉強してみようと思う。
FlashCS3のアクションパネルより断然使いやすいくFlexBuilderより断然軽量なFlashDevelop。もうこれなしでASを書きたくない。とりあえずデフォルトのコードフォーマットが馴染めないのでカスタマイズしてみた。
サンプルXMLはこちら(xml内に申し訳程度にコメントを入れてます)
flashdevelop.zip
(ローカルではC:\Documents and Settings\userName\Local Settings\Application Data\FlashDevelop\以下に配置)
色々FlashDevelopを触った結果、「環境設定」とか「オプション」みたいにGUIで詳細設定を変更でき内容なので、直接コンフィグファイルに相当する部分を編集。CSSのコーディングをしているみたいな感覚でカスタマイズしてく。ちなみにまだBeta4なので最終リリースでどうなっているのかは不明。ひょっとするとリリース時には「環境設定」があるかもしれない(或いは既にあるけど見落としてるのかも)。
そろそろFlexの試用期限も迫ってきたので、購入しようかと考えていたところに思わぬ伏兵が現れた。
「FlashDevelop」がとてもイイ。今のトコBeta4だけど、ほぼ問題なく動作している。時折プロジェクトのロードに時間がかかっているけどそんなのは些細な事だ。
FlexBuilderもデザインモードとかほとんど使わないので、FlashIDE(CS3)とFlashDevelopがあれば当面の開発には事欠かないかも。
難点は日本語環境が無かったり、flex_sdkをインストールしたり、環境を用意するのが純正のFlashやFlexに比べて手間がかかるということだが、それも一時間ほどで整える事が出来る。コードカラーリングとかコードフォーマットのカスタマイズがまだ不明だけど(結構めんどくさいという噂がある)そのうち何とかなるだろ。
UIの見栄えもよくてFlexより美しい。でもって軽くて快適。少なくともFlex3がリリースされるまではFlashDevelopで行こうと思う。
*traceの出力をOutputパネルに表示させるやり方が初めわからんかったが、SWFの表示を「Documment」から「External」に変更してやればOKだった。
>Project >Properties >Output >TestMovie から。
忘れないようにメモ。
ここんところFlexBuilder2ばっかり触っていたので、F11を叩く事が多くなった。そんなわけでFlashでコンパイルするときもF11を叩いてしまう。ライブラリパネルが開いて、また間違えたとか思いつつCtrl+Returnになれてきた頃にはFlexにもどってまたもや間違える。こんな事の繰り返し。
ここら辺のUIの統一はあんまり改善されない。
FlexBuilderがEclipse由来だからといっても、キーボードショートカットやコードフォーマットはFlashに統一させてもいいんじゃ無いかと強く思う。RIAが、とかユーザエクスペリエンスが、とか色々アピールする前にAdobeは自社製品のユーザエクスペリエンスにもう少し配慮してくれても良いんじゃないかしら。
巷で話題のByteArrayも未熟な僕には少々荷が重いです。
ByteArray.writeObject()
ByteArray.readObject()
は任意のオブジェクトをバイナリデータに直列化(シリアライズ)して、それを復元(アンシリアライズ)したりできるらしいのですが、これって、Spriteなんかをバイナリー化してファイルとして保存できるんじゃないかと仮説を立ててみた。
そしたらhttp://noughts.jp/みたいにFlashのデータを補完したい場合、XML化したりDBに格納したりせず、オブジェクトの完全コピーを保存できるんじゃないかと。
(noughts.jpさんが実際にどうやってるのかは知らないけど)
で、ちょっとテストしたけど、そう簡単にはいかないみたい。というのも、
ByteArray.readObject()はどんなオブジェクトでも復元できるわけではない!
から。
おそらくByteArray.readObject()はバイナリーデータの中身を読み込んでそのつどオブジェクトをnewしている様子。実際にClassを作ってコンストラクタにtrace("foo")とか入れるとreadObject()のタイミングで帰ってくる。
そしてここからが重要! コンストラクタに引数を必須で渡さなければならない場合(function Foo(str:String)とか)に、「引数1個が必要ですが0個が指定されました」とエラーが帰ってくる!こりゃあまいった。なぜならreadObject()はバイナリーデータを走査し、オブジェクトをnewするが、、その際に引数を指定できないからだ。
Spriteの復元の場合、flash.geom.Transformで引っかかる。Transformクラスこそは第一引数にDisplayObjectが必須になるのでここで上記のエラーが出る。
これはどうしようもないな~
自分でSpriteByteArrayクラスを作ってreadObject()を実装する他ないのかな...
POPFORGEのasdoc(リポジトリとかに上がってないので自分で生成)と格闘していると、FurnaceFormatの説明文に表組みの文章があったのですごく驚いた。
Classファイルを確認するとソースのコメント部分に普通にhtmlソースが貼り付けてある。すごいよ、これ。asdocの仕様としては標準的なのかもしれないけど、ソースのコメントにhtmlを書くっていう発想がすごい。
やっぱり天才コーダーは開発だけじゃなくてここら辺の発想がかっとんでるのかな。
POPFORGEを使いこなすためにも、やっぱりByteArrayに関する造詣を深めないとどうにもならないな~と思い、とりあえずどういうものなのか試してみる。とりあえず「Hello world」レベルで良いので、まずは「HelloByteArray」クラスを作ってみた。
package
{
import flash.display.Sprite;
import flash.utils.ByteArray;
public class HelloByteArray extends Sprite
{
function HelloByteArray()
{
var byteArr:ByteArray = new ByteArray();
var str:String = 'HelloByteArray';
byteArr.writeUTF(str);
var len:int = byteArr.length;
for (var i:int=0; i<len; i++) {
//16進数で表示してみる
trace('no_'+i+' : '+byteArr[i].toString(16));
}
//ポインタを先頭に移動
byteArr.position = 0;
//UTF-8で表示する
trace(byteArr.readUTF())
}
}
}
これを実行すると下記がトレースされる。
no_0 : 0
no_1 : e
no_2 : 48
no_3 : 65
no_4 : 6c
no_5 : 6c
no_6 : 6f
no_7 : 42
no_8 : 79
no_9 : 74
no_10 : 65
no_11 : 41
no_12 : 72
no_13 : 72
no_14 : 61
no_15 : 79
HelloByteArray
で、今度はテキストエディタで任意のファイルを作成して一行目に「HelloByteArray」と入力して保存、今度はバイナリエディターで開いてみる。すると上記トレース結果のno_2以降の数値とバイトコードが一致していることを確認できる。no_0,no_1はおそらくファイルの種類に関する変数だと思う。詳しいことはまだ分からない。
とりあえずまだ何の役にも立たないが、ちょっとだけメモしておこう。
いま、ちらりとAdobeのwebを見るとFlexが大安売りしていた!!
たしか以前の価格表だと10万円位していたはず...いきなりの価格破壊でビックリ。もうすぐ試用期限も切れるので購入しようかと俄然やる気が出てきた。SDKオンリーでやるのってどうもね。
新たにchartingというのが追加されたようだけど、チャートライブラリらしい。これだけで¥55,000っていったいどんな内容なんだろう(素朴な疑問で)
とりあえず、これだけ大胆に価格変更してくれたことが嬉しい。これより以前に購入した人は気の毒だけど、それだけFlexの普及にAdobeはがんばってるってことで良いかな。
winマシンからphpMyAdminのフィールド編集画面を開くと、データの改行コードがかってに( CRLF )に変換される様な気がする。あまりちゃんと検証していないけど、編集画面を開いても保存しなければ大丈夫だったり...よく分からん。
で、それ( CRLF 変換されちゃったデータ )をFlashに渡してtraceとかしてやると、CRとLFで2回ずつ開業しているので、一行ずつ空白が出来ててとてもビックリ。色々調べて( CRLF)かよ!と憤慨。
ちょっと調べてみるとcrlf2lfを発見。
いいな~と思ったのでそれをAS3.0なので正規表現を使って書いてみた。
function crlf2lf(str:String):String {
str = str.replace(/\r/g,'');
str = str.replace(/\r\n/g, '\n');
return str;
}
FlashカンタンリズムマシンをMySQLと連携してみた。
http://memo.kappa-lab.com/catapio_test/alpha_0_1_2_0.html
実はMySQLは今回が初挑戦。
MySQLが、と言うわけではなくデータベース事態初めてだったが割とすんなり実装できた。
PHPもそんなに得意ではないが、データの参照、追加、編集くらいなら半日くらいで理解、実装できるんだな、と感心。なかなかおもしろかった。データベースは利用するよりインフラとして用意する方がよっぽど大変なんだろう。
でもって、若干UIも変更。
PlayListから他のユーザの演奏情報もプレイできるようにしつつ、視聴回数も表示するようにした。(ここの文言をlistenedとかテキトな言葉なので恥ずかしいがあえてそのままにする)取り合えず一段落。
ここまでの過程は初めに描いていたとおり迷い無く突き進むことができたけど、ここからが問題だ。どういう方向に発展させていくか。ここが凄く重要だと思う。本当におもしろいものになるかどうか、ここからが勝負だと思うが、この分岐点は選択肢がいっぱいで正直、悩む。
以下、妄想を列挙してみる。
1.会員登録とかSNSっぽく!
2.とにかく音楽系機能てんこ盛り!
3.ブログパーツとか作ってみる!
4.もっとUIのデザインを煮詰める!
5.この楽器だけでライブをやる!
6.AIR化する!
7.(何故か)グッズを作ってみる!
上記2/3位は本気だったりするけど、まあ週末にじっくり考えてみよう。
POPFORGEカスタマイズや簡易リズムマシンの系譜を少しばかりブラッシュアップしてみた。
こちら↓↓↓
http://memo.kappa-lab.com/catapio_test/alpha_0_0_1_5.html

前回までと本質的に異なっている(一応進化したと言いたい)のは演奏したデータを保管し、他のユーザがそれを試聴できる点。手垢にまみれた言葉だけど、2.0とかCGM的な性質を持たせてみた。
今後どれだけこのページ(悲しいかなまだサイトではない)がどの程度成長するか、演奏データを蓄積出来るのかが楽しみ。とは言えこの弱小ブログに載せた程度じゃあ告知能力に限界があるので、そのうち何か手だてを考えないと。
今回、演奏データを残すためにこんな具合にした。
1.一定時間(1/50sec)ごとに音源ボールの位置をすべて記録する
2.演奏終了後、音源ボールの差分だけを検出し、記録データを圧縮する
つまり、とりあえず底引き網的にデータ収集、その後、必要なトコロだけ取捨選択する。というやり方にしてみた。当初、圧縮は必要ないかと思いきや180秒で軽く1MBを超すので圧縮を決定。おかげで100KB以下に。
この手のユーザーインタラクションを記録するのはみんなどうやっているだろうか。(次回までの宿題)
AS3からPHPとかにXMLをPOST送信することはよくある事だが、XMLデータが大きい場合、ちょっと問題が生じる。具体的にはデータサイズが100KBとかになると危険。
そんなときは
var req:URLRequest = new URLRequest('target.php');
req.contentType = "application/xml";
var postLoader:URLLoader = new URLLoader();
postLoader.load(req);
この「req.contentType = "application/xml";」が重要で、ヘルプなんかでは「req.contentType = "text/xml";」と書かれている。こうしておけば一応1MBくらいまでは送信可能になる。ただこのやり方で良いのかちょっと不安。ひょっとしてBadTipsかもしれないので、もうちょっと検証が必要かも。
AS3.0の学習を始めてからひと月少々が経つので、ここらでひとつ雑感をまとめて見ようと思う。半年経つとまた認識が変わっているはずなので、自分の心境の変化を後から比較するのにも役に立つかもしれない。
9月初めにこの参考書を購入。AS3.0のヘルプはAS2.0のときより若干サンプルコードが減った気がする。やっぱり新しい事を学ぶにはwebベースの資料も大事だけどハードコピーが一つくらいあった方がはかどる。
学習前の予想として、「AS3.0になってOOPの性格がよりいっそう強くなったけど、実際は新しいクラスや機能が追加されただけでAS2.0の時と同じフレームアクションで構築できるんでしょ?」という予想は当たらずとも遠からずだったようだ。
実際にAS2.0、というかFlash8以前のコーディング方法で外部asファイルを使用せずにフレームアクション主体で構築する事は普通に出来る。(一応断っておくけどAS2.0でも外部asを使った構築は可能)
内容によってはフレームアクションで構築した方が外部asを使うより効率がいい事も多いだろう。
ただ、やはり外部asファイルを使ってクラス定義をしていく方が、それぞれの機能の役割や内容を把握しやすいみたいだ。そして何よりOOPの理解が格段に深まったことが嬉しい。以前にJavaで3Dフレームワークに手を出したとき、行列の計算やらアフィン変換、zバッファとかの勉強にはなったが、OOPに関してはあまり目覚めなかった。
ところが今回、AS3.0の学習によってOOPへの理解が深まったのは、馴染みの深いFlashIDEの恩恵や自分の貧弱だが付き合いが長いAS2.0のスキルによるものではないかと思う。いくつかの共通点があるとはいえ、ロクにさわったことが無いJavaの上ではOOPなんてややこしい概念が腹に落ちるはずがない、と思う。仮に全く前提知識やスキルが無い状態でAS3.0やOOPを理解するのは、骨が折れるというよりも苦痛じゃないだろうか。
とにかくAS2.0やレガシーFlashの存在無くしては今回の取り組みはより格段に大変だったはずだ。
そして当然のことだが、AS2.0のスキルやFlashIDEの習熟も、それ以前のバージョンによって支えられてきたものだ。自分の場合、AS1.0やFlashMX(ここからデビュー、懐かしい)の存在によって、少しずつスキルを磨くことが出来た。ActionScriptが単なるムービーにちょっと色を添えるぐらいの簡易言語(本当の意味でスクリプト)からスタートせずにいきなりOOPとしてJavaの様な仕様だったらこんなところまで付いて来られるはずがない。
そういうわけで自分のスキルは完全にActionScriptの進化によって導かれていると言って過言ではない。macromediaがFlashにスクリプト言語を実装した頃、どの程度のロードマップを描いていたのか知る由も無いが、この進化の速度と課程にたいしてmacromediaに感謝せずにはいられない。そう、Adobeに対してではなくだ。
というわけで、あえて今、macromediaのタグを追加してみた。
前回、FlexでPOPFORGEをカスタマイズしたのがすごく楽しかったので、Flashベースで楽器のような習作を色々作ろうかと思う。
とりあえずリズムマシーンのようなものを作ってみた。
リズムマシーンだけど、極力シンプルにしたかったので、音源は3種類、ドレミ、だけ。
3種類だけ?と思うだろうが、これがどうしてそこそこのシーケンスを作れるかもしれない手応えがある。
もう少し試行錯誤すればいけるかも。
某プロジェクトにも流用したい。
ちなみにロジックはわかりやすく、下のプログレスバーとの衝突を拾って、音を鳴らしているだけ。一応ActionScript3.0(AS3.0)でコーディングしているが、技術的にはAS2.0でできる。(ひょっとするとAS1.0でも出来るかもしれない)今のところAS3.0で無ければ実装出来ない技術は何も盛り込んでいない。だからといって、AS3.0を不要だといったり、AS2.0で十分!と言うつもりは全然無い。何というか、まだうまく言えないがAS3.0はいいんだ。
ActionScript3での音生成をしてみたいぜ!と強く思ったので、ちょっとFlexを弄ってみた。
Flashばっかの人間にはFlexは何となく敷居が高いな~と思っていたけど、同じく敷居が高いと思っていたAS3.0も書いてみると思っていたほどでもなかったので、Flexでも何とかなるだろうと試してみたところ、コレがびっくり。
FlashCS3のIDE機能よりも遙かに洗練されている。コードヒントもimport文の自動挿入も最高にイイ!
というか何故その機能がFlashCS3に実装されていないのかがむしろ不思議だ。
ずいぶん前にJAVAやらPHPで習作を作るためにEclipseを使ったことがあったが、そのときもEclipseってDreamweaverとかより全然使えるじゃない!と思った。で、今回のこともあってEclipseが再燃しそう。
一応AdobeはEclipseFoundationに参加してると以前どこかの記事で目にしたが、Flexはその成果物としてとてもすばらしいんじゃないかと思う。だから、その成果をFlashとDWにも反映して欲しい。
AS2.0からAS3.0の移行で感じた大きなギャップは、今のところコレが一番。
「parentの扱い」について
global変数がなくなったりroot変数の仕様が変わったりは耳にしていたので、予備知識のおかげで大した混乱もなかったものの、コイツにはマイッタ。
たとえば
「hoge_mc」の中に「inner_mc」を入れ子にして、「inner_mc」のフレームアクションに下記のスクリプトを書く
AS2.0の場合
/*inner_mc frame action vr:AS2.0*/
_parent.gotoAndStop(2) ; //hoge_mcは2フレームに移動する
AS3.0の場合 その1
/*inner_mc frame action vr:AS3.0*/
parent.gotoAndStop(2); //コンパイルエラーになる
MovieClip(parent).gotoAndStop(2); //hoge_mcは2フレームに移動する
AS3.0の場合 その2
/*inner_mc frame action vr:AS3.0*/
var parentMc:MovieClip= MovieClip(parent);
parentMc.gotoAndStop(2); //hoge_mcは2フレームに移動する
同様にparentの変数や関数にアクセスするときも
/*inner_mc frame action vr:AS3.0*/
var parentMc:MovieClip= MovieClip(parent);
parentMc.foo_var;
parentMc.foo_func;
と言う具合に型キャストが必要になる訳だけど、その理由はparentの型がMovieClipではなくDisplayObjectContainerだから、だそうです。なにかしら重要な意味があってこうなったとは思うけれど、今の自分の理解じゃあ重要な何かがなんなのかよくわからん。そのうちわかるんだろうか。
とりあえずもう、スクリプト言語じゃあ無いよな、と思う。
ま、忘れはしないだろうから、いちいちメモを取る事も無いんだけど、後から読み返して「ああ、そんな事もあったなあ」と振り返ってみるためにメモ。
ActionScript3(AS3)でXMLの特定のノードにid属性を使ってアクセスするためのメモ。
AS2でいうところのidMap[]だったり、JavaScriptのgetElementById()とかと同様の処理をしようと思ったら意外にハマッてしまった。AS3の仕様が厳格なのか、それとも単なる気まぐれなのかわからないけど、一応メモ。
<body>
<p id='123'>Hello, <b>Bob_1</b>.</p>
<p id='124'>Hello, <b>Bob_2</b>.</p>
<p id='125'>Hello, <b>Bob_3</b>.</p>
<p id='126'>Hello, <b>Bob_4</b>.</p>
<p id='127'>Hello, <b>Bob_5</b>.</p>
<p><b><p id='128'>Hello, <b>Tom</b>.</p></b></p>
</body>
こんな感じのXMLに対してid"128"にアクセスする場合、
AS2だとこう↓
var doc:XML = new XML("<body><p id='123'>Hello, <b>Bob_1</b>.</p><p id='124'>Hello, <b>Bob_2</b>.</p><p id='125'>Hello, <b>Bob_3</b>.</p><p id='126'>Hello, <b>Bob_4</b>.</p><p id='127'>Hello, <b>Bob_5</b>.</p><p><b><p id='128'>Hello, <b>Tom</b>.</p></b></p></body>");
trace(doc.idMap['128']);//<p id="128">Hello, <b>Tom</b>.</p>
AS3だとこう↓
var doc:XML = new XML(
<body>
<p id='123'>Hello, <b>Bob_1</b>.</p>
<p id='124'>Hello, <b>Bob_2</b>.</p>
<p id='125'>Hello, <b>Bob_3</b>.</p>
<p id='126'>Hello, <b>Bob_4</b>.</p>
<p id='127'>Hello, <b>Bob_5</b>.</p>
<p><b><p id='128'>Hello, <b>Tom</b>.</p></b></p>
</body>
trace(doc.descendants().(attribute('id') == '128'));//<p id='128'>Hello, <b>Tom</b>.</p></b>
//trace(doc.(attribute('id') == '128'));//これだと何も返さない(空白)
//trace(doc.descendants().(@id == '128')); //これだとランタイムエラー
//trace(doc.(@id == '128')); //これもランタイムエラー
//trace(doc..(@id == '128')); //これだとコンパイルエラー
AS3の場合、子ノードや孫ノードを含めてid属性を検索する場合、descendants()が必要になるみたいです。AS2のidMapの感覚からするとdoc.(attribute('id') == '128'やdoc.(@id == '128')でアクセス出来そうな気がするけど、これは不可。
とくに@idを使った場合、同一階層の他のノードにid属性がない場合、ランタイムエラーを返すので要注意。
AS3になって、かなりXML環境が強力かつ便利になったみたいでとても格好いいな~と思っていたけど、上記の問題を解決するのに半日費やしてしまった。いまいちFlashのヘルプが貧弱な気がする。
まあとりあえず解決できたので、習作として為替レート表示Flashか天気予報Flashとかベタなコンテンツを作ってみよう。
FlashCS3のマニュアルのAS3の導入部分をざっと読んでみたけど、結構誤植が多い。特にサンプルスクリプトに完全に動作しなくなるような誤植や、ちょっとしたケアレスミスのような誤植が散見した。
別にマニュアルの誤植を鬼の首を取ったかのようにあげつらうつもりは到底ない。マニュアルの製作はアプリケーションの開発より酷な作業だと思う。しかもこれを翻訳するとなってはもう想像がつかない。日本語と英語に堪能で文章力があり、なおかつプログラミングも理解してる人材なんてそうザラに居ないだろう。アプリケーションのローカライズやマニュアルの翻訳が大変だからCS3日本語版は英語版に比べて高額なのかもしれない。
Flash更新用にCMSを実装するとして、自製のCMSを実装することはそんなに難しい訳では無いかもしれないけど、納品物としてマニュアルを製作する必要やティーチングの必要があるなら、MovableTypeやWordPressを外部CMSとして利用する方が良いな、と思う。
CS3の試用期限が切れたので、ようやく購入。
と、いってもSuitではなくFlashCS3単体のみ。
なぜ単体購入かというと、一番大きい理由は「資金不足」これに尽きる。
それともう一つ、現在Winマシンをメインマシンに使ってるけど近い将来
Macに乗り換えるので、Suitはそれまでお預け。
まあその他にも色々理由はある。思ったよりアプリの間で統合がとれていなかったり、CSの機能で十分だったり。実際、IllustratorやPhotoshopは冗長な成長を続けるばかりで革新的とは言えないと思う。Flashの進化に対してIllustratorとPhotoshopの進化はマイナーバージョンアップ位にしか感じられないのだ。
あともう一つの理由がある。実はFlashMX単体のライセンスがあったから。このまま放っておくと次回のバージョンアップでは足切りされるだろうから、今のうちに何とかしたかった。
そして驚く事にこのMXはアカデミックにも関わらず製品版アップグレードが可能だった。てっきりアカデミック版では製品版アップグレードが適用されないと思いこんでいたけど実はちゃんとアップグレード可能だった。これはとてもうれしい。
が、ということは学生時代にMasterCollectionとかを買っていたらもっと良かったのかも...
何にせよ数年前に\15,000で買ったMXが思わぬところで役立ってよかった。学割って本当にいいよな~
少し事情があって、CS3でオーサリングしていたflaを急遽8に落として作業する羽目になってしまった。ターゲットプレイヤーはVr7だったので、そんなに問題はないだろうと思っていたところが予想外に大変だった。
CS3になって、オーサリング上でレイヤーを非表示にすると、パブリッシュしたときも非表示のままだ。この仕様は極々理にかなっていると思う。8以前はレイヤーをガイドレイヤーにすることで非表示にするしかなかった。そんなわけで、見せたくないレイヤーがいっぱい表示されてしまった。これを全部ガイドレイヤーにする作業はなんだかとても寂しい。
一通りレイヤー処理が終わって再度パブリッシュするが、今度は動作が重い。CS3なら快適に動作していた部分が持ったりしている。いろいろ原因を探ってはみたものの、ボトルネックは判明せず。
多分CS3のコンパイラーが優れているんだろうと勝手に納得する。
その後結局どうしたかというと、最終定期にはCS3でオーサリングすることになった。
全ては徒労に終わったわけだが、よくある話なので誰もあんまり気にしなかった。
FlashCS3にバグっぽい挙動を発見!
大したバグではないけど以下のような感じ。
if (foo < -5) {
trace("hi");
}
と記述後、自動フォーマットすると、「次の行の近くに自動フォーマットエラーがあります:trace("hi");」というアラートが出る。目をこらしてtrace文を見るが、やましいことは何もない様子。ちなみにシンタックスを試すと「このスクリプトにエラーはありません。」とのこと。
実害はないのだけど気持ち悪いので、解決すべくいろいろ書き方を変えると結果的にif文にもう一つ括弧を追加するとエラーが出なくなった。
if (foo < (-5)) {
trace("hi");
}
という具合。なんか気持ち悪いぞ!括弧がネストしすぎて読みにくい。
旧来のバグ「シンボル名を変更してreturnを押さずに保存すると変更が反映されない」は解消したみたいだけど、新たなバグ到来だ。指先がcomand+shift+Fに馴染んでしまっているので何かと悩まされそう。
これはFlashがそれだけ普及したな、と言うことでもあると思う。成長痛というか有名税というか、ソフトウェアが流通、普及していく過程でやっぱり避けて通れないな~と。
Flashが広まったのはうれしいことだけど、その分対策はしっかりやらないといけなくなったというわけで、お気軽に遊んで、動かして、実験して、だけじゃあ足らなくなってしまったと言うことだと思う。
数年前、既にオライリーのFlash Hackに「Flashはもう先鋭的な実験的メディアではなくなった」という旨の内容があったが、その言葉どおり、Flashはとっくにそのフェーズにいない。
AIRが今後普及していけば確実にこの傾向は強まるだろうと思う。かと言って「Silverlight」に手を出すかというと、多くのFlasherはそれを選ばないだろう。「Processing」はまたちょっと違うだろうし。
遊びの時間は終わったのかな、と思ったりする。
ここ暫く動画の編集やら素材作りを色々と...
普通はPremiereで編集して、素材はAfterEffectsを使うのが一般的だと思うのだけど、AEはさわらなくなって久しいのでさっぱりわからない。
ということでFlashを使ってタイトルロールやモーションロゴを作っている。
そこで気になるのが、PremiereとFlashのショートカットの違い。
これはなにげにストレスになる。特に再生。Premireは再生するとき
通常は「space」 それに対してFlashは「enter」
Premiereでも「enter」による再生は可能だが、少し意味合いが違って、レンダリングした後の再生になる。すなわちプレビューと違ってレンダリングを待たなければならない。押した後にしまった...となんど思ったことか。
ここら辺の統一はCS3でなされたのだろうか。
多分放置だろうな。
最近ちょっとした短編動画を作っていて気がついたメモ
FLASHでアニメーションロゴやクレジットを制作して、AVIに書き出しをすると、ムービークリップシンボルが意図した形で再生されない。
理由は何となく想像が付くけど、実際の制作中に考慮しなければならないのがメンドイ。
因みにFlash8のフィルターは反映される。
ちょっとやっかい。
AfterEffectsを使うのがまっとうな解決策だとは思いつつも、腰が重いな~。
以前にFlashで音声合成をしたときのメモ。結構お役立ち。(のはず)
Flashアプリにかかわらず、音声を合成したいと言うニーズは結構多いはず。こんなニュースもあるし。
上記で報じている内容はかなり汎用的かつ複雑な開発が必要だろうし、ターゲットもかなり大規模な市場に向けられていると思う。ココではそんな大仰な内容ではなく、もう少し簡単かつ即効性の有るtipsを話したい。
先ず、音声合成の内容とシチュエーションは簡単なもので以下のような感じ。
--------------------------------------------
ユーザーが入力した数値を読み上げる装置
桁数は4桁
言語は日本語
--------------------------------------------
最も簡単な方法は4桁分の音源を全て用意すること。スタジオで9999まで読み上げてもらって、録音する。その後エディターを使って切り出す。さらに音源内容と同様のファイル名を振り分けて、Flashからは入力された数値を確認してファイルを呼び出し、再生する。これで完成。
この方法(仮にシンプルプランとしておく)は音源再生のクオリティを最も高く保つことが出来る。しかし、物理的な限界がいずれ生じる。
現状では4桁だが、それ以上、例えば10桁とかになると音入れが大変な上、切り出しも大変。それからデータの容量もかなりの物になる。特にwebで公開を考えた場合、データの大きさは深刻な懸念材料になる。
従って、やはりここで音声を合成する方法をとる(合成プラン)。合成することによって、データ容量の肥大化と音入れ・切り出しによる時間的な問題を一気にクリアすることが出来る。
ここで録音する音源は以下の通り
--------------------------------------------
1桁:1-9まで
2桁:10,20,30,40,50,60,70,80,90
3桁:100,200,300,400,500,600,700,800,900
4桁:1000,2000,3000,4000,5000,6000,7000,8000,9000
--------------------------------------------
とすると9999個必要だった音源が僅か40個程度で良いことになる。
音源を40個に絞って組み合わせることによって再現する場合、例えば「1234(sen-nihyaku-sanjyu-yon)」を再生したい場合、必要な音源は次の4つ。「1000」「200」「30」「4」だ。
Flashは「1234」を解析して「1000」「200」「30」「4」の4つの音源を選択して順に再生する。
当然のことながら、この場合音源のとぎれが気になる。これから書いていく部分はまさにそこだが、いくら頑張ったところで前述のシンプルプランには後一歩及ばず妥協が必要になることをあらかじめ断っておきたい。また、Flashの解析ロジックはまた次の機会に。
さて、前置きが長くなったが、ここからが本題。
取り上げたいのはここで使用する音源の長さと扱いについてだ。
Flashで音源を扱う場合、やはりmp3を使用することになる。因みに圧縮率は標準的なレベルで問題ない。ただ、音源の長さ(デュレーション)を極限まで切りつめる必要がある。音源の前後に無駄な無音データが残っていると、音源同士の繋がりが悪くなりスムーズに聞こえなくなる。かといって、誤って必要な音源まで切り取ってしまうと当然だが千切れた不自然な再生になる。音源を切り出す際はこの点をかなりシビアにコントロールしなければならない。
しかし、ここでmp3の仕様上の限界に衝突することになる。mp3は圧縮する際のアルゴリズムのために完全に意図した長さ(デュレーション)に調整できない。出典は忘れたが、周波数に依存するため、その倍率でしか音源を作成できないそうだ。端的にいうと60secジャスト、と言う音源は作成不可能であって、60.xxxxsecにならざるを得ないらしい。
こうなると、いくらシビアに切り出しをしたところで意味がないな、と諦めかけたが、FlashのAPIのおかげで解決することが出来た。AS2.0のSoundクラスでは音源再生時に1/1000sec単位でディレイを掛けることが出来る。
スクリプトは次の通り
mySound.start(0.025);
たったこれだけだけど、大幅に改善することが出来る。因みに0.025secというのはこの時経験からなので、ケースバイケースだと思う。また、mp3を切り出すとき、音源の末尾ではなく先頭に無音部分が付加されるように設定する必要が有ることを忘れずに付け加えておく。
Copyright (C) 2007 kappa-lab.com.
All Rights Reserved.