概要
iOSアプリをつくる要件があったが
swiftとかObjective-C勉強する時間がなく、
openFrameworks(以下oF)ならなんとかできたので
oFをつかってiOSアプリをつくった。
それを通して新しく知ったこと、初めて使ったAddonまとめ。
iOSにかぎらずoF全般的なこととiOSのみのことの2部構成です。
・ openFrameworksでiOSアプリをつくった所感oF全般編(本記事)
・ openFrameworksでiOSアプリをつくった所感iOS限定の機能編
次書こうと思っていたらほとんどこっちに書いていたのでネタがいまいちなかったです(9/2)
tr1/memory エラー
内容
これは本当に困った。
Addon入れた後や作業再開した時になぜか出て困った。
PCのoFでは見たことなかったが調べていたらPCでも出るみたいなので
こちらに書いておく。
対策
https://github.com/openframeworks/openFrameworks/pull/2764
に書いてあるとおり
・ Build Setting->architecturesのBaseSDKとかが他の動くプロジェクトと同じになってるか確認する
・ Build Setting->Apple LLVM 6.1 -Language - C++のC++ Standard LibraryをCompiler Defaultからlibstdc++にする
ということなんだけれどそう設定しても全然対策にならなくて
最初は諦めてもう一回最初からプロジェクトつくってたが、途中で対策を発見した。
ずっとプロジェクトのbuild settingを見ていたのだが
openFrameworksというフォルダの中に「iOS+OFLib.xcodeproj」
というプロジェクトがありこっちのC++ Standard Libraryが
Compiler Defaultになっていた。
libstdc++に直したら無事に消えた。
ofxStateMachine
ofxStateMachineを使用してみた
oFでシーンの切り替えなどができるライブラリ
使用シーン
iOSアプリなので最低限のシーンの切り替えが必要。
さすがにofApp.mmの中だけで出し分けるのはつらそうなので今回はじめて使ってみた。
ちなみにoFでも普通にストーリーボードとか画面推移できるらしいが
その辺調べている時間がなかったのと不慣れなところに突っ込むのは
やめようということで断念。
制作終盤に
/example の中に
iosCustomSizeExample
iosStoryboardExample
を見つけた。悔しい。
でもiosStoryboardExampleはビルド通るけど実行すると止まる。
使い方と注意点
大体の使い方は
田所淳さんのサイト: yoppa.org
によくまとまっています。
これを参考にしましょう。
基本
addon入れて、ofApp.h, ofApp.mmに諸々書いて、新しくC++ファイル(hoge.h, hoge.cpp or hoge.mm)つくって
changeState("hoge")
でシーンがうつります。
シーン間で変数を共有したいとき
class sharedData{
public:
int hoge = 10;
};
みたいなクラスつくる
itg::ofxStateMachine<sharedData> stateMachine;
とかく
stateMachine.getSharedData().hoge = 100;
int fuge = stateMachine.getSharedData().hoge;
みたいな感じで使う
シーンクラスでは
class opening: public itg::ofxState<sharedData>{
void setup();
void update();
void draw();
}
みたいにシーンファイルで継承?する。
getSharedData().hoge = 100;
int fuge = getSharedData().hoge;
使う。
注意点
思い出しながら書いているので漏れてるプロセスとかあるかもしれない。
少し考えれば当たり前なのだがsetup()はシーンが変わるたびに
呼ばれるわけではなく実行時に全部のシーンのsetup()が呼ばれる。
なのでむやみにメモリ使い過ぎるのはよくなさそう。
そういうことなのでシーンが変わる瞬間はどうやって判別しようかという
ことになる。
→update()にフラグつくって管理した。
頭悪い感じになってしまった。
今思えばなにか方法ありそう。
あと切り替わり時にupdate()が呼ばれる前にdraw()から始まること
が最後の方あった。突然起きた現象だったので自分の実装が悪い感じもする。
ofxTween
oFでもjs界隈で人気のTweenMaxみたいなことが手軽にしたい。
こんなのあるらしいです。
ofxTween
使用シーン
もうofVec2f pos(0,0);
みたいなのつくって
pos.x++;
みたいなので動かすことから卒業したい。
楽にTweenしていい感じのアニメーションにみせる。
使い方と注意点
こちらのブログに大変良くまとまっています。
ありがとうございます。
基本
# include "ofxTween.h"
(略)
ofxEasingCirc easing_circ;
ofxTween tween;
void ofApp::setup(){
tween.setParameters(0, easing_circ, ofxTween::easeOut,0, 500, 1000, 500);
}
void ofApp::update(){
tween.update();
}
void ofApp::draw(){
ofBackgounr(255);
ofSetColor(0);
ofCircle(0, 0, tween.getTarget(0));
}
こんな感じ。
tween終了時にコールバックも欲しい
# include "ofxTween.h"
(略)
ofxEasingCirc easing_circ;
ofxTween tween;
void callback(int &e);
void ofApp::setup(){
tween.setParameters(0, easing_circ, ofxTween::easeOut,0, 500, 1000, 500);
ofAddListener(tween.end_E, this, &ofApp::callback);
}
void ofApp::update(){
tween.update();
}
void ofApp::draw(){
ofBackgounr(255);
ofSetColor(0);
ofCircle(0, 0, tween.getTarget(0));
}
void ofApp::callback(int &e){
switch (e) {
case 0:
~
break;
case 1:
~
break;
default:
break;
}
}
こういう感じに書く。
callback関数内でswitchで切り替える
この時の引数e
はsetParametersの第一引数。
case 0:
setParameters(1, .....);
とかけばこれが終了時にe
は1になる(はず)
注意点
注意点というか、とても便利なんだけれど色んなところに
色んなことを書くの結構めんどくさいです。
ofxTweenたくさんつくってそれぞれコールバックとるのとか
イヤだなー
たくさん使うときは
vector <ofxTween> twn;
みたいな感じにしてみた。
ofxJSON
oFでjsonファイルつかいたい
こんなのあるらしいです。
ofxJSON
使用シーン
あらかじめ決まってるデータとかをプログラム側に配列として
格納していくのは結構めんどくさいし増えた時の管理もしづらいと思ったとき
今回は違うけどcsvデータで来たなにかをビジュアライズ的な感じで使うとき
JSONで返ってくるAPI叩くとき
使い方と注意点
読み込む
{
"aaa": {
"x": 698,
"y": 234
},
"bbb": {
"x": 664,
"y": 86
},
"ccc": {
"x": 482,
"y": 224
},
"ddd": {
"x": 648,
"y": 366
},
"eee": {
"x": 554,
"y": 352
}
}
例えばこういうjsonファイルを用意した時
# include "ofxJSON.h"
略
ofxJSONElement json;
インポートして宣言する
void ofApp::setup(){
json.open("data.json");
for (int i=0; i<json.getMemberNames().size(); i++) {
string name = json.getMemberNames()[i];
int x = json[name]["x"].asInt();
int y = json[name]["y"].asInt();
cout << name << " :( " << x << ", " << y << ")" << endl;
}
}
みたいな感じに使えて簡単です。
json.open
でdata/内のディレクトリいあるファイルにアクセス
json.getMemberNames()[n]
でn番目のjsonデータの名前が取得できる。
全部並べたいのでまずjson.getMemberNames().size()
で取得し、for文で回す
→とりあえずログに出力
書き出す
すみません、使ってないのでわかんないです。
でもさくっと出来ると思います。
sampleとか見て下さい。
ofDirectory
oFでディレクト内のファイルの情報を得る
そういえばoFでディレクト内のファイル名とかとってくるときとか
どうするんだろうとおもった。
こんなクラスが装備されていた。
使用シーン
画像ファイルをたくさんつかうアプリケーションなどの場合、
ファイル名をいちいち頭で管理できないしdataディレクトリのなか見て
わざわざ確認した後に
img.loadImage("hogehoge.png");
みたいなのもういやだと感じたとき
使い方と注意点
ファイル名を一覧
void ofApp::setup(){
ofDirectory dir("images/");
dir.allowExt("png");
dir.listDir();
for(int i = 0; i < dir.numFiles(); i++){
cout << dir.getName(i) << endl;
}
}
という感じ
ディレクトリの指定はbin/data/以下
もっとたくさん便利メソッドとかありそうだったので
深く使う時にまた調べようと思った。
感想
Qiitaに限らず
投稿するのってすごく体力がいりますね。