クロスプラットフォーム開発についての考察[Android/iPhone]

Aizu Advent Carender 2013 の 17日目の記事です.

今回はスマートフォンでのクロスプラットフォーム開発のお話をしたいと思います.

[はじめに]

アプリ開発においてAndroidJavaiOSobjective-Cを必要とします。(今回はこの2つのOSに重点を置きます)
しかし、AndroidでもiPhoneでも同じアプリを作る場合、2つの言語を使うのは学習コストが高すぎるということで、
多くの開発者がクロスプラットフォーム開発のツールを作り始めました.

[どんなものがあるの?]

ツール名 説明 使用言語 使用料金
Titanium mobile ネイティブ APIが提供されている JavaScript(以下JS) 無料
PhoneGap webviewアプリケーション HTML,CSS,JS 有料
Jquery Mibile jqueryベースなwebviewアプリケーション JS(HTML,CSS) 無料
Sencha Touch webviewアプリケーションでネイティブシェルを使用できる HTML,CSS,JS 無料
Unity 言わずと知れたゲームエンジン C#,JS,Python 無料(object等が有料)
CoronaSDK スマートフォンゲーム用のSDK lua 有料
Qt OpenGL,SVGなどに対応している C++ オープンソース版は無料
Xamarin .NET Frameworkを使用できる C# 有料
Caede デスクトップとモバイルに対応 Curl 無料
Intel XDK chromeプラウザ上で開発をする HTML5,JS 無料

この他にも沢山ありますが、これぐらいにしときます(許して


[本題]

今回紹介したいのはTitanium mobileです.
なぜかというとこの中で一番将来性があると感じたからです.
僕が使ってるっていうのもありますけど.
なのでここからはTitanium mobilenのお話です.
読み方はタイタニウム モバイルです.(チタニウムじゃないよ!)
あと今日(?)新しいSDK(3.2.0GA)がでます!(((o(´∀`)o)))

[特徴]

[長所]

  • ネイティブのAPIがサポートされているためJSなのにネイティブと同等のことができる.
  • 動作が高速
  • 無い機能はJava(Android),Objective-Cで実装することにより補うことができるため実質できないことはない.
  • メモリ管理をする必要性がない(自分としては正直短所な部分でもある)
  • 多くのモジュールがすでに存在している(githubやtitanium storeに存在)
  • AlloyというMVC frameworkがあり開発がかなりしやすい.
  • ドキュメントがかなり充実している.
  • SQLite,ファイルシステム,GPS,google MAP,FaceBook,HTTP系の機能は充実している.

[短所]

  • GC本当に動いているのか信用してないので明示的に開放させる必要がある(個人の感想)
  • fpsが60とか必要なゲームとかには圧倒的不向き(後から補足します)
  • 情報がまだ充実していなくて大半英語の資料を読まなければならない
  • Android2.X系には正直使えない.

[アーキテクチャ]


Titaniumが提供しているAPIを噛ませてる.
OSの上にJSインタプリタを乗せている.

[リンク]

Site
Repository
Reference
ドットインストール

[Hello World]

今回はAlloyを使わずにいきます。

(function(){
	var base = Ti.UI.createWindow({
		width:Ti.UI.FILL,
		height:Ti.UI.FILL,
		backgroundColor:"#ddd"
	});
	
	var helloWorld = Ti.UI.createLabel({
		text:"Hello World!",
		color:"#111",
		font: { fontSize: 20, fontFamily: 'Didact Gothic', } ,
		textAlign:"center"
	});
	
	base.add(helloWorld); 
	base.open(); 
	
	//event
	helloWorld.addEventListener('singletap',function(e){
		alert(e.source.text);	
	});
	
})();

iOS(iOS7)

HelloWolrd!という文字をタップしたとき

Android(2.X系)

HelloWolrd!という文字をタップしたとき

めっちゃ簡単!

もちろん、ネイティブのUIを使っているのでOSのバージョンによってUIも違います.
ネイティブのUIは大体あると思っていいと思います.
また、IDEをカスタマイズするとXcodeやEclipseUIのようにUIをペタペタ貼ることもできます.

[OSによって異なる挙動をさせてみる]

(function(){
	var module;
	
	//OSを判断させる
	if (Ti.Platform.osname == 'iphone') {
		module = require('com.abouthiroppy.iphoneText');
	}	
	else if(Ti.Platform.osname == 'android'){
		module = require('com.abouthiroppy.androidText');
	}
	
	var base = Ti.UI.createWindow({
		width:Ti.UI.FILL,
		height:Ti.UI.FILL,
		backgroundColor:"#ddd"
	});
	
	var helloWorld = Ti.UI.createLabel({
		color:"#111",
		font: { fontSize: 20, fontFamily: 'Didact Gothic', } ,
		width:Ti.UI.SIZE,
		height:Ti.UI.SIZE,
		textAlign:"center"
	});
	helloWorld.text = module.text();
	
	base.add(helloWorld);
	base.open();
	
})();

このような感じで共通ソースは同じでJavaで実装した部分はObjective-Cに変える等の処理が簡潔に書けます.
しかし、大半レイアウトで崩れる(Androidは特に)場合がでるのでOSによってソースは分けることを推奨はします.

[実装の比率は?(言語)]
多い時で僕はだいたい8:2 = JS:Objective-C ぐらいです.
しかし大半JSだけでどうにかなります.

[Titaniumでのゲーム開発はできるのか?]
実はゲーム用のモジュールが存在しています.
しかし、やはりネイティブで書いていないので限界はあります.

[来年には激しいゲームも快適に作れる?]
こちらの記事を見てもらえればわかるのですが、今Titaniumは次世代のバージョンに移ろうとしています.
それがTi.Nextです.
またHyperloopというコンパイラがかなり高速(現状より400倍かそれ以上らしい)で、期待大です.

参考文献

[マーケットにだせるの?]

iOS,Androidどちらも出せます.
またtestFlightやadhoc配布もできます.

[宣伝]
最近だしたアプリ こちら
メモを通知センターに残せるアプリやでw

[最後に]

今の時代、かなりスマートフォンの性能が上がっているのでクロスプラットフォームという手も考えてもいいと思います.
しかし、何を作るかによってクロスプラットフォームで行くかどうかをしっかりと見定める必要があると思います.

何かわからないことがあったら@about_hiroppyに聞いてください.
つぎはやくもさんです.
長々付き合ってくれてありがとうです!

とある試験の解答

期限が迫ってきたので書きました。
FIZZBUZZと同じ問題です。

//#include<stdio.h>
//3 death 5 march
char *a[]={"%d\n","\x4d\x61\x72\x63\x68\n","\x44\x65\x61\x74\x68\n","\x44\x61\x72\x63\x68\x20\x4d\x65\x61\x74\x68\n"};
main(i){
    for(i=1;i<=100;i++)printf(a[!(i%3)*2|!(i%5)],i);
}

2問目

<?while($i++<210)echo$i%3?"":$j =Death,$i%5?"":$j=March,$i%7?"":$j=Tech,$i%11?"":$j=Camp,$j==""?$i:"",$j="","\n"?>

AOJのツールを作りました

2人のユーザーを比較して互いに解いてる問題のdiffをとるプログラムを書きました。
とりあえず徹夜で作ったのでまだalpha版ですが今現在そういうツールがないのとこちらにさく時間がないというのが理由で公開することにしました。

何か問題、要望等あればtwittergmailで送ってもらえるとありがたいです。
よろしくお願いします

http://about-hiroppy.com/AOJ_Compare/

追記

20人までのといてない問題を出力するサイトつくりました。
Arenaでの問題セット作成時に使用してください!
http://about-hiroppy.com/AOJ_Compare_n/

HTML5 canvasの練習です

particleの練習です。
初めてcanvasに触りましたがあまりFlashと変わらず特に苦労することはありませんでした。
変わったことはエディタをsublimeに変えたことぐらいですかねw(JSがりがり書いたのは久々で今までのだとつらかったので)
どうもJSのクラスは使いづらい(prototype object)ので今回は配列にpropertyを持たせてます。
久しぶりにJSを書いたので書き方がASのようになってしまい苦労しました。

index.html

<html lang="ja">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta http-equiv="Content-Language" content="ja" />
    <meta http-equiv="Content-Style-Type" content="text/css" />
    <meta http-equiv="Content-Script-Type" content="text/javascript" />
    <title>Canvas_animation</title>
  </head>
  <body onload="init()">
    <canvas id="canvas" width="500" height="500"></canvas>
      <script type="text/javascript" src="main.js"></script>
  </body>
</html>

main.js

var canvas;
var ctx;
var particles = [];
var mouseX = 250;
var mouseY = 250;
var radian = 100;
var distance = 50;
var spring = 0.6;
var friction = 0.5;

function init(){
	canvas = document.getElementById('canvas');
	ctx = canvas.getContext('2d');
	for(var i=0;i<100;i++){
		for(var j=0;j<100;j++){
			var p = {};
			p.x = i*3+100;
			p.y = j*3+100;
			p.tx = i*3+100;
			p.ty = j*3+100;
			p.vx = 0;
			p.vy = 0;
			particles.push(p);
		}
	}

	canvas.onmousemove = onMouseEvent;
	draw();
}

function onMouseEvent(e){
	mouseX = e.clientX;
    mouseY = e.clientY;
}

function draw(){
	ctx.fillStyle = "rgb(0, 0, 0)";
	ctx.fillRect(0,0,500,500);
	// console.log(mouseX+" "+mouseY);

	ctx.fillStyle = "rgb(0,250,250)";

	var n = particles.length;
	var gx = mouseX;
	var gy = mouseY;

	while(n--){
		var p = particles[n];
		var angle = Math.atan2(p.y - mouseY,p.x - mouseX);
		var d = Math.sqrt(Math.pow(mouseX-p.x,2)+Math.pow(mouseY-p.y,2));
		var circle = radian / distance;
		if(d < distance){
			p.x += circle*Math.cos(angle) + (p.tx - p.x)*0.05;
			p.y += circle*Math.sin(angle) + (p.ty - p.y)*0.05;
		}
		else{
			p.vx += (p.tx - p.x)*spring*friction;
			p.vy += (p.ty - p.y)*spring*friction;
			p.x += (p.tx - p.x)*0.2+p.vx;
			p.y += (p.ty - p.y)*0.2+p.vy;
		}
		ctx.fillRect(p.x,p.y,1,1);
	}
	setTimeout(draw,30);
}

完成品
http://about-hiroppy.com/javascript/particle/

JSでJsonを叩く(忘却録)

こんかいはjqueryを使って初めてJsonを叩いたのでそれの覚え書きです。
特にjsonでの各部分へのアクセスで少し手惑いました(JS勉強不足です><)

まずはJsonの中身
sample.json

{"hoge":[
    {
        "id":1,
        "name":"fuga",
        "genre":"meta"
    },
    {
        "id":2,
        "name":"piyo",
        "genre":"meta"
    }
]}

でJSのそーす

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test</title>
<script src="./jquery-1.3.2.min.js"></script>
<script>
$(function(){
      var cnt = 0;
  $('#get_json').click(function(){
    var url = './sample.json';
    $.getJSON(url, function(data){
      for(var key in data){
        $('#result').append($('<p>').html(key +': '+ data[key][cnt].id
                                         +"  "+data[key][cnt].name+"  "+data[key][cnt].genre));
        cnt++;
      }
    });
  });
});
</script>
</head>
<body>
<button id="get_json">読み込み</button>
<div id="result" style="border: 2px solid #595">[result]</div>
</body>
<html>

実行結果
http://about-hiroppy.com/blog/20130414/