トップページ > 記事閲覧
ゲームのメイン処理中にポーズ画面を実装したいのですが…
名前:kou 日時: 2017/10/08 15:07

自キャラに関する操作をまとめた以下のPlayerクラスを実装し、自キャラの移動や描画までの 実装はうまくいったものの、SPACEキーを押したらポーズ状態にし、ポーズ状態中は ポーズメニューを表示(この段階ではまだポーズメニューのウインドウだけ描画してます)し、 ポーズ状態でZキーが押されるとポーズメニューを解除する、という操作の実装で詰まってしまいました。 プログラム記述でのトグル操作の表現などで調べて、以下コードのAllメソッド内に実際に 実装してみたところ、SPACEキーを押した段階でZ以外のキーには反応しなくなっており、 ポーズ状態にはなっているようなのですが、ポーズメニューのウインドウが表示されません。 そしてその状態からZキーを押すと、Zキーを押した瞬間にポーズメニューのウインドウが一瞬表示され、 すぐに消えて通常のゲーム画面がスタートします。 このポーズメニューウインドウを意図したとおりに表示するためにはどうすればよいでしょうか。 いろいろ試したうえで手詰まりになってしまったので教えていただけると嬉しいです。 <以下Playerクラスのコード> #include <DxLib.h> #include "Map.h" #define WALKTIME 15 class Player { public: int gh[12]; // キャラ画像のグラフィックハンドル int menugh; // メニューウィンドウのグラフィックハンドル int width, height; // キャラ画像のサイズ int walkVec; // 歩く方向。2,4,6,8でテンキー対応 int animCount; // 毎フレーム1ずつ増やすアニメーション用カウンタ bool walkFlag; // 歩いているか止まっているかの判定 int x, y; // グラフィック描画の座標 int targetX, targetY; // プレーヤーの次に向かう座標(マス単位) int speed; // グラフィックの描画ずらしスピード bool pauseFlag; // 中断メニューへ移行するかの判定 bool pauseState; // 中断状態に一度でもなったかの判定 bool pauseReset; // 中断状態を一度でも解除したかの判定 Player() { // デフォルトコンストラクタ LoadDivGraph("Frisk.png", 12, 3, 4, 32, 32, gh); menugh = LoadGraph("menu_window.png"); GetGraphSize(gh[0], &width, &height); walkVec = 2; walkFlag = false; animCount = 0; x = 320; y = 384; speed = 1; targetX = 320; targetY = 384; pauseFlag = false; pauseState = false; pauseReset = false; } void AnimationView(int animState, int firstNum) { // アニメーション描画部 if (animState == 0) DrawExtendGraph(x, y, x + CELL_WIDTH, y + CELL_HEIGHT, gh[firstNum], TRUE); if (animState == 1) DrawExtendGraph(x, y, x + CELL_WIDTH, y + CELL_HEIGHT, gh[firstNum + 1], TRUE); if (animState == 2) DrawExtendGraph(x, y, x + CELL_WIDTH, y + CELL_HEIGHT, gh[firstNum + 2], TRUE); if (animState == 3) DrawExtendGraph(x, y, x + CELL_WIDTH, y + CELL_HEIGHT, gh[firstNum + 1], TRUE); } void Move(Map* map) { // キャラの移動判定部 walkFlag = false; // 歩いている間だけ true (下の[a]に対応) if (targetX == x && targetY == y) { // 移動中でないとき if (CheckHitKey(KEY_INPUT_DOWN)) { // 下向き移動 walkFlag = true; walkVec = 2; if(map->cell[x/ CELL_WIDTH][y / CELL_HEIGHT + 1].canwalk) targetY += CELL_HEIGHT; // targetYを1マス下の座標に設定 } else if (CheckHitKey(KEY_INPUT_LEFT)) { // 左向き移動 walkFlag = true; walkVec = 4; if (map->cell[x / CELL_WIDTH - 1][y / CELL_HEIGHT].canwalk) targetX -= CELL_WIDTH; // targetXを1マス左の座標にに設定 } else if (CheckHitKey(KEY_INPUT_RIGHT)) { // 右向き移動 walkFlag = true; walkVec = 6; if (map->cell[x / CELL_WIDTH + 1][y / CELL_HEIGHT].canwalk) targetX += CELL_WIDTH; // targetXを1マス右の座標にに設定 } else if (CheckHitKey(KEY_INPUT_UP)) { // 上向き移動 walkFlag = true; walkVec = 8; if (map->cell[x / CELL_WIDTH][y / CELL_HEIGHT - 1].canwalk) targetY -= CELL_HEIGHT; // targetYを1マス上の座標に設定 } else { animCount = 0; // キーが押されてないかつ移動してなければanimCountをリセット } } else { // 移動中のとき walkFlag = true; // 歩いている [a] } if (y < targetY) // 下向き移動の途中過程 y += speed; if (x > targetX) // 左向き移動の途中過程 x -= speed; if (x < targetX) // 右向き移動の途中過程 x += speed; if (y > targetY) // 上向き移動の途中過程 y -= speed; } void View() { // キャラの移動描画部 int animState = animCount / WALKTIME; // animCountがWALKTIMEの倍数になるたびにanimStateが1増える if (animState == 4) { // animStateが4になったらリセット animCount = 0; animState = 0; } if (walkFlag) { if (walkVec == 2) { AnimationView(animState, 0); } if (walkVec == 4) { AnimationView(animState, 3); } if (walkVec == 6) { AnimationView(animState, 6); } if (walkVec == 8) { AnimationView(animState, 9); } animCount++; } else { if (walkVec == 2) { DrawExtendGraph(x, y, x + CELL_WIDTH, y + CELL_HEIGHT, gh[1], TRUE); } if (walkVec == 4) { DrawExtendGraph(x, y, x + CELL_WIDTH, y + CELL_HEIGHT, gh[4], TRUE); } if (walkVec == 6) { DrawExtendGraph(x, y, x + CELL_WIDTH, y + CELL_HEIGHT, gh[7], TRUE); } if (walkVec == 8) { DrawExtendGraph(x, y, x + CELL_WIDTH, y + CELL_HEIGHT, gh[10], TRUE); } } } void Pause() { // ゲームの中断およびメニュー部 DrawGraph(32, 32, menugh, FALSE); } void All(Map* map) { // 一通りすべての処理 if (CheckHitKey(KEY_INPUT_SPACE)) { // SPACEが押されたとき if (!pauseState) { // まだ一度もPause状態になってないなら pauseFlag = true; // Pause状態になるというフラグ } pauseState = true; // スペースが押されて一度Pause状態への移行判定をした } else { pauseState = false; // SPACEが押されていなければPauseになっていない } if (!walkFlag && pauseFlag) { // マス移動しておらず、Pause状態にしたいなら while (pauseFlag) { // Pause状態にしたい間だけ Pause(); // Pause処理をする View(); // 画面を描画する if (CheckHitKey(KEY_INPUT_X)) { // Pause状態中にXが押されたとき if (!pauseReset) { // Pause状態が一度もリセットされていないなら pauseFlag = false; // Pause解除状態になるというフラグ } pauseReset = true; // 一度Pause解除状態への移行判定をした } else { pauseReset = false; // Xが押されてなければPause解除になっていない } if (!pauseFlag) { // Pause解除状態にしたいなら break; // Pause状態のループから抜ける } } } Move(map); // キャラを移動し View(); // 画面を描画する } };
メンテ

Page: 1 |

Re: ゲームのメイン処理中にポーズ画面を実装したいのですが… ( No.1 )
名前:通りすがり 日時:2017/10/08 17:55

while (pauseFlag) { // Pause状態にしたい間だけ } のループではおそらく裏画面に書き続けているため実際の画面に反映されていないのではないでしょうか? ScreenFlip()やSetDrawScreen()をそのループに追加すれば描画されるような気がします。 ポーズ解除した瞬間に表示されるということは そのループを抜けた後にScreenFlip()が呼ばれているからなのだと予想します。
メンテ
Re:ゲームのメイン処理中にポーズ画面を実装したいのですが… ( No.2 )
名前:kou(解決) 日時:2017/10/08 21:14

返答ありがとうございます。 おっしゃる通り裏画面に描き続けており、ポーズ処理で新たにループを設けたことで ScreenFlip関数が呼ばれていなかったことが原因だったようです。 アドバイスの通り、ScreenFlip関数をポーズ処理のループ内に記述してみたところ、 ポーズメニューのウインドウがきちんと描画されました。 とても助かりました。ありがとうございます。
メンテ

Page: 1 |

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

   クッキー保存