satkaku

色々かいたものの試行錯誤

AIR for iOS でのカメラの取り扱いメモ【どのクラスを使えばいいのか?】

AIR for iOSでカメラ使う際の選択肢は2つあります。

1. flash.media.CameraUI

iOSデフォルトのカメラアプリを使用する方法です。
CameraUI#launchを使うだけで、簡単に呼び出せます。デフォルトのカメラアプリなので、ズーム、フラッシュの有無、フロントカメラとの切り替え、などがなんも実装しなくてもついてくるのがメリットです。とにかく簡単。

ただ致命的な問題が一点。

撮影した画像データは、MediaEvent.COMPLETEで飛んできたMediaEventのdataをLoader#loadFilePromiseで読み込んだ後、BitmapDataに落とし込んでごにょごにょするのですが、それがとにかく遅いです。

手元のiPhone4S(iOS6)でデバッグビルドで計測したところ、MediaEventを拾ってからLoader#loadFilePromiseがEvent.COMPLETEを返すまでに大体4秒近くかかってます。リリースビルドでもそんなに変わらない印象だったので、正直使い物にならない感じです。なんもいじらない状態での画像サイズが3264×2448あるので、Loaderに渡す前に縮小出来ればなんとかなりそうですが、なんとかならなそうです(そこまで調べてないですが)。

まあ、それに加えて、カメラ画面へのトランジション描写をカスタマイズできないとか、カメラ画面自体をカスタマイズできないとか、融通が効かないので、今自分が作っているアプリではこいつは使わないことに。

画像のロードの遅さはかなり致命的で、これ解決できないとそもそもこのクラス使い物にならないじゃん、ということを考えるとなんか抜け道がありそうな気がするんですけど、どうなんですかね。

2. flash.media.Camera

カメラからの画像をflash.media.Video(DisplayObject)に表示する方法です。
まあ、言ってしまえばそれだけなので、後は好き放題。フィルターをかけて、リアルタイムで画像処理をかけてもいいしカメラ画像の上にグリッドやメーターを表示させるでもいいし、カスタマイズ甲斐があります。最終的にはBitmapData#drawで転写すれば、CameraRollにも保存できます。

BitmapData#drawはかなり早いので、iPhone4Sの画面サイズくらいだと、デバッグビルドでも30ミリ秒くらい。これならサクサクですね。

ただしデメリットもあります。
・高解像度に弱い(高解像度サイズでVideoクラスつくっておいて、その上に画面サイズめいっぱいのBitmapクラス置いて縮小させつつ転写すれば実現できそうな気もしますが、多分めちゃ重。)

・ズームとか、フラッシュの有無とかが使えない

・シャッター音が出ない
所詮BitmapData#drawしてるだけなので、シャッター音とか当然出ません。一応Soundで出せますが、マナーモードにされると出ないし、どうなんでしょうね。AppStoreで、無音カメラ的なのって結構あるから、審査的にOKなんですかね。
もし駄目だったらどうしようもないですね。涙をふきましょう。

・フロントカメラの取り扱いがむかつく
Camera#namesで使用できるカメラの名称の配列が返却されます。
iPhone4Sだとこんなん
「背面側カメラ」「前面側カメラ」

Camera#getCameraは引数として、name:Stringを受け取れるのでついつい「camera.getCemera("前面側カメラ")」とやりたくなりますが、これだと駄目で、ここにはnamesで返却された配列のインデックス位置をStringで渡します。なので正解は「camera.getCamera("1")」。
まあ、ASDocにも書いてあるんですけど、なんなんですかね。


【結論】
まあ、実質的にCameraUIが使えないんで、Camera一択という気がしなくもないんですが、Cameraのシャッター音出ない問題が審査に引っかかるとしたらこっちも駄目なわけで、そうなるとどうなんだAIR for iOSというわけで、やっぱり結論としては、マルチプラットフォームとかの謳い文句なんかに頼るな、というお話になります。

ソーシャルゲームを1人で作る肝、伝授します!@ヒカリエ に行ってきた

Wuah-倭-ワー-Rock'N'Roll&Extasy
企画、実装、デザイン、運営全て一人で行ってソーシャルゲームをつくっている田中一広さんという方の講演に行ってきました。

要塞ビル、ヒカリエの上のほうでやっていたのですが、もうほんとヒカリエとか迷宮。ヒカリとか、リエとか可愛らしい名前の割に、中身はほんとじゃじゃ馬です。

そんことはどうでもいいことです。

一人でやっていく上で意識している点など、色々と興味深い内容でした。

以下メモ。

###

プラットフォーム選び

やっぱり集客がメインなので、GREE、モバゲーがメイン。法人作らないで個人でやるなら現状はGREE。なんかアダルト向けだとDMMとかあるらしいです。アダルトなソーシャルゲームなんてあるんですね。相性は良さそうですけど。

サーバー

2万ユーザーくらいを想定しているなら、スペック結構低いマシンでも1台でいけるとのこと(内容にもよるんでしょうけど)。むしろ人が増えすぎるとサーバー台数を増やさないといけなくなって、サーバー費用が増えるので困るらしい。なので、あんまり人が増えすぎないように、でも確実にユーザー数を確保するためにニッチな分野を狙っているそうです。1台構成で障害とか起きたときにどうするのかは不明。

開発

画像処理はPHPのGDライブラリを使っているらしい。imagemagickより早いとか。今度見てみよう。swfの動的生成はIO_SWFを使用。ソーシャルゲームでの差別化のポイントは、Flashとグラフィックらしいです。
あと、ソーシャルゲームは大体の基本的な仕組みは同じなので、ちゃんと設計して共通化していけば1人で多数プロジェクトまわすことも可能とのこと。

デザイン

素材集使ったり、背景使い回したり。ただ、メインのキャラクターとかに関してはちゃんと1から3DCGをモデリングしたりするらしいです。1人なのでかける時間を選んで、力を抜くとこは抜いて、集中すべきとこに集中していくと。

雑感

「1人で開発していくために一番重要なことは精神力」というのが心に残りました。

###

あと、そういえば僕、ソーシャルゲームとか「ぐんまのやぼう」くらいしかやったことないんですけど試しにやるとしたら何がいいんですかね。

curlで疎通確認自動化(のための便利なオプション)

WebAPIの疎通確認とかを自動化したいなー、とか思ったとき、勿論ちゃんと回帰テスト書いて自動化しましょうよ、ってのは置いといて、簡単なものならcurlとかでやっちゃうのが便利です。Jenkinsなんてすごいcronに過ぎない的感覚によれば、cronでも別に構わないわけです。

ただ、man curlをやれば分かる通り、curlはバカみたいにオプションが多いです。正直見るのがめんどくさいので、疎通確認の自動化に向けて便利なオプションをメモ。あくまで簡単な疎通確認程度なので、HTTPのステータスコードとレスポンス時間くらい分かればまあいいやくらいのものです。

$ curl http://sat.hateblo.jp/

とりあえず、基本。
レスポンス内容をそのまま出します。

$ curl http://sat.hateblo.jp/ -w "%{http_code} %{time_total}"

「-w」オプションで出力内容を加工できるのですが、組み込み変数としてhttp_codeでHTTPステータスコード、time_totalでレスポンス時間を出力できます。これだとレスポンス内容自体も出力されてしまうので、http_codeの前に区切り文字を適当に置いて、| awk -F "区切り文字" '{print $2;}'とかやればHTTPステータスコードとレスポンス時間だけ取れてスッキリします。

と、これで終わりでもいいのですが現実には色々と壁があります。まずはhttpsに接続する際。SSL証明書の警告なんかが出るとこだと上記のだと通りません。

$ curl --insecure http://sat.hateblo.jp/ -w "%{http_code} %{time_total}"

「--insecure」で、SSL証明書の警告を無視します。さて、Basic認証がかかってるなんてこともあります。

$ curl --insecure -u ユーザー名:パスワード http://sat.hateblo.jp/ -w "%{http_code} %{time_total}"

「-u ユーザー名:パスワード」でBasic認証もさくっと通します。しかし、まだ敵はいます。Cookie使ってログインしとかないと使えないAPIなんかの場合は、最初にログインしても、2回目以降に認証情報が引き継がれません。

$ curl --insecure -u ユーザー名:パスワード -c cookie.txt http://sat.hateblo.jp/ -w "%{http_code} %{time_total}"

「-c ファイル名」でCookieを保存できます。これでログインしときます。

$ curl --insecure -u ユーザー名:パスワード -b cookie.txt http://sat.hateblo.jp/ -w "%{http_code} %{time_total}"

「-b ファイル名」でCookieを送信できます。ログイン以降のリクエスト時にはこっちを使うようにすればOKです。

$ curl --insecure -u ユーザー名:パスワード -b cookie.txt -d キー=値 http://sat.hateblo.jp/ -w "%{http_code} %{time_total}"

「-d キー=値」でPOSTデータを送信できます。これでようやく一通りのリクエストを試すことが出来そうです。ですが、これだとサーバーが落ちてた際などにコマンドの実行が終わりません。

$ curl -m 30 --insecure -u ユーザー名:パスワード -b cookie.txt -d キー=値 http://sat.hateblo.jp/ -w "%{http_code} %{time_total}"

「-m 秒数」でタイムアウト時間を秒で設定できます。これで一安心です。

あとは配列つくって確認したいAPIを順次実行するようにしたり、AWKでフォーマット整えたり、結果をファイルに出力したり、結果見てアラート出したり、定期実行するようにすれば完成です。


めんどくさいですよね。

Haxeで列挙型。ついでにswf出力。

というわけで今日はHaxeで列挙型を触ってみます。
ActionScriptは素晴らしい言語ですが、enumが無いのでプンプンしてしまいますね。
腹いせに今回はswfを出力してみます。Test.hxに以下を記述します。

enum Animal {
    Dog;
    Cat;
    Human(salary:Int, pet:Animal);
}

class Test {
    static function main() {
        var cat:Animal = Animal.Cat;
        var human:Animal = Animal.Human(100, Animal.Dog);
    }

    static function bow(animal:Animal):String {
        return switch (animal) {
            case Dog : "wow";
            case Cat : "nyaa";
        }
    }
}


Haxeの列挙型は、パラメーターつきのコンストラクタも定義できます。
ここでは、salaryは人間だけに与えられた業となります。
再帰的にAnimal自体も引数に取れます。
あとは、switch文で、それぞれごとに吠えさせてみます。

build.hxmlを以下のように書いておきます。

-swf test.swf
-main Test


で、ビルド。

 $ haxe build.hxml 
 ./Test.hx:16: lines 16-19 : Some constructors are not matched : Human


Humanのcaseを定義していないので怒られました。いいところを怒ってくれます。
これは地味に便利です。

enum Animal {
    Dog;
    Cat;
    Human(salary:Int, pet:Animal);
}

class Test {
    static function main() {
        var cat:Animal = Animal.Cat;
        var human:Animal = Animal.Human(100, Animal.Dog);
        var richHuman:Animal = Animal.Human(10000, human);
        trace(bow(cat));
        trace(bow(human));
        trace(bow(richHuman));
    }

    static function bow(animal:Animal):String {
        return switch (animal) {
            case Dog : "wow";
            case Cat : "nyaa";
            case Human(salary,pet) : salary + ">>> pet bow:" + bow(pet);
        }
    }
}


Humanのcaseを追加。Humanは自身のsalaryを吠えます。ついでに人間をペットにした人間も定義してみます。
Intは""と連結することでStringになります。salaryだけを出力したい場合は、"" + salary、とすればOK。
これでもう一回ビルドすると、今度は成功し、test.swfが出力されます。
そのswfを実行すると

f:id:sat:20120905001742p:plain


こんな感じです。

MacにHaxe入れてHello Worldしてみた

いい加減、流行にも乗らないとということで、Haxeを触ってみることにします。名前的には、HexEditとかで書けたりするんじゃないですかね。ドキドキですね。

まずはhomebrewでHaxeをインストールします。

$ brew install haxe


終わったら指示通り、.bash_profileに以下を記述します

# /usr/local/Cellar/haxe/2.09 の部分は環境に合わせて
export HAXE_LIBRARY_PATH="/usr/local/Cellar/haxe/2.09/share/haxe/std"


その後、HaxeのVMであるNekoをインストールする前に、Nekoのフォーミュラを書き換えておきます。方法は下記のページを参考にさせていただきました。
Haxeをhomebrewでインストールする方法 - still deeper

$ brew install neko


haxeのパッケージ管理はhaxelibで行われるらしい
http://haxe.org/com/haxelib

$ sudo mkdir -p /usr/lib/haxe/lib
$ sudo chown -R ユーザー:グループ /usr/lib/haxe
$ haxelib setup


Pathを聞かれるので、/usr/lib/haxe/libを指定(デフォルト)
とりあえず試しになんか入れてみます。

$ haxelib search html
nme
pv3d_haxe
DomReady
jsmin
jeash
html5
modernizr
haxe-html
divtastic
HtmlParser
tink_markup
bindable
flambe
sdl
croxit-1
15 libraries found

$ haxelib install html5
$ haxelib list
html5: [1.1]


では早速、Hello Worldを書いてみます。今回はJavaScriptで吐いてみようと思います。
まずは、Test.hxを書きます。

class Test {
    static function main() {
        trace("Hello World!");
    }
}


次にcompile.hxmlをTest.hxと同じディレクトリに作成。

-js test.js
-main Test


そんでもって、コンパイルします。

$ haxe compile.hxml


あとは、このtrace文を吐き出すhtmlを作ります。

<html>
    <body>
        <div id="haxe:trace" />
        <script src="test.js"></script>
    </body>
</html>


これで完成です。吐き出される文字列には、Hello World! に加えて、trace文を書いたファイル名と行数も吐き出されてますね。生成されたtest.jsは行数にして310行。軽いアプリを作ってどの程度の行数になるかは気になります。

まあ、Hello Worldじゃ何も分かんないですよね。明日以降ちょこちょこ触っていこうと思います。Javaコードなんか、どんなの吐き出すか気になりますね。

AWKでQuine

最近、プログラミング言語AWKを買ったので、AWKのお勉強。

 

とりあえずQuineを書いてみます。

Quineとは、自身のソースコードを出力するプログラムです。

 

ポイントはソースコード本文を変数に入れて、それを出力するようにすること。その際に本文中に登場するダブルクォートとかを上手いこと置換していくこととかですね。

他の言語だとevalを使うこともあるそうですが、awkには無いので、printfを使います。

 

BEGIN{s="BEGIN{s=%c%s%c;printf(s,34,s,34);};";printf(s,34,s,34);}

 

これをquine.awkに保存して

 

awk -f quine.awk

 

これで、ソースコード本文が出力されます。

ですが、折角awkを使ってるんだから、コマンドラインから一行野郎で出力したいですよね。

コマンドラインからawkを書く場合は、コード中でシングルクォートが使えないので、\047を使うことで出力します。

ちょっと書いてみました。

 

$ awk 'BEGIN{s="awk @BEGIN{s=%c%s%c;S=s;gsub(/@/,%c\\047%c,s);printf(s,34,S,34,34,34);}@";S=s;gsub(/@/, "\047",s);printf(s,34,S,34,34,34);}'
awk 'BEGIN{s="awk @BEGIN{s=%c%s%c;S=s;gsub(/@/,%c\047%c,s);printf(s,34,S,34,34,34);}@";S=s;gsub(/'/,"\047",s);printf(s,34,S,34,34,34);}'

 

失敗! 

シングルクォートの変換が上手くいかないったらないです。とりあえず今日は時間が来たのでこの辺までで終了。また今度やります。また今度やりますとなったときのやらない率ったらないですよね。