今回はゲームで重要になる入力に関してのプログラムを紹介します。マウスやキー入力を取得する部分に関してはOpenGLの守備範囲外で、入力の制御にはGLFWのライブラリを使用します。従来、GLUTなどのライブラリでは入力系はコールバックとして実装していましたが、GLFWではゲームループ内でトリガを拾う感じになっています。
今回は描画が無いため非常にシンプルなプログラムになっています。簡単に見て行きましょう。
const int g_windowWidth = 640; const int g_windowHeight = 480; void joystick() { const int buttonNum = glfwGetJoystickParam( GLFW_JOYSTICK_1, GLFW_BUTTONS); const int axisNum = glfwGetJoystickParam( GLFW_JOYSTICK_1, GLFW_AXES); unsigned char buttons[buttonNum]; float positions[axisNum]; glfwGetJoystickButtons ( GLFW_JOYSTICK_1,buttons,buttonNum ); glfwGetJoystickPos (GLFW_JOYSTICK_1,positions,axisNum); // アナログスティック for(int i = 0; i < axisNum; ++i){ printf("%.1f,",positions[i]); } printf("\n"); // ボタン for(int i=0;i<buttonNum;i++){ printf("%d,",buttons[i]); } printf("\n"); } int main() { if( !glfwInit() ){ return -1; } if( !glfwOpenWindow(g_windowWidth, g_windowHeight, 0, 0, 0, 0, 0, 0, GLFW_WINDOW)) { return -1; } // モニタとの同期 glfwSwapInterval(1); // ゲームループ while (glfwGetWindowParam(GLFW_OPENED)) { if( glfwGetKey(GLFW_KEY_ESC) == GLFW_PRESS ) break; if( glfwGetKey('A') == GLFW_PRESS ) { printf("button A is pressed\n"); } // マウスのボタンが押されたかを調べる if( glfwGetMouseButton(GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS ) { int mousex, mousey; glfwGetMousePos(&mousex, &mousey); printf("mouse is clicled at (%d, %d)\n", mousex, mousey); } // 画面の初期化 glClearColor(0.2f, 0.2f, 0.2f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); // バッファの入れ替え glfwSwapBuffers(); } glfwTerminate(); return 0; }
今回のデモでは、Aボタンを押すと"button A is pressed"とコンソールに表示され、マウスを左クリックすると、その座標が表示されるようになっています。
キー入力の検出
キー入力を取得するにはglfwGetKeyの引数に押下を検出したいキーを渡してやり、返り値がGLFW_PRESSと等しいかをチェックします。同様にglfwGetKeyの返り値がGLFW_RELEASE と等しければ、キーが離されたことを検出できます。
マウス座標の検出
また、マウスがクリックされたかどうかを検出するにはglfwGetMouseButtonの引数にマウスのキー(GLFW_MOUSE_BUTTON_LEFT, GLFW_MOUSE_BUTTON_RIGHT, GLFW_MOUSE_BUTTON_MIDDLE )を渡してやり、返り値がGLFW_PRESSと等しいかをチェックします。引数によって、マウスの左ボタン、マウスの右ボタン、マウスの真ん中ボタンのどれが押されたかを調べることができます。この辺りはキー入力のチェックと同様の方法なので分かりやすいですね!
マウスがクリックされた座標を取得するにはglfwGetMousePosを使います。この関数にx座標とy座標の変数のポインタを渡してやり、関数内でマウスの座標を詰めて返してもらいます。
ジョイスティックの検出
さて、最後はジョイスティックの検出です。ジョイスティックってなんや??と思う人もいるかもしれませんが、一般的には、ゲーム機に付いているコントローラのようなものを指すみたいです。そんなもの開発時に使わんやろ〜とか思いがちですが、ちゃんとコントローラを握ってデバッグをしたほうが絶対に良い物が作れるので、手元に1つ置いておくと良いと思います。
MacならPS3のコントローラが使えるのでぜひ利用して下さい。必要な物はPS3のコントローラと接続するためのUSBケーブルだけです。このUSBケーブルがちょっとクセモノでして、最近ではあまり見かけないmini-Bの端子(最近はmini-Bよりも薄っぺらいmicro-Bが主流です)なので、家に無いようでしたら同時に一本購入しておきましょう(安いですしね・・・)
接続方法はとっても簡単で「環境設定」→「Bluetooth」と進み、「入」と「検出可能にする」ボタンにチェックを付けた後PS3のコントローラのPSボタンを押すことで自動的にPS3のコントローラが検出されると思います。
ジョイスティックからの入力検出はjoystick()関数で行っています。まずはglfwGetJoystickParam関数にGLFW_BUTTONSとGLFW_AXESを渡すことで、それぞれボタンの数とアナログスティックの軸数を取得しています。PS3コントローラの場合、ボタンの数が19個、アナログスティックの軸数が4本(2本のアナログスティックがそれぞれx軸とy軸を持っている)でした。
ボタンと軸の数だけ、ステータスを格納する配列を用意し glfwGetJoystickButtonsやglfwGetJoystickPosの関数にこれらの配列を渡し、関数の中で配列にボタンの情報を詰めて返してもらっています。アナログスティックはx軸、y軸ともに-1.0〜1.0の値が格納され、ボタンは押されていたら1、押されていなかったら0が格納されてきます。
配列への格納順序とPS3のコントローラボタンの対応は以下のようになっています。参考にして下さい。
[0] SELECTボタン
[1] 左アナログのボタン
[2] 右アナログのボタン
[3] STARTボタン
[4] ↑
[5] →
[6] ↓
[7] ←
[8] L2ボタン
[9] R2ボタン
[10] L1ボタン
[11] R1ボタン
[12] △ボタン
[13] ◯ボタン
[14] ☓ボタン
[15] □ボタン
[16] PSボタン
まとめ
さて、入力系に関してはとりあえずこんなところです。思っていたよりも直感的で簡単だったのではないでしょうか?とくにゲームパッドは馴染みのない開発者も多いと思いますが、一定レベルのゲームを作ろうとすると絶対に必要なので、手元に1つは置いておくと良いと思います。
参考図書
「ゲームプログラマになる前に覚えておきたい技術」
この本は「ゲームをどのように作るのか」といった薄っぺらい内容ではなく、ゲームを動かすための技術を1から理解できるように解説してくれています。そして、この本にはゲーム開発にとどまらず、プログラマに必要な知識がたくさーん詰まっています。C++の基礎からキャッシュの話とか浮動小数点演算の話などのちょっと難しい話、最適化手法の話までもが書かれているので、プログラマならぜったい読むべき一冊ですね。そしてページ数も872ページとボリューミィ!分厚い参考書はいい本です!内部的に使われているのはDirectXですが、基本的にそれを意識する必要は内容に解説されているので、絶対に一度は読んでおきたい一冊です。
秀和システム
売り上げランキング: 10284
「OpenGLで作るiPhone SDKゲームプログラミング」
この本はiPhoneでOpenGLを使う方法を解説した本です。2Dゲームの「はえたたき」から3Dゲームの「カーレース」まで、サンプルがとても充実しているので、ゲームを作りはじめようという時に非常に良い取っ掛かりになります!また、パーティクルや衝突判定などゲームには欠かせない話もしっかりと説明されている数少ない日本語の書籍なので、ぜひぜひ読んでおきたいですねー(^^)v
インプレスジャパン
売り上げランキング: 28,461
「OpenGLプログラミングガイド 原著第5版」
OpenGLといったらまずはコレ。通称赤本と呼ばれるバイブルです。とりあえず、ちょこちょこと参照することが多いので、手元に置いておきたい(というか重すぎてモバイルは無理)一冊です。OpenGLをやるぞ、という意気込み(もしくは自分へのプレッシャ)で買ってしまう一冊です。コレを買ったら後戻りは出来ません。。。
ピアソンエデュケーション
売り上げランキング: 475,144