USB経由でapkをアップデートする

AIRでアプリを開発していて、apkを端末にインストールする際には
adt -installAppを使用しているけど、
既にアプリがインストールされている場合に一度、-uninstallAppで削除しなければならない。
しかし、この場合SharedObjectなどのアプリケーションデータも削除されてしまう。


adtではアプリをアップデートすることはできないのでadbを使う。
adb installにrオプションをつけるとアップデートすることができる。

adb install -r AppName.apk

Starlingの表示オブジェクトのクラス継承関係

Starlingの表示オブジェクトのクラスの継承関係を図にまとめてみました。

(2012.7.2 図が間違っていたので修正しました)


すべてのプロパティやメソッドを書いてしまうと見づらくなってしまうので、
ネイティブの表示オブジェクトにはないプロパティやメソッドのうち、
重要そうなものや自分が忘れがちなものだけ書いてあります。

Starlingでモバイル向けのAIRアプリケーションを開発する際のマルチ解像度対応について、まとめてみた。

基本的には、
http://wiki.starling-framework.org/manual/multi-resolution_development
の内容を参考にしています。

描画範囲の設定

Starlingでは必ず描画がされる範囲をします。
コンストラクタ引数もしくはviewPortで設定。

starling = new Starling(Game, stage, new Rectangle(0, 0, 320, 480));
starling.viewPort = new Rectangle(0, 0, 320, 480);

iPhoneでのマルチ解像度対応

画面サイズの調整

iPhoneの場合、解像度は2種類のみ。
3GSは320x480、4・4Sは640x960で、縦横比は同じなので対応は簡単。
下記のコードでは、ステージサイズを320x480として扱い、
実際の描画は画面全体に合ったサイズで拡大縮小して描画されます。

//フルスクリーン時の縦横幅を取得
var screenWidth:int  = stage.fullScreenWidth;
var screenHeight:int = stage.fullScreenHeight;

//描画範囲を画面全体に指定
var viewPort:Rectangle = new Rectangle(0, 0, screenWidth, screenHeight)
starling = new Starling(Game, stage, viewPort);

//プログラム上で扱うステージのサイズを指定
starling.stage.stageWidth  = 320;
starling.stage.stageHeight = 480;
画面解像度に合わせた画像を使用する

ステージサイズを320x480として開発した場合に、上記コードのようにただ画面を引き延ばしただけでは、iPhone4では画像がぼやけます。


iPhone3GSの場合】


【iPhone4の場合】

これを避けるためには、画面解像度によって使用する画像を切り替える必要があります。
ScaleFactor(スケール係数?)の値によって使用する画像を切り替えます。

var scale:Number = starling.contentScaleFactor;
var bmp:Bitmap;
if(scale == 1) {
    //bmp = 320x480用の画像を読み込み
} else if(scale <= 2) {
    //bmp = 640x960用の画像を読み込み
}
var texture:Texture = Texture.fromBitmap(bmp, true, false, scale);

様々な解像度への対応

iPhoneのみならば上記対応で問題ないが、
ステージサイズの縦横比と画面の縦横比が異なる場合に問題が発生する。
なので以下のように、縦横比を維持しつつ画面にフィットするように拡縮させる。

const STAGE_WIDTH:uint = 320;
const STAGE_HEIGHT:uint = 480;
		
// フルスクリーンの際の縦横幅を取得
var screenWidth:int  = stage.fullScreenWidth;
var screenHeight:int = stage.fullScreenHeight;
			
// ゲーム画面が縦横比を維持しつつ、スクリーンにフィットするようにViewportの縦横幅を算出する
var viewport:Rectangle = new Rectangle();
var stage_aspect_ratio:Number = STAGE_HEIGHT / STAGE_WIDTH;
var screen_aspect_ration:Number = screenHeight / screenWidth;
			
if(stage_aspect_ratio < screen_aspect_ration) {
	//ステージの縦横比に比べると縦長
	viewport.width = screenWidth;
	viewport.height = int( (screenWidth / STAGE_WIDTH) * STAGE_HEIGHT );
} else if(stage_aspect_ratio > screen_aspect_ration) {
	//ステージの縦横比に比べると横長
	viewport.height = screenHeight;
	viewport.width = int( (screenHeight / STAGE_HEIGHT) * STAGE_WIDTH );
} else {
	//ステージの縦横比と同じ
	viewport.width = screenWidth;
	viewport.height = screenHeight;
}
			
//ゲーム画面がセンタリングされるように位置調整
viewport.x = int( (screenWidth - viewport.width) / 2);
viewport.y = int( (screenHeight - viewport.height) / 2);
			
			
var st:Starling = new Starling(MainSprite, stage, viewport);
st.stage.stageWidth  = STAGE_WIDTH;
st.stage.stageHeight = STAGE_HEIGHT;
st.start();

ふにゃもらけのきぐるみ作りました

弊社が展開するキャラクターふにゃもらけのきぐるみを作りました。


ふにゃもらけは11年の長い歴史をもつキャラクターですが、今までゲーム以外の展開をあまり行ってきませんでした。
ただピースとしては、ふにゃもらけをゲームだけで終わるキャラクターではなく、キティちゃんやリラックマのように幅広く世間に知られるキャラクターにしていきたいと思っています。
今まではゲーム開発に手いっぱいの状態でしたが、今後はゲーム以外の展開も進めていくこととなりました。
まずはその象徴として、きぐるみを作ることにしました。


きぐるみを作るにあたっては、もっとも重視したことは再現性です。

というのも、昨年発売した携帯ストラップはファンの方から「こんなのふにゃもらけじゃない!」とか「自分で作ったほうがもっといい物が作れる」といった多くの不満の声が寄せられました。
ファンの期待を裏切らないためにも、クオリティの高いきぐるみを作りたいと考えてました。
ただ自分たちは立体については素人であり、自分たちで作ることは当然できないので、安心して頼むことができる製作会社を探したところ、ピア21という会社にお願いすることになりました。
http://www.pier21.co.jp/aircostume/


きぐるみ製作会社はたくさんあるのですが、正直なところ、素人にはその良し悪しはなかなかわかりません。ただ、そんな中でピア21は他社に比べて圧倒的に信頼できる会社だと感じました。


その要因としては、
・発注前から打ち合わせ可能で、疑問に答えてもらうことができる
・こちらのニーズを把握し、それに対して最適な提案をしてくれる
・打ち合わせ時に、ふにゃに近そうな形のきぐるみを実際に持ってきてくれた
・きぐるみを作る前に粘土で原型を作成。その原型を実際に見て、こちらの要望を伝えると、原型師の方がその場で修正をしてくれる
・運用がしやすいように考えられている
・アフターケアもしっかりしている
といった点が挙げられます。


きぐるみの素人である我々の様々な疑問点に丁寧に答え頂き、おぼろげだった完成像をイメージさせてくれました。なおかつ完成後の運用についても考慮されていることも他社にはない大きなポイントでした。(もちろん他社も考慮はしているのでしょうが、こちらにはそれが伝わらなかったので)


こうしてピア21さんにお願いをしたのが4月末。
そして先日 6/15、完成したきぐるみがいよいよ会社に届きました。


そして、その翌日6/16は開発バトル合宿の罰ゲームとしてティッシュくばりを実施する日。
ちょうどいいタイミングなので、きぐるみのお披露目をしました。

(ファンの方が撮影してくれた動画です)


きぐるみが登場することは事前に告知していなかったのですが、
ファンの方が15人ぐらい遊びにきてくれて感激しました!
だって、ただティッシュを配るだけですよ。
なのに こんなに人が集まるとは思っていませんでした。


せっかく遊びに来てくれても、ティッシュをあげるだけじゃ心苦しいと思っていましたが、きぐるみの登場にみんな喜んでくれたようで幸いでした。初お披露目は大成功だったと思います。


僕にとっては、自分たちのキャラでファンの方々が笑顔になっているところを見れたこと、そして自分がそうした光景を見て嬉しいと感じることがが、何よりの収穫でした。

誕生日プレゼントにStage3D(Starling)を使ってスマホアプリを作ってみた


6月に誕生日をむかえる弊社スタッフ2人の誕生日プレゼントにスマホ用のゲームを作りました。

経緯

5月の僕の誕生日に、スタッフがプチコンmkIIを使って、DSで動作する「よちよち仮面の挑戦状」というゲームを作ってくれました。

僕が好きな8bitっぽいレトロな雰囲気が漂うアクションゲームで、主人公キャラは弊社キャラクターのふにゃもらけ。そして、内輪ネタがふんだんに盛り込まれている敵キャラの数々。


忙しい合間をぬって作ってくれたこともあり、33年間 生きてきて今までもらった誕生日プレゼントの中でも、一番うれしいプレゼントでした。


その「よちよち仮面の挑戦状」の開発において中核を担ったプログラマの誕生日が6月。何をプレゼントするか悩んだ結果、ゲームのお返しはゲームしかないと思い、「よちよち仮面の挑戦状」をスマホアプリに移植することにしました。

なんでAIR

AIRの開発に慣れているので
AndroidiPhone両対応できるので

なんでStage3D?

プチコン版が60fps出てたのに、スマホ版がそれを下回ると悲しいので
・Stage3Dを使ったことなかったので、いい機会だしさわってみたかった

ゲームについて






基本的にはプチコン版をベースに、若干の追加要素を加えてます。
プレイヤーキャラに誕生日をむかえる2人のスタッフを選べたり、敵がプチコン版より派手な攻撃をしてきたりします。

アプリのダウンロード

Android版は以下からダウンロードできます。たぶん設定で提供元不明アプリを許可してないとインストールできないです。
http://bit.ly/MeyWWL

操作方法は、画面の左半分を押していると左へ移動、右半分を押していると右へ移動。
上へフリックでジャンプ、下へフリックで下降します。

ソースコード

粗末なコードですが、以下で公開してます
https://github.com/funyamora/Yotiyoti



以下、感想とか技術的なメモとか

開発期間

5日間(Starlingの勉強時間込みで)
1日はがっつり、あとの4日は2〜3時間程度。

開発環境

Windows7 FlashBuilder4.6 AIR3.2 Starling1.1

Starlingの感想

・パフォーマンスがよい。複数の端末で60fpsでの動作を確認
・従来の表示リストと同じ感覚で使えるので学習コストが低い
・アニメーションをすべてコードで書かなきゃいけないのが手間かも。今までだったら、ちょっとした演出のアニメなどにはswfを作ってそれを表示させるだけですんだけど、すべてコードにするのはめんどい。かといって、アニメをビットマップにすると容量がかさむ。
Windowsだと開発が大変そう。パーティクルエディターもビットマップフォントの書き出しツールも本格的なものがMacにしかない。ANEのこととか、Androidのドライバを何回もインストールすることとか考えたら、Macに移行すべきかも。

Starlingを勉強するにあたって、見たサイト

http://f-site.org/articles/2012/01/25170958.html
わかりやすく、Starlingの概要をつかめるので最初に見ておくべき


http://www.himco.jp/articles/pdf/IntroducingStarling.pdf
Introducing Starlingの日本語訳


http://doc.starling-framework.org/core/
APIリファレンス。かなりあっさりしている印象


http://wiki.starling-framework.org/
http://forum.starling-framework.org/
まだあまり見てないけど、公式のwikiとforum。

各端末の画面サイズに合わせて、ゲーム画面を拡大縮小させる方法

かなり需要がありそうなのですが、情報があまり見当たらず苦戦しました。

starling.core.Starling.viewPort
starling.display.Stage.stageWidth
starling.display.Stage.stageHeight

あたりをいじれば、うまくいきそうだけど、期待する結果が得られず。
時間がなかったので、ルートのSpriteのx,y,scaleX,scaleYを画面解像度に応じて調節するという力技で対応することに。


↓の記事とかが参考になりそうなので、今後読む。
http://wiki.starling-framework.org/manual/multi-resolution_development
http://forum.starling-framework.org/topic/app-resolutions
http://forum.starling-framework.org/topic/retina-display-support
http://forum.starling-framework.org/topic/contentscalefactor-mods

バイスコンテキストのロスト対策

実機で動作確認をしながら開発をしていると、ときどき"Fatal error:The application lost the device context!!"と表示されてアプリが起動できないことがありました。
Starlingオブジェクトの生成前に以下のように設定しておくとメモリ消費量は多くなるけど、上記エラーが発生しなくなりました。

Starling.handleLostContext = true;

http://forum.starling-framework.org/topic/new-feature-handling-a-lost-device-context

Bitmap font generatorの設定

・デフォルトでは、ファイル出力がTextとtgaになっているので、"Export Options"からXMLpngに変更する。
・White with alpha"や"Black with alpha"を設定してもpngが透過にならなかったので、Fireworksで開いて、透過に直して使用した。

パーティクルシステム

パーティクルは標準では使えず、拡張機能として用意されている。
swcにパッケージングされていないので、ソースコードを直接プロジェクトに配置する。
http://wiki.starling-framework.org/extensions/particlesystem

フルスクリーンにするとエミュレーター上での表示が乱れる

アプリケーション記述ファイルに

<fullScreen>true</fullScreen>

のようにフルスクリーン設定をすると、実機では問題ないが、
エミュレーター上での原点の表示位置がずれる。
Starlingの不具合ではなく、AIRの不具合っぽい。
http://forum.starling-framework.org/topic/stage3d-positioning-issue-with-air-32-starling-nd2d#post-3021

実機での開発時にときどき発生するエラー

実機でアプリ起動時にときどき発生するエラーにいくつか遭遇。
リリースビルドでは今のところ発生していない。
・デバイスコンテキストのロストと同じような表示で、"The application is not correctly embedded(wrong wmode value)"と表示される。もちろんrenderModeはdirectなのだけど…
・テクスチャの作成に失敗する

Error: Error #3684: Texture creation failed. Internal error.
	at flash.display3D::Context3D/createTexture()
	at starling.textures::Texture$/fromBitmapData()[/Users/redge/Development/starling/starling/src/starling/textures/Texture.as:130]
	at starling.textures::Texture$/fromBitmap()[/Users/redge/Development/starling/starling/src/starling/textures/Texture.as:111]

AIRアプリでカスタムURIスキームを設定する方法

カスタムURIスキームとは?

URIスキームとは、URI(URL)の先頭の"http"や"ftp"、"mailto"などのこと。
"http"ならWebへのアクセス、"ftp"なFTPでのファイル送受信、"mailto"ならメール送信を行うことを示しています。
iOSAndroidではURIスキームをアプリごと独自に定義することができ、これを使用することで

  • ブラウザからのアプリを起動
  • アプリからの連携

が行うことができます。

たとえば、iPhoneTwitterの公式アプリをインストールされている状態で

twitter://mentions

とブラウザのアドレスバーに入力すると、Twitterのアプリが起動し「みんなの反応」が開きます。

AIRでの設定方法

AIRで作っているアプリに、カスタムURIスキームを設定する場合、アプリケーション記述ファイルに記述することで設定ができます。
AndroidiOSそれぞれ別々に定義を記述する必要があります。

Androidの場合

<android>
  <manifestAdditions>
    <![CDATA[
      <manifest>
        <application>
          <activity>
            <intent-filter>
              <action android:name="android.intent.action.MAIN"/>
              <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
            <intent-filter>
              <action android:name="android.intent.action.VIEW"/>
              <category android:name="android.intent.category.BROWSABLE"/>
              <category android:name="android.intent.category.DEFAULT"/>
              <data android:scheme="test-app"/>
            </intent-filter>
          </activity>
        </application>
      </manifest>
    ]]>
  </manifestAdditions>
</android>


iOSの場合

<iPhone>
      <InfoAdditions><![CDATA[
            <key>CFBundleURLTypes</key> 
            <array> 
                  <dict> 
                        <key>CFBundleURLSchemes</key> 
                        <array> 
                              <string>test-app</string> 
                        </array> 
                        <key>CFBundleURLName</key> 
                        <string>jp.co.piisu.test-app</string> 
                  </dict> 
            </array>
      ]]></InfoAdditions>
</iPhone>

以上で、

<a href="test-app://arg1=funya&arg2=kurage">アプリを起動</a>

のようなリンクをふんだ場合に、アプリが起動されるようになります。

パラメータ読み込み

NativeApplicationオブジェクトのinvokeイベントを通じて読み込むことができます。

var native_app:NativeApplication = NativeApplication.nativeApplication;
native_app.addEventListener(InvokeEvent.INVOKE, function(evt:InvokeEvent):void {
	//通常起動の場合もinvokeイベントが発生し、この場合argumentsのlengthは0なのでチェックを行う
	if(evt.arguments.length > 0) {
		trace(evt.arguments[0].toString());    // "test-app://arg1=funya&arg2=kurage" と出力
	}
});

注意

  • 他のアプリが同じ名前のスキームを登録していると、既存アプリが優先されてしまう
  • StageWebViewではカスタムURIスキームを使用してURLを開くことができない
  • AndroidのブラウザにカスタムURIスキームを直入力しても、アプリを起動できない

Amazon S3 Library for REST in Java使用メモ

mixiアプリなど画像置き場としてS3を使っていて、
更新のたびにCloudBerry Explorerでアップロードしてたけど、
さすがに面倒になってきたのでファイルを同期するためのツールを作成しました。
そのために、Amazon S3 Library for REST in Javaを使ってみたので防備録がわりにメモ。

AWSに接続

AWSAuthConnection conn = new AWSAuthConnection(awsAccessKeyId, awsSecretAccessKey);

バケットの作成/削除

//バケットが存在しなければ、バケットを作成する
if (!conn.checkBucketExists(bucketName)) {
    conn.createBucket(bucketName, AWSAuthConnection.LOCATION_DEFAULT, null);
}

//バケットを削除
conn.deleteBucket(bucketName, null)

バケット内のオブジェクト一覧を取得

//結果は [test.txt, funyatalk.jpg, help/, help/test.html, floor/desert.swf] のように返ってくる
List entries = conn.listBucket(bucketName, null, null, null, null).entries

オブジェクトを保存

//HTTPヘッダを指定してオブジェクトを保存
Map headers = new TreeMap();
headers.put("Content-Type", Arrays.asList(new String[] { "text/plain" }));
headers.put("Expires", Arrays.asList(new String[] { "Tue, 10 Dec 2019 13:43:40 GMT" }));
headers.put("Cache-Control", Arrays.asList(new String[] { "public, max-age=315360000" }));
conn.put(bucketName, keyName, object, headers).connection.getResponseMessage()

オブジェクトをコピー

Map updateMetadata = new TreeMap();
updateMetadata.put("metadata-key", Arrays.asList("this will be the metadata in the copied key"));
conn.copy( bucketName, copiedKeyName, bucketName, copiedKeyName, updateMetadata, null );

オブジェクトを削除

conn.delete(bucketName, keyName, null)

ACLを設定

//ACLはxmlを文字列として渡すことで設定する
conn.putACL(bucketName, keyName, xml, null);

ちなみに、すべてのユーザが読み込みできるようにするには、以下のようなXMLを指定する。

<?xml version=\"1.0\" encoding=\"UTF-8\"?>
   <AccessControlPolicy xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\">
       <Owner>
          <ID>XXXXXX</ID>
          <DisplayName>funya</DisplayName>
       </Owner>
   <AccessControlList>
   <Grant>
       <Grantee xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"CanonicalUser\">
           <ID>XXXXXX</ID>
           <DisplayName>funya</DisplayName>
       </Grantee>
       <Permission>FULL_CONTROL</Permission>
   </Grant>
   <Grant>
       <Grantee xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"Group\">
           <URI>http://acs.amazonaws.com/groups/global/AllUsers</URI>
       </Grantee>
       <Permission>READ</Permission>
   </Grant>
   </AccessControlList>
</AccessControlPolicy>

感想

Amazon S3 Library for REST in Javaはシンプルなのですぐに使えるけど、
機能も大してないので、ちょっと凝ったことがしたいのなら
JetS3tなどのライブラリを使ったほうが楽かも。
JetS3tなら、CloudFrontのエッジサーバのキャッシュをクリアしたりもできるっぽい。