c++で本(ゲームプログラミングC++)を参考にPongゲームを作っています。
プログラムに一時停止のpause機能を実装したのですが、その挙動が不安定です。
キーボードPを押すとmIsPoseのフラグを立つようにし、trueの時はGameの更新処理を行わないようにしました。
しかし、ゲームを実行してPを押すと停止するのですがしない時もあり不安定です。
pause処理を安定させたいのですが、原因とよい解決方法が思いつかずにいます。
何か良い方法があれば教えていただきたいです。
以下、コードです。(省略部分あり)
// 省略 void Game::RunLoop() { while (mIsRunning) { ProcessInput(); if (!mIsPose) UpdateGame(); GenerateOutput(); } } void Game::ProcessInput() { SDL_Event event; while (SDL_PollEvent(&event)) { switch (event.type) { // If we get an SDL_QUIT event, end loop case SDL_QUIT: mIsRunning = false; break; } } // Get state of keyboard const Uint8* state = SDL_GetKeyboardState(NULL); // If escape is pressed, also end loop if (state[SDL_SCANCODE_ESCAPE]) { mIsRunning = false; } if (state[SDL_SCANCODE_P]) { mIsPose = !mIsPose; } // Update paddle direction based on W/S keys mPaddleDir = 0; if (state[SDL_SCANCODE_W]) { mPaddleDir -= 1; } if (state[SDL_SCANCODE_S]) { mPaddleDir += 1; } // Update paddle direction based on W/S keys mPaddleDir2 = 0; if (state[SDL_SCANCODE_I]) { mPaddleDir2 -= 1; } if (state[SDL_SCANCODE_K]) { mPaddleDir2 += 1; } } void Game::UpdateGame() { // Wait until 16ms has elapsed since last frame while (!SDL_TICKS_PASSED(SDL_GetTicks(), mTicksCount + 16)) ; // Delta time is the difference in ticks from last frame // (converted to seconds) float deltaTime = (SDL_GetTicks() - mTicksCount) / 1000.0f; // Clamp maximum delta time value if (deltaTime > 0.05f) { deltaTime = 0.05f; } // 省略 void Game::GenerateOutput() { // Set draw color to right blue SDL_SetRenderDrawColor( mRenderer, 0, // R 0, // G 0, // B 255 // A ); // Clear back buffer SDL_RenderClear(mRenderer); // Draw walls SDL_SetRenderDrawColor(mRenderer, 255, 255, 255, 255); // Draw top wall SDL_Rect wall{ 0, // Top left x 0, // Top left y windowW, // Width thickness // Height }; SDL_RenderFillRect(mRenderer, &wall); // Draw bottom wall wall.y = windowH - thickness; SDL_RenderFillRect(mRenderer, &wall); // Draw right wall //wall.x = windowW - thickness; //wall.y = 0; //wall.w = thickness; //wall.h = windowW; //SDL_RenderFillRect(mRenderer, &wall); // Draw paddle SDL_Rect paddle{ static_cast<int>(mPaddlePos.x), static_cast<int>(mPaddlePos.y - paddleH/2), thickness, static_cast<int>(paddleH) }; SDL_RenderFillRect(mRenderer, &paddle); SDL_Rect paddle2{ static_cast<int>(mPaddlePos2.x), static_cast<int>(mPaddlePos2.y - paddleH / 2), thickness, static_cast<int>(paddleH) }; SDL_RenderFillRect(mRenderer, &paddle2); // Draw ball for (auto& b : mBalls) { SDL_Rect ball{ static_cast<int>(b.pos.x - thickness/2), static_cast<int>(b.pos.y - thickness/2), thickness, thickness }; SDL_RenderFillRect(mRenderer, &ball); } // Swap front buffer and back buffer SDL_RenderPresent(mRenderer); } void Game::Shutdown() { SDL_DestroyRenderer(mRenderer); SDL_DestroyWindow(mWindow); SDL_Quit(); }
解決できました
ありがとうございます。皆様のアドバイスにより解決できました。
Daregadaさんのアドバイスに倣い、
トグル動作を一旦辞め、処理を分けてみたところ安定しました。
そこで、前フレームのキー状態を保存し、トグル処理実行の条件に前フレームのチェックを
加えたコードにしてみたところ安定して動作することが確認できました。
以下解決したコード(thkanaさんのコードを参考にしました。)
c++
1 if (!mPrevPState && state[SDL_SCANCODE_P]) 2 { 3 mIsPose = !mIsPose; 4 } 5 mPrevPState = state[SDL_SCANCODE_P];
ベストアンサーは御三方ともほぼ同じ趣旨の内容と思いますので、最も早く回答して頂いたDaregadaさんに致しました。
皆様、ありがとうございました。
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。