Mercurial > hg > Papers > 2009 > koba-thesis
view A-5-4-055722/A-5-4-055722.tex @ 11:ed5a8511ad3c
finish.
author | e055722 |
---|---|
date | Wed, 25 Feb 2009 20:12:48 +0900 |
parents | b8cfcefb7e56 |
children |
line wrap: on
line source
\documentclass[twocolumn,twoside,9.5pt]{jarticle} \usepackage[dvips]{graphicx} \usepackage{fancyhdr} \usepackage{picins} \pagestyle{fancy} \lhead{\parpic{\includegraphics[height=1zw,clip,keepaspectratio]{pic/emblem-bitmap.eps}}琉球大学主催 工学部情報工学科 卒業研究発表会} \rhead{} \cfoot{} \setlength{\topmargin}{-1in \addtolength{\topmargin}{15mm}} \setlength{\headheight}{0mm} \setlength{\headsep}{5mm} \setlength{\oddsidemargin}{-1in \addtolength{\oddsidemargin}{11mm}} \setlength{\evensidemargin}{-1in \addtolength{\evensidemargin}{21mm}} \setlength{\textwidth}{181mm} \setlength{\textheight}{261mm} \setlength{\footskip}{0mm} \pagestyle{empty} \begin{document} \title{ SceneGraphを用いたゲームプログラムの為のテスト作成手法} \author{055722G 小林 佑亮 {}{} 指導教員 : 河野真治} \date{} \maketitle \thispagestyle{fancy} \section{研究背景・目的} 当研究室では学生実験において、PlayStation3を用いた並列的な ゲームプログラムの作成を行っている。そこで使用されるのが当 研究室で開発したCeriumレンダリングエンジンである。Ceriumを 用いたゲームプログラムの例題としてPlayStation2で動作してい た超弾帝(スーパーダンディ)というゲームの移植を行った。 その際、オブジェクトの描画、衝突判定などで不具合が発生した。 超弾帝には約100種類に及ぶオブジェクトが存在し、今後も同様な 不具合を修正していく必要があると考えられる。 本研究ではゲームプログラムをSceneGraph単位でテストすることで オブジェクトごとの振る舞いや描画をチェックする。これにより、 ゲームのデバッグを容易にし、今後の学生実験におけるゲームの移植や 改良、作成を円滑にすることができる。 \section{SceneGraphによるゲームフレームワーク} ゲームの中の一つの場面(Scene)を構成するオブジェクトやその振 る舞い、ゲームのルールの集合をSceneGraphとする。SceneGraph のノードは親子関係を持つTreeで構成される。(図\ref{fig:sglist}) \begin{figure}[htbp] \includegraphics[width=8.5cm]{pic/SceneGraph.eps} \caption{SceneGraph} \label{fig:sglist} \end{figure} 親子関係とは、親オブジェクトの回転や並行移動等の行列計算に よる頂点座標の変更が子オブジェクトにも反映する関係の事であ る。これは子に対してスタックに積まれた親の変更行列を掛ける 事で実現できる。 ゲーム内で使用するオブジェクトはBlenderというオープンソース の3次元コンピュータグラフィックスソフトウェアで作成する。作 成したオブジェクトモデルはpythonスクリプトによりxmlファイル に変換され、それを元にSceneGraphが生成される。 生成したSceneGraphの各ノードには、オブジェクトの動きを決める \verb+move+ という関数と、オブジェクトの相互作用を決める \verb+collision+という関数を入れる変数がある。この変数は、 \verb+set_move_collision+という関数によって変更される。 \subsection{move} 以下の例では、\verb+boss1_move_right+は、ボス1を右に \verb+node->stack_xyz[0]+だけ移動させる。スクリーン 適当な位置にくると、\verb+move+をボス1を左に移動される関数 \verb+boss1_move_left+に設定する。 {\scriptsize \begin{verbatim} static void boss1_move_right(SceneGraphPtr node, int screen_w, int screen_h) { node->xyz[0] += node->stack_xyz[0]; if(node->xyz[0] > screen_w-280) { node->set_move_collision(boss1_move_left, boss1_collision); } } static void boss1_move_left(SceneGraphPtr node, int screen_w, int screen_h) { node->xyz[0] -= node->stack_xyz[0]; if(node->xyz[0] < 280) { node->set_move_collision(boss1_move_right, boss1_collision); } } \end{verbatim} } この\verb+move+では、ボス1が常に画面内に描画されている必要がある。 これはテストすべき条件の一つとなる。 \subsection{collision} この変数は、オブジェクトの衝突判定する関数を入れる。 例えばシューティングゲームなら自機と敵、または、弾 を引数に持ち、 当たった時のダメージや、ゲームオーバーの判定を行なう。 判定にしたがって、 \verb+set_move_collision+により新しい\verb+move,collsion+ を設定する。これは、State Pattern と呼ばれるパターンである。 \section{CppUnitを用いたSceneGraphのテスト} CppUnitは、C++の単体テストを自動化するframe workである。 CppUnitの特徴は、テストケースを増やす事が容易 であり、1つの事象に対して様々なテストケースを同時にテストす る事が出来る。また、羅列したテストケースは一括で実行、結果 の表示ができる。(図\ref{fig:cpptest}) \begin{figure}[htbp] \includegraphics[width=8.5cm]{pic/test_state.eps} \caption{CppUnitTest} \label{fig:cpptest} \end{figure} \subsection{ゲームプログラムのテスト} 3つのSceneGraphを持つオブジェクトのテストを行った。このオブ ジェクトは本体の他に左右にパーツを1つずつ持つ。本体をTreeの rootとして左右のパーツがその子供になっている。(図\ref{fig:boss1}) \begin{figure}[htbp] \includegraphics{pic/boss1.eps} \caption{Boss1} \label{fig:boss1} \end{figure} \newpage ここで、各オブジェクトのSceneGraphはその親や子、兄弟に対す るアドレスを保持している。従って、パーツオブジェクトのテス トを行いたい場合は、そのオブジェクトのRootである本体から辿 れば、パーツオブジェクトの各パラメータを参照する事が出来る。 そこで、Rootのアドレスを取得するgetSGP()という関数を作成し た。getSGP()関数によって取得してきたRootのアドレスを使って、 各オブジェクトの座標を取得し、その初期化が正しいか、状態遷 移において正しい値を保持しているかテストした。 {\scriptsize \begin{verbatim} void sgTest::rootTest() { test_init(); sg_root->print_member(); CPPUNIT_ASSERT_EQUAL((float)width/2, sg_root->xyz[0]); CPPUNIT_ASSERT_EQUAL(0.0f, sg_root->xyz[1]); CPPUNIT_ASSERT_EQUAL(-100.0f, sg_root->xyz[2]); } void sgTest::childTest() { while (sg_root) { if(sg_root->children != NULL) { sg_root->children->print_member(); ... sg_root = sg_root->children; } else if(sg_root->brother != NULL) { sg_root->brother->print_member(); CPPUNIT_ASSERT_EQUAL(0.0f, sg_root->brother->xyz[0]); ... sg_root = sg_root->brother; } else { ... \end{verbatim} } このテストの結果、全てのオブジェクトの位置の初期値が正しいことは 確認できた。 Ceriumにおいてもこのテストケースは有効であった。 \section{今後の課題} しかし、\verb+move,collision+中の各オブジェクトの座 標は確認出来なかった。よって\verb+move,collision+を テストする為に各\verb+move,collision+を別々に抜き出して テストする手法を今後実装していく。 \thispagestyle{fancy} \begin{thebibliography}{9} \bibitem{1}宮國 渡, 河野 真治, 神里 晃, 杉山 千秋: Cell 用の Fine-grain Task Manager の実装, 第108回システムソフトウェアとオペレーティング・システム研究会(2008) \bibitem{2}高橋 寿一:知識ゼロから学ぶソフトウェアテスト, 翔泳社 (2005) \bibitem{3}伊藤 喜一:CppUnit入門, (http://www.ogis-ri.co.jp/otc/hiroba/technical/CppUnit/) \end{thebibliography} \end{document}