2008年2月29日 20:43

Flex 3で直接Spriteを使用することはできない?

このエントリーを含むはてなブックマーク

Flex中でベクターイメージを使おうと思い、flash.display.Spriteをインポート、ApplicationにaddChildしようとしたのですが...

ApplicationのaddChildの引数にはmx.core.UIComponentのサブクラスのみしか渡せないため、この方法ではクラスの互換性が無く動作しません。つまり、以下のようなコードは動作しません。

<mx:application xmlns:mx="http://www.adobe.com/2006/mxml" applicationcomplete="applicationCompleteHandler();">
	<mx:script>
		<!--[CDATA[
			import mx.core.*;
			import flash.display.*;
			
			private var contain:Sprite = new Sprite();
		]]-->
	</mx:script>
	<mx:script>
		<!--[CDATA[
			private function applicationCompleteHandler():void {
				contain.width = 100;
				contain.height = 100;
				
				//円を描くよ
				contain.graphics.beginFill(0xffffff, 0.8);
				contain.graphics.drawCircle(50, 50, 50);
				contain.graphics.endFill();
				
				this.addChild(contain);
			}
	
	]]-->
	</mx:script>
</mx:application>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" applicationComplete="applicationCompleteHandler();">
	<mx:Script>
		<![CDATA[
			import mx.core.*;
			import flash.display.*;
			
			private var contain:Sprite = new Sprite();
		]]>
	</mx:Script>
	<mx:Script>
		<![CDATA[
			private function applicationCompleteHandler():void {
				contain.width = 100;
				contain.height = 100;
				
				//円を描くよ
				contain.graphics.beginFill(0xffffff, 0.8);
				contain.graphics.drawCircle(50, 50, 50);
				contain.graphics.endFill();
				
				this.addChild(contain);
			}
	
	]]>
	</mx:Script>
</mx:Application>

に対し、

TypeError: Error #1034: 強制型変換に失敗しました。flash.display::Sprite@1c36299 を mx.core.IUIComponent に変換できません。
	at mx.core::Container/http://www.adobe.com/2006/flex/mx/internal::addingChild()
	at mx.core::Container/addChildAt()
	at mx.core::Container/addChild()
	at sprite_test/applicationCompleteHandler()
	at sprite_test/___sprite_test_Application1_applicationComplete()
	at flash.events::EventDispatcher/dispatchEventFunction()
	at flash.events::EventDispatcher/dispatchEvent()
	at mx.core::UIComponent/dispatchEvent()
	at mx.managers::SystemManager/preloader_preloaderDoneHandler()
	at flash.events::EventDispatcher/dispatchEventFunction()
	at flash.events::EventDispatcher/dispatchEvent()
	at mx.preloaders::Preloader/displayClassCompleteHandler()
	at flash.events::EventDispatcher/dispatchEventFunction()
	at flash.events::EventDispatcher/dispatchEvent()
	at mx.preloaders::DownloadProgressBar/timerHandler()
	at mx.preloaders::DownloadProgressBar/initCompleteHandler()
	at flash.events::EventDispatcher/dispatchEventFunction()
	at flash.events::EventDispatcher/dispatchEvent()
	at mx.preloaders::Preloader/dispatchAppEndEvent()
	at mx.preloaders::Preloader/appCreationCompleteHandler()
	at flash.events::EventDispatcher/dispatchEventFunction()
	at flash.events::EventDispatcher/dispatchEvent()
	at mx.core::UIComponent/dispatchEvent()
	at mx.core::UIComponent/set initialized()
	at mx.managers::LayoutManager/doPhasedInstantiation()
	at Function/http://adobe.com/AS3/2006/builtin::apply()
	at mx.core::UIComponent/callLaterDispatcher2()
	at mx.core::UIComponent/callLaterDispatcher()

のような実行時エラーが出力されます。そこで、Flex 2においてはUIComponentの子にすればよいらしい(http://www.ringsbell.net/flash/flex2/addchildsprite.php)ということで、以下のコードで試してみました。

<mx:application xmlns:mx="http://www.adobe.com/2006/mxml" applicationcomplete="applicationCompleteHandler();">
	<mx:script>
		<!--[CDATA[
			import mx.core.*;
			import flash.display.*;
			
			//UIComponentを追加
			private var uicomp:UIComponent = new UIComponent();
			private var contain:Sprite = new Sprite();
		]]-->
	</mx:script>
	<mx:script>
		<!--[CDATA[
			private function applicationCompleteHandler():void {
				contain.width = 100;
				contain.height = 100;
				
				//円を描くよ
				contain.graphics.beginFill(0xffffff, 0.8);
				contain.graphics.drawCircle(50, 50, 50);
				contain.graphics.endFill();
				
				//thisの代わりにuicomp(UIComponent)にaddChild
				uicomp.addChild(contain);
				
				//そしてuicompをthisにaddChild
				this.addChild(uicomp);
			}
	
	]]-->
	</mx:script>
</mx:application>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" applicationComplete="applicationCompleteHandler();">
	<mx:Script>
		<![CDATA[
			import mx.core.*;
			import flash.display.*;
			
			//UIComponentを追加
			private var uicomp:UIComponent = new UIComponent();
			private var contain:Sprite = new Sprite();
		]]>
	</mx:Script>
	<mx:Script>
		<![CDATA[
			private function applicationCompleteHandler():void {
				contain.width = 100;
				contain.height = 100;
				
				//円を描くよ
				contain.graphics.beginFill(0xffffff, 0.8);
				contain.graphics.drawCircle(50, 50, 50);
				contain.graphics.endFill();
				
				//thisの代わりにuicomp(UIComponent)にaddChild
				uicomp.addChild(contain);
				
				//そしてuicompをthisにaddChild
				this.addChild(uicomp);
			}
	
	]]>
	</mx:Script>
</mx:Application>

今回は実行時エラーも無かったのですが、何も表示されません。

MXML Flex Sprite

くっ、な、何も出ない...

そこで困ってしまい、どうしようか...と考えていたのですが、盲点がありました。リファレンスのUIComponentの項を見ていると...

継承	UIComponent → FlexSprite → Sprite → DisplayObjectContainer → InteractiveObject → DisplayObject → EventDispatcher → Object

あ、UIComponentはSpriteを継承しています...

今回は図形を表すコンポーネントさえあればよかったので素直にUIComponentを使う事にしました。次のようなコードで試してみました。

<mx:application xmlns:mx="http://www.adobe.com/2006/mxml" applicationcomplete="applicationCompleteHandler();">
	<mx:script>
		<!--[CDATA[
			import mx.core.*;
			import flash.display.*;
			
			//UIComponentにした
			private var contain:UIComponent = new UIComponent();
		]]-->
	</mx:script>
	<mx:script>
		<!--[CDATA[
			private function applicationCompleteHandler():void {
				contain.width = 100;
				contain.height = 100;
				
				//円を描くよ
				contain.graphics.beginFill(0xffffff, 0.8);
				contain.graphics.drawCircle(50, 50, 50);
				contain.graphics.endFill();

				this.addChild(contain);
			}
	
	]]-->
	</mx:script>
</mx:application>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" applicationComplete="applicationCompleteHandler();">
	<mx:Script>
		<![CDATA[
			import mx.core.*;
			import flash.display.*;
			
			//UIComponentにした
			private var contain:UIComponent = new UIComponent();
		]]>
	</mx:Script>
	<mx:Script>
		<![CDATA[
			private function applicationCompleteHandler():void {
				contain.width = 100;
				contain.height = 100;
				
				//円を描くよ
				contain.graphics.beginFill(0xffffff, 0.8);
				contain.graphics.drawCircle(50, 50, 50);
				contain.graphics.endFill();

				this.addChild(contain);
			}
	
	]]>
	</mx:Script>
</mx:Application>

そしてその実行結果がこれです。

Flex MXML Sprite ok

よし出た!

厳密にはSpriteでは無くなってしまいましたが、UIComponentはFlexのUIでも基本のクラスで、コンテナであったりボタン等コントロールであったりするわけではないので、今回のような図形が欲しいだけの場合はよいかと思います。

2008/06/24追記

今Flex SDK 3.0.0.477で試してみたところ、上記のプログラムはコンパイルできませんでした。お詫びとともに訂正させていただきます。

問題は大文字小文字の区別と、CDATAセクションの記法です。MXMLのタグについて、mx:Applicationのところをmx:application、mx:Scriptのところをmx:script、属性についてapplicationCompleteのところをapplicationcompleteと間違えていました。

次に、CDATAセクションを本来<![CDATA[~~~]]>と記述するのですが、<!--[CDATA[~~~]]-->と誤って記述していました。

確か以前はコンパイルできたと思うのですが(そのときのSDKバージョンは失念)、今回のバージョンで出来なかったということはmxmlcのXMLパーサの厳密性が上がったのでしょうか。

カテゴリ

タグ

関連記事

  1. Flex 3 SDKで"pong"もどきを作りつつ、AIRでのゲームについて考えてみた。
  2. UNIX(Mac OS X)におけるFlex 3 SDKによるAIRプログラミング 環境設定
  3. Flex、AIRへの導入

トラックバック

このブログ記事を参照しているブログ一覧: Flex 3で直接Spriteを使用することはできない?

このブログ記事に対するトラックバックURL: http://www.memorize-being.net/x/mt-engine/mt-tb.cgi/40

 Flashで制作しているときは、当たり前のように  「タイムライン」を利用して行っていたアニメーション効果  (※このあたり    Directo... 続きを読む

コメントする

このブログ記事について

このページは、cottonが2008年2月29日 20:43に書いたブログ記事です。

ひとつ前のブログ記事は「Flex、AIRへの導入」です。

次のブログ記事は「iPhone SDKがβ版でついに登場」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

Powered by Movable Type 4.1
Valid XHTML 1.0 Transitional
Valid CSS!
Mozilla Firefox ブラウザ無料ダウンロード