去年のクリスマスに買った Kinect の箱をようやく開けました・・・。 Open Kinect Projectで公開されているやつですね。 Getting Started とか MacBook Air で Xbox 360 Kinect してみる (Mac OS X with OpenKinect) を参考にやってみました。
MacPorts をインストールしていなければ、インストール。
$ sudo port selfupdate $ sudo port upgrade installed
$ sudo port install git-core $ sudo port install cmake
$ git clone git://git.libusb.org/libusb.git $ git clone https://github.com/OpenKinect/libfreenect.git
$ cd ./libusb/ $ chmod +x autogen.sh $ ./autogen.sh $ patch -p1 < ../libfreenect/platform/osx/libusb-osx-kinect.diff $ ./configure $ make $ sudo make install | tee ./install.log
Xcode のプロジェクトで作成する。 build ディレクトリを作成してインストールするとよい。
$ mkdir ./libfreenect/build $ cd ./libfreenect/build $ ccmake -G Xcode ..
ccmake の画面では [c] で configure してから [g] で genarate する。 最後に、cmake して Xcode プロジェクト libfreenect.xcodeproj が作成される。
cmake -G Xcode ..
Kinect センサを接続して、作成した libfreenect.xcodeproj を起動する。 いくつかサンプルがあるので選択して、【ビルドと実行】する。
hiview で実行した場合 titdemo のサンプルは映像なしでカメラが上下に動いてびっくりしましたw
普通にmake install して起動した場合
しかし、AS3 サーバとかあるんですねぇ。
Wrapper がこんなにあるので、将来的に楽しみです。 - Python - C Synchronous - Actionscript - C++ - C# - Java JNI - Java JNA - Javascript - Common Lisp
案外あっさり動きましたが、これからが大変そうだと思います・・・。
Rails3.0 のリリースに関してはRails 3.0 リリースノート和訳 - 前編で和訳されてます。 第2回: 新規アプリケーションの作成を参考にRails 3.0 を使ってみる。
$ rails new rails_test $ cd rails_test $ ls -al -rw-r--r-- 1 yoo yoo 36 2011-07-17 00:38 .gitignore -rw-r--r-- 1 yoo yoo 743 2011-07-17 00:38 Gemfile -rw-r--r-- 1 yoo yoo 1660 2011-07-17 01:06 Gemfile.lock -rw-r--r-- 1 yoo yoo 9126 2011-07-17 00:38 README -rw-r--r-- 1 yoo yoo 269 2011-07-17 00:38 Rakefile drwxr-xr-x 7 yoo yoo 4096 2011-07-17 00:38 app drwxr-xr-x 5 yoo yoo 4096 2011-07-17 00:38 config -rw-r--r-- 1 yoo yoo 159 2011-07-17 00:38 config.ru drwxr-xr-x 2 yoo yoo 4096 2011-07-17 00:38 db drwxr-xr-x 2 yoo yoo 4096 2011-07-17 00:38 doc drwxr-xr-x 3 yoo yoo 4096 2011-07-17 00:38 lib drwxr-xr-x 2 yoo yoo 4096 2011-07-17 00:38 log drwxr-xr-x 5 yoo yoo 4096 2011-07-17 00:38 public drwxr-xr-x 2 yoo yoo 4096 2011-07-17 00:38 script drwxr-xr-x 7 yoo yoo 4096 2011-07-17 00:38 test drwxr-xr-x 6 yoo yoo 4096 2011-07-17 00:38 tmp drwxr-xr-x 3 yoo yoo 4096 2011-07-17 00:38 vendor
ここら辺ファイル構成は、MVCに慣れてれば問題ないでしょう。 次に、DBを設定してアプリを起動。
$ bundle install Fetching source index for http://rubygems.org/ Using rake (0.9.2) Using abstract (1.0.0) ... $ sudo gem instal sqlite3 $ rails server
ブラウザからポート3000 でアクセスする。 ちゃんとDB(Active Record)も有効になってます。
tasks コントローラと index アクションを指定して作成。
$ rails generate controller tasks index create app/controllers/tasks_controller.rb route get "tasks/index" invoke erb create app/views/tasks create app/views/tasks/index.html.erb invoke test_unit create test/functional/tasks_controller_test.rb invoke helper create app/helpers/tasks_helper.rb invoke test_unit create test/unit/helpers/tasks_helper_test.rb
config/routes.rb にURLアクセス制御の関数が記述されている。
RailsTest::Application.routes.draw do
get "tasks/index"
end
この状態で http://host:3000/tasks/index でアクセスでき、
RailsTest::Application.routes.draw do
resources :tasks, :only => [ :index ]
end
と書き換えると、index を除いた http://host:3000/tasks でアクセスできます。 これは便利!
ここら辺も他のフレームワークと同じなので説明はいらないとは思いますが、
個別のビュー:app/コントローラ名/ビューファイル.erb レイアウト:app/views/layouts/application.html.erb
を修正してやるだけです。 ちなみに「app/views/layouts/コントローラ名.html.erb」レイアウトファイルを作成すると優先して利用されます。 ※application.html.erb は Rails 3.0 で自動作成されるようになったそうです
app/views/ディレクトリ名/ にアンダースコアで始まるテンプレートを入れ、読み込んでやるとパーツのテンプレートが利用できます。
app/views/_footer.html.erb を作成して、テンプレートファイルで読み込み。
<%= render 'ディレクトリ名/footer' %>
最近 Ruby 信者が更に増えてる気がする。 数年前にちょっとさわったくらいで、実際 Ruby でシステム作った事がない!
という事で、今更ながら Ruby on Rails 入門
Debian(Lenny) で構築しました。
# aptitude update # aptitude safe-upgrade # aptitude install libssl-dev zlib1g-dev libreadline6-dev # aptitude install libsqlite3-dev # aptitude install ruby # aptitude install ruby1.9.1 # aptitude install ruby1.9.1-dev # ruby -v ruby 1.8.7 (2010-08-16 patchlevel 302) [i486-linux]
ruby でインストールすると 1.8.7 になったので、切り替え設定をする。
選択肢 パス 優先度 状態 ------------------------------------------------------------ * 0 /usr/bin/ruby1.9.1 1 自動モード 1 /usr/bin/ruby1.8 0 手動モード 2 /usr/bin/ruby1.9.1 1 手動モード 現在の選択 [*] を保持するには Enter、さもなければ選択肢の番号のキーを押してください: 0 # ruby -v ruby 1.9.2p0 (2010-08-18 revision 29036) [i486-linux]
次に、Rails を gemでインストール。 ※gem install は反応が遅いのと、時間がかかります
# aptitude install rubygems # gem install rubygems-update Successfully installed rubygems-update-1.8.5 # gem install tzinfo builder memcache-client rack rack-test rack-mount erubis mail text-format thor bundler i18n # gem install rails ... Successfully installed railties-3.0.9 Successfully installed rails-3.0.9 11 gems installed ...
インストールすると途中でエラー??
File not found: lib
gem のパッケージ一覧を確認
# gem list ... rack-test (0.6.0, 0.5.7) rails (3.0.9, 3.0.0) railties (3.0.9, 3.0.0) rake (0.9.2) ...
うーん、インストールされている。
# gem which rails /var/lib/gems/1.8/gems/railties-3.0.9/lib/rails.rb
しかし、rails のパスが通っていなかったり、‘File not found: lib’ エラーがでる。
‘File not found: lib’の問題は、gem install railsでFile not found: libを参照。 どうやら1.8系ではなく1.9系だとこのエラーがでるようだ(?)。
# cd var/lib/gems/1.8/gems # gem install rdoc-data # gem rdoc --all --overwrite # cd /var/lib/gems/1.8/gems/rails-3.0.9 # mkdir lib # gem rails install
$ vi ~/.bashrc export GEM_HOME=/var/lib/gems/1.8/ export PATH=$PATH:/var/lib/gems/1.8/bin export RUBYLIB=$RUBYLIB:/var/lib/gems/1.8/lib $ rails -v Rails 3.0.9
何かしらエラーがでたら「RailsエラーQA - Ruby」が参考になるかも。
dispatchKeyEvent をオーバライドすることで、キーイベントを取得できる。 これを利用して、KeyEvent.KEYCODE_BAK (戻るボタンフラグ)を判別して、 親クラスの dispatchKeyEvent をさせなければよいみたいだ。
[java] @Override public boolean dispatchKeyEvent(KeyEvent event) { if (event.getAction() == KeyEvent.ACTION_DOWN) { if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) { return true; } } return super.dispatchKeyEvent(event); } [/java]
Context から KeyguardManager を取得し KeyguardManager.KeyguardLock でスクリーンロックをはずします。
KeyguardManager.OnKeyguardExitResult ハンドラが呼ばれると PowerManager.WakeLock でスクリーンスリープから復帰します。
[java] protected WakeLock wakelock; protected KeyguardManager keyguardmanager; protected KeyguardLock keyguardlock;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.alarm);
final Context _context = this.getApplicationContext();
keyguardmanager = (KeyguardManager) _context.getSystemService(Context.KEYGUARD_SERVICE);
keyguardlock = keyguardmanager.newKeyguardLock("FindMyPhone");
keyguardlock.disableKeyguard();
keyguardmanager.exitKeyguardSecurely(new OnKeyguardExitResult() {
public void onKeyguardExitResult(boolean success) {
wakelock = ((PowerManager) _context.getSystemService(Context.POWER_SERVICE))
.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "FindMyPhone");
wakelock.acquire();
}
});
}
@Override
public void onDestroy() {
super.onDestroy();
if (wakelock != null && wakelock.isHeld()) {
wakelock.release();
}
if (keyguardlock != null) {
keyguardlock.reenableKeyguard();
}
}
[/java]
onDestroy() のライフサイクルでキーロックと スクリーンを戻してますが、ちょっと疑問です。 アプリの仕様にもよると思いますが、スクリーンロックは最初の状態にちゃんと戻さないと、予期しない問題が起こるとの事です。
まず、toggle_button_on.png、toggle_button_off.png ファイルをそれぞれ作成し、drawable に入れる。
drawable/toggle_button.xml を作成し、state_checked をそれぞれ設定する。
-
-
layout xmlファイルで ToggleButton の background に toggle_button.xml を設定する。
JavaScript だけでアプリを作っていくので、必然的に行数が多くなります。 という事で、Titanium.inclue を利用してファイルを文字通り include する事ができます。
Titanium.UI.setBackgroundColor('#000');
var tabGroup = Titanium.UI.createTabGroup();
Titanium.include('soundPlayer.js');
Titanium.include('timer.js');
Titanium.include('twitter.js');
// open tab group
tabGroup.open();
あくまでもinclude なのでクラスのような使い方はできないですが、用途別のコード整理には必須ですね。
また、url 指定で処理をスクリプトファイルに委譲できたりもします。
読み込み側の、Titanium.UI.createWindow で読み込む url を指定します。
var twitterWindow = Titanium.UI.createWindow({
title:'Twitter',
backgroundColor:'#000000',
url: 'twitterLoadTimeline.js'
});
twitterWindow.message = "Twitterの読み込み";
読み込まれる側では、Titanium.UI.currentWindw で呼び出し側の Window を取得できます。
var twitterWindow = Titanium.UI.currentWindow;
alert(twitterWindow.message);
var twitterTableView = Titanium.UI.createTableView();
twitterWindow.add(twitterTableView);
var url = "http://api.twitter.com/1/statuses/user_timeline.json?screen_name=yoo_yoo_yoo";
if (Titanium.Network.onLine == false) {
alert('オフラインです');
} else {
var xhr = Titanium.Network.createHTTPClient();
xhr.open("GET", url, false);
xhr.onload = function () {
var json = JSON.parse(this.responseText);
var tableViewData = [];
for (var i = 0; i < json.length; i++) {
tableViewData.push({title :json[i].text});
//Titanium.API.info(json[i].user.screen_name);
//Titanium.API.info(json[i].text);
}
twitterTableView.data = tableViewData;
};
xhr.onerror = function (error) {
alert(error);
}
xhr.send();
}
createWindowのスコープ内のプロパティも後で設定したプロパティ取得、つまりコンテキストが受け渡されます。 これは素晴らしい!
さらに addEventListener を使ってイベント管理もできます。
var messageWindow = Titanium.UI.createWindow({
url: 'messageLoader.js'
});
messageWindow.open();
var messageTab = Titanium.UI.createTab({
title:'Message',
window:messageWindow
});
Titanium.App.addEventListener('showMessage', function(e) {
alert(e.profile.name);
});
tabGroup.addTab(messageTab);
Titanium.App.fireEvent('showMessage', {
message: 'プロフィール',
profile: {
name: 'yoo',
url: 'http://yoo-s.com'
}
});
ウィンドウ作成後に 登録した「showMessage」イベントを呼び出しています。
OSXでAndroidSDKをインストールするが adb のパスを通してなかった。 platform-tools に adb がある。
export PATH=$PATH:/Developer/android-sdk-mac_x86/platform-tools
先週から、Titanium の勉強会に通っています。 仕事だとTittanium まで手を伸ばしている時間がないのと、JavaScriptの勉強もかねて。
果たして本当に効率よく作れるか? 限界はどこまでか?
スクリプト言語なんでファイル構成が悩ましいところですが、まずは簡単なサンプルから。
//TabGroup作成
var tabGroup = Titanium.UI.createTabGroup();
//Window作成
var topWindow = Titanium.UI.createWindow({
title:'Top',
backgroundColor:'#000000'
});
//タブ画面作成
var topTab = Titanium.UI.createTab({
icon:'KS_nav_views.png',
title:'Top',
window:topWindow
});
//ラベル作成
var label1 = Titanium.UI.createLabel({
color:'#999',
text:'I am Window 1',
font:{fontSize:20,fontFamily:'Helvetica Neue'},
textAlign:'center',
width:'auto'
});
//Window に Label を追加
topWindow.add(label1);
//TabGroup に Tabページを追加
tabGroup.addTab(topTab);
//TabGroup を開く
tabGroup.open();
非常にわかりやすくて、簡単ですね。
ただ、全部コーディンしなきゃいけない
って事を考えると、画面設計を作るのはちょっと???という印象です。 InterfaceBuilder がいかに素晴らしいかってのがよくわかります。
しかし、Objective-C や Java では書くのが面倒くさい事を Titanium で簡単に実装できてしまったりします。
例えば UITableView ないし ListView に Twitter のタイムラインを表示させる処理。
var twitterTableView = Titanium.UI.createTableView();
twitterWindow.add(twitterTableView);
var url = "http://api.twitter.com/1/statuses/user_timeline.json?screen_name=yoo_yoo_yoo";
if (Titanium.Network.onLine == false) {
alert('オフラインです');
} else {
var xhr = Titanium.Network.createHTTPClient();
xhr.open("GET", url, false);
xhr.onload = function () {
var json = JSON.parse(this.responseText);
var tableViewData = [];
for (var i = 0; i < json.length; i++) {
tableViewData.push({title :json[i].text});
}
twitterTableView.data = tableViewData;
};
xhr.onerror = function (error) {
alert(error);
}
xhr.send();
}
iPhone は UITableView Delegateメソッド 、Android は ArrayAdapter を記述しますが、 結構長いコーディングになりがちです。 (それだけ細かい事ができるという事ですが) Titanium の場合、上記のような処理だけで動いてくれます。
素晴らしいのは、createHTTPClient() 移行の書き方です。 ちなみに、 open() の第3引数は同期/非同期の設定で、iPhone のみ有効です。
という訳で、何の処理が簡単に書けるか?を知るのが大切かと思います。 ちなみに、Twitter に関しては、iOS5ではもっと簡単にかけてしまいますが(笑)
iOS 4 から使えるようになったブロック構文。 先日の勉強会で初めて知りました。
アニメーションに関しては、ブロック構文で書くのが推奨されているようです。 とりあえず、ブロック構文の文法を把握してないのでサンプルを参考に書いてみた。
UIViewのインスタンス myView を alpha 0 → 1.0 で下から上に移動する。
self.myView.alpha = 0.0f;
[self.playControllerView setFrame:CGRectMake(0, 480, 320, 480)];
[self.view addSubview:myView];
[UIView animateWithDuration:0.5f
delay:0.0f
options:UIViewAnimationOptionAllowUserInteraction
animations:^{
[self.playControllerView setFrame:CGRectMake(0, 0, 320, 480)];
[self.playControllerView setAlpha:1.0f];
}
completion:^(BOOL finished){
//アニメーション終了後の処理
}];
「^」で書かれている部分が非同期で動いてくれるって事でよいのかな? animations にアニメーションの設定、competion にアニメーション終了後の処理を記述
今後iOS 5になったら動かない!なんて事も今後あるかも知れませんし、この記述を使うようにします。