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,070

Published on

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

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

Published in: Technology
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,070
On Slideshare
0
From Embeds
0
Number of Embeds
7
Actions
Shares
0
Downloads
5
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

拙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
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×