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.
Upcoming SlideShare
『こなへん』ができるまで ☆リリース直前編☆
Next
Download to read offline and view in fullscreen.

11

Share

Download to read offline

どこでも動くゲームを作るためのベタープラクティス

Download to read offline

先日iphone_dev_jp 東京iPhone/Mac勉強会で発表してきた時の資料です。
Win/OSX/iOSで動かすために、色々揃っているライブラリをすべて無視してC++の標準ライブラリ+αでアプリを作る『マゾプログラミング的制作手法』についてうんたらかんたら。

Related Audiobooks

Free with a 30 day trial from Scribd

See all

どこでも動くゲームを作るためのベタープラクティス

  1. 1. どこでも動くゲームを作るための ベタープラクティス 西山信行 5mingame2
  2. 2. C++初心者で~ゲームを作るのが大好き☆プログラマ続きはWebで (「でらうま」で検索)
  3. 3. 「こないだサターンでゲーム作ったんだけどさ…」「オレ持ってんのプレステなんだよね」
  4. 4. ハイドライド(1984) テグザー(1985)PC-8801 PC-8001mkIISRX1/turbo PC-8801FM7/77/77AV X1MZ-2000/2200/2500 FM-7/77/77AVMSX MSX2 ファミリーコンピュータPC-6001MkII MZ-2500PC-9801U/F PC-9801ファミリーコンピュータ MSX PC/AT(PC-DOS) AppleIIGS Macintosh
  5. 5. Unity! WebGL! etc,etc…
  6. 6. Unity! WebGL! etc,etc…今はやりの技術を使えばボクにも実現可能!どうやら結論が出たようですね…
  7. 7. 違います!
  8. 8. 違います!そういう正攻法じゃ満足できないんです…今日集まってくれたみなさんも、もうちょっとマゾいと信じています
  9. 9. OpenGL + OpenAL + C++
  10. 10. OpenGL + OpenAL + C++• OpenGLは今やもっとも幅広く使える描画実装 Windows/OSX/iOS/Linux/Android/ゲーム専用機…• OpenALもそれに近い Windows/OSX/iOS/Linux/Android…• C++はCPUに近い言語なので実行速度的に有利 (と思う)• C、C++にもオープンソースの優秀なライブラ リが多数存在する
  11. 11. OpenGL + OpenAL + C++• そして…OpenGLはMESAというソースの公開さ れた実装が存在する
  12. 12. 予告内容• 用意するもの~• 実装のコツ~• ハマった点時間があれば…• デバッグ手法• 最適化
  13. 13. じゃあ始めましょうか!• Windows VisualStudio2010• OSX/iOS Xcode最新版• Linux ターミナルどの環境でもC++の標準ライブラリが使えます
  14. 14. じゃあ始めましょうか!あと、こんだけ準備して。• glut• OpenAL• zlib• libpng• Freetype• FTGL• FTGLES• picojson
  15. 15. じゃあ始めましょうか!• Xcodeではデバッグビルド設定の「プリプロセッ サ」に「_DEBUG」を追加しておく #ifdef _DEBUG /* デバッグ時の実装 */ #endif• iOSでのビルド設定「Compress PNG Files」はオ フっておいてね!ぜったいだよ!
  16. 16. コード書くよ。• ソースの文字コードはUTF-8 BOMあり• しかもVS2010では printf(“ほげほげ”); がcp932に勝手に変換され る(怒) ので #pragma execution_character_set(“utf-8”) で回避• プログラムからテキストデータを読み込む場合は UTF-8で用意
  17. 17. 今回決めたたったひとつのルール• ゲーム本体を.cppに書 かないで全てヘッダフ ァイルに書く• 僕はコード編集は専ら emacsなので問題な いです• ファイルを追加しても プロジェクトを触らな くてイイ!
  18. 18. こんな感じになってます#include “app.hpp“ // 芋づる式に18000行程度読み込まれるApp *app;int main(int argc, char **argv){ glutInit(&argc, argv); app = new App(/* 引数いろいろ */); /* 初期化いろいろ */ glutMainLoop();}
  19. 19. 表示のコールバックvoid displayCallback(){ glClear(GL_COLOR_BUFFER_BIT); app->update(); glutSwapBuffers();}
  20. 20. 入力のコールバックvoid mouseCallBack(const int button, const int state, constint x, const int y){ app->mouse.input(/* 引数いろいろ */);}void keyPushCallback(const u_char key, const int x, constint y){ app->key.input(/*引数いろいろ */);}
  21. 21. それがiOSだと?#include "app.hpp"App *app;- (void)awakeFromNib{ /* いろいろ初期化 */ app = new App(/*引数いろいろ */);}ちなみにソースのファイル名をViewController.mmにしないとC++のコードを混在させられないので注意!
  22. 22. - (void)drawFrame{ [(EAGLView *)self.view setFramebuffer]; glClear(GL_COLOR_BUFFER_BIT); app->update(); [(EAGLView *)self.view presentFramebuffer];}
  23. 23. タッチ入力はこうします- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent*)event{ app->mouse.input(/* 引数いろいろ */);}
  24. 24. OpenGL → OpenGL ES 1.1#if (TARGET_OS_IPHONE)typedef GLfloat GLdouble;#define glFrustum(left, right, bottom, top, znear, zfar)glFrustumf(left, right, bottom, top, znear, zfar)#define glOrtho(left, right, bottom, top, znear, zfar)glOrthof(left, right, bottom, top, znear, zfar)#define glFogi(pname, param) glFogx(pname, param)#endif
  25. 25. OpenGL → OpenGL ES 1.1さすがに gluUnProject() とか gluProject()とか… glu系は実装されてない…MESAの出番!ソースが公開されているのでそれを見ながら自分で実装
  26. 26. いったんまとめ• 文字コード問題はだいたい収束• ゲーム本体を1つのクラスと見立て、その内 部をだいたいどんなコンパイラでも通るよう にお上品に書く。• そのクラスを操作する箇所で入力とかセーブ とか画面の回転とか…環境依存な処理を行え ばよい。• ちょっとした工夫でOpenGLとOpenGL ESの差 異は充分吸収できる
  27. 27. バラバラな解像度をひとつにまとめる
  28. 28. バラバラな解像度をひとつにまとめる• Windows/OSX/Linuxでは、「縦横非固定モー ド」を実装• 初期サイズを960x640と決め、それより狭 かった場合には起動時に調整するみたいな。
  29. 29. バラバラな解像度をひとつにまとめる• iOSは320x480~1536x2048と、多種多様な解 像度が存在するので「見た目固定モード」を 実装
  30. 30. バラバラな解像度をひとつにまとめる• カメラは2つ用意3DglMatrixMode(GL_PROJECTION);glLoadIdentity();glFrustum(width, -width, -height, height, nearZ, farZ);2DglMatrixMode(GL_PROJECTION);glLoadIdentity();glOrtho(-width / 2.0, width / 2.0, height / 2.0, -height /2.0, -1.0, 1.0);
  31. 31. バラバラな解像度をひとつにまとめる• iPhone3GSは2Dのスケーリングを調整して見 た目をiPhone4とあわせる• 新しいiPadも同じように調整すれば対応でき るwidth *= 0.5;height *= 0.5;glOrtho(-width / 2.0, width / 2.0, height / 2.0, -height /2.0, -1.0, 1.0);
  32. 32. 結局UIViewiOSの画面回転でメニューの表示が崩れるのは、UIViewみたく「画面端基準」を自力で実装して切り抜けた
  33. 33. そろそろ音周りも聞きたい!
  34. 34. そろそろ音周りも聞きたい!• OpenALのサンプル通りに書いたら問題ないで す• 自分はwav形式のデータを自力で読み込み、 OpenALに渡してます• ストリーミング関連よくわかんない
  35. 35. 可搬性≒テキストファイル
  36. 36. 可搬性≒テキストファイル• GEOSPOTのセーブデータはすべての動作環境 で互換性がある• バイナリデータだと、とにかく環境依存に なってしまう。たとえばlong型。OSXのx64は 8バイト。それ以外だと4バイト。• 人間が読み書きできるので修正も楽
  37. 37. 可搬性≒テキストファイル• XML…ちょっと自分には読み書きできない• JSON…素晴らしい!
  38. 38. 可搬性≒テキストファイルリプレイデータもプレイ内容をテキストで書き出しているだけ-21.16 13334666110.017 0.156676 -0.807913 -0.247557 0.511317 1955.81 0 0 0 00.0503333 0.156676 -0.807913 -0.247557 0.511317 1955.81 0 00 00.0836667 0.156676 -0.807913 -0.247557 0.511317 1955.81 0 00 00.100667 0.156676 -0.807913 -0.247557 0.511317 1955.81 0 0 00
  39. 39. ファイルはどこから読み込むの?
  40. 40. ファイルはどこから読み込むの?Windows/Linuxの場合実行ファイルがある場所がカレントstd::string path = “”;read(path + “devdata/hoge.png”);
  41. 41. ファイルはどこから読み込むの?OSXの場合起動時に場所を取得CFBundleRef mainBundle = CFBundleGetMainBundle();CFURLRef resourcesURL =CFBundleCopyResourcesDirectoryURL(mainBundle);char str[PATH_MAX];CFURLGetFileSystemRepresentation(resourcesURL, TRUE, (UInt8*)str, PATH_MAX);std::string path = std::string(str) + std::string(“/”);read(path + “devdata/hoge.png”);
  42. 42. ファイルはどこから読み込むの?iOSの場合起動時に場所を取得std::string path = [[[NSBundle mainBundle] resourcePath]UTF8String] + std::string("/");read(path + “devdata/hoge.png”);
  43. 43. ファイルに関してのまとめ• プログラムの開始時、OS別に読み込み時のパ スと書き出し時のパスを取得しておく• iOSも、C++の標準ライブラリ関数を使った ファイルの読み書きができる fstream >> value; こういうファイル読み込みでいける
  44. 44. まさかの:乱数でハマった
  45. 45. まさかの:乱数でハマったGEOSPOTではクイズの出題順序をランダムにシャッフルしているのだが…デモプレイが環境によって違う!どうも、Widnowsとその他でrand()の実装が違うっぽい?
  46. 46. まさかの:乱数でハマったこれは std::tr1::random を使う事で解決!ただし…初期化時の引数はこうしとくunsigned long seed = time(0) & 0x7fffffff;OSXのx64はlongが8バイト、その他は4バイトなのが原因で初期値が変わってしまうのを防ぐ
  47. 47. タイマー処理60FPSで動かない場合でも、ゲーム内の時間経過を正確に行うためにタイマーを使って時間を計測してますWindows• timeGetTime() ←精度が悪い(T T)それ以外• gettimeofday() ←最高!
  48. 48. ここまでのまとめ• ファイルパスや型のサイズなど、実行環境の 違いを吸収する必要のあるもの、必要ないも のを切り分けておけば怖くない!• 週一くらいの間隔でよいので他の環境でもビ ルドが通るかの確認は怠らない。
  49. 49. もしかして:時間切れ?デバッグ手法と最適化に関してはまた次の機会にでも~
  50. 50. いまその瞬間のCPU
  51. 51. いまその瞬間のCPU• VisualStudioもXcodeもデバッガが非常によ くできているので困る事はない。• でもやっぱりプログラムからコンソールに文 字を出力するのは手軽で便利
  52. 52. いまその瞬間のCPUC++だとこう書きますcout << “ほげほげ” << endl;
  53. 53. いまその瞬間のCPUだがしかしWindowsでは出力されないのであった…!class DbgStreambuf : public std::streambuf { std::vector<char> str_;public: int_type overflow(int_type c = EOF) { str_.push_back(c); return c; } int sync() { str_.push_back(0); // 念のため OutputDebugString(&str_[0]); str_.clear(); return 0; }};
  54. 54. いまその瞬間のCPUだがしかしWindowsでは出力されないのであった…!Class Os { DbgStreambuf dbgStream_; std::streambuf *stream_;public: Os() { stream_ = std::cout.rdbuf(&dbgStream_); } ~Os() { std::cout.rdbuf(stream_); }};
  55. 55. いまその瞬間のCPUだがしかしWindowsでは出力されないのであった…!int main() { Os os; cout << “ほげほげ” << endl; return 0;}
  56. 56. いまその瞬間のCPUリリースビルドでcoutを一網打尽#ifdef _DEBUGDOUT std::cout#elseDOUT 0 && std::cout#endifDOUT << “ほげぴよ” << endl;
  57. 57. 最適化は機械任せ☆
  58. 58. 最適化は機械任せ☆XcodeのInstrumentsやOpenGL ES PerformanceDevectiveで計測すれば処理負荷の大きい場所が特定できる。
  59. 59. 最適化は機械任せ☆GEOSPOTではCPUのコードは3GSでも120FPS超えてるので、まったく最適化作業を行ってないてへぺろ。OpenGL ESは分析結果に「VBOとPVRTCテクスチャを使えばいいよ」と出たのでそうしたら、だいたい60FPSになったが…iPhone4が一番重い。
  60. 60. 終わりですこの場を与えてくださった岸川さんを始めお手伝いの方々、今日ここに来てくださった皆さん、聞いてくださったすべての人たちに感謝!
  • ssuser39dd7d

    Dec. 29, 2018
  • kotubuan101

    Jan. 14, 2015
  • shirado

    Sep. 30, 2013
  • chronoborder

    Aug. 25, 2013
  • MsashiTamayama

    Jan. 10, 2013
  • TerufumiOchi

    Nov. 29, 2012
  • AsamiNagasaki

    Sep. 7, 2012
  • KentarouMukunasi

    Sep. 6, 2012
  • lovalotta

    Aug. 28, 2012
  • wx257osn2

    Jun. 1, 2012
  • msasabuchi

    Apr. 18, 2012

先日iphone_dev_jp 東京iPhone/Mac勉強会で発表してきた時の資料です。 Win/OSX/iOSで動かすために、色々揃っているライブラリをすべて無視してC++の標準ライブラリ+αでアプリを作る『マゾプログラミング的制作手法』についてうんたらかんたら。

Views

Total views

12,777

On Slideshare

0

From embeds

0

Number of embeds

6,502

Actions

Downloads

26

Shares

0

Comments

0

Likes

11

×