目次 †第5回以降の趣旨 †企業や研究でのプログラム開発では、開発の効率化やバグ等を減らすため
ライブラリを開発するのにも別のライブラリを使用することは良く行われます.
最終目標 †楽しいゲームを開発しやすくするゲームライブラリの開発 Open Dynamics Engine (ODE) について †ODEはこのゲームライブラリがベースにしているオープンソースの物理シミュレーションライブラリです。
ODEは物理シミュレーションを行う部分と表示を行う部分に分かれています。
サンプルコードのインストール †以下のファイルをダウンロードしてインストールして下さい。 $ wget www.er.ams.eng.osaka-u.ac.jp/kawai/AP2018/ap2018_gamelib.zip $ unzip ap2018_gamelib.zip $ cd ap2018_gamelib $ ./start.sh ./start.sh スクリプトによりODEの解凍、コンパイル、インストールと こちらからでもダウンロードできます。 許可がないと怒られるときは †$ chmod 777 ./start.sh でやってみる。 Open Dynamics Engine とゲームのサンプルプログラム †インストールしたライブラリ等の解説は次のページに詳しく書いてあります。
ライブラリの開発方法を次のページにまとめています。 ODE付属のデモプログラムを動かしてみよう †以下のディレクトリにはODEが解凍されています $ cd src/ode-0.13/ode/demo/ $ ./demo_crash サンプルプログラムを動かしてみよう †$ cd application/shooting_game $ ./exec.sh ./shooting_game 許可がないと怒られた場合は $ chmod 777 ./exec.sh のコマンドを打ってから実行しましょう。 サンプルプログラムでは、敵(enemy_agent)がランダムに動いており、
サンプルプログラムの構造を理解しよう †
application/shooting_game ディレクトリ内にはゲームアプリケーションのソースコードが入っています。
src/gamelib にはライブラリのソースコードが入っています。 アプリケーションとライブラリのディレクトリ内にあるファイルを全てエディタで開いて、
main.c に、drawstuffによるシミュレーション管理のための構造体や関数が書かれており。
shooting_game.c に、実際のゲームのロジックが書かれています。 練習3:マップを広げてみよう †基本的な処理を行う関数を作成し、必要に応じて引数や組み合わせを変更して、 現在のマップは下図のようになっています。 マップの拡張 †map.h †map.hの #define MAP_X_SIZE 3 #define MAP_Y_SIZE 3 はマップの大きさを定義しています。 shooting_game.c †shootint_game.c には void start() という関数があり、ゲーム環境の初期化を行っています。
int make_dead_end_walls(int map_x, int map_y, enum DIRECTION direction) は,MAP_*_SIZEで定義されたマップの座標(map_x, map_y)に行き止まりの通路(壁)を生成する関数です。 コンパイル †コンパイルには $ ./start.sh をすればよいのですが、改めてODEをインストールする必要はないので、 start.sh 中の tar zxvf ode-${ODE_VERSION}.tar.gz から、 cp drawstuff/src/.libs/libdrawstuff.* ../../lib/ までを#でコメントアウトしてください。 それと、その下の cd ../gamelib/ を cd gamelib/ に書き換えてください。 マップライブラリ †マップに関するライブラリのヘッダファイルはinclude/gamelib/map.hです。 マップに関するライブラリのソースコードはsrc/gamelib/map.cです。 マップライブラリの関数では、どのような壁の配置にするかを設定した後に、 int make_wall( dReal wall_center_position_x, dReal wall_center_position_y, dReal wall_direction_x, dReal wall_direction_y, dReal wall_length, struct GameObject* wall_object ); 引数はそれぞれ、壁の中心座標、壁の方向を示す座標、壁の長さ、物体情報です。 物体の生成 †ODEでは、動力学計算と衝突検出計算が独立に実装されています。 make_wall関数での物体の生成法を解説します。 ボディの生成と位置の指定 †dBodyID dBodyCreate(dWorldID world); ボディをワールドworld内に生成し、ボディIDを返します。 void dBodySetPosition(dBodyID body, dReal x, dReal y, dReal z); ボディID bodyを絶対座標系の位置(x, y, z)に設定します。 質量パラメータの設定 †void dMassSetBox (dMass *mass, dReal density, dReal lx, dReal ly, dReal lz); 質量パラメータmassを密度densityとサイズ(lx, ly, lz)のボックスとして設定します。 void dMassAdjust (dMass *mass, dReal newmass); 質量パラメータmassの質量がnewmassになるように設定します。 void dBodySetMass (dBodyID body, const dMass *mass); ボディID bodyに上記の質量パラメータmassに設定します。 ボディの回転 †void dQFromAxisAndAngle (dQuaternion q, dReal ax, dReal ay, dReal az, dReal angle); 軸(ax, ay, az)まわりにangleラジアン回転したときのクオータニオンqを求めます。 void dBodySetQuaternion (dBodyID body, const dQuaternion q); ボディID bodyをクオータニオンqに従って回転させます。 ジョイントの生成 †dJointID dJointCreateFixed(dWorldID world, dJointGroupID); ワールドworld内にジョイントを生成して、そのジョイントIDを返します。 void dJointAttach(dJointID joint, dBodyID body1, dBodyID dBody2); ボディbody1とbody2にジョイントID jointを取り付けます。 void dJointSetFixed(dJointID joint); ジョイントID jointを固定します。 ジオメトリの生成とボディとの対応付け †dGeomID dCreateBox (dSpaceID space, dReal lx, dReal ly, dReal lz); スペース space内にサイズ(lx, ly, lz)のボックスを生成し、そのジオメトリIDを返します。 void dGeomSetBody (dGeomID geom, dBodyID body); ジオメトリID geomとボディID bodyを対応付けます。 課題3:新たなマップ要素を追加しよう †マップに関するライブラリを書き換え、ゲームシステムを更新し、をれを反映したアプリケーションを作ってください。
注意事項 †
提出方法 †
評価方法 †
参考になる情報 †
質問がある場合 †
|