この記事のURL

http://www.dango-itimi.com/blog/archives/2012/001146.html


FLASH tips Toolkit for CreateJS と Haxe による Flash 開発工程の流れに沿った html5 サイト開発手順

Flash 開発を通して培った Webサイト(ゲーム)開発工程の流れを、html5(canvas)サイト開発に生かすにはどうすればよいか、調査した内容を記述します。

制作の流れ

Flash 制作の流れは大体以下のようになります。

 (1)素材データ作成
  ・画像データを Photoshop や Illustrator で作成
  ・BGM や効果音を音楽作成ソフトで制作

 (2)素材データを Flash CS に読み込み編集・管理(オーサリング)
  ・アニメーション作成
  ・スクリプトで制御しやすい形に命名・調節

 (3)オーサリングした素材データを swf と swc に出力
  ・Action Script からオーサリングしたデータの制御が可能に

 (4)プログラミング
  ・Action Script 専用エディタを利用

html5 で上記工程をなぞる場合、(2)(3)と(4)をどうするかが問題となります。

前知識から、Flash CS6 にある機能「Toolkit for CreateJS」を用いれば(3)はなんとかなるのかな、と予測を立てました。「Toolkit for CreateJS」が有用できるのであれば、(2)は Flash 制作と同じ事をすればよしとなりそうです。

(4)に関しては javascript を用いる事になりますが、どうせなら FDT からも利用可能な Haxe で記述できたらいいよね、と思い、「Toolkit for CreateJS」で出力された素材データを Haxe で制御する方法の調査を行う事にしました。

CreateJS と Toolkit for CreateJS

本題に行く前に簡単な前知識となります。
CreateJS とは何であるのか、とてもわかりやすく説明をされている記事があります。

 リッチなHTML5コンテンツのためのフレームワーク「CreateJS」が公式サイトを公開 | ClockMaker Blog
 http://clockmaker.jp/blog/2012/04/createjs-com/

端的に説明しますと CreateJS は、html5 と canvas で行いたい表現の種類を より少ない手間で増やすことができるための javascript ライブラリ、といったところでしょうか。

次に Flash CS6 の機能「Toolkit for CreateJS」ですが、これを利用する事で、Flash CS6 上でオーサリングした素材データを CreateJS で簡単に扱うことができるように変換出力をしてくれます。

Flash CS6 がない場合、CreateJS 公式サイトからダウンロード可能な ZOE というツールを用いると同等の事ができるかと思われます。

Toolkit for CreateJS 利用調査

Toolkit for CreateJS からどのようなデータが出力されるのか調査するために、サンプル fla ファイル(view.fla)を制作しました。
図はサンプル view.fla ファイルの内容となります。

シューティングゲームのプレイヤーの機体となる画像を Photoshop で制作し、Flash CS6 に読み込み、アニメーションの切替のタイミングの調節(フレーム制御)を行っています。
調節を行ったアニメーション用ムービークリップには shooting.player.View クラスという命名を行いました。

Flash CS6 の「Toolkit for CreateJS」機能からパブリッシュを行う事で、デフォルト設定では view.fla と同じディレクトリに各データが出力される事が確認できます。

以下はそのサンプル view.fla ファイルと出力されたデータ群となります。view.fla を開くには Flash CS6 が必要です。

 [ サンプル1 ダウンロード ]

サンプルは以下のようなファイルディレクトリ構造となります。

sample1/
├ view.fla
├ view.html
├ view.js
└ images/
  ├ _0.png
  ├ _1.png
  ├ _2.png
  └ _3.png

各ファイルの内容を見てみるとわかりますが、「view.js」+「images/」= swc といったイメージでしょうか。view.js 内には view.fla で定義した shooting.player.View クラスの定義が行われており(lib.shootingplayerView というクラス名になっている)、そのクラスで利用している画像データが images/ ディレクトリに配置されています。

また、view.html には view.js を利用するための CreateJS を用いたサンプルプログラムが出力されている事がわかります。


Haxe による CreateJS の制御

Haxe に CreateJS 用クラスをインストール

Haxe には CreateJS を利用するためのハブ的なクラスが用意されていました。以下のサイトがとても参考になりました。Haxe から CreateJS を利用するための手順が書かれています。

 ActionScript入門Wiki : HaxeでCreateJSを利用する
 http://www40.atwiki.jp/spellbound/pages/1968.html

view.html 内サンプルプログラム注目点

view.html 内で注目する点は以下の行となります。画像素材を読み込むためのファイルパス一覧が定義されています。

	var manifest = [
		{src:"images/_0.png", id:"_0"},
		{src:"images/_1.png", id:"_1"},
		{src:"images/_2.png", id:"_2"},
		{src:"images/_3.png", id:"_3"}
	];

Flash CS6 内で使用する画像データが増加したり、ライブラリ内の構造に変更がかかると、このファイルパス一覧定義の記述が毎回書き換わる事になります。


view.html 内サンプルプログラムを Haxe で記述

まずは新規で以下の内容の index.html というファイルを作成しました。

<!DOCTYPE html>
<html lang="ja">

	<head>
		<title>CreateJsTestByHaxe</title>
		<meta charset="utf-8"/>
		<script src="http://code.createjs.com/easeljs-0.5.0.min.js"></script>
		<script src="http://code.createjs.com/tweenjs-0.3.0.min.js"></script>
		<script src="http://code.createjs.com/movieclip-0.5.0.min.js"></script>
		<script src="http://code.createjs.com/preloadjs-0.2.0.min.js"></script>
		<script src="createjs/view.js"></script>	
		<script type="text/javascript" src="js/App.js"></script>
	</head>

	<body style="background-color:#D4D4D4">

		<div id="content">
			<div id="head"></div>
			<div id="body">
				<canvas id="canvas" width="550" height="400" style="background-color:#000000"></canvas>	
			</div>
			<div id="footer">
				<div id="haxe:trace"></div>
			</div> 
		</div>
	</body>
</html>

ファイルディレクトリ構造は以下となります。

index.html
├ js/
│ └ App.js
└ createjs/
  ├ view.js
  └ images/
    ├ _0.png
    ├ _1.png
    ├ _2.png
    └ _3.png

Haxe で書かれたプログラムを javascript として変換したものが App.js となります。App.js には view.html 内サンプルプログラムと同等の処理を行う javascript が記述されています。

App.js ファイルの素となる、作成した Haxe 用クラスファイルは以下となります。メイン用クラスと素材データ読み込み用クラス、二つに分けています。

Main.hx

package;

import createjs.easeljs.Stage;
import createjs.easeljs.Shape;
import createjs.easeljs.Ticker;
import createjs.easeljs.Container;
import js.Lib;

class Main {
	
	private var mainFunction:Dynamic;
	private var stage:Stage;
	private var loader:Loader;
	private var shootingplayerView:Container;
	
	public static function main() {
		new Main();
	}
	public function new(){
		
		Lib.window.onload = initialize;
	}
	private function initialize(event){

		Ticker.useRAF = true;		
		Ticker.setFPS(24);
		Ticker.addListener(run);
		
		loader = new Loader();
		stage = new Stage(cast js.Lib.document.getElementById("canvas"));
		
		initializeToLoad();
	}
	private function run(){
		
		mainFunction();
	}
	private function initializeToLoad(){
		
		loader.execute();
		mainFunction = load;
	}
	private function load(){

		if(loader.isFinished())
			mainFunction = setPlayer;
	}
	private function setPlayer(){
		
		shootingplayerView = Lib.eval("new window.lib.shootingplayerView()");
		shootingplayerView.setTransform(70,212,1,1,0,0,0,18,17);
		
		stage.addChild(shootingplayerView);	
		
		mainFunction = play;
	}
	private function play(){
		
		stage.update();
	}
}

Loader.hx

package;

import createjs.preloadjs.PreloadJS;
import js.Lib;

class Loader {

	private var BASE_DIRECTORY:String;
	private var IMAGE_DIRECTORY:String;
	private var loader:PreloadJS;
	private var images:Dynamic;
	private var completed:Bool;
	private var manifest:Array<Dynamic>;
	
	public function new(){
		
		setField();
		setManifest();
		setLoader();
	}
	private function setField(){
		
		images = Lib.eval("window.images||{}");
		
		BASE_DIRECTORY = "createjs/";
		IMAGE_DIRECTORY = BASE_DIRECTORY + "images/";
	}
	private function setManifest(){
		
		manifest = [
			{src:"_0.png", id:"_0"},
			{src:"_1.png", id:"_1"},
			{src:"_2.png", id:"_2"},
			{src:"_3.png", id:"_3"}
		];
		
		for(i in 0...manifest.length){
			manifest[i].src = IMAGE_DIRECTORY + manifest[i].src;
		}
	}
	private function setLoader(){
		
		loader = new PreloadJS();
		loader.initialize(false);
		loader.onFileLoad = onFileLoad;
		loader.onComplete = onComplete;
	}
	public function execute(){
		
		completed = false;
		loader.loadManifest(manifest);
	}
	private function onFileLoad(event){
		
		if(event.type == "image"){
			images[event.id] = event.result;
		}
	}
	private function onComplete(){
		
		completed = true;
	}
	public function isFinished():Bool{
		
		return completed;
	}
}

Loader.hx 内には前述の注目点として挙げた、ファイルパス一覧定義の記述があります。Flash CS6 でのオーサリング内容に変更がかかるたびに Loader.hx の内容の変更を行わなくてはいけません。

これは面倒なので、別途何か方法を考える必要は後々出てきそうです。AIR を用いて Loader.hx を自動で書き換えてくれるアプリケーションを作る等々。

サンプルデモ

以下が今回作成したサンプルのデモとなります。html5 対応のブラウザで閲覧する必要があります。

 http://www.dango-itimi.com/blog/swf/173/sample2/

このデモでは、Main.hx の play メソッドに プレイヤーの機体が右にゆっくりと動作するような記述を一行付け加えました。

	private function play(){
		
		shootingplayerView.x += 1;
		stage.update();
	}

ここまでくれば、後は ActionScript でプログラミングするのと同等に、Haxe でも問題なくプログラミングしていける事でしょう。

以上で調査報告は終了となります。Toolkit for CreateJS と Haxe による Flash 開発工程の流れに沿った html5(canvas)サイト開発は、そこそこ問題なく行えることがわかりました。


余談

Haxe 用エディタとして FDT を利用しましたが、不具合なのか quickfix には easelJS パッケージのクラスしか出てきません。

CreateJS で画像拡大縮小を行うと必ずアンチエイリアスがかかってしまう模様。ドット絵とは相性が悪いため、psd ファイル制作の段階で二倍、三倍等に拡大しておく必要あり。

追記)其ノ二 に続きます。
http://www.dango-itimi.com/blog/archives/2013/001147.html

[ FLASH ] [ tips ] 投稿者 siratama : 2012年12月29日 01:08

トラックバック

http://www.dango-itimi.com/blog/mt-tb.cgi/1106

コメント

以下コメントを書き込むだけでは、管理人には通知が行われません。通知を行いたい場合、管理人の書き込みに「返信」を押してコメントをしていただくか、あるいは Google+, Twitter へご連絡ください。




[EDIT]