第 5 回:はじめての3Dプログラミング・すごい、星がいっぱいだ編

プロジェクト演習Ⅱ
インタラクティブゲーム制作
第5回
はじめての3Dプログラミング
すごい、星がいっぱいだ…編
今日の内容
• 配列と繰り返し
– プログラミング演習に先駆けてやっちゃう
• 当たり判定の初歩の初歩
– まずはシンプルで簡単なところから
今週のプロジェクト
• 授業資料ページからダウンロードします
– 落としたZipファイルを解凍して、
出てきたフォルダを好きなところに配置
• 今週のFKUT更新情報
– 衝突判定関連の機能を追加
今日のサンプル
• 丸がいっぱい出ます
• それにぶつかれます
先週の例題について
• かなりの人から「早すぎる!」
「見えない!」「分かんない!」との声を
頂戴しました
– スンマセン
– 見えない人は出来るだけ前に来て下さい
– タイピング速度は致し方ない部分もありますが、
エラー対策をしっかりしましょう
• 前回分については追記したものをアップして
おきます
– 出来れば自力で打つ経験を通じて学んで欲しいの
で、眺めて分かった気分にはならないように!
エラー対策
• 行番号を表示する
– ツール→オプション→テキストエディタ
→C/C++→全般→行番号、にチェック
• ビルド前には必ず前に動かしていたプロ
グラムは終了しておく
• エラーメッセージはダブルクリックする
と原因行に飛ぶので、そこでタイプミス
や文法ミスを調べる
一応プログラミング演習にあわせて自重してたんだけど
配列、使っちゃいます
C++での配列
• Javaより簡単に扱えます
– int
– double
iDs[10];
dDs[20];
• これだけでOK
• あまり無茶な数量はやめてあげてね
– fk_Vector や fkut_(ほげほげ)Model とかも
配列として使ってOK
何故配列を使うのか?
• 繰り返しと組み合わ
せると嬉しいから!
fkut_SphereModel maru[20];
for(int i = 0; i < 20; i++) {
maru[i].glMoveTo(-100.0 +
i*10.0, 0.0, 0.0);
maru[i].create(4, 5.0);
window.entry(&maru[i]);
}
• 座標値を計算して、
ずらっと細かい物体
を並べたりできます
• 共通の設定項目をま
とめて書けます
どんどん使いましょう
• いっぱい敵を出したり、地形用のパーツ
を作るときには配列の方が便利なことが
多いです
• iを座標値の計算に使うと、手間のかかる
配置が楽できたり、計算式次第では美し
い形ができたりします
– 2重、3重のループにすれば平面や立体空間に
展開する形状が作れます
配列を使う上での注意点
• 添え字が[要素数-1]を超えないように!
– iDs[10]で作ったら0,1,2,…,8,9までです
– オーバーした場合、落っこちるならまだよし、
落ちずに不可思議な挙動をすることも。。。
ガチ数学の世界へようこそ
当たり判定の基礎
衝突判定とは
•
•
•
•
CG上で物がぶつかっているか
どこでぶつかったか
いつぶつかったか
どのくらい位置を動かすと帳尻が合うか
• などなどを計算して求める、絶望的な
までに数学スパイラルな技術分野である
衝突判定用の形状
• 見た目重視で表示している形状で厳密な
判定をすると、大量にぶつかる物体が存
在するゲーム(無双など)はやってられ
ないことになる
– 力業で考えた場合、物体数*物体数の回数分
判定処理を行わなければならない
• 判定用の簡易形状を用意し、裏ではそれ
で計算するのがセオリー
球ベース判定
• 球
– シンプルイズベスト
– 球だけで押し通すのは厳しいが、他の判定と併用
することも多い
– 球の中心を「点」から「線分」に拡張することに
より、「カプセル」へと進化する
• カプセル
– 球よりボリュームの広いエリアをカバー
– 球の弾丸貫通問題対策としても使用
– ボーンのように組み合わせれば人型キャラの判定
は十分作れる
球とカプセル
• 中心間の距離が、お
互いの半径の合計よ
り小さかったら衝突
• 球がうぞぞぞぞっと
動いた軌跡
• 組み合わせて人型に
したり、弾丸貫通
問題への対処に使う
判定の原理
• 2つの球の中心点をA,Bとする
• 2点(A,B)間の距離は以下のように表せる
– C=B-A
– dist = √(C.x*C.x + C.y*C.y + C.z*C.z)
• 2点間の距離が2つの球の半径の合計以上
なら未衝突、以下なら衝突発生
とりあえず
• 前のような細かいことはこっちでやって
おきました
• create()したもの同士はすぐ判定できます
– sphere.checkToSphere(other_s, back);
• other_sの部分に他のSphereModelを、backには
空のfk_Vectorを渡す
– if(命令 == true)でYesなら衝突している
• backの部分に渡したfk_Vectorには、sphereを
どれだけglTranslate()すれば衝突寸前まで戻せる
かを表す戻しベクトルが入る
戻し方
• 操作キャラVS障害物全部の判定が必要
• 1つずつ調べ、ぶつかっていたらめり込み
分動かして元に戻す
• 障害物が別々変数だと大変、だが。。。
– 配列を使うことで繰り返しで片付けられる
注意点
• あまり高速に動かしていると、貫通して
しまう場合がある
– 速度が大きい場合は、少しずつ動かして判定
するのが吉
• 物体が密集していると、押し合いへし合
いしてあらぬ方向へ押し出される
– ゲームを構成する最低限の配置を工夫しよう
次回に向けての課題
• 今回のサンプルはジャンプ関係の処理を
一切入れていません
• どう組み合わせたらいけるだろう?
• ジャンプして乗っかるってどうすれば?
今回の課題
• BASIC
– ボンバーマン的なフィールドを作ってみよう
• ADVANCED
– マリオ64的なフィールドを作ってみよう
• EXTREME
– 物体をぐいぐい押せるようなフィールドを
作ってみよう(かなり難)