トップページ > 記事閲覧
Sword Bout をステージオブジェ無しで
名前:軽い3Dアクション作りたい男 日時: 2015/04/05 14:46

 管理人さん、はじめまして、こんにちは、 お尋ねしたいことがあります。 サンプルゲーム『Sword Bout』 の「攻撃とステージ・オブジェクトの衝突判定」 については知りたいのです。 私は 「超本格!サンプルで覚えるC言語 3Dゲームプログラミング教室」 を購入した者なのですが、 「攻撃とステージ・オブジェクトの衝突判定」 については 本の中では258ページの真ん中あたりから、 260ページの始めあたりに記述があるだけでした。 『Sword Bout』を、試しに全ての「オブジェクト」を削除して、一つもオブジェクトがない状態にして ゲームを起動してみようと思いました。 『Sword Bout』のパッケージファイル 同梱の「StageEditor」で「オブジェクト」を 全て削除して、 「イベント」 「クリア条件」 「敵データ」は、そのまま 「VS Express 2013 for Desktop」で 「SwordBout.vcxproj」 プロジェクトファイルを開き、 「デバックを開始」で ゲームを起動しました。 .cppファイル、 .hファイルは一切弄っていません。 「ウィンドモードで起動」、 「低処理負荷モードで起動」、 「オープニング」で「ゲームスタート」を選択、 「STAGE1」表示、 ステージ描画、 プレイヤーキャラ現れ、 BGMが流れ、 敵も現れ、 岩、木、草、柵、無い状態でゲームがスタート 上下左右移動、良し 上下左右カメラ周回、良し、 ジャンプ、良し ガード、良し ところが「攻撃ボタン」押して 「プレイヤーキャラ」の攻撃モーション が始まると同時にゲームがと止まり、 「ダイアログボックス」が表示されました。 「ハンドルされない例外が 0x016A635E (SwordBout.exe) で発生しました  : 0xC0000005: 場所 0x16C23FE6 の読み取り中にアクセス違反が発生しました」 と出ました。 「プレイヤーキャラ」の攻撃だけではなく 「蜂」 「ゴブリン緑」 「ゴブリン赤」 の攻撃でもゲームが止まり、 同じ内容の「ダイアログボックス」 が表示されました。 プレイヤーキャラ、敵、共に攻撃を 空振りしても 敵をロックした状態でも 武器を振り始めた瞬間止まるのです。 原因の場所は、 「Chara.cpp」の 「Chara_AttackInfo_Check」関数、 3791行の // 当たり判定結果の後始末 MV1CollResultPolyDimTerminate( HitDim ); のようです。   どうやら3654行で、 関数「MV1CollResultPolyDimTerminate」に、 コリジョン結果ポリゴン配列の 後始末をされた「HitDim」が、 (本来なら、3656行のfor文{}内で、 「HitDim」に当たり判定結果が 代入されるはずが、 「オブジェクト」が一つもないので、 「StageObjectNum」の値は「0」、 for文{}内は一度も実行されず、 「HitDim」は後始末をされたままの状態で、) 3791行の関数「MV1CollResultPolyDimTerminate」に、 後始末をされたのが原因のようです。  関数「MV1CollResultPolyDimTerminate」 がメモリ領域を動的に確保しているので 「MV1_COLL_RESULT_POLY_DIM」構造体の メンバ構造体ポインタ 「MV1_COLL_RESULT_POLY*」のメモリ領域を 開放したあと、 開放された領域をさらに 開放しているのが問題なんだと 思いますが、 「MV1_COLL_RESULT_POLY*」には 関数「MV1CollCheck_Triangle」等で 動的確保されたメモリ領域のアドレスが代入されるの のだと思いますが、 関数「MV1CollResultPolyDimTerminate」で後始末が されても、「MV1_COLL_RESULT_POLY*」によって 指し示されたアドレスのメモリ領域が開放された だけで、「MV1_COLL_RESULT_POLY*」にはメモリ領域 のアドレスがそのまま残っているのではありませんか? 間違っているかもしれませんが、このサンプルは、 ステージに「オブジェクト」が一つもない状態で、 「プレイヤーキャラ」又は「敵」が攻撃をすると ゲームが止まってしまうようなのです。  ひょっとしたら、当たり判定を持つ オブジェが一つでも有れば問題は 解決するのではないか? と思い、ステージに 「Stage_Obj001」木を一本 置いてみました、 すると、 プレイヤー、敵、共に攻撃を 空振りしても、 敵に当てても、 敵がプレイヤーに当てても ステージモデルに当てても、 止まらなくなりましたが、 ステージオブジェクトの 木に攻撃を当てようとしたら ゲームが止まってしまい、 同様のダイアログが出ました。   当たり判定のない、オブジェクトなら どうだろうと思い (「StageObjectNum」の値は1になるから) 「Stage_Obj006.mv1」草を一つ置いてみました すると、空振りでゲームが止まり、 同様のダイアログがでました。 何も置いてないときと同じでした。 当たり判定を持つオブジェが複数有れば どうだろうと思いステージに 「Stage_Obj001」木を2本 置いてみました、すると、 プレイヤー、敵、共に攻撃を 空振りしても、 敵に当てても、 敵がプレイヤーに当てても ステージモデルに当てても、 止まらなくなりました さらに一本目の木(0番のオブジェ) を叩いても止まらなくなりました。 何度、どの方向から叩いても止まりません。 しかし、二本目の木(1番オブジェ)は、 叩こうとすると止まったり 一回、二回叩けたと思ったら、 二振りめ、 三振りめで、止まったり、 とまったら同様のダイアログでます。  サンプルゲーム『Sword Bout』のプログラムは ステージオブジェクトを置かない状態で ゲームを動かす事を想定してないのでしょうか? 教えてください。 やった事、 『Sword Bout』のパッケージファイル同梱の「StageEditor」で「Stage00.dat」ファイルを編集 「オブジェクト一覧」のオブジェクトを、 「オブジェクト削除ボタン」で削除、 画面左上の「オブジェクトボタン」を押して オブジェクト一覧をとじてから 画面右下の「SAVE」ボタンクリックし、「StageEditor」ウィンド閉じました。 「VS Express 2013 for Desktop」で 「SwordBout.vcxproj」 プロジェクトファイルを開き、 「デバックを開始」で ゲームを起動しました。 .cppファイル、.hファイルは一切弄っていません。 環境 OS Window7 Home Premium 32bit プロセッサ AMD Athlon(tm) U X2 255 Procesor 3.10 GHz 実装メモリ 4.00 GB (3.25 GB 使用可能) 「VS Express 2013 for Desktop」のバージョンは Version 12.0.21005.1 REL DXライブラリのバージョンは Ver 3.13d ダウンロードした「SwordBout.exe」 ファイルを解凍した、 「SwordBout」フォルダ内 .cpp,.h,SwordBout.vcxproj ファイルの入っている 「Game」の更新日時は 2015/02/28/17:27 です。
メンテ

Page: 1 |

Re: Sword Bout をステージオブジェ無しで ( No.1 )
名前:管理人 日時:2015/04/05 15:52

ご指摘の通りオブジェクトが一つもない状態で攻撃を繰り出すとメモリの不正なアクセスが 発生するバグがありました ( より厳密には「オブジェクトが一つも無いか、又はオブジェクトがある場合でも順番的に最後に判定することになる  オブジェクトとの簡易的な当たり判定では「当たった」と判定されるも厳密な判定では「当たっていない」と判定された  場合にメモリの不正なアクセスが発生するバグ」となります ) Sword Bout のプログラムを変更して対応することも可能ですが、以下の流れでDXライブラリの プログラムを変更して対応することにしました  仕様1:MV1CollCheck_Capsule などの関数が「全てのポリゴンに当たっていない場合でも MV1_COLL_RESULT_POLY_DIM 構造体の      メンバー変数 Dim に NULL 以外が入ることがある」  仕様2:MV1CollResultPolyDimTerminate は「MV1_COLL_RESULT_POLY_DIM 構造体のメンバー変数 Dim に NULL が代入されている      場合は何回呼び出しても問題が無い」    ↓  Sword Bout のプログラムを見た所、仕様1 の挙動について「全てのポリゴンに当たっていない場合は、  MV1_COLL_RESULT_POLY_DIM 構造体のメンバー変数 Dim に必ず NULL が代入されるようにする」ことで、  Sword Bout のプログラムを変更しなくても本件の問題が解消されることが判明    ↓  仕様1の「全てのポリゴンに当たってない場合でも、MV1_COLL_RESULT_POLY_DIM 構造体のメンバー変数 Dim には NULL が代入  されているときもあれば NULL が代入されていないときもある」というのは仕様的にも変なので、本件の問題解消にもなるので  「全てのポリゴンに当たっていない場合は MV1_COLL_RESULT_POLY_DIM 構造体のメンバー変数 Dim には必ず NULL が代入される」  ように仕様を変更することに決定 上記の変更を加えてエラーが発生しなくなったバージョンをこちらにアップしましたので、よろしければお使いください m(_ _)m https://dxlib.xsrv.jp/temp/DxLibVCTest.exe // VisualC++ 用 (中身を既存のライブラリのファイルに上書きして、『リビルド』をして下さい)
メンテ
Re: Sword Bout をステージオブジェ無しで ( No.2 )
名前:軽い3Dアクション作りたい男 日時:2015/04/05 21:18

 返信、対応、ありがとうございます 「Chara.cpp」、17ヶ所 「Stage.cpp」、2ヶ所の 関数「MV1CollResultPolyDimTerminate」が実行された次の行に 一行ずつ後始末された、「HitDim」のメンバポインタ「Dim」 に「NULL」を代入する記述をしたら 問題なく動くようになりましたが、 これだけだと問題が起こることがあるのでしょうか? こういった具合にそれぞれの場所に記述しました MV1CollResultPolyDimTerminate(HitDim[HitNum]); HitDim[HitNum].Dim = NULL; MV1CollResultPolyDimTerminate(HitDim[k]); HitDim[k].Dim = NULL; MV1CollResultPolyDimTerminate(HitDim[i]); HitDim[i].Dim = NULL; 初心者なので、これで大丈夫な気がしてしまうのです。 この件はアップしていただいた、ファイルを解凍、上書き、リビルドで、 確実に解決すると思いますが、よければ教えてください。
メンテ
Re: Sword Bout をステージオブジェ無しで ( No.3 )
名前:管理人 日時:2015/04/05 21:54

> これだけだと問題が起こることがあるのでしょうか? いえ、その方法でも問題ありません 今回DXライブラリのプログラムを変更して解決しようと思ったのは、私自身が 「当たったポリゴンが一つも無い場合でも Dim に NULL 以外が入るのは気持ち悪いなぁ」 と思ったのが大きいので、MV1CollResultPolyDimTerminate の後に Dim に NULL を代入する という方法でも全く問題ありません
メンテ
Re: Sword Bout をステージオブジェ無しで ( No.4 )
名前:軽い3Dアクション作りたい男(解決) 日時:2015/04/05 22:21

 速い回答ありがとうございます。 また、分からない事があったら質問します。 ありがとうございました。
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存