*目次 [#y067346b]
#contents

* gamelibとは何か [#s556f7a3]
2012年度のアドバンストプログラミングに向けて、
この授業のために開発された簡易的なゲームライブラリとアプリケーションのプログラムです。
~
担当の森が開発した簡易的なゲームライブラリとアプリケーションのプログラムです。
ライブラリとアプリケーションを分けることで、
~
ライブラリとアプリケーションを分ける事で、
~
統一されたシステムをベースにした柔軟なゲーム開発が可能になります(はず…)。
~
ゲームシステム(ヒットポイント管理、ゲームクリア・オーバー条件、ステージマップ管理、敵キャラ行動プログラム)等は
~
ライブラリに任せ、具体的なステージ構成はアプリケーション側にプログラムしましょう。
~
難易度の異なる複数のステージを作ったりする際には、ライブラリで構築した関数や構造体を使い、
~
使用する関数やパラメータ等を変更する事で実現します。
~
ライブラリに任せる部分とアプリケーションに任せる部分を切り分けてプログラムする設計が重要です。
~
最初は提供されているライブラリやアプリケーションのプログラムを修正する事で課題を達成し、
~
次にライブラリを本格的に変更して独自のゲームシステムを構築しましょう。

* Open Dynamics Engine (ODE)について [#tdb9b966]
ODEはこのゲームライブラリがベースにしている
~
オープンソースの物理シミュレーションライブラリです。
~
正確な物理シミュレーションより速度を重視した設計でゲーム用途に向いています。
~
今回はスクリプトファイルを実行する事で、自動的にインストールされます。

ODEは物理シミュレーションを行う部分と表示を行う部分に分かれています。
~
表示プログラムは自分でOpenGL等を用いて作成することも可能ですが、
~
ODEには予めdrawstuffという簡易的な表示ライブラリが付属しています。
~
内部でOpenGLを用いてますが、特に意識する事はありません。

*サンプルコードのインストール [#h20c55aa]
** 演習室(linux)でのインストール [#yd6e7c0e]
適当なディレクトリに移動して,以下のコマンドを実行します.
 $ wget jeap-res.ams.eng.osaka-u.ac.jp/~hiroki/ap2013_gamelib_linux_20130513.tar.gz
 $ tar zxvf ap2013_gamelib_linux_20130513.tar.gz
 $ cd ap2013_gamelib_linux
 $ ./MAKE
./MAKE スクリプトによりODEの解凍、コンパイル、インストールと
今回の課題のサンプルプログラムのコンパイルとインストールが行われます。
~
サンプルプログラム(演習室 VineLinux 用)へのリンク http://jeap-res.ams.eng.osaka-u.ac.jp/~hiroki/ap2013_gamelib_linux_20130513.tar.gz
~
演習室のVine LinuxとUbutuにて動作確認しています。

** Mac OSXでのインストール [#qc30ad98]
Mac OSXや最新のlinuxで行いたい場合は以下のファイルをダウンロードしてインストールして下さい。
 $ wget jeap-res.ams.eng.osaka-u.ac.jp/~hiroki/ap2013_gamelib_osx_20130513.tar.gz
 $ tar zxvf ap2013_gamelib_osx_20130513.tar.gz
 $ cd ap2013_gamelib_osx
 $ ./MAKE
./MAKE スクリプトによりODEの解凍、コンパイル、インストールと
今回の課題のサンプルプログラムのコンパイルとインストールが行われます。
ODEの最新版を使っています。
Linuxの場合と同じコマンドを実行しますが、
~
ODEをコンパイルするためには予めMacPortsやyum,apt-get等を用いて、
~
freeglut等のOpenGL関係のライブラリをインストールしておく必要があります。
(最新のODEは演習室の環境でコンパイルできず、古いODEはOSXで動作しません)
~
サンプルプログラム(演習室 MacOS X 用)へのリンク  http://jeap-res.ams.eng.osaka-u.ac.jp/~hiroki/ap2013_gamelib_osx_20130513.tar.gz



* 開発方法 [#sa09ce3d]

大規模なプログラム開発では、デバッグの容易さやコンパイル時間の短縮のために、
~
プログラムの要素毎にファイルを作成し、それぞれ分割コンパイルを行い、最後に結合します。
~
また、頻繁に使用する関数等は共有ライブラリとしてまとめ、
~
複数のアプリケーションプログラムから呼び出して使用します。
~
さらに、コンパイルする際に一々コマンドを入力するのは面倒なので、
~
makeによってコンパイルを自動化します。

以下では、大規模なプログラム開発で常識的に行われている以上の3点について解説します。
(例ではコンパイルのためにgccを使っていますが、
~
gamelibではodeを使用する関係でC++のコンパイラが必要なため、g++を用いてコンパイルしています。)

**分割コンパイル [#uc776c7f]
一つのアプリケーションプログラムを開発するために
~
複数のファイルでプログラムソースを管理し、それぞれを別々にコンパイルして、
~
最後に結合します。
~
- 分割コンパイル例

以下の.cファイルがあるとします。
 main.c
 func.c
以上のファイルの中にはただ一つmain関数があるものとします。

まず、ぞれぞれを"-c"オプションをつけてコンパイルします。
 $ gcc -c main.c
 $ gcc -c func.c
 $ ls
 main.o func.o
"gcc -c"により.oファイルが生成されました。
最後に以下のように実行ファイルを生成します。
 $ gcc -o test_func main.o func.o
ただし、"-o"オプションは実行ファイルの名前を指定しています。


** 共有ライブラリ開発 [#se80496f]
ライブラリを用意する事、はアプリケーションプログラムで頻繁に使用する関数等を予め開発して、
~
アプリケーション開発時に何度も同じプログラムを開発する手間を省いたり、
~
予め十分に構造を設計しておく事でバグの発生を防ぐ狙いがあります。
~
試しに普段使用しているコンピュータで使われている共有ライブラリを以下のコマンドで見てみましょう。
 $ ls /usr/lib
 $ ls /usr/local/lib
アプリケーションプログラム開発時には、そのライブラリの思想を十分汲み取る事で、
~
効率の良いプログラム開発ができ、アプリケーションプログラムのアイディア実現に集中する事ができます。

- MacOS Xの例

MacOS Xの場合、共有ライブラリのファイルは"lib"で始まり.dylibで終わる事になっており
~
今回はlibfunc.dylibを作成するものとします。
~
まず、以下の.cファイルがあるとします。
 func1.c
 func2.c
以上のファイルの中にはmain関数があってはいけません。

まず、ぞれぞれを"-c"オプションをつけてコンパイルします。
 $ gcc -c func1.c
 $ gcc -c func2.c
 $ ls
 main.o func.o
"gcc -c"により.oファイルが生成されました。
最後に以下のように共有ファイルを作成します。
 $ gcc -dynamiclib -o libfunc.dylib func1.o func2.o
 $ ls
 func1.c func1.o func2.c func2.o libfunc.dylib
ただし、"-o"オプションは共有ファイルの名前を指定している。

- linuxの例

linuxの場合、共有ライブラリのファイルは"lib"で始まり.soで終わる事になっており
~
今回はlibfunc.soを作成するものとします。
~
まず、以下の.cファイルがあるとします。
 func1.c
 func2.c
以上のファイルの中にはmain関数があってはいけません。

まず、ぞれぞれを"-c"オプションをつけてコンパイルします。
 $ gcc -c func1.c
 $ gcc -c func2.c
 $ ls
 main.o func.o
"gcc -c"により.oファイルが生成されました。
最後に以下のように共有ファイルを作成します。
 $ gcc -shared -o libfunc.so func1.o func2.o
 $ ls
 func1.c func1.o func2.c func2.o libfunc.so
ただし、"-o"オプションは共有ファイルの名前を指定しています。

** 共有ライブラリの使用方法 [#l5ca86a5]
共有ライブラリを使用するためにはコンパイラにオプションを渡す必要があります。
 gcc -L../lib -lfunc -o test_func main.c

 -L: ライブラリの場所を指定するオプション
 -l: リンクするライブラリを指定するオプション。ライブラリのファイル名はlib??.so (linux等)、lib??.dylib (MacOS X)のようになっているが、??の部分のみ記述します。

-実行する際の注意点(linuxの場合)
ライブラリはldconfigで指定された場所か、
~
環境変数LD_LIBRARY_PATHで指定された場所を探すため、
~
適切に設定する必要があります。

本ライブラリでは"/usr/local/lib"等、通常システム用のディレクトリにインストールされるライブラリが
~
ユーザ領域にインストールされる設計になっています。
~
これは演習室の環境がユーザにシステム領域へのアクセスを禁じているためで、
~
LD_LIBRARY_PATH(MacOS Xの場合はDYLD_LIBRARY_PATH)を実行環境に合わせて設定し直す必要があります。

そのため以下のような記述をexec.shに自動的に書き込むようにスクリプトを作っていますので、
~
exec.shを通して完成したプログラウを実行する事ができます。
 $cat exec.sh
 #!/bin/sh
 export DYLD_LIBRARY_PATH="../../lib" #MacOS X用の記述
 export LD_LIBRARY_PATH=../../lib:$LD_LIBRARY_PATH
 $* # スクリプトの引数を全て展開
 $ ./exec.sh ./shoothing_game


** makeによるコンパイルの自動化 [#s5ab3edc]



* gamelibのディレクトリ構造 [#ic9a84e2]
** application [#e02faab1]
具体的なゲームアプリケーションはここに作成します。
~
shooting_gameディレクトリにサンプルとなる以下の基本ファイルが保存されています。
~
 main.c
 shooting_game.c
 shooting_game.h
 Makefile
 exec.sh


** include [#w7fb3b1b]
- include/gamelib/

gamelibのヘッダファイルのディレクトリです。
以下のファイルが含まれています。
 gamelib.h
 game_map.h
 self_agent.h
 enemy_agent.h
 interaction.h


- include/ode/

Open Dynamics Engine(ODE)のヘッダファイルのディレクトリです。

- include/drawstuff/

ODEに付属しているODEを簡易に実行し、表示する環境のヘッダファイルのディレクトリです。

~

** src [#zf884f51]
ソースファイルのディレクトリです。
- src/ode-0.12/ あるいは src/ode-0.11.1/
ODEのソースコードの圧縮ファイルを解凍すると現れるディレクトリです。
~
物理シミュレーション、衝突判定、表示や操作のためのライブラリ等がおさめられています。
~
MAKEスクリプトを実行する事で自動的にコンパイルとインストールが行われます。

- src/gamelib/
本ライブラリの本体のソースコードが保存されています。
~
以下のファイルが存在します。
 gamelib.c
 game_map.c
 self_agent.c
 enemy_agent.c
 interaction.c
 Makefile

* プログラム説明 [#afb835ca]
** アプリーケーションソースコード [#ode9390b]
- Makefile

makeを行う際の情報を書き込む。

- メイン関数を記述するファイル
 application/shooting_game/main.c

--drawstuffへの関数等の登録
 dsFunctions fn; // drawstuffに登録する情報を格納する構造体を宣言
 fn.version = DS_VERSION; // drawstuffのバージョンを登録する。
 fn.start = &start; //物理シミュレーション開始時に実行される関数(start)を登録する。
 fn.step = &simLoop;//各ステップ毎に実行される関数(simLoop)を登録する。
 fn.command = &command;//キーボードのキーが押された時に実行される関数(command)を登録する。
 fn.stop = &stop;//シミュレーション終了時に実行される関数(stop)を登録する。
 fn.path_to_textures = "./textures/";//テクスチャの画像ファイルを保存しているディレクトリの場所(./textures)を登録する。
-- ODEによる物理シミュレーションの実行
 dInitODE2(0); // ODEの初期化(詳細は参考サイトか参考文献で)
 dsSimulationLoop (argc,argv,600,500,&fn); //物理シミュレーションと表示を開始(画面サイズ600x500)
 dCloseODE(); // ODEの修了処理
画面サイズを小さくすると処理が軽くなりますので、
~
演習室PCでは遅くなる場合に試してみて下さい。

- ステージ定義等を記述するファイル
 application/shooting_game/shooting_game.c
 application/shooting_game/shooting_game.h
ODEを簡易に実行するdrawstuffに登録するコールバック関数を定義します。
~
定義された関数はmain関数の中で登録している。

-- 物理シミュレーション開始時に一度だけ呼び出される関数
 void start();
以下、内容解説
 initialize_gamelib(); // gamelibの初期化。必ず最初に行う。
 dAllocateODEDataForThread(dAllocateMaskAll); // ODEの初期化
 
 float default_view_position[3] = {0.0f,0.0f,3.0f};
 float default_view_direction[3] = {0.0f,30.0f,0.0f};
 dsSetViewpoint (default_view_position, default_view_direction);
 
 // マップの作成
 // マップの座標(x,y) x:西→東(0→2)、y:南→北(0→2) と設定 
 make_dead_end_walls(0,0, FROM_NORTH );
 make_t_junction_walls(0,1, FROM_EAST );
 make_dead_end_walls(0,2, FROM_SOUTH );
 make_turn_walls(1,0, FROM_EAST_TO_NORTH );
 make_cross_road_walls(1,1);
 make_turn_walls(1,2, FROM_SOUTH_TO_EAST );
 make_turn_walls(2,0, FROM_NORTH_TO_WEST );
 make_turn_walls(2,1,FROM_WEST_TO_SOUTH );
 make_dead_end_walls(2,2, FROM_WEST );
 
 self_agent = make_self_agent( 0,0, 100,M_PI/2 ); /*セルフエージェントを初期化。構造体のデータはself_agent.hで定義されている。 */
 set_first_person_view_point( self_agent ); /* ファーストパーソンビューに切り替える */
 enemy_agent0 = make_enemy_agent(0,1, 10); // enemy_agent 0番の定義(ポインタが代入される)
 enemy_agent1 = make_enemy_agent(0,2, 10); // enemy_agent 1番の定義(ポインタが代入される)
 initialize_self_agent( 0,0, 100,M_PI/2 ); /*セルフエージェントを初期化。構造体のデータはself_agent.hで定義されている。 */
 set_first_person_view_point(); /* ファーストパーソンビューに切り替える */
 make_enemy_agent(0,0,1, 10); // enemy_agent 0番の定義
 make_enemy_agent(1,0,2, 10); // enemy_agent 1番の定義

-- シミュレーションステップ毎に呼び出される関数
 void simLoop( int pause );
以下はアップデート内容
 update_gamelib(); /* gamelib全体のアップデート。主にODEの処理。中身はgamelib.cに記述*/
 
 if( NULL != self_agent ){ /* self_agentポインタがNULLでない事を確認*/
    update_self_agent( self_agent );  /*自機のアップデート。中身はself_agent.cに記述*/
 update_self_agent();  /*自機のアップデート。中身はself_agent.cに記述*/
 
    /* 視点切り替え処理。view_point_switchのラベルに従って視点切り替え */
    if( view_point_switch == BEHIND_VIEW ){
      /* Behind mode */
      set_behind_view_point( self_agent );
      visualize_self_agent( self_agent );
    }else{
      /* First person view mode*/
      set_first_person_view_point( self_agent );
    }
    visualize_self_agent_bullets( self_agent );
  }
 /* 視点切り替え処理。view_point_switchのラベルに従って視点切り替え */
 if( view_point_switch == BEHIND_VIEW ){
    /* Behind mode */
    set_behind_view_point();
    visualize_self_agent();
 }else{
    /* First person view mode*/
    set_first_person_view_point();
 }
 visualize_self_agent_bullets();
 visualize_map();
 
 if( enemy_agent0 != NULL && 0 == enemy_agent0->hit_point ){
   /* もしenemy_agent0のポインタがNULLでなく、enemy_agent0のヒットポイントが0の時 */
   destroy_enemy_agent( enemy_agent0 ); // enemy_agent0のメモリを解放
   enemy_agent0 = NULL; // ポインタにNULLを代入
 //敵エージェントの更新
 if( true == enabled_enemy_agent( 0 ) && 0 == get_enemy_agent_hit_point( 0 ) ){
   /* もし0番目のenemy_agentが存在し、そのヒットポイントが0の時 */
   destroy_enemy_agent(0); // 0番目のenemy_agentのメモリを解放
   printf("destroy_enemy_agent(0)\n")
 }
 if( true == enabled_enemy_agent( 1 ) && 0 == get_enemy_agent_hit_point( 1 ) ){
   /* もし1番目のenemy_agentが存在し、そのヒットポイントが0の時 */
   destroy_enemy_agent( 1 ); // 0番目のenemy_agentのメモリを解放
   printf("destroy_enemy_agent( 1 )\n")
 }
 
 if( true == enabled_enemy_agent( 0 ) ){
   update_enemy_agent( 0 ); // 0番目のenemy_agentの更新
   visualize_enemy_agent( 0 );
 }
 if( true == enabled_enemy_agent( 1 ) ){
   update_enemy_agent( 1 ); // 1番目のenemy_agentの更新
   visualize_enemy_agent( 1 );
 }
 
 // ゲーム終了処理
 if( NULL == enemy_agent0 && NULL == enemy_agent1 ){
 if( false == enabled_enemy_agent( 0 ) && false == enabled_enemy_agent( 1 ) ){
   printf("Congraturations! Game Clear!\n");
   stop();
   exit(0);
 }
 if( get_self_agent_hit_point() <= 0 ){
   printf("You lose! Game Over!\n");
   stop();
   exit(0);
 }


-- キーボードからの入力を受け付ける関数
 void command( int c );


-- 終了処理を行う関数
 void stop();




**ライブラリソースコード [#rb97bf25]
- ゲームシステム全体を管理する関数を記述するファイル
 include/gamelib/gamelib.h
 src/gamelib/gamelib.c

-- プログラム中に必要な資産を管理する仕組み
~
一旦全てのデータはGameObject構造体に格納されて管理される。
 struct GameObject{
   enum ObjectType object_type;
   void* data;
 };
enum ObjectTypeはGameObjectに格納されたデータがどのような種類かを示している。
~
この値に基づいて "void* data" をキャストすることが可能になる。
 enum ObjectType{
   GROUND,
   WALL,
   SELF_AGENT,
   SELF_AGENT_BULLET,
   ENEMY_AGENT,
 };
voidポインタはどのようなポインタでも格納できる万能なポインタである。
~
ただし、ポインタで指し示している先がどのようなデータか把握していないとデータを読む事ができない。
~
~
キャストとは、ある型の変数を別の方の変数として使用するC言語の仕組みである。
~
以下のように用いる。
 void* void_p;
 double* double_p
 double_p = (double*) void_p;
 
 int i = 10;
 double d;
 d = (double)i;

-- gamelib.cに記述された関数
--- プログラムの最初にシステム全体を初期化するための関数
 void initialize_gamelib();

--- プログラムの最後にシステム全体の最終処理をするための関数
 void finalize_gamelib();

--- 毎回のアップデートをする関数
 void update_gamelib();
主にODEの物理シミュレーションのアップデートを行う。
 dSpaceCollide (space,0,&nearCallback); /* ODEの衝突計算 */
 dWorldStep (world,SIMULATION_TIME_STEP); /* ODEの力学シミュレーション1ステップ */
 dJointGroupEmpty (contactgroup); /* ODEの衝突情報の開放 */

--- ODEで2つの物体が近づいて、衝突しそうになった時(衝突している時)に呼び出されるコールバック関数 
 void nearCallback( void *data, dGeomID geom1, dGeomID geom2 );
Self Agent と Enemy Agentの間等の衝突処理を行う。
~


- 自機エージェント構造体定義と関数を記述するファイル
 include/gamelib/self_agent.h
 src/gamelib/self_agent.c
~
--自機の情報を格納する構造体
 struct SelfAgentData{
   dBodyID body_ID; /* ODEの物理計算に必要なID(実際はポインタ) */
   dGeomID geom_ID; /* ODEの衝突計算に必要なID(実際はポインタ)*/
   int hit_point; /* 自機のヒットポイント*/
   dReal direction_angle; /* 自機の方向。東が0ラジアン */
   dVector3 pulling_force; /* 自機を移動させるための力をセットする変数 */
 };
---direction_angleの角度と向き
 東:    0 [rad] (  0[deg])
 北:  M_PI/2 [rad] ( 90[deg])
 西:  M_PI   [rad] (180[deg])
 南: -M_PI/2 [rad] (-90[deg])

--自機から発射される弾丸の情報を管理する構造体。
 struct SelfAgentBulletData{
   dBodyID body_ID;
   dGeomID geom_ID;
   int countdown_timer;
   /*
     発射されると初速度を与え、タイマーに値をセットする。
     ステップ毎にタイマーをカウントダウンして、0になったら位置をリセットする。
     値が0の場合、物理シミュレーションと衝突判定を行わない。
   */
 };

--自機のデータを生成してポインタを返す関数
 struct SelfAgentData* make_self_agent( int map_x, int map_y,
--自機のデータを生成する関数
 void initialize_self_agent( int map_x, int map_y,
                       int initial_hit_point,
                       dReal initial_direction_angle);

--自機のポインタを安全に消去する関数
 void destroy_self_agent(struct SelfAgentData* self_agent_data);
 void destroy_self_agent();

--自機をアップデートする関数
 void update_self_agent(struct SelfAgentData* self_agent_data);
 void update_self_agent();

-- 自機の背後から視点に切り替える関数
 void set_behind_view_point(struct SelfAgentData* self_agent_data);
 void set_behind_view_point();

--自機の一人称視点に切り替える関数
 void set_first_person_view_point(struct SelfAgentData* self_agent_data);
 void set_first_person_view_point();

--自機を操作するコマンドを入力して、必要な処理を行う関数
 void command_self_agent( int command, struct SelfAgentData* self_agent_data );
 void command_self_agent( int command );

--自機から弾丸を発射する関数
 void self_agent_shoot_gun(struct SelfAgentData* self_agent_data);
 void self_agent_shoot_gun();

--自機を可視化する関数
 void visualize_self_agent(struct SelfAgentData* self_agent_data);
 void visualize_self_agent();

--自機の弾丸を可視化する関数
 void visualize_self_agent_bullets(struct SelfAgentData* self_agent_data);
 void visualize_self_agent_bullets();

--自機の位置を返す関数
 const dReal* get_self_agent_position(struct SelfAgentData* self_agent_data);
 const dReal* get_self_agent_position();

--自機のヒットポイントを返す関数
 int get_self_agent_hit_point(struct SelfAgentData* self_agent_data);
 int get_self_agent_hit_point();
以下の値を直接参照する事もできるが、
ヒットポイントの処理について何らかの変更を行いたい時に関数化しておくと便利。
 self_agent_data->hit_point;

--自機のヒットポイントを増減する関数
 void change_self_agent_hit_point( struct SelfAgentData* self_agent_data, int hit_point ); 
 void change_self_agent_hit_point( int hit_point ); 
正の値で増加し、負の値で減少する。
以下のように直接操作する事もできるが、
ヒットポイントの処理について何らかの変更を行いたい時に関数化しておくと便利。
 self_agent_data->hit_point --;


- 敵エージェント構造体定義と関数を記述するファイル
 include/gamelib/enemy_agent.h
 src/gamelib/enemy_agent.c

--敵機の情報を格納する構造体
 struct EnemyAgentData{
   bool enabled;
   int hit_point;
   dBodyID body_ID;
   dGeomID geom_ID;
 };

--敵機のデータを生成してポインタを返す関数
 struct EnemyAgentData* make_enemy_agent( int map_x, int map_y, int initial_hit_point );
--敵機を初期化する関数
 void initialize_enemy_agent();

--敵機のデータを生成する関数
 void make_enemy_agent( int enemy_agent_index, int initiali_position_map_x, int initial_position_map_y, int initial_hit_point );

--敵機を可視化する関数
 void visualize_enemy_agent( struct EnemyAgentData* enemy_agent_data );
 void visualize_enemy_agent( int enemy_agent_index );

--敵機をアップデートする関数
 void update_enemy_agent( struct EnemyAgentData* enemy_agent_data );
 void update_enemy_agent( int enemy_agent_index );

--敵機を安全に消去する関数
 void destroy_enemy_agent( struct EnemyAgentData* enemy_agent_data );
 void destroy_enemy_agent( int enemy_agent_index );

--敵機のヒットポイントを返す関数
 int get_enemy_agent_hit_point( struct EnemyAgentData* enemy_agent_data );
 int get_enemy_agent_hit_point( int enemy_agent_index );
以下の値を直接参照する事もできるが、
ヒットポイントの処理について何らかの変更を行いたい時に関数化しておくと便利。
 enemy_agent_data->hit_point;

--敵機のヒットポイントを増減する関数
 void change_enemy_agent_hit_point( struct EnemyAgentData* enemy_agent_data, int hit_point );
以下のように直接操作する事もできるが、
ヒットポイントの処理について何らかの変更を行いたい時に関数化しておくと便利。
 self_agent_data->hit_point --;
--敵機の存在を示す関数
 bool enabled_enemy_agent( int enemy_agent_index );
敵機が存在していればtrue、破壊されていればfalseを返す。



- ゲームマップの構造体定義と関数を記述するファイル
 include/gamelib/game_map.h
 src/gamelib/game_map.c

--マップの情報を格納する構造体
---壁の情報を保存
 struct WallData{
   dGeomID geom_ID; /* ODEの衝突計算に使うID*/
   dBodyID body_ID; /* ODEの物理計算に使うID。実際には壁は移動しないがbodyIDが無いとdGeomIDを設定できないため */
   dJointID fixed_joint_ID; /*空間に壁を固定するためのジョイント。固定するだけなのでfixedジョイントを用いる*/
 };
 
 struct MapData{
   dReal center_position[2]; //[0]->x, [1]->y
   int wall_size;
   struct GameObject wall_object[MAP_ONE_SQUIRE_MAX_WALL_SIZE];
    /*現在、"WALL"しか代入されないためこの情報は使用されていないが、必要に応じて意味のある情報に書き替えても良い*/
   struct WallData wall_data[MAP_ONE_SQUIRE_MAX_WALL_SIZE];
    /*voidのポインタとして管理する事で、様々なオブジェクトを格納してマップ要素を構成する事は可能。
     そのオブジェクトが何かはwall_objectで指示すれば良い*/
 };

--マップの初期化をする関数
 void initialize_map();
--マップの情報を安全に消去する関数
 void destroy_map();

--直線的な通路を生成する関数
 int make_strait_walls( int map_x, int map_y, enum DIRECTION direction );
 int make_straight_walls( int map_x, int map_y, enum DIRECTION direction );

--曲がる通路を生成する関数
 int make_turn_walls( int map_x, int map_y, enum DIRECTION direction );

--T字路を生成する関数
 int make_t_junction_walls( int map_x, int map_y, enum DIRECTION direction );

--交差点を生成する関数
 int make_cross_road_walls( int map_x, int map_y);

--行き止まりを生成する関数
 int make_dead_end_walls( int map_x, int map_y, enum DIRECTION direction );

--game_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 );

--game_map.cの内部で使用する2次元ベクトルを回転する関数
 void rotate_90deg_clockwise( dReal* vec2 );
 void rotate_90deg_anticlockwise( dReal* vec2 );
 void rotate_180deg( dReal* vec2 );

--マップを可視化する関数
 void visualize_map();


- インタラクションのための関数を記述するファイル
 include/gamelib/interaction.h
 src/gamelib/interaction.c
自機と敵、弾と敵がぶつかった時の処理プログラム。

--自機の弾丸と敵機が接触したときの処理関数
 void self_agent_bullet_hits_to_enemy_agent( struct EnemyAgentData* enemy_agent_data );
 void self_agent_bullet_hits_to_enemy_agent( struct SelfAgentBulletData* self_agent_bullet_data,
                                             struct EnemyAgentData* enemy_agent_data );

--自機と敵機が接触したときの処理関数
 void contact_self_agent_and_enemy_agent( struct SelfAgentData* self_agent_data,
                                                                    struct EnemyAgentData* enemy_agent_data );
 void contact_self_agent_and_enemy_agent( struct EnemyAgentData* enemy_agent_data );


*参考になる情報 [#v3647a89]
-公式ホームページ http://www.ode.org/

-demura.net: ロボットの開発と教育 http://demura.net/ode
~
金沢工業大学の出村先生のページ
~
非常に分かりやすい解説

-簡単!実践!ロボットシミュレーション - Open Dynamics Engineによるロボットプログラミング
~
http://www.amazon.co.jp/dp/4627846916
~
出村先生が執筆されたODEの解説本

-『Open Dynamics Engine(ODE)』のオリジナルマニュアル
~
http://www.koj-m.sakura.ne.jp/ode/
~
大阪大学の松下先生のページ


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS