Advanced Programing 2012?

目次

第5回以降の趣旨

企業や研究でのプログラム開発では、開発の効率化やバグ等を減らすため
同じような処理は関数等にまとめて、ライブラリ化する事が良く行われます。
そこで今回はゲーム開発を題材にライブラリ開発の意義や方法について学びます。

ライブラリを開発するのにも別のライブラリを使用することは良く行われます.
今回の課題では、3次元物理シミュレータとしてOpen Dynamics Engineを使用して、
ライブラリの使用と開発の両方を経験する事によって、使いやすいライブラリや
開発やメンテナンスしやすいライブラリはどのようなものかを実際に作る事で考えてもらいます。

最終目標

楽しいゲームを開発しやすくするゲームライブラリの開発

サンプルコードのインストール

演習室(linux)でのインストール

適当なディレクトリに移動して,以下のコマンドを実行します.

$ wget www.er.ams.eng.osaka-u.ac.jp/kawai/AP2016/ap2014_gamelib_linux_20140507.zip
$ unzip ap2014_gamelib_linux_20140507.zip
$ cd ap2013_gamelib_linux_20140507
$ ./start.sh

./start.sh スクリプトによりODEの解凍、コンパイル、インストールと 今回の課題のサンプルプログラムのコンパイルとインストールが行われます。
サンプルプログラム(演習室 VineLinux? 用)へのリンク http://www.er.ams.eng.osaka-u.ac.jp/kawai/AP2016/ap2014_gamelib_linux_20140507.zip
演習室のVine Linuxにて動作確認しています。

Mac OSXでのインストール

Mac OSXや最新のlinuxで行いたい場合は以下のファイルをダウンロードしてインストールして下さい。

$ wget www.er.ams.eng.osaka-u.ac.jp/kawai/AP2016/ap2015_gamelib_mac_20150328.zip
$ unzip ap2015_gamelib_mac_20150328.zip
$ cd ap2015_gamelib_mac_20150328
$ ./start.sh

./start.sh スクリプトによりODEの解凍、コンパイル、インストールと 今回の課題のサンプルプログラムのコンパイルとインストールが行われます。 ODEの最新版を使っています。 Linuxの場合と同じコマンドを実行しますが、
ODEをコンパイルするためには予めMacPorts?HomeBrew?等を用いて、
freeglut等のOpenGL関係のライブラリをインストールしておく必要があります。 (最新のODEは演習室の環境でコンパイルできず、古いODEはOSXで動作しません)
サンプルプログラム(演習室 MacOS X 用)へのリンク http://www.er.ams.eng.osaka-u.ac.jp/kawai/AP2016/ap2015_gamelib_mac_20150328.zip

権限がないと怒られるときは

$ chmod 777 ./start.sh

でやってみる。

Open Dynamics Engine とゲームのサンプルプログラム

インストールしたライブラリ等の解説は次のページに詳しく書いてあります。
gamelibの解説?

ODE付属のデモプログラムを動かしてみよう

以下のディレクトリにはODEが解凍されています

src/ode-0.11.1 # または src/ode-0.13(最新ODEバージョン)
$ cd src/ode-0.11.1/ode/demo/ # または、src/ode-0.13/ode/demo/
$ ./demo_crash

サンプルプログラムを動かしてみよう

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

サンプルプログラムでは、敵(enemy_agent)がランダムに動いており、
弾を撃って当てるとhit_pointが減少し、0になると消滅します。
全ての敵が消滅するとGame Clearが表示され、ゲームが終了されます。
自機(self_agent)と敵の本体が接触すると、
自機のhitpointが減少し、0になるとGame Overが表示され、ゲームが終了されます。

サンプルプログラムの構造を理解しよう

application/shooting_game

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

src/gamelib

にはライブラリのソースコードが入っています。

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

main.c

に、drawstuffによるシミュレーション管理のための構造体や関数が書かれており。

shooting_game.c

に、実際のゲームのロジックが書かれています。

練習1:サンプルを改造してみよう

マップの変更

shoogint_game.c

には

start()

という関数があり、ゲーム環境の初期化を行っています。
そこにマップを構成するための関数が書かれているので、
関数を修正してマップを変更してみましょう。
最初のマップは3x3ですが、ライブラリのソースを変更するともっと大きなマップにする事は可能です。
何を変更すれば良いか、ソースコードを読んで調べてみよう。

基本的な処理を行う関数を作成し、必要に応じて引数や組み合わせを変更して、
様々なアプリケーションを作成する事を可能にするのがライブラリ開発の醍醐味です。
マップの変更はその1つなので、まず始めに挑戦してみてください。

敵エージェントの追加

shooting_game.c

start()

では、敵エージェントの配置についても初期化しています。
関数を追加して、敵エージェントの数を増やしてみましょう。
なお、

simLoop(int pause)

stop()

も敵エージェントについてのコードの追加が必要になります。

コンパイル

コンパイルには

$ ./start.sh

をすればよいのですが、改めてODEをインストールする必要はないので、

start.sh

中の

tar zxvf ode-${ODE_VERSION}.tar.gz

から、

cp drawstuff/src/.libs/libdrawstuff.* ../../lib/

までを#でコメントアウトしてください。 それと、その下の

cd ../gamelib/

cd gamelib/

に書き換えてください。

練習2:自機エージェントに近寄る敵エージェント

enemy_agent.h

enemy_agent.hに

#define ENEMY_AGENT_SPEED 1.2
#define FLAG_DISTANCE_ENEMY_TO_SELF_AGENT 1.5

を加える。
ENEMY_AGENT_SPEEDは敵エージェントが自機エージェントに近寄る速さ。
FLAG_DISTANCE_ENEMY_TO_SELF_AGENTは敵エージェントが自機エージェントに近寄る行動をする範囲。範囲外だと近寄ってこない。
次に、update_enemy_agent関数の引数を次のように追加する。

void update_enemy_agent( int enemy_agent_index, const dReal* self_agent_position);

enemy_agent.c

まずはmath.hのインクルードを追加。

#include <math.h>

そして、update_enemy_agent関数を改造する。
引数に自機の位置を示す変数を追加。

void update_enemy_agent( int enemy_agent_index, const dReal* self_agent_position){

次に、

force[2] = drand48()

の下で、対象となっている敵エージェントの位置を取得する。

const dReal* enemy_agent_position = dBodyGetPosition(enemy_agent_data[ enemy_agent_index ].body_ID);

自機エージェントと敵エージェントの距離を計算する。

double distance = sqrt((self_agent_position[0] - enemy_agent_position[0])*(self_agent_position[0] - enemy_agent_position[0]) + (self_agent_position[1] - enemy_agent_position[1])*(self_agent_position[1] - enemy_agent_position[1]));

その距離がFLAG_DISTANCE_TO_SELF_AGENTより小さければ,その距離に応じた大きさの,敵エージェントから自機エージェントに向かう力を敵エージェントに与える。

 if(distance < FLAG_DISTANCE_ENEMY_TO_SELF_AGENT){
     force[0] = (self_agent_position[0] - enemy_agent_position[0]) * ENEMY_AGENT_SPEED;
     force[1] = (self_agent_position[1] - enemy_agent_position[1]) * ENEMY_AGENT_SPEED;
     force[2] = 0.0;
     dBodyAddForce( enemy_agent_data[ enemy_agent_index ].body_ID, force[0], force[1], force[2] );
 }
 else{
     dBodyAddForce( enemy_agent_data[ enemy_agent_index ].body_ID, drand48()-0.5, drand48()-0.5, drand48()-0.5 );
 }

shooting_game.c

simLoop関数を改造する。
update_enemy_agent関数に関するif文の前に,自機エージェントの位置を取得する。

const dReal* self_agent_position = get_self_agent_position();

update_enemy_agentの引数にself_agent_positionを追加する。IDが0の敵エージェントの場合、

update_enemy_agent( 0,  self_agent_position);

課題

物理シミュレータ(ODE)を使ったシューティングゲームを作ろう(6月1日までの課題)

ライブラリを書き換えゲームシステムを完成させる。
下記項目を全て行う。
自由度の高い課題は自分なりのアイディアを実現して良いですが、
思いつかなければ(例)の一つを実現して下さい。

シューティングゲームツクールを作ろう(6月22日までの発展的課題)

最終目標へ近づく!:「楽しいゲームを作るためのゲームライブラリの開発」

工夫して、自分なりのゲームシステムを持つライブラリとアプリケーションを作成して下さい。
提出時に全員の前で、作成したゲームを見せながらプレゼンしてもらいます。
独創的なシステムやキャラがあるほど評価を高くします。

注意事項

サンプルコードにバグがある可能性や、課題が分かりづらい等の問題点がある可能性もあります。
何か気がついた事があれば担当教員やTAに連絡をお願いします。

課題の達成方法等にあまり細かいルールは設定しません。
ライブラリを全面的に書き換えて、C++にしてもらっても構いません。
サンプルより良いゲームライブラリにしてくれれば、1つ1つの課題をクリアするよりも良い評価にします。
その代わりしっかり動く様にして来てください。

提出方法

評価方法

第9回(6/22)のプレゼンテーション資料

  1. ゲームタイトル,学籍番号,氏名
  2. 概要
  3. (実演)
  4. 工夫した点,頑張った点

参考になる情報

質問がある場合


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