29
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

openFrameworksでiOSアプリをつくった所感oF全般編

Last updated at Posted at 2015-08-29

概要

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でシーンの切り替えなどができるライブラリ

ofxStateMachine

使用シーン

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")
でシーンがうつります。

シーン間で変数を共有したいとき

sharedData.h
class sharedData{
public:

	int hoge = 10;
    
};

みたいなクラスつくる

ofApp.h
itg::ofxStateMachine<sharedData> stateMachine;

とかく

ofApp.mm
stateMachine.getSharedData().hoge = 100;
int fuge = stateMachine.getSharedData().hoge;

みたいな感じで使う

シーンクラスでは

opening.h
class opening: public itg::ofxState<sharedData>{
	void setup();
    void update();
    void draw();
}

みたいにシーンファイルで継承?する。

opening.mm
getSharedData().hoge = 100;
int fuge = getSharedData().hoge;

使う。

注意点

思い出しながら書いているので漏れてるプロセスとかあるかもしれない。

少し考えれば当たり前なのだがsetup()はシーンが変わるたびに
呼ばれるわけではなく実行時に全部のシーンのsetup()が呼ばれる。

なのでむやみにメモリ使い過ぎるのはよくなさそう。

そういうことなのでシーンが変わる瞬間はどうやって判別しようかという
ことになる。
→update()にフラグつくって管理した。

頭悪い感じになってしまった。

今思えばなにか方法ありそう。

あと切り替わり時にupdate()が呼ばれる前にdraw()から始まること
が最後の方あった。突然起きた現象だったので自分の実装が悪い感じもする。

ofxTween

oFでもjs界隈で人気のTweenMaxみたいなことが手軽にしたい。

こんなのあるらしいです。
ofxTween

使用シーン

もうofVec2f pos(0,0);みたいなのつくって
pos.x++;みたいなので動かすことから卒業したい。

楽にTweenしていい感じのアニメーションにみせる。

使い方と注意点

こちらのブログに大変良くまとまっています。
ありがとうございます。

基本

ofApp.h
# include "ofxTween.h"
()
ofxEasingCirc 	easing_circ;
ofxTween tween;
ofApp.mm
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終了時にコールバックも欲しい

ofApp.h
# include "ofxTween.h"
()
ofxEasingCirc 	easing_circ;
ofxTween tween;
void callback(int &e);
ofApp.mm
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の第一引数。

ofApp.mm
case 0:
	setParameters(1, .....);

とかけばこれが終了時にeは1になる(はず)

注意点

注意点というか、とても便利なんだけれど色んなところに
色んなことを書くの結構めんどくさいです。

ofxTweenたくさんつくってそれぞれコールバックとるのとか
イヤだなー

たくさん使うときは

vector <ofxTween> twn;

みたいな感じにしてみた。

ofxJSON

oFでjsonファイルつかいたい

こんなのあるらしいです。
ofxJSON

使用シーン

あらかじめ決まってるデータとかをプログラム側に配列として
格納していくのは結構めんどくさいし増えた時の管理もしづらいと思ったとき

今回は違うけどcsvデータで来たなにかをビジュアライズ的な感じで使うとき

JSONで返ってくるAPI叩くとき

使い方と注意点

読み込む

data.json

{
  "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ファイルを用意した時

ofApp.h

# include "ofxJSON.h"



ofxJSONElement json;



インポートして宣言する

ofApp.mm

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でディレクト内のファイル名とかとってくるときとか
どうするんだろうとおもった。

こんなクラスが装備されていた。

ofDirectory

使用シーン

画像ファイルをたくさんつかうアプリケーションなどの場合、
ファイル名をいちいち頭で管理できないしdataディレクトリのなか見て
わざわざ確認した後に
img.loadImage("hogehoge.png");
みたいなのもういやだと感じたとき

使い方と注意点

ファイル名を一覧

ofApp.mm

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に限らず
投稿するのってすごく体力がいりますね。

29
27
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?