2009.10.21
category
comments

Progression4(ベータ版)でPRMLLoaderを使うには

※Progression4(正式版)でPRMLLoaderの仕様が一部変更されました。下記の方法よりも、よりスマートに実装出来るようになってるのでこちらを参考にして下さい。

Progression4では仕様変更により今までのお作法が通用しない部分が結構あって、PRMLLoaderもその一つ。最近はPRMLからシーン構成を生成するので解決法をずっと探ってたんだけど、ようやく動作したのでメモ。同じとこで詰まってる人がいたら参考にしてみて下さい。

ポイントは以下の3つ。
1、PRML内で設定するシーンクラスをあらかじめ宣言しておく(25~26行目)
 → 宣言してないとエラーが出る。

2、親クラスを呼び出すときに第1、第2引数をnullにしておく(34行目)
 → 通常はsuper(“index”, IndexScene, new WebConfig());となるが、PRMLをつかってシーンを生成すると全部自動で設定してくれるため、ここで宣言したidとPRMLで自動宣言されるidが重複してしまいエラーが出る。

3、PRMLLoaderクラス内のmanagerを使う(45~56行目)
 → ここが一番の鬼門。PRMLLoaderを使ってシーン構造を生成した場合はPRMLLoader.managerに展開される。なので「外部同期機能」や「最初のシーンに移動」とかを下記のようにしてしまうと別管理のmanagerとして動作してエラーが出る。

manager.sync = true;
manager.goto(manager.syncedSceneId);

この3つのポイントをまとめると、ドキュメントクラスは以下のようになる。

Index.as

package {
	import jp.progression.casts.*;
	import jp.progression.commands.display.*;
	import jp.progression.commands.lists.*;
	import jp.progression.commands.net.*;
	import jp.progression.commands.tweens.*;
	import jp.progression.commands.*;
	import jp.progression.config.*;
	import jp.progression.data.*;
	import jp.progression.debug.*;
	import jp.progression.events.*;
	import jp.progression.scenes.*;

	import flash.events.Event;
	import flash.net.URLRequest;
	import jp.progression.loader.PRMLLoader;

	/**
	 * ...
	 * @author ...
	 */
	public class Index extends CastDocument {

		//PRMLで使うシーンクラスを宣言
		IndexScene;
		MyScene;

		/**
		 * 新しい Index インスタンスを作成します。
		 */
		public function Index() {
			// 自動的に作成される Progression インスタンスの初期設定を行います。
			// 生成されたインスタンスにアクセスする場合には manager プロパティを参照してください。
			super( null, null, new WebConfig() );
		}

		/**
		 * SWF ファイルの読み込みが完了し、stage 及び loaderInfo にアクセス可能になった場合に送出されます。
		 */
		protected override function atReady():void {

			var pl:PRMLLoader = new PRMLLoader(stage, new URLRequest("xml/prml.xml"));
			pl.addEventListener(Event.COMPLETE, function(e:Event):void
			{
				pl.removeEventListener(Event.COMPLETE, arguments.callee);

				// 開発者用に Progression の動作状況を出力します。
				Debugger.addTarget(pl.manager);

				// 外部同期機能を有効化します。
				pl.manager.sync = true;

				// 最初のシーンに移動します。
				pl.manager.goto(pl.manager.syncedSceneId);

				// prml.xmlの内容
				trace("prml="+pl.manager.root.toXMLString());
			});
		}
	}
}

prml.xml




    
    
    

2009.07.21
category
comments

WordPressからProgressionのPRMLを出力してみる

Flashネタをエントリーするのは久々だなー。先日の福岡てら子で発表した内容ですが、WordPressからProgressionで使うPRMLというXMLを出力する方法。PRMLの詳しい説明は本家リファレンスを参照して下さい。これを使うことにより、WordPressからProgressionにダイレクトにシーンを生成出来るようになる。今回はWordPressのカテゴリーをシーンに見立てて出力しているので、親、子、孫、曾孫といった深い階層のシーン構造も簡単に作ることができる。下記のPHPをWPがインストールされているサーバーのテーマフォルダにアップします。次にWPのメニューからページを新規で追加して、タイトルに「prml」と入力し、右サイドバーの属性のテンプレートから「prml」を選択。この状態でページを公開すると、タイトルの下にパーマリンクが表示されるので、このURLにアクセスすると現在のカテゴリー構造を維持したままのPRMLが出力されるようになる。こんな感じ

prml.php

<?php /*
Template Name: prml
*/ ?>
<?php
 header('Content-Type: text/xml; charset='.get_option('blog_charset'), true);

 //-----[PRMLのヘッダー生成]
 $title = get_option('blogname');
 $header .= '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>';
 $header .= '<prml version="2.0.0" type="text/prml">';
 $header .= '<scene name="index" cls="myproject.IndexScene" title="'.$title.'">';

 //-----[WPから全階層のカテゴリー取得]
 $str = wp_list_categories('orderby=id&echo=0&hide_empty=0&use_desc_for_title=0&title_li=');
 $str = strip_tags($str, '<li>');

 //-----[PRML形式に変換]
 $category = strip_tags($str, '');
 $category = str_replace(array("\r\n","\r","\n"), '', $category);
 $category = preg_replace('/\s+/', ' ', $category);
 $category = ltrim($category);
 $category = split(' ', $category);

 for($i=0; $i<count($category); $i++)
 {
 	$str = str_replace(">".$category[$i]."\n", $i.">", $str);
 }

 $str = preg_replace('/"(.*?)"/', '', $str);
 $str = str_replace('li', 'scene', $str);

 for($i=0; $i<count($category); $i++)
 {
 	$str = str_replace('class='.$i, 'name="'.$category[$i].'" cls="myproject.'.ucfirst($category[$i]).'Scene" title="'.$title." | ".$category[$i].'"', $str);
 }

 //-----[PRMLとして出力]
 echo $header.$str.'</scene></prml>';
?>

このPHPでやっていることはwp_list_categories()で取得したリストタグ付きカテゴリーを力技でPRML形式のXMLに変換してるだけ。ソースを見てもらえば苦笑いできると思います。w

ここではシーン構造のみをPRMLとして出力してるけど、Progressionの各ページ内にWPから画像を読み込んだり、テキストを流し込む場合は個別にXMLを作ったほうが管理しやすいと思う。その場合は以前エントリーしたこの記事が役立つと思います。

今回参考にさせて頂いたのはMotuLogさんのエントリー。ありがとうございます!またflabakaさんは自分とは違ったアプローチでWordPressやMovableTypeとProgressionを連携させる方法をエントリーされてます。

■参考サイト
・MotuLogさん Progression(3.1.52) 動的にシーンを作成する
・flabakaさん ProgressionとWordPressの連携

2008.12.10
category
tag
comments

PHPで動的生成されたXMLをjQueryで読み込むときの注意

WordPressとかのPHPから動的生成されたxmlをjQueryを使って読み込むときにワナがあるので注意が必要。Flashでは普通に読み込めたので気付かなかったけど、動的生成のxmlをjQueryで読み込むとエラーになる。調べたらPHPから出力されるxmlのヘッダーのContent-Typeをtext/xmlに設定していないことが原因だった。なのでヘッダーを書き換えてやるとうまく読み込めるようになる。

WordPressでxmlを出力する場合は最初にこれを入れること。

header('Content-Type: text/xml; charset='.get_option('blog_charset'), true);
2008.11.21
category
comments

WordPressでFlash用に複数のxmlを出力する方法

デフォルトのRSS配信とは別にページ機能を使ってxmlを出力する事が出来たのね。今まで気付かなかったのでメモ。

まずはページ用PHPの冒頭でTemplate Nameを設定する。今回の場合は「newsXML」とする。このPHPを、現在使用しているテーマフォルダにアップする。次にWordPressの管理メニューからページをクリック。タイトルを「newsXML」として、下の方にあるページテンプレートを「デフォルトテンプレート」から「newsXML」にする(page-newsXML.phpをアップしていないと、ページテンプレートというオプションが出てこないので注意)。公開ボタンを押下してから再度newsXMLの管理ページを開くと、タイトルの下にパーマリンクのURLが記載されるので、このアドレスにアクセスするとxmlが動的生成されるようになる。

Flashから必要な分だけWordPressでページを作っておいて、個別のxmlを吐き出せば管理が楽になりますよと。ちなみに下のPHPだとカテゴリーが「news」のエントリーの最新5件だけを出力する仕様にしてます。用途に合わせてquery_posts()の引数を変えてやればなんでも出せる。

page-newsXML.php

<?php header('Content-Type: text/xml; charset='.get_option('blog_charset'), true); ?>
<?php /*
Template Name: newsXML
*/ ?>
<?php echo '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>'; ?>
<root>
<?php query_posts("posts_per_page=5&category_name='news'"); ?>
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<item>
<pubdate><?php echo get_post_time('Y-m-d H:i:s', true); ?></pubdate>
<?php the_category_rss(); ?>
<description><![CDATA[<?php the_excerpt_rss(); ?>]]></description>
</item>
<?php endwhile; endif; ?>
</root>
2007.07.02
category
comments

CASA Frameworkを試す

CASAが良いらしい、とよく聞くので使ってみる。クラスを一通り見てみると「LoadGroup」と「XmlUtil」あたりが便利そうだ。

「LoadGroup」を使うと複数のxmlや画像を一括管理で読み込む事ができる。今回は自分のTwitterのuserとfriendsのRSSをまとめて読み込んでみる。読み込んだ後はxpathにてノードを取得する。(CASAでもノード取得できるはずなんだけど、なぜかセレクトできなかったので。)

注目すべきは「new Percent(25)」の部分。読み込む対称に対して全体の何パーセントを割り当てるか、を設定できる。ここでは1つ目のxmlを読み込んだ時点で全体の25%読込完了となる。ローディングバーとかに細かく反映できたりしてこそばゆい。

読込が完了したら、「getXML()」でxmlに変換してやりxpathにて取り出す。trace文にはTwitterの最新タイトルがそれぞれ表示されます。CASAを使うと、ちょこちょこしたスクリプトを簡便化できるので、地味だけど後からジワジワ効いてきます。「ArrayUtil」クラスとかも使う機会多いんじゃないかな。ちなみに画像をまとめて読み込む場合は「MediaLoad」クラスを使います。詳しくはドキュメントを参照されたし。

import org.casaframework.load.LoadGroup
import org.casaframework.load.base.BytesLoadInterface;
import org.casaframework.load.data.xml.XmlLoad;
import org.casaframework.load.media.MediaLoad;
import org.casaframework.math.Percent;
import org.casaframework.util.XmlUtil;

//-----[xmlの取得先]
var userXML:XmlLoad = new XmlLoad("http://twitter.com/statuses/user_timeline/6023282.rss?"+getTimer());
var friendsXML:XmlLoad = new XmlLoad("http://twitter.com/statuses/friends_timeline/6023282.rss?"+getTimer());
var myLoadGroup = new LoadGroup();

//-----[初期化関数]
init();
function init()
{
   //-----[ロードオブジェクトを追加]
   myLoadGroup.addLoad(userXML, new Percent(25));
   myLoadGroup.addLoad(friendsXML, new Percent(75));

   //-----[オブザーバーの登録]
   myLoadGroup.addEventObserver(this, LoadGroup.EVENT_LOAD_PERCENT, "onGroupLoadPercent");
   myLoadGroup.addEventObserver(this, LoadGroup.EVENT_LOAD_ERROR, "onGroupLoadError");
   myLoadGroup.addEventObserver(this, LoadGroup.EVENT_LOAD_COMPLETE, "onGroupLoadComplete");
   myLoadGroup.start();
}

//-----[ロードグループイベントハンドラー]
function onGroupLoadPercent(sender:LoadGroup, progress:Percent):Void
{
   trace("My group is " + progress.getPercentage() + "% loaded.");
}

function onGroupLoadError(sender:LoadGroup, failedLoad:BytesLoadInterface):Void
{
   myLoadGroup.removeLoad(failedLoad);
   myLoadGroup.start();
}

function onGroupLoadComplete():Void
{
   trace("xml complete");

   var userObj:Object = XmlUtil.xmlToObject(userXML.getXml())['rss'][0]['channel'][0]['item'];
   var friendsObj:Object = XmlUtil.xmlToObject(friendsXML.getXml())['rss'][0]['channel'][0]['item'];

   trace(userObj[1].title[0].nodeValue);
   trace(friendsObj[1].title[0].nodeValue);
}

7/17追記
xpathを使わずにcasaのみでノードを取得するやり方が分かったのでコードを修正しました。

2007.05.17
category
comments

ドメイン間ポリシーファイルについて

異なるドメイン間でXMLとかをやり取りする場合、「crossdomain.xml」を設置する必要がある。Flash側にはcrossdomain.xmlが置かれているドメインを設定することでクロスアクセスが可能になる。アクセス許可の範囲はポリシーファイルの置かれたディレクトリ以下に限られる。毎回忘れるのでメモ。

Flash側に以下を記述。

System.security.loadPolicyFile("crossdomain.xmlのパス");

Flashからアクセスしたいサーバーにcrossdomain.xmlをアップする。
crossdomain.xml

<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
	<site-control permitted-cross-domain-policies="all" />
	<allow-access-from domain="許可したいドメイン" />
</cross-domain-policy>
page 1 / 11