2009-08-14

【AIR】NativeWindowクラスによるウインドウ操作

AIRで追加されたNativeWindowクラス.

ウインドウ操作を扱うクラスで,簡単にウインドウを生成・制御可能.

Flash独特のグラフィックス環境を用いて,オリジナルのスキンでウインドウを作ることができる.

そのサンプルがこれ.

あまり一般的な書き方してないけど.

 
package {
import flash.events.Event;
import flash.events.MouseEvent;
import flash.display.Sprite;
import flash.display.NativeWindow;
import flash.display.NativeWindowType;
import flash.display.NativeWindowInitOptions;
import flash.display.NativeWindowSystemChrome;
import flash.display.StageScaleMode;
import flash.display.StageAlign;
import flash.geom.Rectangle;
import flash.display.DisplayObject;

// Tweener(ウインドウのエフェクト用)
import caurina.transitions.Tweener;
import caurina.transitions.properties.FilterShortcuts;


public class NativeWindowEx extends NativeWindow {
protected var base:Sprite;
// ウインドウのオリジナルスキン(CS4で作成後Sprite継承でASに書き込み指定)
private var skin:DialogSkin;

public function NativeWindowEx(initX:int, initY:int, initTitle:String, initDO:DisplayObject) {
// NativeWindowのオプション
var nwOptions:NativeWindowInitOptions = new NativeWindowInitOptions();
// ウインドウタイプ
nwOptions.type = NativeWindowType.LIGHTWEIGHT;
// システムクロームの設定
nwOptions.systemChrome = NativeWindowSystemChrome.NONE;
// ウインドウにalpha値を適用するかどうか
nwOptions.transparent = true;
// 最小化できるかどうか
nwOptions.minimizable = true;
// 最大化できるかどうか
nwOptions.maximizable = false;
// ウインドウサイズを変更できるかどうか
nwOptions.resizable= false;
super(nwOptions);

base = new Sprite();
base.alpha = 0.0;
// NativeWindowの持つstageにaddChild
this.stage.addChild(base);

skin = new DialogSkin();
skin.window.addEventListener(MouseEvent.MOUSE_DOWN, skinWindowDragHandler);
skin.close.addEventListener(MouseEvent.MOUSE_DOWN, skinCloseButtonHandler);
skin.close.addEventListener(MouseEvent.MOUSE_OVER, skinCloseMouseOverHandler);
skin.close.addEventListener(MouseEvent.MOUSE_OUT, skinCloseMouseOutHandler);
// 貼り付ける内容に合わせてスケール変換(skinはscale9Gridを設定済み)
skin.close.scaleX = (initDO.width) / 490;
skin.close.scaleY = (initDO.height) / 300;
skin.window.scaleX = (initDO.width) / 490;
skin.window.scaleY = (initDO.height) / 300;
skin.x = 10;
skin.y = 10;
base.addChild(skin);

var rect:Rectangle = skin.scale9Grid;
initDO.x = rect.left + 10;
initDO.y = rect.top + 10;
base.addChild(initDO);

super.activate();

this.x = initX;
this.y = initY;
this.width = skin.width + 20;
this.height = skin.height + 20;
this.title = initTitle;
this.stage.scaleMode = StageScaleMode.NO_SCALE;
this.stage.align = StageAlign.TOP_LEFT;
this.addEventListener(Event.CLOSE, windowCloseHandler);
// フェードインでウインドウを表示
Tweener.addTween(base, {alpha:1.0, time:0.5, transition:"linear"});
}

public function deleteReference():void {
skin.window.removeEventListener(MouseEvent.MOUSE_DOWN, skinWindowDragHandler);
skin.close.removeEventListener(MouseEvent.MOUSE_DOWN, skinCloseButtonHandler);
skin.close.removeEventListener(MouseEvent.MOUSE_OVER, skinCloseMouseOverHandler);
skin.close.removeEventListener(MouseEvent.MOUSE_OUT, skinCloseMouseOutHandler);
}

// Event Handler /////////////////////////////////////////////
private function skinCloseMouseOverHandler(event:MouseEvent):void {
// マウスオーバーでGlowエフェクト
Tweener.addTween(event.currentTarget, {time:0.5, transition:"linear",
_Glow_alpha:0.7, _Glow_blurX:15, _Glow_blurY:15,
_Glow_color:0x00CCCC,
_Glow_quality:1, _Glow_strength:1});
}

private function skinCloseMouseOutHandler(event:MouseEvent):void {
// マウスアウトでGlowエフェクト解除
Tweener.addTween(event.currentTarget, {time:0.5, transition:"linear",
_Glow_alpha:0});
}

protected function windowCloseHandler(event:Event):void {
this.removeEventListener(Event.CLOSE, windowCloseHandler);
}

private function windowCloseTweenComp():void {
super.close();
deleteReference();
}

protected function skinWindowDragHandler(event:MouseEvent):void {
this.startMove();
}

protected function skinCloseButtonHandler(event:MouseEvent):void {
// フェードアウトでウインドウを閉じる
Tweener.addTween(base, {alpha:0.0, time:0.5, transition:"linear",
onComplete:windowCloseTweenComp});
}
}
}

NativeWindowInitOptionsで事前に作成するウインドウの設定.

オリジナルスキンを使うなら,

nwOptions.systemChrome = NativeWindowSystemChrome.NONE;

としておく.



新しく作ったウインドウにどうやってオブジェクトを表示するかというと,実は今までのやり方と全く変わらない.

this.stage.addChild(base);

というように,実は各NativeWindowがstageを所持している.

だから,今まで同様に,NativeWindow内のstageにaddChildすればいい.

つまり,表示オブジェクト的にFlashとAIRでは,



Flash:stageをトップとした階層構造

AIR :1つまたは複数のNativeWindow内のstageをトップとした階層構造



という違いがある.







各NativeWindowのメソッドについて.



activateでウインドウにフォーカスする.



このメソッドを呼び出すか,visibleをtrueにしないとウインドウが表示されないので注意.

closeでウインドウを閉じる.



startMoveでウインドウをドラッグ.

これ呼び出すだけで自動でドラッグされるとかwゆとり仕様乙

2009-08-13

今週のオススメ嫁曲:「期待の新人」タグ特集

最近の「期待の新人」のクォリティーが高すぎる件について.





▲3D空間を浮遊する文字がすごい.HTMLを破壊するFlashを思い出した





▲激しくアニメ化希望



処女作でこのレベルのPVとか.

最近の作り手のレベルはハンパないっす.

見ていて飽きない.



・・・そして研究が進まないwww







▲歌詞がガチなのかネタなのか分からないw





▲普通に聴いていて気持ちがいい.動画は軽くアハ体験





▲格好良すぎる!がくぽにぴったりの曲かもね



どれもサビがかっこいいっす.



曲ももちろんだが,とても聞き取りやすい.

もうこのぐらいの調教レベルが普通になってきてるんだろうか?







みんな競うようにしてクォリティーを引き上げるのは当然いいことなんだけど・・・

なんか,気軽に投稿できなくなってしまいそうなのでこわいなぁ.



底辺の人でも気軽に参加できる仕組みがほしいと思う.

そんな自分は,音楽のできない底辺以下っすw

2009-08-10

8bit darling project; DELUXE にみるCGM文化

【Step1】 ニコ動徘徊中にこんな動画を見つける。







→ ヵヮ。゚+.(・∀・)゚+.゚ィィ!! なにこれ!?かわいすぎw





【Step2】 投稿コメに貼ってある、特設サイトへアクセス。

『8 bit darling project』特設サイト :http://www.sweetvacation.jp/8bitdx/



→ あー「8 bit darling project」か。そういえば、曲はまだ聴いてなかったなぁ。

  TUTAYAで先行発売!?初回特典に『初音ミク×Sweet Vacationスリーヴ・ケース』とな。





【Step3】 ケースの画像を確認する。

ケースの画像 :http://www.sweetvacation.jp/8bitdx/img/suribu-case.jpg



→ Σ(゚Д゚) 

→ ヽ(°▽、°)ノエヘヘヘヘ





【Step4】 TUTAYAへダッシュ!ε≡≡ヘ(* ´Д`*)ノ





みごとに釣られますたw



というか、もう、PV見た時点で9割方買うつもりでしたが、何か?





----



うん、いや、実のところ、この企画自体、前から興味あったんだ。



サマバケの原曲「8bit darling」の素材を無料公開して、ボーカロイドにリミックスする企画。

しかも、ボーカロイドを使ったものに対しては、著作権使用料も気にせず、非営利で公開可能。



もともとCD化する予定なかったらしいけど、

TUTAYAで本家サマバケのアルバム先行レンタル時に収録 → さらに企画が膨らんで今回のCD発売

となった模様。



----



とても面白い試みだよね。

著作権という壁を破ったことが(破ったというより、実際には回避した)、

音楽の新しい形を提案しているように思える。



CGM、消費者が自ら曲を完成形にもっていく文化が確実に根付いてきている、ということなんだろうな。

音楽に限らず、今後、消費者が気軽にクリエイティブを楽しむ時代が来るのかと思うとワクワクする。



ミクさんにはまさにその象徴となるキャラクターになってほしい。



だからこそ、くさもちは全力で嫁を応援します。



・・・要するに、絶好のカモということですね?わかりますw

2009-08-09

Ubuntu Tweak



【AS3.0】XMLの送受信【PHP】

GDP企画の際必要になった,ActionScriptを使ったXMLの送受信.

Flash/AIRとPHP間でXMLのやりとりをするのに使った.



試行錯誤した結果,結局こんな感じでうまくいくことがわかった.

基本的に,URLRequestで送信データ,およびその設定を行い,

URLLoaderでリクエスト(送信),Completeイベントでphpからのレスポンスが帰ってくる仕組み.

package {
import flash.events.Event;
import flash.events.ProgressEvent;
import flash.events.IOErrorEvent;
import flash.events.EventDispatcher;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
import flash.utils.ByteArray;

/**
* ConnectPHP
* @auther kusamochi
*/
public class ConnectPHP extends EventDispatcher {
public static const COMPLETE:String = "complete";
public static const IO_ERROR:String = "io_error";
public static const PROGRESS:String = "progress";
public static const FAILED:String = "failed";

private var _urlRequest:URLRequest;
private var _result:XML;

private var urlLoader:URLLoader;

// コンストラクタ
public function ConnectPHP() {
}

// XMLの送信
public function sendAndLoad_XML(url:String, xml:XML):void {
// 送信するデータを設定
_urlRequest = new URLRequest(url);
_urlRequest.contentType = "text/xml";
_urlRequest.data = xml.toXMLString();
// データはPOSTで送信
_urlRequest.method = URLRequestMethod.POST;

// URL
urlLoader = new URLLoader();
urlLoader.dataFormat = URLLoaderDataFormat.TEXT;

// イベントリスナー登録
urlLoader.addEventListener(Event.COMPLETE, completeHandler);
urlLoader.addEventListener(ProgressEvent.PROGRESS, progressHandler);
urlLoader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
urlLoader.load(_urlRequest);
}

// データロード完了のイベントリスナー
private function completeHandler(event:Event):void {
urlLoader.removeEventListener(Event.COMPLETE, completeHandler);
urlLoader.removeEventListener(ProgressEvent.PROGRESS, progressHandler);
urlLoader.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
// reusltに格納
try {
_result = new XML(event.target.data);
}
catch(error:TypeError) {
// イベントをブロードキャスト
dispatchEvent(new Event(FAILED));
return;
}

// イベントをブロードキャスト
dispatchEvent(new Event(COMPLETE));
}

// 送信中に一定間隔で発生するイベントリスナー
private function progressHandler(event:ProgressEvent):void {
// イベントをブロードキャスト
dispatchEvent(new ProgressEvent(PROGRESS));
}

// 送信エラーのイベントリスナー
private function ioErrorHandler(event:IOErrorEvent):void {
urlLoader.removeEventListener(Event.COMPLETE, completeHandler);
urlLoader.removeEventListener(ProgressEvent.PROGRESS, progressHandler);
urlLoader.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
// イベントをブロードキャスト
dispatchEvent(new IOErrorEvent(IO_ERROR));
}

// 参照削除
public function deleteReference():void {
if(urlLoader) {
urlLoader.addEventListener(Event.COMPLETE, completeHandler);
urlLoader.addEventListener(ProgressEvent.PROGRESS, progressHandler);
urlLoader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
urlLoader.close();
}
_urlRequest = null;
_result = null;
}

// getter //////////////////////////////////////////////////////
// result
public function get result():XML {
if(_result) return _result;
else        return null;
}
}
}

ポイントは,Content-typeを"text/xml"にして,xmlのStringを送信すること.

当初,Content-typeを"application/octet-stream"(バイナリデータの意)として,

XMLをBinaryArrayで送っていたけど,

それだと送信先でヘッダーに文字化けが起きる.



ちなみに,PHP側では,

$inputStr = file_get_contents("php://input");
$xml = simplexml_load_string($inputStr);

print "<result>";
// Flash側に送りたいデータをほげほげ
print "</result>";

というように,file_get_contents("php://input")で,

生データを丸ごと読みこんでPHPのXMLクラスに変換.

Flash側に送りたいXMLは,PHP自身にタグをprintすればいい.

ソフト公開の難しさ

原因が見えてこない・・・。

問題は起きることは予想していたが、これほどとは・・・。





とりあえず、現時点で必要な修正をします。



今日中にはどうにか。









本当に謝るしかできない、自分の能力のなさに気づく。



特に、



「ソフトウェアを広く一般の方に配布する」



という部分に関しては、それほど経験がなかったのも問題を大きくしていることの一つ。





申し訳ないと、ただこれしか言えないのは悔しい。

今週のオススメ嫁曲:【初音ミク】Alice【オリジナル】





 ミクトロニカ。



たまには、こんなゆったりした曲もよいかも。

むしろ、こういう曲の方がミクに合ってるのかもね。





古川Pの曲は今まで聴いたことなかったけど、↓のはイントロでマイリス余裕でした。





2009-08-01

GDPイベント始まっちゃった

((((;゚Д゚))))ガクガクブルブル



自分の作ったものに信頼が持てないっす(;´Д`)





GDP始まってしまいました.

・・・たぶんバグあります.きっとあります.



自分でもなるべく問題が起きないように最大限の努力で保守を行う所存です.

それでも,何かあったときには・・・



どうか生暖かい目で.











一応イベント告知しておく.



GDPは国内総生産ではありませんw

DTX Maniaというゲームのイベント企画の1つです.



イベント本会場



イベントIRページ



このイベントのIR(インターネットランキング)サイトの制作・運営,およびIRを行うために必要なアプリケーション制作を担当をさせて頂きました.





そう.GDPイベントの主催者さんからの突然の制作依頼を受けて,作ることになったIRシステム.

そのときは,DTXは知らなかったし,自分は就活してたし,PHPもSQLも使ったことなかったし・・・.

正直,依頼を受けるべきか本当に迷った.



でも,気合いで受けてしまったw





結果として,一応の形にはなったけれども,

やっぱり自分の力不足を感じることが多かった.



デバッグでテストプレイしたとき,音楽のクオリティの高さに驚いた(゚д゚)!

そして,到底それらを支えるに値しないほど稚拙なものしか作れない自分orz







イベント関係者の皆様へ.

なんとか始まりました・・・がまだバグがある可能性は十分あるので,

今後もデバッグをしながら,保守を中心に作業していきます.



どうにか,無事にイベントが終了するよう努力する所存ですので,

よろしくお願い致します.

アニサマに初音ミク出演(゚∀゚)キタコレ!!

公式サイト:

http://pc.animelo.jp/rebridge/whatsnew/?p=090731_artist_KdsJe



嫁がキタ━ヽ(ヽ(゚ヽ(゚∀ヽ(゚∀゚ヽ(゚∀゚)ノ゚∀゚)ノ∀゚)ノ゚)ノ)ノ━!!!!





プロデューサーさん!ライブですよ!ライブ!









・・・(冷静になり)つーか,どうゆうこと?これw



ライブでヴァーチャルっておかしくね?



中の人じゃなくて,あえて「初音ミク」だし・・・一体どうなるんでしょう?