質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

DXライブラリ

DXライブラリとは、DirectXを使ったWindowsソフトの開発に必ず付いて回るDirectXやWindows関連のプログラムを使い易くまとめた形で利用できるようにしたC++言語用のゲームライブラリです。

Q&A

解決済

1回答

2110閲覧

マップチップの当たり判定が反応しない

fkcz_yfm_carp

総合スコア4

Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

DXライブラリ

DXライブラリとは、DirectXを使ったWindowsソフトの開発に必ず付いて回るDirectXやWindows関連のプログラムを使い易くまとめた形で利用できるようにしたC++言語用のゲームライブラリです。

0グッド

0クリップ

投稿2021/09/03 09:19

前提・実現したいこと

DXライブラリを使用してアクションゲームを制作しています。
スクロールする背景を描画するためにマップチップを実装したところ問題が発生しました。

発生している問題・エラーメッセージ

プログラムは動いておりエラーメッセージも出ませんが、プレイヤー(player_t p1)がマップチップのブロック(Handle_mc[5])と接触しても当たり判定(bool coflag)がtrueになりません。

該当のソースコード

C++

1// Main.cpp 2 3#include "DxLib.h" 4#include "Main.h" 5#include "Sound.h" 6#include "Player.h" 7 8extern int Handle_bgm; 9 10char Key[256]; 11bool initialize = true; 12bool finalize = false; 13 14int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 15 LPSTR lpCmdLine, int nCmdShow) { 16 if (ChangeWindowMode(TRUE) != 0) { 17 return 0; 18 } 19 if (DxLib_Init() != 0) { 20 return 0; 21 } 22 if (SetDrawScreen(DX_SCREEN_BACK) != 0) { 23 return 0; 24 } 25 if (SetBackgroundColor(0, 0, 0) != 0) { 26 return 0; 27 } 28 Sound_Initialize(); 29 PlaySoundMem(Handle_bgm, DX_PLAYTYPE_LOOP); 30 while (1) { 31 if (ScreenFlip() != 0) { 32 break; 33 } 34 if (ProcessMessage() != 0) { 35 break; 36 } 37 if (ClearDrawScreen() != 0) { 38 break; 39 } 40 if (GetHitKeyStateAll(Key) != 0) { 41 break; 42 } 43 Player_Initialize(); 44 Player_Update(); 45 Player_Draw(); 46 Player_Finalize(); 47 } 48 return 0; 49} 50 51//-------------------------------------------------- 52 53// Main.h 54 55#ifndef DEF_MAIN_H 56 57#define DEF_MAIN_H 58 59int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 60 LPSTR lpCmdLine, int nCmdShow); 61 62#endif 63 64//-------------------------------------------------- 65 66// Player.cpp 67 68#include "DxLib.h" 69#include "Main.h" 70#include "Sound.h" 71#include "Player.h" 72 73extern char Key[256]; 74extern bool initialize; 75extern bool finalize; 76 77//マップチップ 78const int SIZE_MAP_X = 64; 79const int SIZE_MAP_Y = 64; 80const int NUM_MAP_X = 50; 81const int NUM_MAP_Y = 8; 82int data[NUM_MAP_Y][NUM_MAP_X] = { 83 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 88 89 {0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 90 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 92 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93 0, 1, 2, 0, 0, 0, 0, 0, 0, 0}, 94 95 {0, 0, 0, 0, 1, 2, 0, 0, 5, 5, 96 5, 5, 0, 0, 0, 0, 0, 1, 2, 0, 97 0, 0, 0, 0, 1, 2, 0, 0, 5, 5, 98 5, 5, 0, 0, 0, 0, 0, 1, 2, 0, 99 0, 0, 0, 0, 1, 2, 0, 0, 0, 0}, 100 101 {0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 102 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 103 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 104 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 105 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 106 107 {0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 108 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 110 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 112 113 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 118 119 {0, 3, 4, 0, 5, 3, 4, 0, 0, 3, 120 4, 0, 0, 3, 4, 0, 0, 3, 4, 0, 121 0, 3, 4, 0, 5, 3, 4, 0, 0, 3, 122 4, 0, 0, 3, 4, 0, 0, 3, 4, 0, 123 0, 3, 4, 0, 5, 3, 4, 0, 0, 3}, 124 125 {5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 126 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 127 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 128 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 129 5, 5, 5, 5, 5, 5, 5, 5, 5, 5}, 130}; 131 132//プレイヤー画像用 133object_t fi; 134object_t mc; 135object_t cf; 136player_t p1; 137int Handle_fi[1]; 138int Handle_mc[6]; 139int Handle_cf[1]; 140int Handle_p1[16]; 141int p1count = 0; 142 143//プレイヤー用フラグ 144bool mflag = false; 145bool jflag = false; 146bool sqflag = false; 147bool jdflag = false; 148bool fip1flag = false; 149bool coflag = false; 150 151//プレイヤー用座標 152int old_x = p1.x; 153int old_y = p1.y; 154int new_x = p1.x; 155int new_y = p1.y; 156int L_p1 = p1.x + 16; 157int R_p1 = p1.x + 48; 158int U_p1 = p1.y; 159int D_p1 = p1.y + 64; 160int L_block = p1.x * SIZE_MAP_X / 64; 161int R_block = p1.x * SIZE_MAP_X / 64 + 64; 162int U_block = p1.y * SIZE_MAP_Y / 64; 163int D_block = p1.y * SIZE_MAP_Y / 64 + 64; 164 165//フォントデータロード 166int Font = CreateFontToHandle("メイリオ", 32, 4, DX_FONTTYPE_ANTIALIASING_EDGE); 167 168//初期化 169void Player_Initialize() { 170 if (initialize == true) { 171 //画像ファイルロード 172 LoadDivGraph("./Image/field.png", 1, 1, 1, 3200, 480, Handle_fi); 173 LoadDivGraph("./Image/mapchip.png", 6, 3, 2, SIZE_MAP_X, SIZE_MAP_Y, Handle_mc); 174 LoadDivGraph("./Image/chequeredflag.png", 1, 1, 1, 64, 64, Handle_cf); 175 LoadDivGraph("./Image/player1.png", 16, 4, 4, 64, 64, Handle_p1); 176 177 //背景座標 178 fi.x = 0; 179 fi.y = 0; 180 fi.img = Handle_fi[0]; 181 182 //ゴール座標 183 cf.x = 3072; 184 cf.y = 64; 185 cf.img = Handle_cf[0]; 186 187 //プレイヤー座標 188 p1.x = 64 / 2; 189 p1.y = 480 - (64 / 2); 190 p1.y_prev = 0; 191 p1.y_temp = 0; 192 193 //フラグ 194 p1.flag = 0; 195 p1.fflag = 0; 196 mflag = true; 197 jflag = false; 198 sqflag = false; 199 jdflag = false; 200 fip1flag = false; 201 coflag = false; 202 } 203 initialize = false; 204} 205 206//計算 207void Player_Update() { 208 if (Key[KEY_INPUT_RETURN] == 1) { 209 finalize = true; 210 DxLib_End(); 211 } 212 213 for (new_y = 0; new_y < NUM_MAP_Y; new_y++) { 214 for (new_x = 0; new_x < NUM_MAP_X; new_x++) { 215 int no = data[new_y][new_x]; 216 DrawGraph(new_x * SIZE_MAP_X + fi.x, new_y * SIZE_MAP_Y, Handle_mc[no], FALSE); 217 } 218 } 219 220 if (data[U_p1 / SIZE_MAP_Y][L_p1 / SIZE_MAP_X] == 5) { 221 coflag = true; 222 } else { 223 coflag = false; 224 } 225 226 if (mflag == true) { 227 //プレイヤー移動制御 228 if (p1.x < (64 / 2)) { 229 p1.x = (64 / 2); 230 } 231 if (p1.x + (64 / 2) > 640) { 232 p1.x = 640 - (64 / 2); 233 } 234 if (p1.y < (64 / 2) - 480) { 235 p1.y = (64 / 2) - 480; 236 } 237 if (p1.y + (64 / 2) > 448) { 238 p1.y = 448 - (64 / 2); 239 } 240 241 //下キーが押下された場合 242 if (Key[KEY_INPUT_DOWN] == 1) { 243 //しゃがみフラグ 244 sqflag = true; 245 } else { 246 sqflag = false; 247 } 248 249 //上キーが押下され現在のy座標が448 - (64 / 2)でしゃがみフラグが立っていない場合 250 if (Key[KEY_INPUT_UP] == 1 && p1.y == 448 - (64 / 2) && sqflag == false) { 251 //ジャンプフラグ 252 jflag = true; 253 //現在のy座標を前回分に保存 254 p1.y_prev = p1.y; 255 //現在のy座標を20減らす 256 p1.y = p1.y - 20; 257 } 258 259 //ジャンプフラグが立っている場合 260 if (jflag == true) { 261 //現在のy座標を一時分に保存 262 p1.y_temp = p1.y; 263 //現在y += (現在y - 前回y) + 3 / 2 264 p1.y += (p1.y - p1.y_prev) + 3 / 2; 265 //一時保存のy座標を前回分に保存 266 p1.y_prev = p1.y_temp; 267 //現在のy座標が前回分よりも大きい場合 268 if (p1.y - p1.y_prev > 0) { 269 //下降フラグ 270 jdflag = true; 271 } else { 272 jdflag = false; 273 } 274 //現在のy座標が448 - (64 / 2)の場合 275 if (p1.y == 448 - (64 / 2)) { 276 //ジャンプフラグと下降フラグを元に戻す 277 jflag = false; 278 jdflag = false; 279 } 280 } 281 282 //右キーが押下された場合 283 if (Key[KEY_INPUT_RIGHT] == 1) { 284 //右フラグ 285 p1.flag = 1; 286 //左キーが押下された場合 287 } else if (Key[KEY_INPUT_LEFT] == 1) { 288 //左フラグ 289 p1.flag = 2; 290 //押下されなかった場合 291 } else { 292 //停止フラグ 293 p1.flag = 0; 294 } 295 } 296 297 if (p1.flag == 2) { 298 if (sqflag == true) { 299 p1.img = Handle_p1[13]; 300 } else { 301 if (fip1flag == false) { 302 //p1.xを減らす 303 p1.x--; 304 } 305 if (fip1flag == true) { 306 //fi.xを増やす 307 fi.x++; 308 //cf.xを増やす 309 cf.x++; 310 } 311 p1.fflag = 2; 312 if (jflag == true) { 313 p1.img = Handle_p1[12]; 314 } else { 315 //x座標に合わせた画像を指定 316 if (fip1flag == true) { 317 p1.img = Handle_p1[(fi.x % 64) / 16 + 11]; 318 } else { 319 p1.img = Handle_p1[(p1.x % 64) / 16 + 8]; 320 } 321 } 322 } 323 } else if (p1.flag == 1) { 324 if (sqflag == true) { 325 p1.img = Handle_p1[5]; 326 } else { 327 if (fip1flag == false) { 328 //p1.xを増やす 329 p1.x++; 330 } 331 if (fip1flag == true) { 332 //fi.xを減らす 333 fi.x--; 334 //cf.xを減らす 335 cf.x--; 336 } 337 p1.fflag = 1; 338 if (jflag == true) { 339 p1.img = Handle_p1[4]; 340 } else { 341 //x座標に合わせた画像を指定 342 if (fip1flag == true) { 343 p1.img = Handle_p1[(fi.x % 64) / 16 + 3]; 344 } else { 345 p1.img = Handle_p1[(p1.x % 64) / 16]; 346 } 347 } 348 } 349 } else if (p1.fflag == 2) { 350 if (sqflag == true) { 351 p1.img = Handle_p1[13]; 352 } else if (jflag == true) { 353 p1.img = Handle_p1[12]; 354 } else { 355 p1.img = Handle_p1[8]; 356 } 357 } else { 358 if (sqflag == true) { 359 p1.img = Handle_p1[5]; 360 } else if (jflag == true) { 361 p1.img = Handle_p1[4]; 362 } else { 363 p1.img = Handle_p1[0]; 364 } 365 } 366 367 if (p1.flag == 1 && fip1flag == false && p1.x == 320) { 368 fip1flag = true; 369 } 370 if (p1.flag == 2 && fip1flag == false && p1.x == 320) { 371 fip1flag = true; 372 } 373 if (p1.flag == 1 && fip1flag == true && fi.x == 0 - 2560) { 374 fip1flag = false; 375 } 376 if (p1.flag == 2 && fip1flag == true && fi.x == 0) { 377 fip1flag = false; 378 } 379} 380 381//描画 382void Player_Draw() { 383 //画像描画 384 DrawGraph(cf.x, cf.y, cf.img, TRUE); 385 DrawGraph(p1.x - (64 / 2), p1.y - (64 / 2), p1.img, TRUE); 386 DrawFormatString(20, 20, GetColor(0, 0, 0), "p1.x : %d", p1.x); 387 DrawFormatString(20, 40, GetColor(0, 0, 0), "p1.y : %d", p1.y); 388 DrawFormatString(20, 60, GetColor(0, 0, 0), "old_x : %d", old_x); 389 DrawFormatString(20, 80, GetColor(0, 0, 0), "old_y : %d", old_y); 390 DrawFormatString(20, 100, GetColor(0, 0, 0), "new_x : %d", new_x); 391 DrawFormatString(20, 120, GetColor(0, 0, 0), "new_y : %d", new_y); 392 DrawFormatString(20, 140, GetColor(0, 0, 0), "coflag : %d", coflag); 393 DrawFormatString(20, 160, GetColor(0, 0, 0), "L_X : %d", L_p1 / SIZE_MAP_X); 394 DrawFormatString(20, 180, GetColor(0, 0, 0), "U_Y : %d", U_p1 / SIZE_MAP_Y); 395} 396 397//終了処理 398void Player_Finalize() { 399 if (finalize == true) { 400 DeleteGraph(fi.img); 401 DeleteGraph(mc.img); 402 DeleteGraph(cf.img); 403 DeleteGraph(p1.img); 404 DeleteFontToHandle(Font); 405 } 406 finalize = false; 407} 408 409//-------------------------------------------------- 410 411// Player.h 412 413#ifndef DEF_PLAYER_H 414 415#define DEF_PLAYER_H 416 417typedef struct { 418 int x, y, img; 419} object_t; 420typedef struct { 421 int x, y, y_prev, y_temp, flag, fflag, img; 422} player_t; 423typedef struct { 424 int x, y; 425} Vec2; 426 427void Player_Initialize(); 428 429void Player_Update(); 430 431void Player_Draw(); 432 433void Player_Finalize(); 434 435#endif

試したこと

https://yttm-work.jp/collision/collision_0010.html を参考にしながらDXLibに落とし込もうとしていますが行き詰まってしまっています。

補足情報(FW/ツールのバージョンなど)

Microsoft Visual C++ 2019
DXライブラリ Windows版 Visual C++用 Ver3.22c

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

当たり判定(bool coflag)がtrueになりません。

示されたコード内を coflag で検索すると,trueにしそうな処理は

if (data[U_p1 / SIZE_MAP_Y][L_p1 / SIZE_MAP_X] == 5) { coflag = true; } else { ...

の部分しかなさそうです.
SIZE_MAP_YSIZE_MAP_X は定数であり,
U_p1L_p1 は外部変数ですが,初期化以降に値を変化させる記述はなさそうです.

よって,現状では,
U_p1L_p1 の初期値でこのifの条件を満たさない限り,coflag がtrueになることはないであろうと推測します.

投稿2021/09/03 09:33

fana

総合スコア11658

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fkcz_yfm_carp

2021/09/04 08:58

回答ありがとうございます。 Player.cppのループごとにプレイヤーとブロックの上下左右の値を更新するようにしフィールドのスクロール量を加えたところcoflagが反応するようになりました。 ただ、当たり判定がブロックよりも32ドット左にずれているようです。 以下にPlayer.cppの変更部分を抜粋しました(他のファイルに変更はありません)。 // Player.cpp //-------------------------------------------------- int old_x = p1.x; int old_y = p1.y; int new_x = p1.x; int new_y = p1.y; int L_p1 = p1.x - fi.x + 16; int R_p1 = p1.x - fi.x + 48; int U_p1 = p1.y - fi.y; int D_p1 = p1.y - fi.y + 64; int L_block = p1.x - fi.x * SIZE_MAP_X / 64; int R_block = p1.x - fi.x * SIZE_MAP_X / 64 + 64; int U_block = p1.y - fi.y * SIZE_MAP_Y / 64; int D_block = p1.y - fi.y * SIZE_MAP_Y / 64 + 64; //-------------------------------------------------- if (data[U_p1 / SIZE_MAP_Y][L_p1 / SIZE_MAP_X] == 5 || data[U_p1 / SIZE_MAP_Y][R_p1 / SIZE_MAP_X] == 5) { coflag = true; } else { coflag = false; } //-------------------------------------------------- old_x = p1.x; old_y = p1.y; new_x = p1.x; new_y = p1.y; L_p1 = p1.x - fi.x + 16; R_p1 = p1.x - fi.x + 48; U_p1 = p1.y - fi.y; D_p1 = p1.y - fi.y + 64; L_block = p1.x - fi.x * SIZE_MAP_X / 64; R_block = p1.x - fi.x * SIZE_MAP_X / 64 + 64; U_block = p1.y - fi.y * SIZE_MAP_Y / 64; D_block = p1.y - fi.y * SIZE_MAP_Y / 64 + 64; } void Player_Draw() { DrawGraph(cf.x, cf.y, cf.img, TRUE); DrawGraph(p1.x - (64 / 2), p1.y - (64 / 2), p1.img, TRUE); DrawFormatString(20, 20, GetColor(0, 0, 0), "p1_x : %d", p1.x - fi.x); DrawFormatString(20, 40, GetColor(0, 0, 0), "p1_y : %d", p1.y - fi.y); DrawFormatString(20, 60, GetColor(0, 0, 0), "old_x : %d", old_x); DrawFormatString(20, 80, GetColor(0, 0, 0), "old_y : %d", old_y); DrawFormatString(20, 100, GetColor(0, 0, 0), "new_x : %d", new_x); DrawFormatString(20, 120, GetColor(0, 0, 0), "new_y : %d", new_y); DrawFormatString(20, 140, GetColor(0, 0, 0), "coflag : %d", coflag); DrawFormatString(20, 160, GetColor(0, 0, 0), "L_X : %d", L_p1 / SIZE_MAP_X); DrawFormatString(20, 180, GetColor(0, 0, 0), "U_Y : %d", U_p1 / SIZE_MAP_Y); }
fana

2021/09/06 02:37

いや,そんなコード示されてもリアクションに困る… ここは,「完全に所望の結果が得られるコードができるまでデバッグに付き合ってもらう場所」ではないのだし, 判定がずれてるようならそこはデバッグしてください,としか.
fana

2021/09/06 03:54

余計なお世話かもしれませんが, もう少し「手続き:処理手順」を考えて固めてから実装作業に移った方がよいのでは?という雰囲気を感じます. 例えば, Player_Initialize() とか Player_Finalize() というのは, 1回のプログラム実行(プログラムが始まってから終わるまでの間)において何回実行されるべきものなのか? いつ実行されるべきものなのか? とか. (現状,while (1){ ... } の中に書かれているので何度も実行されそうですが,それで妥当なのか?) 本件の当たり判定がどうの~ いう話でも, まず何をして,次にどうして,この時点でもしこうだったら… という,やるべき事柄の順番をきっちり(細部まで徹底的に)考えてみることから始めると良いでしょう. 「この条件のときにこのタイミングでこの変数の値をこうする」という考えをまずしっかり確定させることで,値の更新忘れのようなことを防止することができるでしょう.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問