Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
iPhoneアプリ『ういろう』
でのboost成分
C++三年目で初めて触れたboostでアプリを作ってみた
西山信行
• 各種パソコン
• SS

C
• N64
• PS、PS2
• GC
• DC
• PSP

2011~

アセンブラ

1996~

1990~

自己紹介
C++
• iPhone
• Windows
• OSX
• Cで書いた最後
のゲーム
• Win&OSX

こなへん
• C++で初めて
作ったゲーム
• Win&OSX&iPhone

2013

TieGunner

2012

2011

最近の活動

ういろう
• C++11とboostで
...
ちょいとDEMOタイム

せっかくなので、ゲームも観てもらいます;)
今日の内容

C++三年目のiPhoneアプリで
初めて使ったboostについての報告
みなさんにお願いしたい!!

なにぶんC++初心者なので…
なにかあればぜひ、
その場で挙手をお願いします
よっしゃboost使うぜ!!
• 使おうとしたのがC++11でけっこう実現されてる…
• for_each
• 範囲ベースfor文

• random
• std::random

• lexcal_cast
• std::to_string
いろいろ検証してみて
• 拙作『ういろう』ではこの4つを使いました
• boost::noncopyable
• boost::signals2
• boost::any
• boost::bind

• どれもヘッダをインクルードするだけなの...
boost::noncopyable
boost::noncopyable
• コピーされたくない型が継承するだけでよい
#include <boost/noncopyable.hpp>
class X : private boost::noncopyable {};

int m...
boost::noncopyable
• コピーされたら困る型を扱う時のうっかりミスを防げた
• ポインタやstd::unique_ptrを内包してるとか
struct Hoge : private boost::noncopyable { /...
boost::noncopyable
• OpenGLのハンドルを扱う時にも
struct Texture {
GLuint id;
Texture() {
glGenTextures(1, &id);
}
~Texture() {
glDel...
boost::noncopyable
• これならコンパイル時にミスを発見できる
struct Texture : private boost::noncopyable {
GLuint id;
Texture() {
glGenTexture...
boost::noncopyable

ここまでで
気になった点や疑問点は
ありますか??
boost::signals2
boost::signals2
#include <iostream>
#include <boost/signals2/signal.hpp>
struct Hoge {
void step(const int value) {
std::c...
boost::signals2
• ういろうでは、ほぼすべてのオブジェクトを
boost::signals2に登録して、更新や描画、オブジェクト間
通信を処理しました
ゲームロ
ジック
黒ういろう

白ういろう

メニュー

signals

...
boost::signals2
enum Msg {
UPDATE,
DRAW
};
void mainLoop() {
// 全オブジェクトに更新を通知
sendMessage(Msg::UPDATE);
// 全オブジェクトに描画を通知
s...
boost::signals2
// signals2に登録されている関数
void getMessage(const int msg) {
switch (msg) {
case Msg::UPDATE:
// 更新
update();
re...
boost::signals2
例えば、プレイヤーの攻撃を実装
する場合には…
// プレイヤーの更新処理
void update() {
...
// 攻撃を全オブジェクトに通知
sendMessage(Msg::PLAYER_JUMPATT...
boost::signals2
// signals2に登録されている関数
void getMessage(const int msg) {
switch (msg) {
case Msg::UPDATE:
// 更新
update();
re...
boost::signals2
• ただし、気を付けないとめっちゃネストして処理が重くなる
ので注意です

プレイ
ヤー

攻撃を
送信

敵

攻撃で
やられ
たのを
送信

ゲーム
ロジッ
ク

スコア
計算を
送信
boost::signals2

ここまでで
なにか気になった点や疑問点は
ありますか??
boost::any
boost::any
• boost::signals2の話できっとこう思われたでしょう
「値のやりとりはしてないの??」
と…
boost::any
// signals2に登録されている関数
void getMessage(const int msg, params) {
switch (msg) {
case Msg::UPDATE:
// 更新
update(pa...
boost::any
• これを解決してくれたのが、どんな値も格納できる
boost::anyと、コンテナとの組み合わせです
#include <iostream>
#include <string>
#include <boost/any.h...
boost::any
• boost::signals2に登録する関数をこんな感じにしました
// signals2に登録されている関数
void getMessage(const int msg, std::map<std::string, ...
boost::any
• これで「値の名前と型さえ知っていればやり取り可能」が実
現しました
typedef map<string, boost::any> Params;
// 更新処理
void update(Params params) ...
boost::any
• ただし、気を付けないとめっちゃ値が増えてこんがらかりま
す!!
更新

描画

プレイヤー攻撃

• 経過時間

• 描画プリミティブ
• 画面サイズ

• プレイヤーの位置
• プレイヤーの大きさ

アイテムゲット
...
boost::any

ここまでで
なにか…!!
boost::bind
boost::bind
• boost::signals2にstd::shared_ptrを登録する時に必須で
した
struct Hoge {
void CallBack(int value) { /* 何らかの処理 */ }
};
type...
boost::bind

ここま…!!
まとめ
• boostが、コードの正確さや簡潔さにすごく貢献してくれた
• boostjpがほんとうに素晴らしい
• boostjpがほんとうに素晴らしい!!
• boostjpのURLは
https://sites.google.com/si...
おまけ
• 拙作アプリ『こなへん』と『ういろう』をよろしくね☆

2013 10.14 西山信行
twitter: @5mingame2
Facebook: 5mingame2
Upcoming SlideShare
Loading in …5
×

拙iPhoneアプリ『ういろう』でのboost成分

3,781 views

Published on

2013/10/19 boost勉強会@仙台で発表したスライドです。

C++三年目のプログラマが作ったiPhoneアプリで役立ったboostのライブラリに関しての発表です。

Published in: Technology
  • Be the first to comment

拙iPhoneアプリ『ういろう』でのboost成分

  1. 1. iPhoneアプリ『ういろう』 でのboost成分 C++三年目で初めて触れたboostでアプリを作ってみた 西山信行
  2. 2. • 各種パソコン • SS C • N64 • PS、PS2 • GC • DC • PSP 2011~ アセンブラ 1996~ 1990~ 自己紹介 C++ • iPhone • Windows • OSX
  3. 3. • Cで書いた最後 のゲーム • Win&OSX こなへん • C++で初めて 作ったゲーム • Win&OSX&iPhone 2013 TieGunner 2012 2011 最近の活動 ういろう • C++11とboostで 作ったゲーム • Win&OSX&iPhone
  4. 4. ちょいとDEMOタイム せっかくなので、ゲームも観てもらいます;)
  5. 5. 今日の内容 C++三年目のiPhoneアプリで 初めて使ったboostについての報告
  6. 6. みなさんにお願いしたい!! なにぶんC++初心者なので… なにかあればぜひ、 その場で挙手をお願いします
  7. 7. よっしゃboost使うぜ!! • 使おうとしたのがC++11でけっこう実現されてる… • for_each • 範囲ベースfor文 • random • std::random • lexcal_cast • std::to_string
  8. 8. いろいろ検証してみて • 拙作『ういろう』ではこの4つを使いました • boost::noncopyable • boost::signals2 • boost::any • boost::bind • どれもヘッダをインクルードするだけなのでお手軽!! • ビルドはiPhone向けがしんどい(armv7、armv7s、arm64、i386…)
  9. 9. boost::noncopyable
  10. 10. boost::noncopyable • コピーされたくない型が継承するだけでよい #include <boost/noncopyable.hpp> class X : private boost::noncopyable {}; int main() { X a; X b = a; } // エラー!
  11. 11. boost::noncopyable • コピーされたら困る型を扱う時のうっかりミスを防げた • ポインタやstd::unique_ptrを内包してるとか struct Hoge : private boost::noncopyable { /* いろいろ定義 */ }; std::vector<Hoge> objects; Hoge obj; objects.push_back(obj); for (Hoge obj : objects) { // いろいろ処理 } // エラーにできる // エラーにできる
  12. 12. boost::noncopyable • OpenGLのハンドルを扱う時にも struct Texture { GLuint id; Texture() { glGenTextures(1, &id); } ~Texture() { glDeleteTextures(1, &id); } }; int main() { Texture hoge; Texture fuga = hoge; } // コンストラクタでOpenGLのハンドルを生成 // デストラクタでハンドルを破棄 // この操作でidが二重化されてしまい、破棄の際に動作が未定義になる
  13. 13. boost::noncopyable • これならコンパイル時にミスを発見できる struct Texture : private boost::noncopyable { GLuint id; Texture() { glGenTextures(1, &id); } ~Texture() { glDeleteTextures(1, &id); } }; int main() { Texture hoge; Texture fuga = hoge; } // エラー! この操作を禁止できる
  14. 14. boost::noncopyable ここまでで 気になった点や疑問点は ありますか??
  15. 15. boost::signals2
  16. 16. boost::signals2 #include <iostream> #include <boost/signals2/signal.hpp> struct Hoge { void step(const int value) { std::cout << "Hoge:" << value << std::endl; } }; struct Fuga { void draw(const int value) { std::cout << "Fuga:" << value + 1 << std::endl; } }; int main() { boost::signals2::signal<void (const int)> signal; Hoge hoge; signal.connect(boost::bind(&Hoge::step, &hoge, _1)); Fuga fuga; signal.connect(boost::bind(&Fuga::draw, &fuga, _1)); signal(10); } • 登録した関数をまとめて呼び出し てくれる • 関数の引数と戻り値の型が一致し ているだけでよく、抽象クラスを 継承したりする必要がない • std::shared_ptrを利用すると、登 録元が消滅したときに自動的に登 録を解除してくれる(別項で説明)
  17. 17. boost::signals2 • ういろうでは、ほぼすべてのオブジェクトを boost::signals2に登録して、更新や描画、オブジェクト間 通信を処理しました ゲームロ ジック 黒ういろう 白ういろう メニュー signals 背景
  18. 18. boost::signals2 enum Msg { UPDATE, DRAW }; void mainLoop() { // 全オブジェクトに更新を通知 sendMessage(Msg::UPDATE); // 全オブジェクトに描画を通知 sendMessage(Msg::DRAW); } メインの処理は、こんな感じになっ ています
  19. 19. boost::signals2 // signals2に登録されている関数 void getMessage(const int msg) { switch (msg) { case Msg::UPDATE: // 更新 update(); return; case Msg::DRAW: // 描画 draw(); return; } default: return; } 各オブジェクトではこういう感じに 実装されています • 描画の必要のないオブジェクトなら、 その分岐を書かないだけでよい
  20. 20. boost::signals2 例えば、プレイヤーの攻撃を実装 する場合には… // プレイヤーの更新処理 void update() { ... // 攻撃を全オブジェクトに通知 sendMessage(Msg::PLAYER_JUMPATTACK); ... } • プレイヤー側は、「オレの攻撃を受 けてみろ!!」とメッセージを送信
  21. 21. boost::signals2 // signals2に登録されている関数 void getMessage(const int msg) { switch (msg) { case Msg::UPDATE: // 更新 update(); return; case Msg::DRAW: // 描画 draw(); return; } case Msg::PLAYER_JUMPATTACK: // プレイヤーからのジャンプアタックを処理 hitCheck(); return; } 攻撃対象のオブジェクトは、攻撃 メッセージを受け取った時の処理 を追加 • プレイヤー側では、どのオブジェク トが攻撃対象かを知る必要がない • 「攻撃演出」も、他のオブジェクト で独立して簡単に処理できる
  22. 22. boost::signals2 • ただし、気を付けないとめっちゃネストして処理が重くなる ので注意です プレイ ヤー 攻撃を 送信 敵 攻撃で やられ たのを 送信 ゲーム ロジッ ク スコア 計算を 送信
  23. 23. boost::signals2 ここまでで なにか気になった点や疑問点は ありますか??
  24. 24. boost::any
  25. 25. boost::any • boost::signals2の話できっとこう思われたでしょう 「値のやりとりはしてないの??」 と…
  26. 26. boost::any // signals2に登録されている関数 void getMessage(const int msg, params) { switch (msg) { case Msg::UPDATE: // 更新 update(params); return; case Msg::DRAW: // 描画 draw(params); return; } メッセージ送信で問題になったの が、値の受け渡しでした • メッセージごとに構造体を作ったと して…それをどうやって関数に渡そ う。キャスト?? • ういろうでは50種類ほどメッセージ が存在します
  27. 27. boost::any • これを解決してくれたのが、どんな値も格納できる boost::anyと、コンテナとの組み合わせです #include <iostream> #include <string> #include <boost/any.hpp> int main() { boost::any x = 1; x = std::string("Hello"); } // int値を格納 // std::string値を格納 // 格納されている型をチェック if (x.type() == typeid(std::string)) { // 元の型に変換 std::cout << boost::any_cast<std::string>(x) << std::endl; } else { std::cout << "not string" << std::endl; }
  28. 28. boost::any • boost::signals2に登録する関数をこんな感じにしました // signals2に登録されている関数 void getMessage(const int msg, std::map<std::string, boost::any> params) { switch (msg) { case Msg::UPDATE: // 更新 update(params); return; case Msg::DRAW: // 描画 draw(params); return; }
  29. 29. boost::any • これで「値の名前と型さえ知っていればやり取り可能」が実 現しました typedef map<string, boost::any> Params; // 更新処理 void update(Params params) { // 処理時間を取り出す float delta_time_sec = boost::any_cast<float>(params.at(“delta_time”)); ... // 何か値を書き込む Hoge result; params.insert(Params::value_type(“result", result)); }
  30. 30. boost::any • ただし、気を付けないとめっちゃ値が増えてこんがらかりま す!! 更新 描画 プレイヤー攻撃 • 経過時間 • 描画プリミティブ • 画面サイズ • プレイヤーの位置 • プレイヤーの大きさ アイテムゲット 惑星操作 • アイテムの種類 • アイテムの位置 • 回転量 • カメラ情報
  31. 31. boost::any ここまでで なにか…!!
  32. 32. boost::bind
  33. 33. boost::bind • boost::signals2にstd::shared_ptrを登録する時に必須で した struct Hoge { void CallBack(int value) { /* 何らかの処理 */ } }; typedef boost::signals2::signal<void (int value)> Signal; Signal signal; void connect(std::shared_ptr<Hoge> object) { // boost::bindが使われている signal.connect(Signal::slot_type(&Hoge::CallBack, object.get(), _1).track_foreign(object)); }
  34. 34. boost::bind ここま…!!
  35. 35. まとめ • boostが、コードの正確さや簡潔さにすごく貢献してくれた • boostjpがほんとうに素晴らしい • boostjpがほんとうに素晴らしい!! • boostjpのURLは https://sites.google.com/site/boostjp/
  36. 36. おまけ • 拙作アプリ『こなへん』と『ういろう』をよろしくね☆ 2013 10.14 西山信行 twitter: @5mingame2 Facebook: 5mingame2

×