himco.jpの[翻訳記事]ページに、Flash Player、AIR 3のStage3Dを強化するStarlingライブラリを紹介した原書の日本語訳を追加しました。全140ページ。Stage3Dは従来の表示リストのさらに下層に位置し、GPUに描画することで画面のレンダリングを飛躍的に向上させます。Starlingはこれを扱いやすくしたライブラリで、ゲームやモバイルデバイスでの利用が期待されます。

モバイルAndroidアプリケーションを作成するための基礎
himco.jpの[翻訳記事]ページに、Flash Player、AIR 3のStage3Dを強化するStarlingライブラリを紹介した原書の日本語訳を追加しました。全140ページ。Stage3Dは従来の表示リストのさらに下層に位置し、GPUに描画することで画面のレンダリングを飛躍的に向上させます。Starlingはこれを扱いやすくしたライブラリで、ゲームやモバイルデバイスでの利用が期待されます。

himco.jpの[翻訳記事]ページに、http://shop.oreilly.comから無料で入手できる、デスクトップとモバイル向けAIR 3の新機能を紹介した英語書籍の日本語訳をアップしました。大きなセールスポイントはStage3DとActionScript Native Extenstion(ANE)です。

AIRとは直接関係はありませんが、オライリー・ジャパンより、わたしが翻訳した「プログラミングAndroid」が発売されます。言語はJavaです。
http://www.oreilly.co.jp/books/9784873115351/

オライリー・ジャパンより、わたしが翻訳した「Flex 4.5によるAndroidアプリケーション開発」がEbookとして発売されます。
http://www.oreilly.co.jp/books/9784873115184/

「Adobe Flash CS5.5 で作るスマートフォンアプリ作成入門」という講座を担当します。
詳細はこちらです。http://m-school.biz/course/adobe/flash-cs5.5-smartphone.htm
AndroidとiOSアプリをFlash CS5.5で作成するための基本を学ぶ講座で、FlashとActionScript3.0を使った経験があれば、どなたでも参加できます。
具体的には以下の内容を予定しています。
・モバイルAIRの基本
・簡単なAndroidアプリの作成
・デバッグ方法
・AIR for Android設定パネルの使い方
・マルチタッチ
・加速度メータを使用するActionScript
・カメラとファイル操作を扱うActionScript
・マルチ画面に対応するための考え方
・縦横両用アプリに対応するためのテクニック
・モバイルAIRで利用できるMadComponentsの使い方
[2-20-6: Stage.orientationChangeイベントを使った縦横両用アプリケーション]の方法よりもっとコードが短く、手続きももっと簡単になる方法があります。
それはStageのresizeイベントを使った方法です。resizeイベントはStage.scaleModeプロパティがStageScaleMode.NO_SCALEに設定されたSWFファイルで、ステージサイズが変更されたときに発生します。この方法はAIRでもFlash Playerでも、またWindows、Mac、Androidでも使用できるシンプルな方法で、かつ汎用性があります。
この方法でも[AIR for Android設定]の[自動回転を有効にする]を選択します。これによりアプリケーション記述ファイルの
// 共通のセット
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
var titleBar:Title = new Title("タイトルバー");
titleBar.x = 0;
titleBar.y = 0;
var footer = new Footer("Aボタン","Bボタン");
footer.x = 0;
var buta:ButaMC = new ButaMC();
// 縦長のときのレイアウト
function setPortrait():void
{
trace("stageW :" + stage.stageWidth);
trace("stageH :" + stage.stageHeight);
titleBar.width = stage.stageWidth;
addChild(titleBar);
footer.width = stage.stageWidth;
footer.y = stage.stageHeight - footer.height;
addChild(footer);
buta.x = (stage.stageWidth / 2) - (buta.width / 2);
buta.y = (stage.stageHeight / 2) - (buta.height / 2);
addChild(buta);
}
// 横長のときのレイアウト
function setLandscape():void
{
trace("stageW :" + stage.stageWidth);
trace("stageH :" + stage.stageHeight);
titleBar.width = stage.stageWidth;
addChild(titleBar);
footer.width = stage.stageWidth;
footer.y = stage.stageHeight - footer.height;
addChild(footer);
buta.x = (stage.stageWidth / 2) - (buta.width / 2);
buta.y = (stage.stageHeight / 2) - (buta.height / 2);
addChild(buta);
}
stage.addEventListener(Event.RESIZE, onResizeLayout);
function onResizeLayout(evt:Event):void
{
trace("RESIZEイベント発生");
while (numChildren > 0)
{
removeChildAt(0);
}
if(stage.stageWidth > stage.stageHeight){
// 横長
trace("横長")
setLandscape();
}else{
// 縦長
trace("縦長")
setPortrait();
}
var aspect:String = stage.stageWidth >= stage.stageHeight ? StageAspectRatio.LANDSCAPE : StageAspectRatio.PORTRAIT;
trace(aspect);
}
理屈は簡単です。デバイスの向きが変わると、ステージの向きも自動的に変更され、縦から横、または横から縦に変わります。これはステージサイズの変更を意味しています。するとresizeイベントが発生し、リスナー関数が呼び出されます。リスナー関数ではステージの幅と高さを比べ、幅の方が大きい場合には横長用レイアウトの関数を呼び出し、そうでないときには縦長用レイアウト用の関数を呼び出します。
最後のコードは、ステージの幅と高さを調べ、今の画面を縦長にすべきか横長にすべきかを導く論理を1行で表した、覚えておいて損のないコードです。
var aspect:String = stage.stageWidth >= stage.stageHeight ? StageAspectRatio.LANDSCAPE : StageAspectRatio.PORTRAIT;
縦横両用アプリケーションを作成するには、[AIR for Android設定]の[自動回転を有効にする]を選択します。これによりアプリケーション記述ファイルの<autoOrients>の値がtrueになります。これはStage.autoOrientsをtrueに設定することと同じです。自動回転が有効になると、デバイスの向きによってステージの向きも自動的に変わるようになります。
[2-20-4:絶対配置]と[2-20-5:相対配置]の方法のもとづき、Stage.orientationChangeイベントを利用した縦横両用アプリケーションは次のように記述できます。
// 共通のセット
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
// ケビンホイトのコンポーネント
var titleBar:Title = new Title("タイトルバー");
// タイトルバーのxとy位置は変化しない
titleBar.x = 0;
titleBar.y = 0;
var footer = new Footer("Aボタン","Bボタン");
// フッターのxも変化しない
footer.x = 0;
var buta:ButaMC = new ButaMC();
if (Stage.supportsOrientationChange)
{
trace("デバイスの回転をサポートしている");
// デバイスの向きの変更に関するイベントリスナー
stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGE, onOrientationChange);
}
else
{
trace("デバイスの回転はサポートされない");
}
// 縦向きの場合に呼び出す
function setPortrait():void
{
trace("stageW :" + stage.stageWidth);
trace("stageH :" + stage.stageHeight);
// ステージの幅と高さはデバイスの向きによって変わるので、
// それに依存する相対要素は毎回設定する
titleBar.width = stage.stageWidth;
addChild(titleBar);
footer.width = stage.stageWidth;
footer.y = stage.stageHeight - footer.height;
addChild(footer);
buta.x = (stage.stageWidth / 2) - (buta.width / 2);
buta.y = (stage.stageHeight / 2) - (buta.height / 2);
addChild(buta);
}
// 横向きの場合に呼び出す
function setLandscape():void
{
trace("stageW :" + stage.stageWidth);
trace("stageH :" + stage.stageHeight);
// ステージの幅と高さはデバイスの向きによって変わるので、
// それに依存する相対要素は毎回設定する
titleBar.width = stage.stageWidth;
addChild(titleBar);
footer.width = stage.stageWidth;
footer.y = stage.stageHeight - footer.height;
addChild(footer);
buta.x = (stage.stageWidth / 2) - (buta.width / 2);
buta.y = (stage.stageHeight / 2) - (buta.height / 2);
addChild(buta);
}
// デバイスの向きが変わると呼び出される
function onOrientationChange(evt:StageOrientationEvent):void
{
trace("ORIENTATION_CHANGEイベント発生");
// すべての子をいったん表示リストから削除
while (numChildren > 0)
{
removeChildAt(0);
}
// デバイスの向きによって処理を分ける
switch (evt.afterOrientation)
{
case StageOrientation.DEFAULT :
setPortrait();
break;
case StageOrientation.ROTATED_RIGHT :
setLandscape();
break;
case StageOrientation.ROTATED_LEFT :
setLandscape();
break;
case StageOrientation.UPSIDE_DOWN :
setPortrait();
break;
}
}
// Stage.orientationChangeイベントは変更があるまで発生しないので、
// デバイスの向きに応じて最初に一度だけ実行する
switch (stage.deviceOrientation)
{
case StageOrientation.DEFAULT :
setPortrait();
trace("縦向き");
break;
case StageOrientation.ROTATED_RIGHT :
setLandscape();
trace("横向き");
break;
case StageOrientation.ROTATED_LEFT :
setLandscape();
trace("横向き");
break;
case StageOrientation.UPSIDE_DOWN :
setPortrait();
trace("縦向き");
break;
case StageOrientation.UNKNOWN :
setPortrait();
trace("縦向き");
break;
}
下図は上記コードの実行画面です。
ステージの向きの変更イベントの監視は合理的に思えますが、残念なことに変更があって初めて機能するので、アプリケーションの最初の画面を手動で作成する必要があります。それを行っているのがコード最後のswitchステートメントです。
なおActionScriptリファレンスのStageクラスにはorientationという、ステージの現在の方向を表すプロパティがあり、これはAIR 2.6以降で使用できると書かれています(以前はAIR2.5では不推奨と書かれていました)。switchステートメントで使っているdeviceOrientationはアプリケーションの最初の起動時などでunknownになる場合があり、そのため上記コードではUNKNOWNのときは強制的に縦長にしています。しかしorientationはステージ自体の向きだと書かれており、アプリケーションの起動時でも利用できるだろうと推察できるので、AIR 2.6ではdeviceOrientationの代わりに使用できるかもしれません。
デバイスには向きがあります。これはStage.deviceOrientationプロパティで求めることができます。これはモバイルデバイスでのみサポートされrtプロパティで、デバイスが縦に立っている状態をデフォルトとし、左を向いた状態、右を向いた状態、逆立ちした状態を返します。[起動時の縦横比]を横長モードに設定したアプリケーションでも結果は変わりません。
deviceOrientationの値は、デバイスの加速度メータを元に決められるので、デバイスの起動時やデバイスが水平に置かれているときにはunknownになる場合があります。またスライド式のハードウェアキーボードを持つデバイスでは、キーボードが開いているときには必ずrotatedLeftになります。
デバイスの向きの変更に起因するステージの自動的な向きの変更は、StageのorientationChangeイベントに関するイベントリスナーを設定することで感知できます。
stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGE, onOrientationChange);
リスナー関数に送られてくるStageOrientationEventオブジェクトは、デバイスの以前の方向を示すbeforeOrientationと、デバイスの新しい方向を示すafterOrientationプロパティを持っています。このafterOrientationプロパティの値を調べることで、デバイスの新しい向きに応じたステージ要素の処理を行うことができます。
次のコードはデバイスの向きの変更を監視し、変わったときにStageOrientationクラスの定数を表す文字をテキストフィールドに表示します。Galaxy Tabではどの向きの変更も示されましたが、Nexus Oneでは逆向きの”UPSIDE_DOWN”は示されませんでした。
info_txt.text = "";
// アプリケーションがステージの向き、デバイスの向きの変更をサポートしているかどうか。
if (Stage.supportsOrientationChange)
{
trace("デバイスの回転をサポートしている");
stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGE, onOrientationChange);
}
else
{
trace("デバイスの回転はサポートされない");
}
function onOrientationChange(evt:StageOrientationEvent):void {
log(evt.beforeOrientation + " から " + evt.afterOrientation + "に変わった");
switch (evt.afterOrientation) {
case StageOrientation.DEFAULT:
log("DEFAULT");
break;
case StageOrientation.ROTATED_RIGHT:
log("ROTATED_RIGHT");
break;
case StageOrientation.ROTATED_LEFT:
log("ROTATED_LEFT");
break;
case StageOrientation.UPSIDE_DOWN:
log("UPSIDE_DOWN");
break;
case StageOrientation.UNKNOWN:
log("UNKNOWN");
break;
}
}
function log(txt:String):void
{
info_txt.appendText( txt + "\n");
}
ActionScriptにはFlash PlayerやAIRランタイムのステージの拡大縮小方法を決めることのできる、FlashユーザーにはおなじみのStageScaleModeがあります。これは表示オブジェクトのstageプロパティのscaleModeに、StageScaleModeクラスの定数を割り当てることで行います。
stage.scaleMode = StageScaleMode.NO_SCALE;
StageScaleModeクラスの定数には次のものがあります。
(各定数の下の図は左が変更前、真ん中がマウスで右方向に拡大したときの、右がマウスで左下方向に拡大したときのFlash Playerのウィンドウを示しています)
・StageScaleMode.SHOW_ALL:
アプリケーション全体がその縦横比(アスペクト比)を維持したまま歪まずに、ステージ内に収まるように拡大縮小される。ステージからはみ出ることはないが、上下左右に隙間が生まれる。境界枠が表示されることがある。デフォルトの設定。
StageScaleMode.NO_BORDER:
アプリケーションがその縦横比を維持したまま歪まずに、ステージ内側に収まるように拡大縮小される。上下左右に隙間は生まれないが、ステージからはみ出た分はトリミングされる。境界枠は表示されない。
StageScaleMode.EXACT_FIT:
アプリケーションとステージが一致するように拡大縮小される。アスペクト比は維持されない。
StageScaleMode.NO_SCALE:
アプリケーションのサイズが固定され、拡大縮小されない。つまりステージからはみ出ることがある。
アプリケーションを縦長と横長両対応にする場合、拡大縮小が発生するとレイアウトによっては残念な結果に終わる可能性があります。またアプリケーションの縦横比が維持されないのもおそらく好ましくありません。
これらの定数の中でモバイルアプリケーションに適したものは、ステージサイズが変わろうとも自分のサイズを変えない頑固一徹のNO_SCALEです。デバイスが縦向きから横、横向きから縦に変わったタイミングはステージのresizeイベントの発生で検出できますが、これはNO_SCALEに設定したときだけなので、resizeイベントでデバイスの向きの変更を見極めようとするときには、NO_SCALEに設定する必要があります。
ただしNO_SCALEは自分からは何も変えてくれないので、ステージ要素をプログラミングで配置することになります。
ステージのscaleModeをStageScaleMode.NO_SCALEに設定したら、ステージの基点を定めます。通常はステージの左上隅を指定します。これによりステージの左上隅が固定され、ステージが拡大縮小しなくなります。
stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_LEFT;
この2行はまた、複数の画面サイズに対応するアプリケーションを作成するときにも必要になります。
スマートフォンやタブレットなどモバイルデバイスの中には、デバイスを横にすると内容を横長に表示し、デバイスを立てると内容を縦長に表示するものがあります。下図はNexus OneでGmailアプリケーションを起動させ、デバイスを縦にしたとき(左図)と横にしたとき(右図)の画面です。
アプリケーションには画面が縦長の方が向いているもの、横長の方が向いているもの、どちらでも構わないものがあります。たとえば「Angry Birds」は弾を右方向に飛ばす物理アクションゲームなので横向きだけで、縦向きには対応していません。
AIR for Androidでアプリケーションを縦長だけで表示したい場合には、アプリケーションのステージサイズを縦長(480 x 800など)で作成し、AIR for Androidの設定パネルにある[起動時の縦横比]で縦長モードを選びます。縦長モードを選ぶことで、アプリケーション記述ファイルの<aspectRatio>タグの値がportraitに設定され、アプリケーションはつねに縦長で表示されます。
<aspectRatio>portrait</aspectRatio>
横長だけで表示したい場合には、ステージサイズを横長(800 x 480など)で作成して、[起動時の縦横比]で横長モードを選びます。これによってアプリケーション記述ファイルの<aspectRatio>タグの値がlandscapeに設定され、アプリケーションはつねに横長で表示されます。ちなみにportraitは肖像画(多くは縦長)、landscapeは風景画(多くは横長)の意味です。
<aspectRatio>landscape</aspectRatio>
また縦長横長両対応にしたい場合には、起動時のサイズでアプリケーションを作成し、それに合った[起動時の縦横比]を選んで、さらに設定パネルにある[自動回転を有効にする]チェックボックスを有効にします。これによりアプリケーション記述ファイルの<autoOrients>の値がtrueになります。自動回転が有効になると、デバイスの向きによってステージの向きも自動的に変わるようになります。たとえばデバイスを横にするとステージは横長に、デバイスを立てるとステージは縦長になります。これはStage.autoOrientsをtrueに設定することと同じです。
<autoOrients>true</autoOrients>
こういうといたって論理的に聞こえますが、アプリケーションを縦横両対応にするには面倒なプログラミングが必要です。以降ではその方法について見ていきます。