RetroWeb ~iPhoneとAndroidでハイブリッドゲームアプリ開発~

AIR for iOS+AndroidでSmartPhone Game ハイブリッドアプリ開発

最近作ったアプリ
100億本の抜け毛 100億匹のモナー DQ3闘技場アプリ モナーペット(進化)

毎日自動でPHPプログラムにPHPプログラムを書かせるようにしました。

PHP連想配列変数くらい、PHPに毎日自動で更新してもらうことにしましたw
デイリー過去ログランキングのリンクと、1位の名前の配列更新。

画面キャプチャと、役に立つか謎なプログラムはこんな感じです。includeするphpを自動で更新してます。自動イベント運用も夢じゃない!
f:id:hisashi_vc:20140508005035j:plain

include_once "rankerInfo.php";

$mod = filemtime("rankerInfo.php");
//print "最終更新日:".date("Y/m/d H:i",$mod);

$isYesterdayUpdate = date("d") != date("d", $mod);

//PHPファイルを更新する。
if($isYesterdayUpdate){
	function get_filename_arr($dir, $ext0){//$match) {
	    $filename_arr = array();
	    $dh = opendir($dir);
	    while(($filename = readdir($dh)) !== false) {
			$ext = substr($filename, strrpos($filename, '.') + 1);
	        if($ext === $ext0){
	            $filename_arr[] = $filename;
	        }
	    }
	    return $filename_arr;
	}

	$logNames = get_filename_arr(".", "log");

	$todayStr = date('y')."d".date('z').".log";
	$thisWeekStr = date('y')."x".date('W').".log";

	$dailyArrayStr = "";//14d122.log
	$weeklyArrayStr = "";//14x18.log

	for($i=0; $i < count($logNames); $i++){
		$fileName = $logNames[$i];
		if($todayStr !== $fileName && strpos($fileName, "d")){
			//ファイル名先頭から名前取得?
			//echo $fileName."@日間<br>";
			//ロード
			$fp = fopen($fileName, 'r');
			if ($fp){
			    if (flock($fp, LOCK_SH)){
					$rank1Name = fgets($fp);
					$rank1Name = substr($rank1Name, 0, strpos($rank1Name, "\t"));
			        flock($fp, LOCK_UN);
			    }else{
			        //print('ファイルロックに失敗しました');
			    }
			}
			fclose($fp);
			$dailyArrayStr = "'".str_replace(".log", "", $fileName)."'=>'".$rank1Name."',\n".$dailyArrayStr;

		}else if($thisWeekStr !== $fileName && strpos($fileName, "x")){
			//ファイル名先頭から名前取得?
			//echo $fileName."@週間<br>";
			//ロード
			$fp = fopen($fileName, 'r');
			if ($fp){
			    if (flock($fp, LOCK_SH)){
					$rank1Name = fgets($fp);
					$rank1Name = substr($rank1Name, 0, strpos($rank1Name, "\t"));
			        flock($fp, LOCK_UN);
			    }else{
			        //print('ファイルロックに失敗しました');
			    }
			}
			fclose($fp);
			$weeklyArrayStr = "'".str_replace(".log", "", $fileName)."'=>'".$rank1Name."',\n".$weeklyArrayStr;
		}
	}


	$phpTxt = "<?php\n".
		"\$dailyRank1Array = array(\n".
		$dailyArrayStr.//"	'14d125'=>'あんっー',\n".
		");\n".
		"\$weeklyRank1Array = array(\n".
		$weeklyArrayStr.//"	'14x18'=>'(ま゜ー゜さ)ノ'\n".
		");\n".
	"?>";

	//phpでまるごと保存
	file_put_contents("rankerInfo.php", $phpTxt);
}

https://play.google.com/store/apps/details?id=air.retroweb.flappysimamura.production&0508

なぜかイベントが発生しない、サーバーエラーやnull系エラーはどうすれば良いか。

あたりまえかもしれませんが、下記で揉み消せましたw
拾えないネットワークエラーや、テスト時で埋め込みフォント(などのクラス)が存在しないエラーなどを静かにさせました。

try{
	//ここにエラー起きそうな処理を書く。
}catch(e:Object){
	trace("●エラー!e="+e);
}

https://play.google.com/store/apps/details?id=air.retroweb.flappysimamura.production&0507n6

カジュアルゲームでイベントを実現

初のイベントを開催しました。ウィークリーでイベント終了までのカウントダウンも実装。
無事終了し、成績上位者に報酬と賞状を配布しました(賞状はテスト用のデータのものです)
https://play.google.com/store/apps/details?id=air.retroweb.flappysimamura.production&0507n4
f:id:hisashi_vc:20140507143736j:plainf:id:hisashi_vc:20140507143743j:plain

自動アップデート機能を搭載

限界ギリギリまで、サーバー側で随時更新できるようにしました。
アプリ自体のファイル、ローカルファイル、キャッシュファイル、サーバー側ファイルで場合分けしてやり取り。

iPhoneは審査通るかな~

https://play.google.com/store/apps/details?id=air.retroweb.flappysimamura.production&0507n3

サーバー側のセキュリティ強化

そろそろユーザーデータが蓄積されてきたので、サーバー側のセキュリティを強化しました。
PHPのファイル数、そろそろ2ケタの大台に乗るかなw

https://play.google.com/store/apps/details?id=air.retroweb.flappysimamura.production&0507n2

殿堂ランキング(日々の過去ログ)を搭載

ひさびさの更新ですんません。日々少しづつアップデートしてますー。
これで日々のランキング上位者の名前が消えずに、永久の歴史に残るようになりましたw
https://play.google.com/store/apps/details?id=air.retroweb.flappysimamura.production&0507
f:id:hisashi_vc:20140507142542j:plain

iPhoneアプリに「テスト」の文字があるとリジェクト

リジェクトされました。日本語でもしかり。以下Appleからの全文

――――――――――――――――――――――――――――――
Resolution Center
Binary Rejected

Reasons

2.9: Apps that are “beta”, “demo”, “trial”, or “test” versions will be rejected
2.9

We found that your app appears to be a pre-release, test, or trial version with a very limited feature set. Apps that are in beta form, or that are for demonstration or trial purposes only, are not appropriate for the App Store and are not in compliance with the App Store Review Guidelines.

It would be appropriate to complete, remove, or fully configure any partially implemented features and/or to remove any references to "demo", "trial", "beta", or "test" in your application description and release notes, and from within the app.

If you are interested in conducting a beta trial for your app, Ad Hoc distribution is available to broaden your test user base. Information on Ad Hoc distribution is available in the iOS Developer Program User Guide.

新着情報UIの仕上げ

サーバーから賞状送れるようにして、スクロール化で大量の新着情報も閲覧可能にして、タップも調整して、スクロールバーつけて、デバッグUIも更新してと、地味にコツコツ開発。新着バナーにも来週前半には対応したいな~。あと魔法石以外にも、コインやアイテムまで配布可能にしたい。そしてAppleどころか、Googleまでさっぱり更新してくれないこの頃w
ユーザーから装備を任意で変えたいとのメールフォームが来たので、これもその次あたりで対応せねば。
f:id:hisashi_vc:20140428021805j:plain

イベント用の表彰状を作成

賞状までもらえたらかなり嬉しいし、ツイートもしやすいかなと思い、ひとまずデザインpsd作成。その後Flash化してロジック組んで表示。あとXMLのフォーマット作って、サーバーサイドも対応せねば。
f:id:hisashi_vc:20140426130527j:plain

AIRカジュアルゲームアプリで、イベント機能を実現

新着情報から、特定ユーザーに対して報酬があげられるようになりました。イコール、イベントが打てるようになりました。今月のランキング上位者に魔法石とか。

f:id:hisashi_vc:20140425153111j:plain

新着情報UIと、運営からの報酬機能を作成

またしてもGoogleAndroid版が謎に更新されないさなか(3時間で反映されなかったら、永遠に反映されないのがほぼ確定っぽいけど、24時間以上たたないとGoogleのおしりを叩けない)、新着情報UIと、運営からの報酬(感謝やお詫びの魔法石とか)機能を7割くらい実装しました。新着情報は、以前WebViewで作ったんですが、重かった&見栄えショボかったので、新たに作成。
f:id:hisashi_vc:20140424155130j:plain

アイテムのバリエーション追加

アイテムの違いがテクスチャ(模様)の変化しかなかったので、形の違う帽子を追加し始めました。アイテム作るの結構たのしいかも。
f:id:hisashi_vc:20140423184312j:plain

AIRアプリの起動を200%高速にする方法

先に結果の秒数はこんな感じです。

①GalaxyS3の場合…7338=192%高速化(ちなみに空アプリは37)
②IS03の場合…17381=214%高速化(ちなみに空アプリは57)

そしてそのアプリのAndroid版。(いつものしまむらくん。数日中に起動高速化版(Ver1.4.3)が、反映されるはず。。)
https://play.google.com/store/apps/details?id=air.retroweb.flappysimamura.production

iOS版も審査通る気がするけど、確認中(なのでまだ未反映)
https://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=825465264

で、やったことは単純で、.swcでnewしてたAsset一式を、.swfにしてAIR for Android設定の含めるファイル内にいれて、バイナリロードからのnewにしただけ。引数のurlは、.swfのファイル名だけで読めるので楽ちん。これでアプリ起動が遅いAIRアプリが、200%高速に。

function LoadByte(url:String, callBack:Function):void {
	var urlLoader:URLLoader = new URLLoader();
	var req:URLRequest = new URLRequest(url);
	urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
	urlLoader.addEventListener(Event.COMPLETE, onCompleteUrlLoader);
	urlLoader.load(req);
	urlLoader.addEventListener(IOErrorEvent.IO_ERROR, function(e):void{
		trace("265_IOエラーです。"+url);
		trace("e.text = " + e.text);
	});
	
	function onCompleteUrlLoader():void {
		var ba:ByteArray = urlLoader.data;
		var lc:LoaderContext = new LoaderContext();
		//if(Com.IsAir()) 
		lc.allowLoadBytesCodeExecution = true;
		var loader:Loader = new Loader();
		loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteLoader);
		loader.loadBytes(ba, lc);
		function onCompleteLoader():void {
			var apd:ApplicationDomain = loader.contentLoaderInfo.applicationDomain;
			callBack(apd);
		}
	}
}


ロードしたswfから、リンケージしたクラスを抽出するときは、下記メソッド。

function getClass(d:ApplicationDomain, s:String):Class{
	return d.getDefinition(s) as Class;
}

近況4月中旬

リア充イベントにもたまには出ねばと、10年ぶりくらいに花見。やはりいたたまれなくなり、ショックを受けてかえってくるw嘘です最高です!
f:id:hisashi_vc:20140423020917j:plain

何気に行ってなかったスカイタワーにいき、神コスプレレベルのウェイトレスがいる、世界中のビールが飲める店体験
f:id:hisashi_vc:20140423020936j:plain

ゲーセンの頭D、聖地・神奈川編完結。しかし次ステージのオーラ出過ぎな、藤原拓海の86に瞬殺されるw
f:id:hisashi_vc:20140423021041j:plain

ハッピービスコの裏面が生きる力を与えてくれます
f:id:hisashi_vc:20140423021032j:plain

秋葉の穴場。牛肉の刺身カツ?が1200円で食える店。ねぎしのインターバルに。
f:id:hisashi_vc:20140423021055j:plain

声優グランプリ。みもりんずば抜けてる
f:id:hisashi_vc:20140423021105j:plain

声グラ内の、神がかってる同志すみぺ(上坂すみれ)のページ。今週のアニゲラ・ディドゥーンにも出るのか。チェックせねば。
f:id:hisashi_vc:20140423021117j:plain