Starlingとは、stage3Dで2D描画で扱いやすく作られたフレームワークです。
stage3Dではハードウェアアクセラレーションで高速なGPU描画が可能となります。
airアプリプロジェクトを作ってみたらはまったからメモ。
webアプリケーションの設定でプロジェクトを作ると、インストールされているFlashPlayerで実行できるんですが、airだとそうじゃないらしい。。。
怒られた。。
そこでair3.9っていう最新っぽいのを試してみる。
http://www.adobe.com/devnet/air/air-sdk-download.html
上記はコンパイラなので、以下のアーカイブを参照したほうがいいかも。
http://helpx.adobe.com/air/kb/archived-air-sdk-version.html
ランタイムバージョンを落としてみた。
けど、通らない…!
普通にwebアプリケーションプロジェクトとして始めようかな。
でもそれだと、ローカルでクロスドメインとか面倒なことでてきそうだな。
2013年12月19日木曜日
2013年12月10日火曜日
テンプレートメソッド、ファクトリーパターン
テンプレートメソッドパターン
大本の汎用的なアルゴリズムを記述したテンプレートクラス抽象インターフェース
package factory { public interface IField { // 「フィールドを描く」というメソッドを定義 function drawField():void; } }
実装クラス
package factory { public class FootballField implements IField { public function FootballField() { } public function drawField():void { trace('Drawing the Football Fieald!'); } } }
抽象テンプレートクラス
package factory { /** * テンプレートメソッド抽象クラス * */ public class BaseGame { public function BaseGame() { } public function initialize():void { // 無処理 } public function createField():IField { throw new Error('createField:Abstract Methd!'); } } }
継承クラス
package factory { /** * テンプレートメソッドを継承するクラス * */ public class FootballGame extends BaseGame { public function FootballGame() { super(); } override public function initialize():void { var field:IField = createField(); field.drawField(); } override public function createField():IField { return new FootballField(); } } }
コードだけでは理解するのが難しいので、クラス図を書いたほうがいい。
「テンプレートとなる抽象クラスで処理のアルゴリズムを書き、
抽象インターフェースで各処理の詳細を記述していく」
というイメージかな。
2013年12月9日月曜日
シングルトンパターン
デザインパターンの勉強を始めたので、その勉強録です。
まともに今までデザインパターンを勉強したことがなく、なんとなくソース読んで、似たような仕様で書くっていうのを今まで繰り返してました。
インターンの時にシングルトンを全く意味不明なまま使っていて、結局その時理解せずにインターンを終えてしまった苦い思い出が思い出されます。
今回はこの本に沿って、ActionScriptでデザインパターンを勉強していきたいと思います。(本当はC++とかでやりたい)
ActionScriptでデザインパターンを解説している唯一の本で、丁寧に解説してくれていて理解しやすいと思います。
静的なデータとかこういった形で持つ事が多いですかね。
SingletonEnforcerクラス
シングルトンのクラスのみが使用できるSingletonEnforcerクラスをコンストラクタの引数にして、強制的にコンストラクタを外部で呼び出せなくする手法。
まともに今までデザインパターンを勉強したことがなく、なんとなくソース読んで、似たような仕様で書くっていうのを今まで繰り返してました。
インターンの時にシングルトンを全く意味不明なまま使っていて、結局その時理解せずにインターンを終えてしまった苦い思い出が思い出されます。
今回はこの本に沿って、ActionScriptでデザインパターンを勉強していきたいと思います。(本当はC++とかでやりたい)
ActionScriptでデザインパターンを解説している唯一の本で、丁寧に解説してくれていて理解しやすいと思います。
シングルトンパターン
「クラスのインスタンスを一つしか作らない」ようにするパターンです。静的なデータとかこういった形で持つ事が多いですかね。
SingletonEnforcerクラス
シングルトンのクラスのみが使用できるSingletonEnforcerクラスをコンストラクタの引数にして、強制的にコンストラクタを外部で呼び出せなくする手法。
package { /** * シングルトンパターンクラス * */ public class SingletonClass { // privateでstaticな変数 private static var _instance:SingletonClass; /** * constructor * */ public function SingletonClass(enforcer:SingletonEnforcer) { } /** * インスタンス取得メソッド * @return SingletonClass * */ public static function getInstance():SingletonClass { if (SingletonClass._instance == null) { SingletonClass._instance = new SingletonClass(new SingletonEnforcer()); } return SingletonClass._instance; } public function sayHello():void { trace('Hello World'); } } } /** * コンストラクタを強制的に呼び出せなくするため * 外部からアクセス不可能な空クラスを定義 * */ class SingletonEnforcer {}
2013年12月7日土曜日
AS3でカスタムイベント
Flash開発する上ではイベントの処理は必要ですよね。
僕はFlashを勉強し始めて、二週間ちょっとですが、もう何回使ったかわかりません。
そのくらい頻繁に用いるイベント処理。
ゲームを制作する時とかは自分でイベントを作りたくなります。
「着地した瞬間」とか「的に当たった瞬間」とか「ゴール地点に到達した瞬間」とかね。
今日、カスタムイベントの定義の方法を勉強したので、復習を込めた備忘録です。
カヤックのブログの説明がよかったです。
今回作成したサンプルです。
壁にボールが当たるとイベントが発生します。
【Main.as】
メインのクラス
package { import flash.display.MovieClip; import flash.events.Event; import flash.events.MouseEvent; /** * 円をクリックすれば、ステージを円が跳ね返っていく * 跳ね返った瞬間にイベントディスパッチする */ public class Main extends MovieClip { // キャラインスタンス private var chara:Chara; // 壁にあたった回数 private var cnt:uint; public function Main() { // キャラのインスタンスを生成 chara = new Chara(); // クリックイベントを設定 chara.addEventListener(MouseEvent.CLICK, onCharaClick); // 壁に当たるカスタムイベントを設定 chara.addEventListener(CharaEvent.HIT_WALL, onCharaHitWall); // 中央に配置 chara.x = stage.stageWidth / 2; chara.y = stage.stageHeight / 2; addChild(chara); // 壁にあたった回数 cnt = 0; // テキスト表示 outputText.text = cnt.toString() + "回 壁にあたった"; } /** * キャラのクリックイベント * @param {MouseEvent.CLICK} e : マウスイベントオブジェクト * @return {void} : */ private function onCharaClick(e:MouseEvent):void { // キャラの毎フレームイベントを設定 chara.addEventListener(Event.ENTER_FRAME, onCharaEnterFrame); } /** * キャラの毎フレーム関数 * @param {Event} e : イベントオブジェクト * @return {void} : */ private function onCharaEnterFrame(e:Event):void { chara.moveChara(); } /** * キャラが壁にあたったイベントハンドラ * @param {CharaEvent} e : キャライベントオブジェクト * @return {void} : */ private function onCharaHitWall(e:CharaEvent):void { // 壁にあたった回数をインクリメント cnt++; trace("壁にあたった" + cnt.toString() + "回"); // テキスト表示 outputText.text = cnt.toString() + "回 壁にあたった"; } } }
【Chara.as】
キャラの動きとイベントの設定
package { import flash.display.MovieClip; public class Chara extends MovieClip { // キャラのスピード private var speedX:int; private var speedY:int; public function Chara() { // ランダムなスピードの値設定 speedX = Math.random() * 10; speedY = Math.random() * 10; } /** * キャラを動かす関数 * @param {} : * @return {void} : */ public function moveChara():void { // 動かす x += speedX; y += speedY; // 壁にあたったかどうかのフラグ var isHitWall:Boolean = false; // 壁にあたった時のはねかえり処理 if(x < width / 2) { x = width / 2; speedX *= -1; isHitWall = true; } else if(x > stage.stageWidth - width / 2) { x = stage.stageWidth - width / 2; speedX *= -1; isHitWall = true; } if(y < height / 2) { y = height / 2; speedY *= -1; isHitWall = true; } else if(y > stage.stageHeight - height / 2) { y = stage.stageHeight - height / 2; speedY *= -1; isHitWall = true; } // ヒットイベントをブロードキャスト( = 登録されたリスナーのメソッドを実行する)する if(isHitWall == true) { var evt:CharaEvent = new CharaEvent(CharaEvent.HIT_WALL); dispatchEvent(evt); } } } }
【CharaEvent.as】
このクラスでイベントを定義している
package { import flash.events.Event; public class CharaEvent extends Event { // イベントの種類を定義(静的なプロパティ) public static const HIT_WALL:String = "hitWall"; public function CharaEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false) { // 継承元のEventクラスのコンストラクタを呼び出す super(type, bubbles, cancelable); } // EventDispacherを呼び出すためのオーバーライド override public function clone():Event { return new CharaEvent(type, bubbles, cancelable); } // toString()出力用 override public function toString():String { return formatToString("CharaEvent", "type", "bubbles", "cancelable"); } } }
FlashからJSON書き出し
タイトルの通り、FlashからJSONファイルの書き出しをやってみました。
今回は、「Flashからphpファイルに値を渡して、それをJSON形式で書き出す」という流れです。
こちらのサイトにphpとFlashの連携方法が書かれていたので、そちらを参考にしつつ行いました。
AS3でPHPと通信する
【ConnectPHP.as】
phpファイルにデータを送信 + phpファイルを実行
package connectphp { import flash.events.Event; import flash.events.EventDispatcher; import flash.net.URLLoader; import flash.net.URLLoaderDataFormat; import flash.net.URLRequest; import flash.net.URLRequestMethod; import flash.net.URLVariables; public class ConnectPHP extends EventDispatcher { public static const COMPLETE:String = "connectPHP_complete"; /** * コンストラクタ */ public function ConnectPHP(url:String = null, variables:Object = null) { if (url && variables) { sendAndLoad(url, variables); } } /** * phpファイルにデータの内容を送信する * @param {String} : phpデータのパス * @param {String} : データの中身 */ public function sendAndLoad(url:String, variables:Object):void { var urlRequest:URLRequest = new URLRequest(url); // php に送信するデータをオブジェクト形式で保存する var urlVariables:URLVariables = new URLVariables(); // 引数のデータを全て渡す for (var i:String in variables) { urlVariables[i] = variables[i]; } // urlRequest.dataに渡す urlRequest.data = urlVariables; // phpへの送信方法 urlRequest.method = URLRequestMethod.POST; // phpファイルをリクエスト var urlLoader:URLLoader = new URLLoader(); urlLoader.dataFormat = URLLoaderDataFormat.VARIABLES; urlLoader.addEventListener(Event.COMPLETE, completeHandler); urlLoader.load(urlRequest); } /** * phpファイルの呼び出しが終了したときのイベントハンドラ */ private function completeHandler(e:Event):void { // イベントディスパッチ dispatchEvent(new Event(COMPLETE)); } } }
【data.php】
phpファイル
このファイルを通せば、"name".jsonというJSON形式のファイルが出来上がります。
【Main.as】
メインのドキュメントクラス
package connectphp { import flash.display.MovieClip; import flash.events.Event; import connectphp.*; public class Main extends MovieClip { /** * コンストラクタ */ public function Main() { // 保存したいデータのオブジェクトを作る var userData:Object = { // 名前 name: "tanaka", // 買い物リスト item:[ "ファブリーズ", "ジョイ", "キャベツ", "カレールー", "じゃがいも" ] }; // オブジェクトをJSON形式の文字列に変換 var userDataForJson:String = JSON.stringify(userData); // 送るデータ var sendData:Object = new Object(); sendData.name = userData.name.toString(); sendData.userData = userDataForJson; // データをphpに送る var connectPHP:ConnectPHP = new ConnectPHP(); connectPHP.addEventListener(ConnectPHP.COMPLETE, completeHandler); connectPHP.sendAndLoad("data.php", sendData); } private function completeHandler(e:Event):void { trace("送信完了"); } } }
earth.idlコンパイル方法
(1) Microsoft Visual C++ 2008 Express EditionからVisual Studio 2008 コマンド プロンプトを起動
(2) コマンドラインは以下の通り
midl /cpp_cmd cl.exe /cpp_opt "/E" /out "出力先ディレクトリ" "earth.idlのあるディレクトリ"
*スペースに注意
参考:IDLコンパイル成功!
http://futr.cocolog-nifty.com/blog/2008/04/idl_f4f5.html
Google Earth COM API を C++ で使う
http://oshiro.bpe.es.osaka-u.ac.jp/people/staff/imura/computer/misc/google_earth_com_api/disp_content
------以下サンプルプログラムを空のプロジェクトから記述(追加のインクルードファイルにearth.hを追加)------
// main.cpp
(2) コマンドラインは以下の通り
midl /cpp_cmd cl.exe /cpp_opt "/E" /out "出力先ディレクトリ" "earth.idlのあるディレクトリ"
*スペースに注意
参考:IDLコンパイル成功!
http://futr.cocolog-nifty.com/blog/2008/04/idl_f4f5.html
Google Earth COM API を C++ で使う
http://oshiro.bpe.es.osaka-u.ac.jp/people/staff/imura/computer/misc/google_earth_com_api/disp_content
------以下サンプルプログラムを空のプロジェクトから記述(追加のインクルードファイルにearth.hを追加)------
// main.cpp
#include <windows.h> #include <iostream> #include "earth.h" using namespace std; int main( int argc, char **argv ) { IApplicationGE *app; ICameraInfoGE *camera; HRESULT hr; // COMの初期化 CoInitialize( 0 ); // IApplicationGE を得る hr = CoCreateInstance( CLSID_ApplicationGE, 0, CLSCTX_LOCAL_SERVER, IID_IApplicationGE, reinterpret_cast<LPVOID *>( &app )); if ( FAILED( hr )) { cerr << "cannot create IApplicationGE" << endl; return -1; } // Google Earth の情報を得る AppTypeGE app_type; int major, minor, build; app->get_VersionAppType( &app_type ); app->get_VersionMajor( &major ); app->get_VersionMinor( &minor ); app->get_VersionBuild( &build ); cout << "You are using "; switch ( app_type ) { case EnterpriseClientGE: cout << "Google Earth Enterprise Client" << endl; break; case ProGE: cout << "Google Earth Pro" << endl; break; case PlusGE: cout << "Google Earth Plus" << endl; break; case FreeGE: cout << "Google Earth Free" << endl; break; default: cout << "Unknown" << endl; break; } cout << "version: " << major << "." << minor << "." << build << endl; // 初期化が終了するまで待つ BOOL is_initialized; do { hr = app->IsInitialized( &is_initialized ); } while ( is_initialized == false ); // 現在のカメラ位置に関する情報を得る // まずカメラのインスタンスを取得する hr = app->GetCamera( true, &camera ); if ( FAILED( hr )) { cerr << "IApplicationGE::GetCamera() failed" << endl; return -1; } // 各種パラメータの値を得る double lat, lon, alt; AltitudeModeGE alt_mode; double range, tilt, azimuth; camera->get_FocusPointLatitude( &lat ); // 緯度 camera->get_FocusPointLongitude( &lon ); // 経度 camera->get_FocusPointAltitude( &alt ); // 高度 camera->get_FocusPointAltitudeMode( &alt_mode ); // 高度の計測方法 camera->get_Range( &range ); camera->get_Tilt( &tilt ); camera->get_Azimuth( &azimuth ); cout << "現在の視点情報" << endl; cout << "注視点の緯度: " << lat << endl; cout << "注視点の経度: " << lon << endl; cout << "注視点の高度: " << alt << endl; cout << "高度の原点は地表: " << alt_mode << endl; cout << "注視点からの距離: " << range << endl; cout << "天頂角: " << tilt << endl; // 水平だと90度 cout << "方位角: " << azimuth << endl; // 注視点に対して視点が真南にあると // 0度。そこから時計まわりに角度が増える。 // カメラを設定する app->SetCameraParams( 34.7316, // 緯度 135.734, // 経度 0.0, // 高度 RelativeToGroundAltitudeGE, // 高度の計測方法 300.0, // 距離 0.0, // 天頂角 0.0, // 方位角 0.1 ); // 移動速度 (5.0より大きいと瞬時に移動) // 終了 CoUninitialize(); return 0; }
for each
var mc1:MovieClip = new MovieClip(); mc1.name = 'material'; var mc2:MovieClip = new MovieClip(); mc2.name = 'furniture'; var mc3:MovieClip = new MovieClip(); mc3.name = 'instant'; var obj:Object = { material: mc1, furniture:mc2, instant:mc3 }; trace('--------------------------------------'); for (var key:String in obj) { trace(obj[key]); trace(key); } /* [object MovieClip] furniture [object MovieClip] instant [object MovieClip] material */ trace('obj[item]--------------------------------------'); for each(var item:String in obj) { trace(item); } /* [object MovieClip] [object MovieClip] [object MovieClip] */ trace('elementがobjになる--------------------------------------'); for each(var element:Object in obj) { trace(element); } /* [object MovieClip] [object MovieClip] [object MovieClip] */
as3でlzma圧縮
FlashPlayer11.3から搭載された新機能。
今まではzip圧縮しかできなかったのが高効率のlzma圧縮も対応できるようになっているらしい。
Adobe純正の flex sdk4.6 では compress('lzma') に対応していなくて、コードから直接読み込むのは不可能でした。
flex sdkはAdobeではもう作っていなくて、apache flex sdkになっているらしい。
apache flex sdk 4.11 をダウンロードして使ってみたら、lzma呼び出せました。
ByteArray形式のデータを保存するだけなので、すごい簡単です。
flex sdkはAdobeではもう作っていなくて、apache flex sdkになっているらしい。
apache flex sdk 4.11 をダウンロードして使ってみたら、lzma呼び出せました。
ByteArray形式のデータを保存するだけなので、すごい簡単です。
// 保存したいファイルのデータ(本当はこのデータを外部ファイルを読み込む形になる) var file:FileReference = new FileReference(); // ByteArrayのデータを抽出 var data:ByteArray = new ByteArray(); data.writeBytes(file.data); // 圧縮するとき data.compress(CompressionAlgorithm.LZMA); file.save(data); // 解凍するとき data.uncompress(CompressionAlgorithm.LZMA); file.save(data);
登録:
投稿 (Atom)