DoExecutor
2010 年 8月 31 日 火曜日 kosukeProgression 4 で追加されたコマンドにDoExecutorがあります。
このコマンドはその名の通り指定したExecutorObjectを実行出来るのですが、便利そうなケースがあったので記録しておきます。
- トップページは、直下に子シーンを持つ。
- 子シーンは背景イメージを変更する。
- トップページでは子シーンのいずれかの背景イメージを表示する。
ぎゅっと簡略した形ですがギャラリーコンテンツなんかでありそうなケース。
子シーンはこんな感じです。シーンに到達したら背景イメージを追加するだけ。
package{ import flash.display.Bitmap; import jp.progression.commands.Prop; import jp.progression.commands.display.*; import jp.progression.scenes.SceneObject; public class ChildScene extends SceneObject{ public function ChildScene(name:String=null, initObject:Object=null){ super(name, initObject); } public var bmp:Bitmap; //背景イメージ protected override function atSceneLoad():void{ //※確認用、シーンパスを表示 var indexScene:IndexScene = parent as IndexScene; addCommand( new Prop( indexScene.field, { text:sceneId.path } ) ); } //背景イメージ追加 protected override function atSceneInit():void{ addCommand( new AddChildAt( container, bmp, 0 ) ); } //背景イメージ削除 protected override function atSceneUnload():void{ addCommand( new RemoveChild( container, bmp ) ); } } } |
トップページはこちら。トップページでは背景イメージをランダムに選んで表示したいのですが、背景イメージの表示は子シーンにも記述があります。なのでこれをDoExecutorコマンドで動かしてしまおうという魂胆。
package{ import flash.display.Bitmap; import flash.text.*; import jp.nipx.debug.btn.Btn; import jp.progression.casts.*; import jp.progression.commands.*; import jp.progression.commands.display.*; import jp.progression.commands.lists.*; import jp.progression.commands.managers.*; import jp.progression.commands.media.*; import jp.progression.commands.net.*; import jp.progression.commands.tweens.*; import jp.progression.data.*; import jp.progression.events.*; import jp.progression.executors.*; import jp.progression.scenes.*; public class IndexScene extends SceneObject{ public function IndexScene(){ var btn:Btn; btn = new Btn( { label:"Index", sceneId:new SceneId( "/index" ), x:5, y:225 } ); container.addChild( btn ); btn = new Btn( { label:"1", sceneId:new SceneId( "/index/1" ), x:btn.x + 5 + btn.width, y:225 } ); container.addChild( btn ); btn = new Btn( { label:"2", sceneId:new SceneId( "/index/2" ), x:btn.x + 5 + btn.width, y:225 } ); container.addChild( btn ); btn = new Btn( { label:"3", sceneId:new SceneId( "/index/3" ), x:btn.x + 5 + btn.width, y:225 } ); container.addChild( btn ); addScene( new ChildScene( "1", { bmp:new Bitmap( new Img1( 250,250 ) ) } ) ) as ChildScene; addScene( new ChildScene( "2", { bmp:new Bitmap( new Img2( 250,250 ) ) } ) ) as ChildScene; addScene( new ChildScene( "3", { bmp:new Bitmap( new Img3( 250,250 ) ) } ) ) as ChildScene; field = new TextField(); field.defaultTextFormat = new TextFormat( "_ゴシック", 10, 0x333333 ); field.x = 5; container.addChild( field ); } public var field:TextField; protected override function atSceneInit():void{ //子シーンをランダムに選ぶ var i:Number = Math.round( numScenes * Math.random() ); i = ( i == numScenes ) ? 0 : i; var scene:SceneObject = getSceneAt( i ); addCommand( new Prop( field, { text:sceneId.path } ), //子シーンexecutorを動かす、シーン到着時のイベントを送信 new DoExecutor( scene.executor, new SceneEvent( SceneEvent.SCENE_INIT ) ) ); } protected override function atSceneGoto():void{ addCommand( new RemoveChildAt( container, 0 ) ); } } } |
こんな形で使うと似たような処理をいくつものSceneObjectに書くようなことを減らせることもありそうですね。
ここでは、もともとSceneObjectに実装されているイベントでExecutorObjectを動かしていますが、独自のイベントでExecutorObjectを動かすことも可能です。
このあたりExecutorObjectってなに?ってところから、解りやすく書かれている記事を見つけました。
Progression 4 の DoExecutorコマンドを使い倒す!
DoExecutorコマンドは、動かしたExecutorObjectの処理でもコマンドシークエンスが有効ってところがとても便利ですね。
CS5の埋め込み文字
2010 年 8月 30 日 月曜日 kosuke埋め込みフォントをSWCに書き出して利用すれば、高速なパブリッシュが出来んだが、Flashで利用する際、アウトラインフォーマットがクラシック(DF3)で、SWCに書き出したフォントと同じフォントを指定したテキストフィールドがあるとうまくSWCのフォントを利用できなかったのでメモしておく。
SWCに書き出すほうのflaファイルでは以下のように日本語フォントを埋め込んでSWCに書き出します。パブリッシュのSWF設定、SWC書き出しにチェックでSWCに書き出せる。
SWCを利用するほうのflaファイルで、SWCにパスを通し書き出したクラス名のインスタンスを宣言すると埋め込みフォントとして利用できるようになる。しかもパブリッシュは軽い。
package{ import flash.display.Sprite; import flash.text.*; public class EmbedDF3 extends Sprite{ public function EmbedDF3(){ //SWCに埋め込んだフォントを利用 var embedFont:Font = new HiraginoKakuGoProW3DF3(); //利用できる埋め込みフォントを確認 var arr:Array = Font.enumerateFonts(); for each( var i:Font in arr ){ trace( i.fontName ); //出力:Hiragino Kaku Gothic Pro W3 } var str:String = "SWCの埋め込みフォントを利用" + "\n"; str += "Hiragino Kaku Gothic Pro W3"; var format:TextFormat = new TextFormat(); format.font = embedFont.fontName; format.color= 0x999999; var field:TextField = new TextField(); field.defaultTextFormat = format; field.x = 25; field.y = 25; field.width = 200; field.height= 100; field.borderColor = 0x999999; field.border = true; field.multiline = true; field.wordWrap = true; field.embedFonts= true; field.text = str; addChild( field ); } } } |
ここまではいいんです。とっても便利。
しかし、flaに同じフォントを指定したテキストフィールドがあったとします。
ここではステージにテキストフィールドを配置していますがどこにあっても同じ。
このテキストフィールドのアンチエイリアスはデバイスフォントとしています。
これで書き出すと、
埋め込みフォントが利用できません。
どうも同名のフォントがあるとそちらが優先される模様。
この時は、
//利用できる埋め込みフォントを確認 var arr:Array = Font.enumerateFonts(); for each( var i:Font in arr ){ trace( i.fontName ); //出力:無し(arr.length = 0) } |
も出力されないので、埋め込みでない同名フォントが優先されているのかなと。
試しにステージに配置したテキストフィールドのアンチエイリアスを「アンチエイリアス(アニメーション優先)」とした場合、テキストフィールドに入っている文字だけが表示される。
traceの部分では、Hiragino Kaku Gothic Pro W3が出力されているんだけど、Flashが自動的に埋め込む、ステージに配置したテキストフィールドのフォントになっているんだと思う。
update takahiromiki.com
2010 年 8月 26 日 木曜日 kosuke三木さんのサイトをプチアップデートしました。
Twitterのつぶやき表示を追加しました。あと新しい三木さんの作品が5点追加されています。
46のPVが個人的に好きな感じ。応援歌にぴったりな映像にぐっときてしまいました。
Safari 5とSWFAddressの不具合の件
2010 年 8月 25 日 水曜日 kosuke前にエントリーした不具合の件、公式に載っていました。
SWFAddress.back() doesn’t work in Safari 5
Safari 5とDebugger バージョンのFlash PlayerだとNGらしい。試しに通常バージョンのFlash Playerにしたらちゃんと動いていた。作る人はDebuggerのほう使うだろうに。めんどくさい話だなぁ…。
ちなみにSWFAddress 2.1まで落とすとDebuggerでも動く。なんでって話だけど調べる気にはなれん…。一概にSafari 5のせいとも言えない話でした。
BLACKOPERATOR Collaborated 01
2010 年 8月 20 日 金曜日 kosuke
ファッションブランド、BLACKOPERATORの新作がWebで公開されました。
RAIDSYSTEM、およびWORLDS END GIRLFRIENDとコラボレーションしたT-Shirtsがリリースされています。
Webのコンテンツは今回もnssgraphica町田さんとのお仕事で、僕は引き続きFlashをやらせていただきました。
選択範囲の境界線を描くまで
2010 年 8月 12 日 木曜日 kosukePhotoshopで選択範囲を取ったときの点線の輪郭線を描きたくて試した方法。
輪郭線を描きたい対象を透明なBitmapDataにdrawする。
輪郭を得るために一旦このBitmapDataを透明と黒100%で二値化する。
var rect:Rectangle = new Rectangle( 0, 0, 200, 200 ); var master:BitmapData = new BitmapData( rect.width, rect.height, true, 0x00000000 ); var pt:Point = new Point(); master.draw( container ); master.threshold( master, rect, pt,">",0x00000000, 0xFF000000, 0xFFFFFFFF, false ); |
エッジ部分のアンチエイリアスも含めて輪郭としたかったんで、ここでは透明以外のピクセルはすべて黒100%にしているけど0x00000000を変更すれば、輪郭に含むアンチエイリアスの許容値を調整できる。
元の文字と二値化した文字。
二値化したBitmapDataを複製しておく。元のBitmapDataにConvolutionFilterを適用。
以下のマトリックスで適用すると境界の内側、外側に1ピクセルずつ不透明ピクセルが出来て滲んだ画像になる。ConvolutionFilterって前にエントリー書いたけど、なるほどこんなケースで使えるんだなぁと思いました。
var convolution:ConvolutionFilter = new ConvolutionFilter( 3,3, [ 1, 1, 1, 1, 1, 1, 1, 1, 1 ], 9, 0, false ); var clone:BitmapData = master.clone(); master.applyFilter( master, rect, pt, convolution ); master.draw( clone ); |
次に滲んだBitmapDataに複製しておいたBitmapDataをdrawする。これで輪郭の外側1ピクセルが滲んだ状態になる。
輪郭の内側・外側が滲んだ文字と、輪郭の外側が滲んだ文字。
輪郭の外側の滲んだ部分が選択範囲の境界線として使いたい部分なのでこれを取り出す。
BitmapDataに対し今度は黒100%の部分を透明に置き換えた後、再度、透明と黒100%で二値化する。
master.threshold( master, rect, pt,"==",0xFF000000, 0x00000000, 0xFFFFFFFF, false ); master.threshold( master, rect, pt,">" ,0x00000000, 0xFF000000, 0xFFFFFFFF, false ); |
これで選択範囲の境界線が出来た。
続いてチカチカ流れる部分。これ一時悩んだのですが(輪郭を時計回りに回っているものだと思った)よく見ると水平線は左から右へ、垂直線は上から下へ流れているだけ。難しく考え過ぎてた。斜めの線動かせばいんじゃない?ってYさんの一言で気づいた。
斜め線のパターンを作ってBitmapDataのサイズ同じサイズでShapeを塗りつぶす。
var b:uint = 0xFF000000; var pattern:BitmapData = new BitmapData( 6,6, true, 0x00000000 ); pattern.setVector( new Rectangle( 0,0,6,6 ), Vector.<uint>([ 0,0,0,b,b,b, 0,0,b,b,b,0, 0,b,b,b,0,0, b,b,b,0,0,0, b,b,0,0,0,b, b,0,0,0,b,b ]) ); var shape:Shape = new Shape(); var g:Graphics = shape.graphics; g.beginBitmapFill( pattern ); g.drawRect( 0,0, rect.width, rect.height ); |
選択範囲の境界線と斜め線のパターン。
あとは斜め線のパターンを1ピクセルずつ動かしながら選択範囲の境界線に合成すれば、Photoshop風の点線境界線の完成です。
var matrix:Matrix = new Matrix(); addEventListener( Event.ENTER_FRAME, function(e:Event):void{ matrix.tx = ( matrix.tx + 1 ) % 6; g.clear(); g.beginBitmapFill( pattern, matrix ); g.drawRect( 0,0, rect.width, rect.height ); outline.fillRect( rect, 0 ); outline.draw( master ); outline.draw( shape, null, null, BlendMode.ALPHA ); }); |
Safari…
2010 年 8月 10 日 火曜日 kosuke5.0.1になって、この間の画面が溶ける現象がなおったと思ったら、こんどはSWFAddressが効かなくなったような気が…。いい加減にしてほしい。
直リンクはOKですけど、ブラウザの戻る進むの時反応しなくないですか?俺だけ?
http://www.asual.com/swfaddress/samples/flash/
バージョン 5.0.1 (6533.17.8)
外部パートナー募集
2010 年 8月 4 日 水曜日 kosukephpやperlのプログラマーの方で、一緒に仕事してもいいよ。
というフリーランス・個人の外部パートナーを募集しています。
サーバーサイドのプログラムが必要な案件では、こちらで対応しきれないことがあります。案件の数は多くないけど、そんな話があった時に見積もりレベルから気軽に相談できる方がいたらいいなと。もちろん逆にFlashやデザインが必要な時には相談に乗らせていただきますので。
それほど複雑な案件は過去ありませんので、企業キャンペーンサイトのクライアント案件実績があればスキルよりも誠実・堅実・責任感のある方で都内で打ち合わせ可能な方。
よかったらご連絡ください。まずは一度お会いしてみませんか。
気が合いそうでしたら一緒に仕事をしましょう。
【過去にあった具体的な案件例】
Twitter APIを操作したい。
サーバーサイドで画像生成したい。
ゲームのハイスコアを記録したい。
トラックバックを集計したい。
MTやWPのカスタマイズなどで簡易CMSにしたい。
Flashだけでファイルをダウンロードさせる
2010 年 7月 23 日 金曜日 kosukeTLFTextField独習 その2
2010 年 7月 8 日 木曜日 kosukePhotoshopで文字組したPSDファイルをFlashに読み込んだ時の再現性を確認してみた。
TextFieldでインポートされていた前バージョンと比べれば良くなっているんだけど、まだ調整無しで使うのは厳しいっぽいなぁと。
確認してみたのは以下のパターン。
Photoshopで2書体混在、カーニングをメトリックス、左揃え、赤字の箇所を字詰めしたポイントテキスト。
・元のPSD
このPSDをFlashにインポートしてみる。書き出したSWFのスクリーンショットを元のPSDに重ねてみたのがこれ。
「TLFTextFieldで美しい日本語。」以外はビットマップになっているのでズレない。
TLFTextFieldには文字を埋め込んだ以外(自動カーニングがあるので)は、インポートした状態からいじっていない。
淡い方が元のPSDの位置。全体的に下に移動している。
字詰め自体はほぼ正しく反映されているように見えるんだけど、字詰め前の段階からして文字間隔が変わっちゃってるところもある。PSD側の自動カーニング(メトリックスなど)を使わない場合はもう少しズレが減る感じでした。
試しに同じPSDをCS5でPlayer9ターゲットのflaにしてTextFieldでインポートしたのがこちら。
こちらはぜんぜん字詰めが生きていない。上下位置はズレなかったりするんだけども。
この後、ブロックテキストで均等配置にしたPSDなども試したんですけど、再現性はさらに悪くなる感じでしたので、このあたりであきらめ…。レイアウトの再現性は微妙な感じがしますがTLFTextFieldでインポートした場合、字詰めなど書式を変更した箇所はTextFlowの構造に反映されます。この点は凄いんじゃないかと思う。
<TextFlow alignmentBaseline="useDominantBaseline" blockProgression="tb" columnCount="inherit" columnGap="inherit" columnWidth="inherit" direction="ltr" dominantBaseline="auto" fontLookup="embeddedCFF" lineBreak="explicit" paddingBottom="inherit" paddingLeft="inherit" paddingRight="inherit" paddingTop="inherit" paragraphEndIndent="0" paragraphSpaceAfter="0" paragraphSpaceBefore="0" paragraphStartIndent="0" textAlign="start" textIndent="0" verticalAlign="inherit" whiteSpaceCollapse="preserve" xmlns="http://ns.adobe.com/textLayout/2008"> <p baselineShift="0" breakOpportunity="auto" color="#000000" digitCase="default" digitWidth="default" direction="ltr" fontFamily="小塚ゴシック Pro R" fontSize="60" fontStyle="normal" fontWeight="normal" ligatureLevel="common" lineHeight="72" lineThrough="false" locale="en" textAlpha="1" textDecoration="none" textRotation="auto" trackingRight="0%" typographicCase="default"> <span fontLookup="inherit">TLF</span> <span fontLookup="inherit" trackingRight="-10%">T</span> <span fontLookup="inherit">ext</span> <span fontLookup="inherit" trackingRight="-2%">F</span> <span fontLookup="inherit">ield</span> <span fontFamily="小塚明朝 Pro M" fontLookup="inherit">で</span> </p> <p baselineShift="0" breakOpportunity="auto" color="#000000" digitCase="default" digitWidth="default" direction="ltr" fontFamily="小塚明朝 Pro M" fontSize="60" fontStyle="normal" fontWeight="normal" ligatureLevel="common" lineHeight="72" lineThrough="false" locale="en" textAlpha="1" textDecoration="none" textRotation="auto" trackingRight="0%" typographicCase="default"> <span fontLookup="inherit">美し</span> <span fontLookup="inherit" trackingRight="-4%">い</span> <span fontLookup="inherit" trackingRight="-6%">日</span> <span fontLookup="inherit" trackingRight="2%">本</span> <span fontLookup="inherit">語。</span> </p> </TextFlow> |
ちなみに、PSDで文字間の字詰めをする時はカーニング(普通こっちを使うと思うけど)ではなくトラッキングを使って字詰めをしたほうがインポートの結果はよさそうです。
カーニングだとなんかむちゃくちゃ。