[[Advanced Programing 2012]]

*目次 [#ead26fae]
*目次 [#y067346b]
#contents

*第5回以降の趣旨 [#o46d6207]
企業や研究でのプログラム開発では、開発の効率化やバグ等を減らすため
* gamelibとは何か [#s556f7a3]
この授業のために開発された簡易的なゲームライブラリとアプリケーションのプログラムです。
~
同じような処理は関数等にまとめて、ライブラリ化する事が良く行われます。
ライブラリとアプリケーションを分けることで、
~
そこで今回はゲーム開発を題材にライブラリ開発の意義や方法について学びます。

ライブラリを開発するのにも別のライブラリを使用することは良く行われます.
統一されたシステムをベースにした柔軟なゲーム開発が可能になります(はず…)。
~
今回の課題では、3次元物理シミュレータとしてOpen Dynamics Engineを使用して、
ゲームシステム(ヒットポイント管理、ゲームクリア・オーバー条件、ステージマップ管理、敵キャラ行動プログラム)等は
~
ライブラリの使用と開発の両方を経験する事によって、使いやすいライブラリや
ライブラリに任せ、具体的なステージ構成はアプリケーション側にプログラムしましょう。
~
開発やメンテナンスしやすいライブラリはどのようなものかを実際に作る事で考えてもらいます。
難易度の異なる複数のステージを作ったりする際には、ライブラリで構築した関数や構造体を使い、
~
使用する関数やパラメータ等を変更する事で実現します。
~
ライブラリに任せる部分とアプリケーションに任せる部分を切り分けてプログラムする設計が重要です。
~
最初は提供されているライブラリやアプリケーションのプログラムを修正する事で課題を達成し、
~
次にライブラリを本格的に変更して独自のゲームシステムを構築しましょう。

*最終目標 [#rc9a527a]
楽しいゲームを開発しやすくするゲームライブラリの開発

*サンプルコードのインストール [#c5ce9295]
適当なディレクトリに移動して,以下のコマンドを実行します.
 $ wget jeap-res.ams.eng.osaka-u.ac.jp/~hiroki/AdvancedPrograming2012_gamelib_ode-0.11.1_20120516.tar.gz
 $ tar zxvf AdvancedPrograming2012_gamelib_ode-0.11.1_20120516.tar.gz
 $ cd AdvancedPrograming2012_gamelib_ode-0.11.1_20120516
 $ ./MAKE
./MAKE スクリプトによりODEの解凍、コンパイル、インストールと
今回の課題のサンプルプログラムのコンパイルとインストールが行われます。

Mac OSXや最新のlinuxで行いたい場合は以下のファイルをダウンロードしてください。
 $ wget jeap-res.ams.eng.osaka-u.ac.jp/~hiroki/AdvancedPrograming2012_gamelib_ode-0.12_20120515.tar.gz 
ODEの最新版を使っています。
上記と同じコマンドを実行しますが、ODEをコンパイルするためには予めMacPortsやyum,apt-get等を用いて、
* gamelibのディレクトリ構造 [#ic9a84e2]
** application [#e02faab1]
具体的なゲームアプリケーションはここに作成します。
~
freeglut等のOpenGL関係のライブラリをインストールしておく必要があります。
(最新のODEは演習室の環境でコンパイルできず、古いODEはOSXで動作しません)
shooting_gameディレクトリにサンプルとなる以下の基本ファイルが保存されています。
~
 main.c
 shooting_game.c
 shooting_game.h
 Makefile
 exec.sh

*Open Dynamics Engine とゲームのサンプルプログラム [#z8a21639]
**ODE付属のデモプログラムを動かしてみよう [#qb1b0d14]
以下のディレクトリにはODEが解凍されています
 src/ode-0.11.1 # または src/ode-0.12

 $ cd src/ode-0.11.1/ode/demo/ # または、src/ode-0.12/ode/demo/
 $ ./demo_crash
** include [#w7fb3b1b]
- include/gamelib/

**サンプルプログラムを動かしてみよう [#nd86997e]
 $ cd bin
 $ ./exec.sh ./shooting_game
gamelibのヘッダファイルのディレクトリです。
以下のファイルが含まれています。
 gamelib.h
 game_map.h
 self_agent.h
 enemy_agent.h
 interaction.h

 $ cd application/shooting_game
 $ ./exec.sh ./shooting_game

-サンプルプログラムのボタン配置(後の改造で変更可)
 d: 前進
 s: 後進
 f: 右平行移動
 a: 左平行移動
 e: 右旋回
 w: 左旋回
 g: ジャンプ
 v: 視点切り替え(一人称視点と背後霊(?)視点.ゲームによってはどちらかに固定した方がよいかも)
 u: 敵キャラ 消滅/生成 (最終的なゲームでは無意味なので削除すべきだが、動作確認のため実装)
 h: 強制終了
- include/ode/

**サンプルプログラムの構造を理解しよう [#m403dd3c]
-全てのファイルをエディタで見てみよう。
Open Dynamics Engine(ODE)のヘッダファイルのディレクトリです。

 application/shooting_game_c-lang
ディレクトリ内にはゲームアプリケーションのソースコードが入っています。
~
ゲームアプリケーションはライブラリを使用して具体的なゲームを構成します。
- include/drawstuff/

 src/gamelib
にはライブラリのソースコードが入っています。
ODEに付属しているODEを簡易に実行し、表示する環境のヘッダファイルのディレクトリです。

アプリケーションとライブラリのディレクトリ内にあるファイルを全てエディタで開いて、
~
中身を確認してください。

 main.c
に、drawstuffによるシミュレーション管理のための構造体や関数が書かれており。
** src [#zf884f51]
ソースファイルのディレクトリです。
- src/ode-0.12/ あるいは src/ode-0.11.1/
ODEのソースコードの圧縮ファイルを解凍すると現れるディレクトリです。
~
 shooting_game.c
に、実際のゲームのロジックが書かれています。

**サンプルを改造してみよう [#b7189778]
 shoogint_game.c
には
 start()
という関数があり、ゲーム環境の初期化を行っています。
物理シミュレーション、衝突判定、表示や操作のためのライブラリ等がおさめられています。
~
そこにマップを構成するための関数が書かれているので、
~
関数を修正してマップを変更してみましょう。
~
最初のマップは3x3だが、ライブラリのソースを変更するともっと大きなマップにする事は可能です。
~
何を変更すれば良いか、ソースコードを読んで調べてみよう。
MAKEスクリプトを実行する事で自動的にコンパイルとインストールが行われます。

基本的な処理を行う関数を作成し、必要に応じて引数や組み合わせを変更して、
- src/gamelib/
本ライブラリの本体のソースコードが保存されています。
~
様々なアプリケーションを作成する事を可能にするのがライブラリ開発の醍醐味です。
~
マップの変更はその1つなので、まず始めに挑戦してみてください。
以下のファイルが存在します。
 gamelib.c
 game_map.c
 self_agent.c
 enemy_agent.c
 interaction.c
 Makefile

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

*課題 [#n4f9e52b]
**物理シミュレータ(ODE)を使ったシューティングゲームを作ろう(5月30日までの課題) [#k336938d]
ライブラリを書き換えゲームシステムを完成させる
-Enemy Agentが動くようにする.
-球が当たるとEnemy AgentのHit Pointが減少
-Hit Pointが0になると敵エージェントが消滅
-Self Agentが敵の身体に接触するとSelf AgentのHit Pointが減少
-Self AgentのHit Pointが0になると「Game Over」を表示してゲーム終了
-ボスエージェントを設定して、ボスのHit Pointが0になると「Game Clear」を表示してゲーム終了
-バグ報告←これが一番評価が高い
makeを行う際の情報を書き込む。

**シューティングゲームツクールを作ろう(6月13日までの発展的課題) [#baf4cb0c]
最終目標へ近づく!:「楽しいゲームを作るためのゲームライブラリの開発」
-同じゲームライブラリを使用して複数のステージを作成する.
--ディレクトリを改めて作成して、その下で開発しても良い.
--マップが異なっている.敵の動きが違う.
--難易度が変わる
--同一プログラム中でステージ変化をするにはどうしたら良いか考える.
-新たなマップ要素を追加する~
--例)坂道
--例)ジャンプでしか移動できない段差等…
-複数のEnemy Agentを作成~
--例)動きや形を変更する.
--例)Self Agentのコードを参考にして、弾を撃てる様にする.等…
-Enemy Agentの動きを知能化する~
--例)Self Agentに近寄る.
--Hit Point等の状況によって動きを変える、等…
-物理シミュレーションを活かしたゲームシステムを作成する
--商業ゲーム開発に携わった中西先生は~
「Hit Pointシステムに頼らないゲームシステムは楽しい」~
とおっしゃっています.~
Hit Pointシステムがなく、物理シミュレーションを活かした楽しいゲームは作れるでしょうか?~
考えてみてください.
- メイン関数を記述するファイル
 application/shooting_game/main.c

**注意事項 [#edaed87e]
今回の課題は、今年度が初めてになります。
--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の修了処理
画面サイズを小さくすると処理が軽くなりますので、
~
サンプルコードにバグがある可能性や、課題が分かりづらい等の問題点があると思います。
~
何か気がついた事があれば担当の森やTAに連絡をお願いします。
演習室PCでは遅くなる場合に試してみて下さい。

課題の達成方法等にあまり細かいルールは設定しません。
- ステージ定義等を記述するファイル
 application/shooting_game/shooting_game.c
 application/shooting_game/shooting_game.h
ODEを簡易に実行するdrawstuffに登録するコールバック関数を定義します。
~
ライブラリを全面的に書き換えて、C++にしてもらっても構いません。
~
サンプルより良いゲームライブラリにしてくれれば、1つ1つの課題をクリアするよりも良い評価にします。
~
その代わりしっかり動く様にして来てください。
定義された関数はmain関数の中で登録している。

**提出方法 [#ua81513a]
-下記の提出物を第7回(5/30)と第9回(6/13)の講義開始時に回収する
-提出物一式を入れるフォルダの名前は学生番号とする
-提出物
--ソースコード
--コンパイルに使用するMakefile
--その他,コンパイル・実行に必要なファイル
-- 物理シミュレーション開始時に一度だけ呼び出される関数
 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 );
 
 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番の定義

**評価方法 [#sc013076]
-仕様を満たしているか
--担当の森とTAで実際に動いているかを提出者の環境で確認する
-ソースコードの可読性の高さ
--機能ごとに関数を分け,分かりやすい関数名をつけているか(機能ごとにソースを分けて分割コンパイルをする)
--分かりやすい変数名をつけているか
--分かりやすいコメントを記述しているか
-機能に対応した分かりやすい関数を設計しているか
-無駄な処理を行っていないか
-工夫に応じて加点する
-- シミュレーションステップ毎に呼び出される関数
 void simLoop( int pause );
以下はアップデート内容
 update_gamelib(); /* gamelib全体のアップデート。主にODEの処理。中身はgamelib.cに記述*/
 
 update_self_agent();  /*自機のアップデート。中身はself_agent.cに記述*/
 
 /* 視点切り替え処理。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( 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( 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);
 }

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

-demura.net: ロボットの開発と教育 http://demura.net/ode
~
金沢工業大学の出村先生のページ
~
非常に分かりやすい解説
-- キーボードからの入力を受け付ける関数
 void command( int c );

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

-『Open Dynamics Engine(ODE)』のオリジナルマニュアル
~
http://www.koj-m.sakura.ne.jp/ode/
~
大阪大学の松下先生のページ
-- 終了処理を行う関数
 void stop();

-この授業の担当の中西先生のページや論文等



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

-- プログラム中に必要な資産を管理する仕組み
~
中西先生が手がけたゲーム作品
一旦全てのデータはGameObject構造体に格納されて管理される。
 struct GameObject{
   enum ObjectType object_type;
   void* data;
 };
enum ObjectTypeはGameObjectに格納されたデータがどのような種類かを示している。
~
http://smg.ams.eng.osaka-u.ac.jp/~nakanishi/hn_designs_j.html
この値に基づいて "void* data" をキャストすることが可能になる。
 enum ObjectType{
   GROUND,
   WALL,
   SELF_AGENT,
   SELF_AGENT_BULLET,
   ENEMY_AGENT,
 };
voidポインタはどのようなポインタでも格納できる万能なポインタである。
~
中西 英之. ビデオゲームデザインのためのモデル. 情報処理学会研究報告 モデル化と問題解決, 98-MPS-18-9, 1998.
ただし、ポインタで指し示している先がどのようなデータか把握していないとデータを読む事ができない。
~
http://smg.ams.eng.osaka-u.ac.jp/~nakanishi/hnp_1998_mps.pdf
~
中西 英之, Katherine Isbister. ビデオゲームに浸透するエージェント技術. 情報処理, Vol. 48, No. 3, pp. 250-256, 2007.
キャストとは、ある型の変数を別の方の変数として使用するC言語の仕組みである。
~
http://smg.ams.eng.osaka-u.ac.jp/~nakanishi/hnp_2007_ipsjmag.pdf
以下のように用いる。
 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の間等の衝突処理を行う。
~


*質問がある場合 [#id0fbb11]
-浅田研 森までメールをください.~
なお,件名は「AP2012:課題3」としてください.~
hiroki_AT_ams.eng.osaka-u.ac.jp (_AT_は@に変えてください)
- 自機エージェント構造体定義と関数を記述するファイル
 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の場合、物理シミュレーションと衝突判定を行わない。
   */
 };

--自機のデータを生成する関数
 void initialize_self_agent( int map_x, int map_y,
                       int initial_hit_point,
                       dReal initial_direction_angle);

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

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

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

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

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

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

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

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

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

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

--敵機を初期化する関数
 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( int enemy_agent_index );

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

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

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

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


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