前提・実現したいこと
Dxlibにて2Dアクションを作っています。
二次元配列に沿ってマップを描画するようなコードを書いていて、1ステージ目の走破は出来るのですが、2ステージ目に進む前にゲームが強制終了してしまいます。
エラーメッセージには
”ハンドルされない例外が 0x00007FF6E90BD6E5 (2DActionGame.exe) で発生しました: 0xC0000005: 場所 0x0000000000000105 の読み取り中にアクセス違反が発生しました。”
と書いており、ローカルや呼び出し履歴を見ても明らかにおかしいのはわかるのですが、対処の仕方がわかりません。
他の方の質問を色々調べてみたのですが、当方のプログラミングスキルはアクセス違反の意味を理解することがやっとのレベルです。
どなたか教えていただけると助かります。
発生している問題・エラーメッセージ
ハンドルされない例外が 0x00007FF6E90BD6E5 (2DActionGame.exe) で発生しました: 0xC0000005: 場所 0x0000000000000105 の読み取り中にアクセス違反が発生しました。
該当のソースコード
C++
1#include "Stage.h" 2#include "DxLib.h" 3 4//サンプルマップデータ 5char g_MapDataA[STAGE_H][STAGE_W] = { 6 7 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 9 1, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10 1, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 11 1, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 12 13 1, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 14 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 3, 0, 1, 15 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 16 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17 1, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 18 19 1, 0, 0, 0, 0, 3, 3, 3, 3, 3, 0, 0, 0, 0, 3, 3, 0, 0, 0, 1, 20 1, 0, 0, 0, 0, 3, 3, 3, 3, 3, 0, 0, 0, 3, 3, 3, 0, 0, 0, 1, 21 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 1, 22 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 23 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 24}; 25 26//クラスに宣言した関数の実装法 27//戻り値 クラス名::関数名(引数) 28Stage::Stage() //コンストラクタのため戻り値なし 29 :m_PlayerStartPos() 30{ 31 for (int y = 0; y < STAGE_H; y++) 32 { 33 for (int x = 0; x < STAGE_W; x++) 34 { 35 switch (g_MapDataA[y][x]) 36 { 37 case ChipType_StartPos: 38 m_PlayerStartPos.x = (CHIP_SIZE * x) + (HALF_CHIP); 39 m_PlayerStartPos.y = (CHIP_SIZE * y) + (HALF_CHIP); 40 m_Data[y][x] = ChipType_Non; 41 break; 42 default: 43 m_Data[y][x] = g_MapDataA[y][x]; 44 break; 45 } 46 } 47 } 48} 49 50Stage::~Stage() 51{ 52} 53 54void Stage::Draw() 55{ 56 for (int y = 0; y < STAGE_H; y++) 57 { 58 for (int x = 0; x < STAGE_W; x++) 59 { 60 //処理しない条件で判定 61 if (m_Data[y][x] == ChipType_Non) 62 { 63 continue; 64 } 65 /* 66 ここを通過した時点で、何かしら描画する必要がある 67 →DrawBoxを共通化できる 68 */ 69 unsigned int color = 0; //色はマップチップごとに違う 70 71 //マップチップごとに分岐処理 72 switch (m_Data[y][x]) 73 { 74 case ChipType_Wall: color = GetColor(125, 125, 125); break; 75 case ChipType_Ground: color = GetColor(0, 200, 0); break; 76 case ChipType_Footing: color = GetColor(128, 0, 0); break; 77 case ChipType_GoalPos: color = GetColor(255, 0, 0); break; 78 } 79 80 DrawBox( 81 x * CHIP_SIZE, y * CHIP_SIZE, 82 x * CHIP_SIZE + CHIP_SIZE, y * CHIP_SIZE + CHIP_SIZE, 83 color, 84 TRUE 85 ); 86 } 87 } 88} 89 90//プレイヤーの初期座標の取得 91//constメンバ関数…関数名にconstが後置されている関数 92//関数内でメンバ変数の変更を行っていないことを保証する 93const Position& Stage::GetPlayerStartPos() const 94{ 95 return m_PlayerStartPos; 96} 97 98//マップとの当たり判定 99//もし当たっていた場合、めり込まないように移動量 moveX_, moveY_ を補正する 100//当たっている辺の情報をbitフラグにして返す 101int Stage::CheckCollision(const Position& pos_, float* moveX_, float* moveY_) const 102{ 103 //当たった辺の種類 104 int hitFlg = 0; 105 106 //現在座標に移動量を加算して、移動後の座標を出す 107 float afterX = pos_.x; 108 float afterY = pos_.y; 109 afterX += (moveX_ == nullptr ? 0.0f : *moveX_); 110 afterY += (moveY_ == nullptr ? 0.0f : *moveY_); 111 112 //移動後の座標にどのようなマップチップがあるかをチェック 113 //もし何かあれば、必要な処理を行う 114 if (GetChipType(afterX, afterY) != ChipType_Non && GetChipType(afterX, afterY) != ChipType_GoalPos) 115 { 116 //2020/12/14現在、この中にはChipType_Wallの時しか来ない 117 //すなわち、壁に接触している間の処理をここで行う 118 119 //マップチップの上下左右の座標を計算 120 float chipLeft = int (afterX / CHIP_SIZE) * CHIP_SIZE; //左端 121 float chipRight = chipLeft + CHIP_SIZE; //右端 122 float chipTop = int (afterY / CHIP_SIZE) * CHIP_SIZE; //上端 123 float chipBottom = chipTop + CHIP_SIZE; //下端 124 125 //y方向のチェック 126 if (moveY_ != nullptr) 127 { 128 //マップチップの上端に当たっていた場合の処理 129 if (*moveY_ > 0.0f) 130 { 131 *moveY_ = chipTop - pos_.y - 1.0f; 132 hitFlg |= (1 << CollisionDir_Up); 133 } 134 //マップチップの下端に当たっていた場合の処理 135 else if (*moveY_ < 0.0f) 136 { 137 *moveY_ = chipBottom - pos_.y + 1.0f; 138 hitFlg |= (1 << CollidionDir_Down); 139 } 140 } 141 142 //x方向のチェック 143 if (moveX_ != nullptr) 144 { 145 //マップチップの左端に当たっていた場合の処理 146 if (*moveX_ > 0.0f) 147 { 148 *moveX_ = chipLeft - pos_.x - 1.0f; 149 hitFlg |= (1 << CollisionDir_Left); 150 } 151 //マップチップの右端に当たっていた場合の処理 152 else if (*moveX_ < 0.0f) 153 { 154 *moveX_ = chipRight - pos_.x + 1.0f; 155 hitFlg |= (1 << CollisionDir_Right); 156 } 157 } 158 } 159 return hitFlg; 160} 161 162/* 163 @param x_ スクリーン座標x 164 y_ スクリーン座標y 165*/ 166ChipType Stage::GetChipType(float x_, float y_) const 167{ 168 //画面上の座標から、配列上の座標へ変換する 169 const int x = int(x_ / CHIP_SIZE); 170 const int y = int(y_ / CHIP_SIZE); 171 172 /* 173 例題:配列[1][10]はマップチップ上のどこに描画されるか? 174 マップチップの縦横はCHIP_SIZEとする。 175 y = CHIP_SIZE * 1 = 32 176 x = CHIP_SIZE * 10 = 320 177 */ 178 179 //配列のx、yが計算出来たら… 180 if (x < 0 || y < 0 || x >= STAGE_W || y >= STAGE_H) 181 { 182 //何もなかったことにする 183 return ChipType_Non; 184 } 185 186 //指定の座標に該当するマップの情報を返す 187 return ChipType(m_Data[y][x]); //←ここでアクセス違反が起こる 188} 189 190
試したこと
補足情報(FW/ツールのバージョンなど)
使用ツール:
Visual Studio 2019
Dxlib
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/02/22 01:30
2021/02/22 01:56
2021/02/22 02:30
2021/02/23 01:16 編集