Logに戻る?
4月17日(月) ゲーム班初日 編集者:045714B 大城 信孝 †
ゲーム班の初日。
今期のゲーム班のメンバーは、
- 大城 和輝
- 大城 信孝
- 杉山 千秋
- 仲村 章吾
- 小野 雅俊
に決まりました。
自己紹介を行い、
- 氏名
- ゲーム班を選んだ理由
- 作りたいゲームの種類
を話しました。
ゲーム班の実験日は木曜日に決定。
班分けがまだなのと、最初の課題が
Blenderによる3次元モデルの作成
PS2で3次元モデルの表示
なのでしばらくはここにログを書くことにします。
4月20日(木) Blenderのインストール 編集者 045714B 大城 信孝 †
Blenderをダウンロードし、自分のiBookにインストール。
チュートリアルはここを参照。
4月25日(火) Subversionのインストール 編集者:045714B 大城 信孝 †
SubversionをiBookにインストール。
SubversionのMac OS X用バイナリはここからダウンロード。
4月25日(火) メモ 編集者:045714B 大城 信孝 †
PS2:Ginaにログイン
ssh j04014@gina.cr.ieu-ryukyu.ac.jp
sampleのダウンロード
svn co svn+ssh://game@firefly-old.cr.ie.u-ryukyu.ac.jp/home/one/repos/project/game/ps2/example
sampleの実行
(実行したいsampleのディレクトリに移動して)
make # コンパイル
su # rootになる
./main -obj ファイル名(hogehoge.xml) # 実行
とりあえず、
- example/simple/tags/second/simpleBall.xml
- example/simple/tags/second/cube.xml
- example/simple/tags/second/red_car.xml
を動かしてみました。
4月26日(水) メモ 編集者:045727C 杉山 千秋 †
blenderで作成したものとx3d2xmlで変換したものに違いがでる原因はどうやら親オブジェクトの宣言にあるようです。
『control + p』でオブジェクト間に親子関係を作り、blender上で親オブジェクトをいじると子オブジェクト
にも同様の変化がありますが、xmlでは親オブジェクトの変化だけが表現され、子オブジェクトの変化は無視
されています。
また、『control + j』で全体を一つのオブジェクトにして、頂点の数が2700を超えると表示できなくなってしまうことがわかりました。
7月15日(土) メモ 編集者:045727C 杉山 千秋 †
こまめにメモしていくのを忘れてしまったので、思い出しながらやってきたことをまとめていきます。
blenderでよく使うコマンド †
- 準備段階
- 編集する画面の分割・・・編集するマス目の画面の境界線上でマウスカーソルの形が変わったら『command +クリック』
- 選択関係
- tab オブジェクトモードとエディットモードの切り替え
- command + クリック オブジェクトモードではオブジェクトの選択、エディットモードでは頂点の選択
- shift + command + クリック オブジェクトや頂点の追加選択
- alt + command + クリック エディットモードで使い、選択した頂点が属する辺の集合を選択する
- A + クリック 選択したオブジェクトや頂点の全選択または選択の解除
- B + クリック 四角の範囲内にあるオブジェクトや頂点を選択。Bを2回押すと円形の選択範囲になる。この場合はtabで選択の終了
- 視点関係
- alt + ドラック オブジェクトを見る視点の角度を任意に変更
- alt + shift + ドラック オブジェクトを見る視点を任意にスライドする
- 移動関係
- G 選択したオブジェクトや頂点の移動。Gを押した後にx,y,zを押すことでその軸に平行して移動ができる。
- R 選択したオブジェクトや頂点の回転。controlを押しながら回転させると5度ずつ回転できる。もう一度Rを押すと回転方向が90度変わる。
- S 選択したオブジェクトや頂点の拡大縮小
- コピー/削除関係
- shift + D 選択したオブジェクトや頂点の複製
- X 選択したオブジェクトや頂点の削除
- E 選択した頂点や辺、面を複製して引き延ばす。
- 分割/結合関係
- P 選択した頂点や辺、面を別のオブジェクトに分割
- control+ J 選択したオブジェクトを一つのオブジェクトにまとめる
- F 選択した頂点で面を作る
- その他
- U エディットモードのUndo
- command + Z オブジェクトモードのUndo
- F1 ファイルを開く
- F2 セーブ
- オブジェクトの中心点変更
PanelsにあるEditingのMesh項目にある「Centre」「Centre New」「Centre Curso」を使う
- Centre オブジェクトを中心点に合わせて移動
- Centre New 中心点をオブジェクトに合わせて移動
- Centre Curso 中心点をカーソルに合わせて移動
オブジェクトモードでオブジェクト全体を移動させると中心点は一緒に移動する。
オブジェクトを追加するときはカーソルを中心点としてオブジェクトが置かれる。
- 面ごとの色の変更
- 色を変えたい部分をエディットモードで選択する。
- PanelsにあるEditingのLink and Materialsの『New』を押す。
- 上の表示が『2 Mat 2』になったら『Assign』を押す。
- PanelsにあるEditingのShadingのMaterialのMEの部分を『2 Mat 2』に
- Materialの選択をADD NEWにする。これで色が変更できる。
- テクスチャーの貼り方
- 編集画面を2つ以上用意する。
- オブジェクトモードを「UV Face Select」に変更する。
- 編集画面の左下にあるモードを「3D View」から「UV/Image Editor」に変更
- ImageのOpenで画像ファイルを選択
- 後は貼りたい部分等をオブジェクトモード等の操作と同様に編集していく
- カクカクをなくして丸っぽくする
- PanelsにあるEditingのLink and MaterialsのSet Smootを押す。
PS2で使用するオブジェクト作成での注意点 †
- 使用できるオブジェクトはMeshで宣言したものだけ。Surface等は使えない。
- x3dとlwoでの違い
- x3dからxmlに変換した場合
- テクスチャーが貼れる。
- blenderでのオブジェクトの中心を全てblender上の中心に揃えないとPS2での表示がずれてしまう。
- lwoからxmlに変更した場合
- オブジェクトごとの中心点は関係ない。blenderの中心との位置関係がそのまま反映される。
- blenderでの色の変更がそのまま反映される。
- テクスチャーは貼れない。
ベクターユニット †
blenderで作成したオブジェクトの表示の次の課題はベクターユニットを用いてレースゲームで車のタイヤを回すこと。
ベクターユニットは行列の乗算やコピー、内積等を計算する関数です。オブジェクトが向いた方向に移動したり、オブジェクトにカメラが付いていくような処理をするときに使います。主なベクターユニット関数を以下に示します。
- void ps2_vu0_apply_matrix(ps2_vu0_fvector v0, ps2_vu0_fmatrix m0, ps2_vu0_fvector v1)
- マトリックスm0にベクトルv1を右から乗算してv0に与える
v0 = m0 * v1
- void ps2_vu0_add_vector(ps2_vu0_fvector v0, ps2_vu0_fvector v1, ps2_vu0_fvector v2)
- ベクトルv1の各要素とベクトルv2の各要素を各々加算してv0に与える
v0 = v1 + v2
- void ps2_vu0_copy_vector(ps2_vu0_fvector v0, ps2_vu0_fvector v1);
- void ps2_vu0_unit_matrix(ps2_vu0_fmatrix m0);
- void ps2_vu0_rot_matrix_x(ps2_vu0_fmatrix m0, ps2_vu0_fmatrix m1, float rx);
- X軸を中心とした行列の回転
回転角rxよりX軸を中心とした回転行列を求め、マトリックスm1に左側から乗算して、その結果をマトリックスm0に与える。
X軸だけでなくY軸、Z軸を中心とした関数もある。また3ついっぺんに回転させる関数もある。
その他にも多く存在するので詳しくはlibvu0.cを参照のこと。
関数を知ることよりも、ベクトルの乗算や内積で何ができるかを把握することが重要になります。
カメラや光源などの設定にもベクターユニットを用います。
オブジェクトの移動とカメラの設定の勉強として作ったものをgame/ps2/awinに置いておきます。
Lindaについて †
ネットワーク型のゲームを作成するために使用したLindaについてまとめる。
Lindaとは、タプルと呼ばれるIDとDATAがセットになったものを、各クライアントがLindaサーバに対して書き込み、読み込み等を行うことでデータの交換、共有を行い、通信をしているシステムである。以下にLindaのAPIを示す。
- void start_linda(hostname);
- 通信を初期化して、Linda APIをhostnameで使用可能にする
- int psx_out(int id, char *data, int size);
- dataが示すアドレスから、指定したIDのタプルにsize byteのデータを書き込むコマンドである。
- int psx_in(int id);
- 指定したIDのタプルを読み込みsequence番号を取得する。指定したIDのタプルはデータを読み込んだ後サーバ上から削除される。
- int psx_rd(int id);
- 指定したIDのタプルを読み込みsequence番号を取得する。指定したIDのタプルはデータを読み込んだ後もサーバ上に残る。
- void psx_sync_n();
- psx_out(),psx_in(),psx_rd()等のタプル送受信のAPIを実行した段階ですぐに通信が行われるのではなく、送信タプルはCOMMANDキューに、受信タプルはREPLYキューにためられる。このpsx_sync_n()はそれをプログラマの好きなタイミングで一気に送受信するためのAPIである。
- unsigned char psx_reply(int seq);
- psx_in()かpsx_rd()で取得したシークエンス番号を引数として渡すと、要求したデータがREPLYキューにあればタプルへのポインタを返す。そのポインタには、先頭にタプルのヘッダ情報12byteが格納されていて、その後にデータが格納されている。
- void psx_free(unsigned char reply)
- psx_reply()で取得したタプルを消去する。これをしないとREPLYキューにデータが溜まってしまう。
Lindaでの通信の流れを下の図で示す。
図からも分かるように実際にLindaにアクセスするのはpsx_sync_n()を実行したときだけである。つまりLindaは非同期である。psx_sync_n()が実行されるまで通信は行われないので、相手との同期はとれません。この方式なのでプロセッサは待ち状態のときに余分な情報を処理する必要がなくなる。
実際には図のように送信側と受信側がきっちり分かれるのではなく、全てのクライアントが送受信することになる。
linda使用時に気をつけること †
Lindaは非同期なので送信元は受信先が受信したのを確認してからpsx_out()を行う必要がある。そうしなければLindaサーバにタプルが溜まってしまい処理が重くなってしまう。なので受信側も受信したことを示す為のタプルを送り、送信側はそのタプルをpsx_in()かpsx_rd()で受け取ってから、次のpsx_out()をしなければならない。
データが更新されていないのにpsx_out()を繰り返してしまうことでもLindaサーバに負荷がかかってしまう。なので以下のようにしてデータが更新されたときだけpsx_out()をする必要がある。
if(key!=old_key){
psx_out(id,key,sizeof(key));
}
また、psx_reply()が完了したら、psx_free()を実行してREPLYキューにデータが溜まるのを防ぐ必要がある。
今回のゲーム班の主な作業 †
一応役割分担は
こんな感じってことになってます。
レースゲームの改良では、y03/後期のゲーム班が作成した「五木さんレーシング」に主に以下の改良を加えました。
- コースが崩れるのを軽減し、コースの見た目をUP
- カーブ時に車体の横が見えるようにした
- タイムの表示
- タイトル画面や文字等に使用するpngファイルをよりきれいに
プログラムでもちょくちょく細かいところの改良はしましたが、見た目重視の改良を加えました。以下に詳しく載せます。
コースの改良について †
コースの改良はblender上での工夫が大きな鍵になりました。
コースが崩れる原因は、処理を軽くする為にカメラの後ろにいったオブジェクトの頂点の削除をする行う処理の設定が悪いせいらしいです。本当はそこを直すべきなのですが、かなりしんどそうなのでblender上で調整しました。
コースのオブジェクトを大きな長方形一枚にするのではなく、blenderのMeshの中にあるGridのように細かくオブジェクトを分割することで、コースが崩れるのを軽減しました。
しかしこの方法ではオブジェクトの頂点の数がかなり増えるので、コースを細かく分けて読み込まなくてはならなくなりました。
またカメラをコースから少し離れたところに設置することでもコースが崩れるのを軽減させました。
それでもまだ少し崩れるところが確認できるので、やはり元を絶たないとダメみたいです。
カーブ時の改良について †
前のレースゲームではカーブの時もカメラが車の真後ろを移していて、カーブを曲がったという感じがしなかったのでそこを改良しました。
具体的には十字キーの左右が押されたとき、カメラのアングルを少し傾けるようにしました。
if(pad.left>0 && game.jiki->speed !=0){
if(def_camera.angle[1]<=0.2){
def_camera.angle[1]+=0.02;
}
}
else if(pad.right>0 && game.jiki->speed !=0){
if(def_camera.angle[1]>=-0.2){
def_camera.angle[1]-=0.02;
}
}
else {
if(def_camera.angle[1]<-0.01){
def_camera.angle[1]+=0.02;
}
else if(def_camera.angle[1]>0.01){
def_camera.angle[1]-=0.02;
}
タイムの表示 †
タイムはclock()を使って実時間に近い値を得て、フォントを表示するスプライトを使って表現しています。
しかしこの方法だとlindaでの通信時など処理が重くなるとタイムの表示も遅くなってしまいます。なのでPS2本体の内部時計を用いてタイムの計測をする方が望ましいやり方ですが、その実装まではできませんでした。
pngファイルの改良 †
まさに見た目の改良になる部分です。元々PS2上でpngを表示をするとかなり明るく映るのでそれをふまえてpngの作成をしなくてはなりません。また黒は透過処理されるように設定されていることも注意しなければなりません。
pngのファイルは縦横の大きさが2^nである必要があります。またnが0<n<10の整数でなくてはなりません。n=10の1024の大きさのpngを使うと表示がバグってしまいます。しかし元のpngが小さくてそれを拡大表示すると、かなりPS2上での表示がぼやけてしまします。なのでタイトル画面等のように表示だけの処理ですむ場面では極力大きなpngを使いました。
後はきれいな絵を描いてpngに出力するだけです。
最後に †
僕たちが改良を加えて出来上がった『孫六レーシング』はsvnの
game/ps2/magoroku_racing
に置いてあります。
ついでにベクターユニットとカメラの勉強の為に作った『スターフォックスもどき』も
game/ps2/awin
に置いておきます。
おまけとお願い †
『孫六レーシング』の名前の由来を書きます。
『五木さんレーシング』を改良して作ったので「五の次は六だろ」と思って六のつく名前にしました。
もしこの孫六レーシングが改良されて、あるいはまた新たにレースゲームを作る人がいたら是非次のレースゲームの名前には『七』を入れてください。
こういうのがあった方が「代々続いてるんだなぁ」って感じがでるような気がするもんでさ。