Home > Tags > framework
framework
[progression勉強]CastImageLoaderのロード中にCastMovieClipを表示してみる
- 2008-12-03 (水)
- progression | study
今日はこの前作ったサンプルのソースを基に、
サムネイルをCastImageLoaderでロード中にアニメーションを入れてみたいと思います。
ということで、ググる。
apeirophobia: progression検証 #15 CastImageLoaderをコマンドで監視編
このエントリ、コメントを読んでると、
castImageLoaderにはデフォルトで読み込み状況を取得するイベントはない様子。
ということでこちら
CastImageLoaderを使ってみる - Is It So Easy?
を参考にCastImageLoaderのサブクラスを作成してみる。
CastImageLoaderではロードの進捗は監視できないけど、
_onCastLoadStart():voidでロード開始時
_onCastLoadComplete():voidでロード完了時
のイベントが受け取れるから、
ロードし始めたらローディングするMCをCastMovieClipにしたものをaddChildして、
ロードが完了したらremoveChildしてやって、それらしく見せてみようと思います。
この前作ったサンプルのクラス以外に、追加で作ったクラス
- MyImgLoader.as(CastImageLoaderのサブクラス)
- LoadImg.as(CastMovieClipのサブクラス)
LoadImg.asを作成
コンストラクタはこんな感じ。
- public function LoadImg( initObject:Object = null ) {
- super(initObject);
- //loaderの中央に表示
- this.x = (initObject.loaderW - this.width) / 2;
- this.y = (initObject.loaderH - this.height) / 2;
- //透明にする
- alpha = 0;
- }
Index.flaの中にロード中に表示するMCを作る
ローディングはアニメGIFを使用。
こちらのサイトからダウンロードしたものを、
そのままライブラリにインポート。
できたMCにLoadImgクラスを設定するだけ。
MyImgLoader.asを作成
こんな感じ。
- package myproject {
- import jp.progression.casts.*;
- import jp.progression.commands.*;
- import jp.progression.events.*;
- import jp.progression.loader.*;
- import jp.progression.*;
- import jp.progression.scenes.*;
- import myproject.LoadImg;
- /**
- * ...
- * @author kanariia
- */
- public class MyImgLoader extends CastImageLoader {
- private var _container:CastButton;
- private var _loadImg:LoadImg;
- /*======================================================================*//**
- * コンストラクタ
- */
- public function MyImgLoader(initObject:Object=null) {
- super(initObject );
- //縦横比を固定
- this.ratio = true;
- //リサイズ
- this.width = initObject.valueW;
- this.height = initObject.valueH;
- //表示リストは呼び出し元のCastButtonを参照する
- _container = initObject.container;
- //ロード中に表示するMCを作成
- _loadImg = new LoadImg({loaderW:initObject.valueW,loaderH:initObject.valueH});
- }
- /*======================================================================*//**
- /*Load開始時*/
- protected override function _onCastLoadStart():void
- {
- addCommand(
- //_loadImgを表示リストに追加
- new AddChild(_container, _loadImg),
- new Trace("読み込み開始")
- )
- }
- /*Load完了時*/
- protected override function _onCastLoadComplete():void
- {
- this.alpha = 0;
- addCommand(
- //_loadImgを表示リストから削除
- new RemoveChild(_container, _loadImg),
- new Trace("読み込み完了"),
- //loaderを表示リストに追加、アルファ100にする
- [new AddChild(_container, this),
- new DoTweener(this,{alpha:1,time:2})]
- );
- }
- }
- }
MyBtn.asを修正
コンストラクタを大幅に修正
- public function MyBtn( initObject:Object = null ) {
- super( initObject );
- //リンク先設定
- sceneId = new SceneId( "/index/photo"+initObject.num);
- //画像のサイズ
- var loaderW:Number = 80;
- var loaderH:Number = 60;
- //loaderの作成
- _loader = new MyImgLoader( { container:this, valueW:loaderW, valueH:loaderH } );
- //画像を読み込み
- _loader.load(new URLRequest(initObject.url),new LoaderContext(true,null, null));
- }
前のソースのままでは MyBtn.asの中で_loaderの座標を指定して
btnの位置が変わっているように見えていただけだったことに気づき、
(↑このままではloadImgが画面左上にくる)
_loaderの位置指定を消してIndexScene.asでbtnの位置を設定するように修正。
で、できたのがこれ!
気づいたこと
MyImgLoaderでload完了時、
自分をaddhildしてからDoTweenerしようとしたが、
エラーは出ないがTweenerが動作せず、ちょっとハマる。
結果、[ ]で囲んでParallelListにしたら、動いた!
//loaderを表示リストに追加、アルファ100にする
[new AddChild(_container, this), new DoTweener(this,{alpha:1,time:2})]
addChildのあとにはコマンドがきかないということなのか‥?
関連する投稿
- Comments: 0
- Trackbacks: 1
[progression勉強]CastImageLoaderで他サイトの画像を読み込みリサイズできない件
- 2008-11-30 (日)
- progression | study
前回の記事でローカルではCastImageLoaderのリサイズが効くのに、
サーバーにアップしたらリサイズが効かない!!と嘆いていたのですが、
Is It So Easy?のnorthprintさんのご好意によりコードを解析いただいて、
原因がわかりました!
画像をFrickrから読み込んでいたのですが、crossdomainあたりの設定だったようで。。。
前回の使った
シーンの共通表示作成クラスMyPage.as(CastSpriteを継承)のコンストラクタを例にあげると、
CastImageLoaderへの読み込み指示は、
_loader.load(new URLRequest(initObject.url));
こう書いていたのですが、下記のようにLoaderContextを書く必要があったようです。
import flash.system.LoaderContext;と書いた上で、
_loader.load(new URLRequest(initObject.url),new LoaderContext(true,null, null));
でOK。
成功したサンプルはこれ!
LoaderContextとはなんぞや?と調べてみました。
LoaderContext - ActionScript 3.0 コンポーネントリファレンスガイド
LoaderContextの第一引数のcheckPolicyFileプロパティがの初期値はfalseですが、
イメージ (JPEG、GIF、または PNG) を呼び出し元 SWF ファイル自体のドメイン外からロードし、そのイメージのコンテンツに ActionScript からアクセスする必要がある場合に、 trueにする必要がある
ということのようです!
いやぁすごく勉強になりました。
このことはよく覚えとかないと!
私なんかのソースを見てくれて、問題を検証してくださった、
Is It So Easy?のnorthprintさん、本当にありがとうございました(*´∀`)!!
関連する投稿
- Comments: 2
- Trackbacks: 2
[progression勉強]外部画像データをXMLで読み込んでシーンに貼り付け
- 2008-11-26 (水)
- progression | study
今回はXMLによる外部データ読み込みをやってみます。
CastImageLoaderで画像を読み込んでSceneObjectに貼り付けて、
フォトギャラリーみたいな感じになったらいいなーというかんじです。
CastImageLoaderについて参考にしたサイト
まず、画像のパスを格納するXMLを作成します。
こんな感じ。
- <photolist>
- <photo url="http://farm4.static.flickr.com/3269/3020887992_9de4220109.jpg">photo1</photo>
- <photo url="http://farm4.static.flickr.com/3070/2642213778_9886cee9da.jpg">photo2</photo>
- <photo url="http://farm4.static.flickr.com/3233/2616211855_6ce07f1f25.jpg">photo3</photo>
- <photo url="http://farm4.static.flickr.com/3174/3027030848_f282d05845.jpg">photo4</photo>
- <photo url="http://farm4.static.flickr.com/3054/3014909628_3235985fde.jpg">photo5</photo>
- <photo url="http://farm4.static.flickr.com/3269/3020887992_9de4220109.jpg">photo6</photo>
- </photolist>
次にIndexScene.asのonLoadでXMLを読み込みます。
匿名関数内にthis.latestDataと書くと
直近に読み込んだデータを参照することができる
ので、匿名関数を使ってXMLオブジェクトを生成します。
XMLを読み込んでからシーン数とボタン数を決めるので、
コンストラクタじゃなくてonLoadでシーンとボタンを追加します。
- protected override function _onLoad():void {
- addCommand(
- new AddChild(progression.container, _page),
- // XML ファイルを読み込みます。
- new LoadURL( new URLRequest( "photo.xml")),
- //匿名関数(this.latestDataが使える)
- function():void {
- //読んだデータをxmlオブジェクトに
- _photolist = new XML(this.latestData);
- //xmlの要素の数をシーン数とする
- sceneNum=_photolist.children().length()
- //読み込む画像urlを指定してボタンとシーンをnewする
- for (var i = 0; i <= sceneNum; i++ ) {
- //シーン
- _scene = new MyScene("photo" + (i+1), { url:_photolist.photo.@url[i] } );
- addScene(_scene);
- //ボタン
- _btn = new MyBtn( { num:i+1, url:_photolist.photo.@url[i] } );
- progression.container.addChild(_btn)
- trace(progression.container.getChildIndex(_btn))
- }
- }
- );
- }
シーンの共通クラスはこんな感じ。
MyPageクラス(シーンの共通表示作成)とMyBackBtn(indexへ戻るボタン)をaddChild。
- public function MyScene(name:String=null, initObject:Object = null ) {
- super( name, initObject );
- trace(initObject.url)
- _page = new MyPage( { url:initObject.url } );
- _btn = new MyBackBtn();
- }
シーンの共通表示作成クラスMyPage.as(CastSpriteを継承)のコンストラクタはこんな感じ。
InitObjectで受け取った画像のURLをCastImageLoaderで読み込んで、
640*480にリサイズして表示してます。
- public function MyPage( initObject:Object = null ) {
- super( initObject );
- _loader = new CastImageLoader();
- _loader.x = 0;
- _loader.y = 0;
- //縦横比固定
- _loader.ratio = true;
- //画像をリサイズする
- _loader.width = 640;
- _loader.height = 480;
- _loader.load(new URLRequest(initObject.url));
- addChild(_loader)
- alpha = 0;
- }
ボタンの共通クラスMyBtn.as(CastButtonを継承)のコンストラクタはこんな感じ。
シーンの共通クラス同様、
InitObjectで受け取った画像のURLをCastImageLoaderで読み込んで、
80*60にリサイズして表示してます。これでサムネイル風ボタンのできあがり!
サムネイル読み込み中のローディングはまた今度。。
- public function MyBtn( initObject:Object = null ) {
- super( initObject );
- //リンク先設定
- sceneId = new SceneId( "/index/photo"+initObject.num);
- //画像を読み込み
- _loader = new CastImageLoader();
- _loader.x = 110 * (initObject.num-1);
- _loader.y = 300;
- //縦横比固定
- _loader.ratio = true;
- //画像をリサイズする
- _loader.width = 80;
- _loader.height = 60;
- _loader.load(new URLRequest(initObject.url));
- addChild(_loader)
- }
写真を押したらindexへ戻るボタンMyBackBtn.asを別途作成。
こんなん。
写真と同じサイズにして、アルファ0にした状態。透明ボタンを追加する方法が正しいのかはわからないけど、これしか思いつかないので。。。本当はCastButtonクラスで表示も作成して、ボタン機能もつけたかったけど、CastButtonクラスだとonCastAdded(表示リストに追加されたとき)のコマンドがオーバーライドできないようなので、表示はCastSpriteでボタン機能はCastButtonで別途作成。
- public function MyBackBtn( initObject:Object = null )
- {
- super( initObject );
- //リンク先設定
- sceneId = new SceneId( "/index");
- //表示を作成する
- _shape = new Shape;
- _shape.graphics.beginFill(0x000000)
- _shape.graphics.drawRect(0, 0, 640, 480);
- _shape.graphics.endFill();
- addChild(_shape);
- alpha = 0;
- }
よーし、できたっ!てテストアップしたところ…
あれ、画像のリサイズが効いてない(;><)何で?何で?
ローカルだとちゃんといけてるのに…!!
てゆーかアップしてバグってたら致命的やん(;゚Д゚)
いろいろやってみたけど、自分の力ではもうわかりませーん!
何でだぁ~
テストアップしてるのはこれ↓
http://kanariia.com/blog/sample/081126/
ローカル確認用zipデータはこれ↓
http://kanariia.com/blog/sample/081126.zip
おバカなつまづき
最初MyBtn.asのコンストラクタでシリアルリストでxmlを読もうとしたら、
xmlは読めるけどノードにアクセスできない。。
だいぶおこられました。。
Spriteのサブクラスではノードにアクセスできないってことかな?
結局、シーンオブジェクトでxml読み込み。
てか、それが正しいんやろなぁ!
追記
画像のリサイズが効かない件、解決!!
[progression勉強]CastImageLoaderで他サイトの画像を読み込みリサイズできない件
関連する投稿
- Comments: 7
- Trackbacks: 3
[progression勉強]階層のあるサイトを作ってみる
- 2008-11-17 (月)
- progression | study
progressionのasDocやら、as3事体理解しきれてないので、この本を見たりしながら、
ちょこちょここの前のサンプルをベースにいじっていますが、
スピードは超スローで、
本当どうってことないとこでひっかかったりしてます。。。
が、めげずにぼちぼちやってきます!
この前のエントリのサンプルを基に、
シーンの中にさらに子シーン(ポップアップして閉じるような)を追加したものを作りたいと思います。
Scene1の中に子シーンChild1,Child2,Child3を作成してみます。
Child~はボタンを押したらScene1内でポップアップしてChild~内の閉じるボタンで元に戻るっていうイメージです。
ちょこちょこ前のサンプルを修正していますが、
新たに作成したクラスは
- 子シーンの共通クラス MyChildScene.as(SceneObjectを継承)
- 子シーンの中の表示要素 MyChildPage.as(CastSpriteを継承)
これだけ。
Scene1~3の共通クラスMyScene.asのコンストラクタに、
Scene1のときだけさらに子シーンとボタンを追加するように記述。
- //コンストラクタ
- public function MyScene( name:String = null, initObject:Object = null ) {
- super( name, initObject );
- //ページを作成します。
- _page = new MyPage( { myPageNum:initObject.mySceneNum } );
- //scene1の子シーン・ボタンを作成
- if (initObject.mySceneNum == 1) {
- var myChildNum:int = 3;
- for (var i:int = 1; i <= myChildNum; i++) {
- //シーン
- var myChildScene:MyChildScene = new MyChildScene("child" + i, { myChildSceneNum:i } );
- addScene(myChildScene);
- //ボタン
- var btn:MyBtn = new MyBtn({myname:"child"+i,sceneNum:initObject.mySceneNum,childNum:i} );
- btn.x = 110 * i;
- btn.y = 250;
- _page.addChild(btn);
- }
- }
- }
これで追加OK。
次は子シーン(ポップアップさせたいページ)の表示をMyChildPage.asで定義。
- //コンストラクタ
- public function MyChildPage( initObject:Object = null ) {
- super( initObject );
- // 表示を作成する
- var myShape:Shape = new Shape();
- myShape.graphics.beginFill(0xFCFCFC);
- myShape.graphics.drawRect(0, 0, 400, 300);
- myShape.graphics.endFill();
- addChildAt(myShape,0);
- _txt = new TextField();
- _txt.mouseEnabled = false;
- _txt.textColor = 0x000000;
- _txt.text = "child" + initObject.myChildPageNum;
- this.x = 200;
- this.y = 100;
- this.alpha = 0;
- }
あと、MyBtn.asのコンストラクタのSceneId設定を修正
- // クリック時の移動先を設定する
- if (!initObject.sceneNum) {
- sceneId = new SceneId( "/index" );
- if (initObject.back) {
- sceneId = new SceneId( "/index/myScene1");
- }
- } else if (!initObject.childNum) {
- sceneId = new SceneId( "/index/" + "myScene" + initObject.sceneNum );
- } else {
- sceneId = new SceneId( "/index/" + "myScene" + initObject.sceneNum+"/child"+initObject.childNum);
- }
ちょっとこのへん効率悪い書き方な気するけど、initObjectの値で移動先を振り分けてるってかんじです。
そんなこんなで、できたのはこれです。
ちゃんとurlも変わってくれてます!
さらに遷移のモーションを変えようとしたところ、気づいた点がいくつか。
1.ナビゲーションが最前面にきていない
前のサンプルではIndex.asでボタンを作成していたけど、表示リストには追加されるものの、IndexSceneの背面にきてしまうので、
今回はindexScene.asのコンストラクタに以下を追記
- // ボタンを作成する
- var btnId:Array=["index","scene1","scene2","scene3"];
- for (var j:int = 0; j <= 3; j++) {
- var btn:MyBtn = new MyBtn({myname:btnId[j], sceneNum:j } );
- btn.x = 10;
- btn.y = 60 * j;
- trace(btn);
- progression.container.addChildAt(btn,100*j);
- }
progression.container.addChildAt(btn,100*i);
IndexSceneではほかの子シーンもaddSceneするので、かぶらないようにaddChildAtでいきなり表示リストの100番代においてやります(←このいきなり番号とばすのはprogressionだからこそできるみたい)。
2.addCommand内でthis.x=○○とかは無理
シーンの遷移方法を左から右にスーッって感じにしたかったんやけど、遷移する前に位置を戻したくて、
this.x=○○って書いてみたけど、「xというプロパティはありません」ってゆうかんじのエラー。
たぶんこれ、as3わかってたら当たり前なんやろうけど、
深いとこわかってないので、エラーなくなるまでとりあえずいろいろやってみた。
funcコマンドの中に書いてみたりとかも無理。
結局、DoTweenerはいけるから、それ使ってやってみよ!と思ったけど、
位置もどしたいだけやしに時間は指定いらんよなーって考えてて、じゃあどう記述したらいいのかわからんくて、
ちょっと悩み、結果「time:0」でもいけるんじゃ?と思って書いてみたところいけた!
こんな感じで。(MyPage.asの_onCastAdded)
- addCommand(
- //初期位置に戻す
- new DoTweener(this,{x:640,time:0}),
- //移動
- new DoTweener(this, { x:120, time:0.5, transition:"EaseOutExpo" } )
- );
たぶんもっといい方法があるんやろうけど、今回はとりあえずこれで。。。誰か教えてください(;´Д`)
う~んうまく文にできない(;^ω^)
今度は外部データの読み込みやってみるかな。
関連する投稿
- Comments: 2
- Trackbacks: 3
[progression勉強]シーン、ボタンを一気に量産してみる
- 2008-11-12 (水)
- progression | study
progressionのワークショップではsceneの数だけクラスを用意する基本的な方法を教えていただきましたが、
trick7さんのこの記事や、
apeirophobiaさんのこの記事のように、
シーンの共通クラスからシーンを量産したり、ボタンの共通クラスからボタンを量産するのをやってみました。
まず、src>classes>myproject(デフォルトの書き出し場所)直下のIndex.as,Preloader.as,IndexScene.asのほかに
- シーンの共通クラス MyScene.as(SceneObjectを継承)
- シーンの中の要素 MyPage.as(CastSpriteを継承)
- ボタンの共通クラス MyBtn.as(CastBtnを継承)
を用意します。
ボタンはIndex.asで作成、
シーンはIndexScene.as作成で追加することにします。
Index.asの_onInitに、下記のコードを追加。
- // ボタンを作成する
- var btnId:Array=["index","scene1","scene2","scene3"];
- for (var i:int = 0; i <= 3; i++) {
- var btn:MyBtn = new MyBtn( { sId: btnId[i], sceneNum:i } );
- btn.x = 10;
- btn.y = 60 * i;
- addChild( btn);
- }
MyBtn.asのコンストラクタの引数initObject にオブジェクト形式でデータ渡を渡す。
arrayに入れてるのはボタンに表示したい名前。sceneNumはボタンの識別番号。
んで、これがMyBtn.asのコンストラクタ↓
- public function MyBtn( initObject:Object = null ) {
- super( initObject );
- // クリック時の移動先を設定する
- if (!initObject.sceneNum) {
- sceneId = new SceneId( "/index" );
- } else {
- sceneId = new SceneId( "/index/"+"myScene"+initObject.sceneNum );
- }
- // 表示を作成する
- var myShape:Shape = new Shape();
- myShape.graphics.beginFill(0x000000);
- myShape.graphics.drawRect(0, 0, 100, 50);
- myShape.graphics.endFill();
- addChildAt(myShape,0);
- var txt:TextField = new TextField();
- txt.mouseEnabled = false;
- txt.textColor = 0xFFFFFF;
- txt.text = initObject.sId;
- addChild(txt);
- }
sceneNumが0ならindexに、それ以外なら/index/myscene+sceneNumにリンクするように設定。
あとはボタンらしくするためにシェイプで四角形書いて、テキストフィールドにsIdを表示させました。
これでボタンは終了。
次はシーンの追加です。
IndexScene.asのコンストラクタに下記を追加
- //シーンを追加します。
- var sceneNum:int =3;
- for (var i:int = 1; i <= sceneNum; i++ ) {
- // sceneを作成する
- var myScene:MyScene = new MyScene ("myScene" + i, { mySceneNum:i } );
- myScene.name = "myScene" + i;
- addScene(myScene);
- }
これはほとんどtrick7さんのコピペですけどwありがたや~
ボタンの時とおんなじ感じでinitObjectに値渡して個性つけてます。
んで、これがMySceneのコンストラクタ。
- public function MyScene( name:String = null, initObject:Object = null ) {
- super( name, initObject );
- //ページを作成します。
- _page = new MyPage({myPageNum:initObject.mySceneNum});
- }
あと、なにも中にないので、ボタンと一緒でシェイプとテキストだけ入れたいと思うのでCastSpriteを継承したMyPageクラスで表示を作成します。sceneObjectはシーンの制御だけであと(表示)はキャストに任せるってわけです。
MyPageクラスのコンストラクタを以下のように設定。
- public function MyPage( initObject:Object = null ) {
- super( initObject );
- // 表示を作成する
- var myShape:Shape = new Shape();
- myShape.graphics.beginFill(0x999999);
- myShape.graphics.drawRect(0, 0, 640, 480);
- myShape.graphics.endFill();
- addChildAt(myShape,0);
- var txt:TextField = new TextField();
- txt.mouseEnabled = false;
- txt.textColor = 0x000000;
- txt.text = "scene" + initObject.myPageNum;
- addChild( txt );
- this.x = 640;
- this.y = 0;
- this.width = 640;
- this.height = 480;
- }
ここのクラスのaddcommandを設定してやって、完了!
さーっと手順書いてますが、出来上がるまでは結構モタモタしてました。。。
メモ代わりなんでわかりずらいと思います。
as3まだあんまりよくわかっていない私の記事なので、
もっといい方法がたくさんあると思うので参考になるかどうかわかりませんが…
あっ!あと、すっごいしょうもないとこでつまづきました。
addCommannd内でnew DoTweenerを使おうとしてるときに、
new DoTweener(this, { x:120, time:1,transition:EaseOutExpo}
と書くと、
「未定義のプロパティ EaseOutExpo へのアクセスです。」ってエラー返ってきて、
なんでなんでーと迷路にはまり、必死でググるがヒットする記事がなく…
二時間後ぐらいにやっと解決。
new DoTweener(this, { x:120, time:1,transition:"EaseOutExpo"}
EaseOutExpoを""で囲んでやればいいだけでした。。。
あぁぁぁぁぁなんてしょぼいミスなんやろう。。。
はずかしいー
as3とかtweenerとかよくわかってないからやぁー
もっとちゃんと理解していかなあかんなぁ(;´∀`)
関連する投稿
- Comments: 0
- Trackbacks: 3
Home > Tags > framework
