最近のハイライト(4月19日版)
最近のAir for iOSでのアプリ制作で困ったこと、考えたこと、どうやって解決したか、などをつらつらとメモっておく。(主にプログラム周り)
イベントを活用しようと思った
今までサーバーサイドのプログラムばかり書いていたせいかイベント駆動の概念が無かったが、これからは使ってみようと思った。
例えば『メニュー』クリックで『シーン』を切り替える処理を書く場合、
イベント使わない → メニュークラス から シーンクラス の シーンを切り替える() メソッドを呼ぶ。
イベント使う → メニュークラス から シーン切り替えのイベントを送出。シーンクラスでイベントを受け取り、シーンを切り替える。
こんな感じに書ける。
何が嬉しいかというと、メニュークラスとシーンクラスの依存を断ち切る事ができる。うん。嬉しい。使っていこう。
データの永続化どうしよう
これは書いているうちに長くなったので別エントリにまとめた。
→Air for iOSでのデータ保存について - わーくあうと!
リファレンス見やすくて嬉しい
あと ActionScript 3.0 のリファレンスガイドがとても見やすい。それぞれのクラスの継承関係から使用例、メソッドの詳細まで細かく書いてるので、リンクを辿って読んでいくと新しい発見もあって楽しい。
例えば上のほうで書いた、「イベントを使おう」と思ったきっかけも、
俺:「SharedObjectが継承しているEventDispatcherってなんだろう」
(リファレンス読む)
俺:「へーこんな事できるのかー面白そう。使ってみよう」
って経緯だった。リファレンス読もう。
その他AS3についてもろもろ
AS3ってこんな書き方できないのーとTwitterでつぶやいてみた
as3って func(a, c="hoge"); みたいな書き方できないのかな — にっくさん (@nickworks_net) 2013年4月15日
actionscriptって静的メソッドの継承できないのかな — にっくさん (@nickworks_net) 2013年4月16日
もちろん誰からもリプライは無かった。
以上、最近のハイライトでした。
Air for iOSでのデータ保存について
ゲームを作ってるとゲーム内の値(所持金、経験値など)をローカルに保存する必要が出てくる。
方法は色々あるが、『SharedObject』や『File』、『SQLite』なんかを使う方法があるらしい。
これは特に迷う事無くSharedObjectを使おうと決めた。理由はオブジェクトをそのまま保存できて自前でシリアライズする手間もなく、一番ラクそうだったから。
カスタムクラスの保存ができない・・・
そんなこんなで使ってみたがカスタムクラスの保存ができない。というかObject型で保存される。少し調べてみたら、『registerClassAlias』関数でカスタムクラスをあらかじめ登録することでカスタムクラスのインスタンスを保存できるようになるようだった。
registerClassAlias("HogeModel", HogeModel); SharedObject.getLocal(Defines.APP_SO_NAME_SPACE);
↑こんな感じでSharedObject.getLocalの前にカスタムクラスを登録する。
(これはこれで保存するカスタムクラスをいちいち書かないといけなくて面倒だけど)
勝手に保存される・・・
SharedObjectの動きを確認していると、SharedObject.flush()を読んでいなくても保存されていることに気がついた。どこかに.flush()するコード残ってたかなーと探してみたが見当たらない。
あれー、、と思いながらリファレンスのflushの説明を読んでみると
ローカルに永続化された共有オブジェクトを直ちにローカルファイルに書き込みます。このメソッドを使用しない場合、共有オブジェクトがファイルに書き込まれるのは、共有オブジェクトセッションの終了時となります。つまり、SWF ファイルが閉じられるとき、共有オブジェクトが参照されなくなってガベージコレクションされるとき、SharedObject.clear()
またはSharedObject.close()
が呼び出されたとき、のいずれかの時点です。
と書かれている。仕様でした。
これはこれで便利だが、自分が想定していない所で保存されると追い辛いバグを孕みそうな予感がしたので、自前の保存関数をかまして使うことで、自動で保存されないようにした。
コードで書くと下記のような感じ
public class AppData { public function AppData() { } /* * SharedObjectを取得. */ public static function getSharedObject():SharedObject { registerClassAlias("HogeModel", HogeModel); return SharedObject.getLocal(Defines.APP_SO_NAME_SPACE); } /* * (1)SharedObjectの保存領域部分を返す. */ private static var __tmp:Object; public static function getDataObject():Object { var so:SharedObject = AppData.getSharedObject(); if(__tmp == null){ __tmp = ObjectUtil.clone(so.data); } return __tmp; } /* * (2)保存. */ public static function saveAll():void { var so:SharedObject = AppData.getSharedObject(); //↓__tmpを入れなおしている. so.data = AppData.getDataObject(); so.flush(); } }
(1)で保存領域を複製した物(__tmp)を返し、(2)でso.dataに代入しなおして保存している。
これはまぁぶっちゃけ保存し忘れするかもしれないってのとトレードオフの関係なので、やるべきかどうかは個人の自由かなと思う。
以上。そんな感じ。
Air Debug Lancher(ADL)のプレビューが画面に収まらない件
Air for iOSでのアプリ開発、普段は Air Debug Lancher(ADL) でプレビューしてるんだけど
自分の環境ではディスプレイに収まらなかった。
↑下のほう収まってないんです。
ADLの表示倍率を変更できる設定がないか探したけど見当たらなかった。
iOSシュミレーターなら表示倍率が変えられるし、3GSの解像度で表示もできるからどうにかなるがパブリッシュに時間が掛かり過ぎて使ってられないし。 で、どうしたものかと。
Air Debug LauncherでプレビューしてもPCの画面に収まりきらなくて下のほうが確認できない・・・ — にっくさん (@nickworks_net) 2013年4月13日
考えた末に思いつきました。
縦横比を横長モードにして開発する技を思いついた — にっくさん (@nickworks_net) 2013年4月13日
Air for iOS設定を開いて、『起動時の縦横比』を『横長モード』にしてプレビューしたのがこれ↓
うーん、、まあ正しい対応かと言われると微妙だが、仕方ないのでとりあえずはこれでやってみる。
十分な容量がどうとかでiOS端末にipa送れない件
なんかAir for iOSでパブリッシュしてiPhoneにipa送るときに「デバイスエラー デバイスに十分な容量があるか確認してください。」とか言われた。
もちろん容量は余っている。
http://kuniakisuzuki.cocolog-nifty.com/blog/2012/09/flash-cs6air-fo.html
で、適当にググったら↑の記事を発見。どうやら.p12ファイルを使い回してると出る場合があるらしい。
確かにテストアプリを作った時から使い回して使ってるわ。ということでキーチェーンアクセスから.p12形式の証明書を作り直してパブリッシュした。
が、状況変わらず・・・
なんだろうなーと、Flashの再インストールとかしてみようかなーでもそれは面倒だなーと悩んだが、少し寝たら原因分かった。
アプリケーションIDが違ってた。しょうもない。
ということでアプリケーションIDを iOS Dev Center で設定したものに変更してパブリッシュしたら無事端末に送れた。
めでたしめでたし。
4月13日追記==========================
全然めでたく無かった。やっぱりおかしい。ちょっと作業してパブリッシュしたらまた同じ症状がでた。
アプリケーションIDも合ってる、.p12ファイルも合ってる、プロビジョニングファイルも合ってる。謎・・・
とりあえず出来上がったipaをiTunesから入れてみたら入った。
この問題を追うと時間かかりそう&解決できなさそうなので、しばらくはiTunesから実機に送ることにしよう。
Flash CS6での基本クラス
どうでもいいっちゃどうでもいいんだが・・・
挿入 → 新規シンボル
で、ActionScript用に書き出しにチェックを入れると『クラス』『基本クラス』を設定できるようだったので
・MovieClip を継承した BaseHoge を作成して、その後
・BaseHoge を継承した Hoge を作成した。で、ライブラリ内のHogeを右クリック→クラスを編集
で自動生成されたコードを編集しようとしたら
public class Hoge extends MovieClip
となっていて、「あれ?BaseHoge継承してなくね?」ってなった。
その後、ライブラリ内のHogeを右クリック→プロパティ から基本クラスを確認したら空欄になっていた。
せめてMovieClipだろ。空欄ってなんだよ・・・と思ったんだけどこれは自分の解釈や操作が何か間違ってるんだろうか。謎。
http://www.flash-jp.com/modules/newbb/viewtopic.php?topic_id=9923&forum=20
↑ここでも基本クラス名が消えるとかなんとか言われてるしFlash側のバグなのかな。
とりあえずは 『extends MovieClip』 を 『extends BaseHoge』 と手打ちで編集して使う方向でやってみる。
ActionScript3.0の条件付きコンパイル
ちょっと他の人のactionscriptソースを漁っていたら
CONFIG::DEBUG
と『::』が使われていた。条件によって処理を分けるような使われ方をしていたが、ちゃんとした読み方がわからず「ダブルコロン」とか「コロンコロン」で検索したけど中々見つからなかった。が、やっと判明した。
これはコンパイル定数というものらしい。普通にコード中のif文で処理を切り替えてもいいが、これを使って条件分岐することでコンパイル後のアプリにコードが残らない。メリットとしては逆コンパイルされてもその部分は見られないとかかな。
設定方法は、Flash CS6 の場合 ファイル → ActionScript設定 → 条件付きコンパイル設定タブ から設定できる。
それ以外のバージョンも設定方法は大きく変わらないと思う。
めでたしめでたし。