2016-12-12 2 views
0

이 항목을 검색 한 결과 을 사용하여 프레임 독립적 업데이트 (deltaTime 사용)를 구현하면 문제를 해결하는 데 도움이 될 수 있음을 발견했습니다. 그러나 그것을 추가 한 후에도 패들 운동이 약간 더듬 거리는 경우가 있습니다. 반면에 케이스를 deltatime을 사용하지 않고 event polling loop으로 바꾸면 게임이 원활하게 실행되는 것처럼 보입니다.SFML에서 원활한 동작을 수행 할 수 없음

어떻게 내 코드에서 제대로 sf::Clock을 사용 가야합니까 왜 내 게임은 내가 심지어 deltatime를 사용하지 않고 이벤트 풀 루프에서 Playing 경우를 이동할 때 원활하게 실행하는 것입니까?

게임 초기화 :

void Game::start() { 
    if (_gameState != Uninitialized) { 
     return; 
    } 
    //Creating window 
    _mainWindow.create(sf::VideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 32), "Pong"); 
    _gameState = ShowingMenu; 

    //Adding game entities to the manager  
    VisibleGameObject *paddle1 = new PlayerPaddle("Player1", 1.0f, sf::Keyboard::Key::Up, sf::Keyboard::Key::Down); 
    VisibleGameObject *paddle2 = new PlayerPaddle("Player2", 1.0f, sf::Keyboard::Key::W, sf::Keyboard::Key::S); 
    VisibleGameObject *background = new Background("Background", 0.0f); 
    paddle1 -> setPosition(SCREEN_WIDTH - (paddle1 -> getWidth()), 0); 
    paddle2->setPosition(0, 0); 
    manager.addObject(paddle1); 
    manager.addObject(paddle2); 
    manager.addObject(background); 

    //Starting Clock 
    deltaTime = 0.0f; 
    frameClock.restart(); 


    while (!isExiting()) {  
     gameLoop(); 
    } 
    _mainWindow.close(); 
} 

게임 루프 :

void Game::gameLoop() 
{ 
    static bool firstPass = true; 
    sf::Event currentEvent; 

    //Event loop 
    while(_mainWindow.pollEvent(currentEvent) || firstPass) 
    { 

     if (firstPass) { 
      currentEvent = sf::Event(); 
      currentEvent.type = sf::Event::GainedFocus; 
      firstPass = false; 
     } 

     if (currentEvent.type == sf::Event::Closed) 
     { 
      _gameState = Exiting; 
     } 

     switch (_gameState) 
     { 
      case ShowingMenu: 
      { 
       showingMenu(); 
       break; 
      } 
      case Paused: 
      { 
       break; 
      } 


      default: 
       break; 
     } 

    } 

    //Extracting deltaTime to update game logic 

    deltaTime = frameClock.restart().asSeconds(); 
    if(_gameState == Playing) 
    { 
     manager.updateAllLayers(deltaTime); 
     manager.drawAllLayers(_mainWindow); 
     _mainWindow.display(); 
    } 
} 

패들 업데이트 로직 :

void PlayerPaddle::update(const float & elapsedTime) 
{ 
    sf::Vector2f currentPos = getPosition(); 
    float displacement = 0.0f; 

    if (sf::Keyboard::isKeyPressed(controls.up)) 
    { 
     displacement = -speed * elapsedTime;  
    } 
    else if (sf::Keyboard::isKeyPressed(controls.down)) 
    { 
     displacement = speed * elapsedTime; 
    } 

    if (displacement + currentPos.y < 0.0f) 
    { 
     setPosition(currentPos.x, 0.0f); 
     return; 
    } 
    else if (displacement + currentPos.y + getHeight() > Game::SCREEN_HEIGHT) 
    { 
     setPosition(currentPos.x, Game::SCREEN_HEIGHT - getHeight()); 
     return; 
    } 

    setPosition(currentPos.x, currentPos.y + displacement); 
} 
+0

을 업데이트 기능에 어떤 값을 전달합니까? –

+0

@DenisErmolin 1 –

+0

@KaranJoisher 얼마나 자주 firstPass가 사실입니까? 코드를 보여줄 수 있습니까? –

답변

0

나는 코멘트를 게시 할 충분한 명성이 없기 때문에 대답을해야합니다 ...

모든 프레임을 업데이트 (그리고 그립니다). 고정 된 업데이트 시간 단계를 구현하려면 게임 루프가 적합하지 않습니다.

게임 루프가 이렇게 보입니다. 나는 당신의 편의를 위해 당신의 변수 이름을 사용 : 이것은 고정 금리 (1/60)에서 게임을 업데이트하고 가능하면 (당신이 FPS를 제한하는 setFramerateLimit()를 사용하여 렌더링

// ... 

sf::Clock frameClock; 
const sf::Time timePerFrame = sf::seconds(1.0f/60.0f); 
sf::Time timeSinceLastUpdate = sf::Time::Zero; 

while (_mainWindow.isOpen()) { 
    timeSinceLastUpdate += frameClock.restart(); 

    // events 
    { 
    sf::Event evt; 
    while (_mainWindow.pollEvent(evt)) { 
     //... 
    } 
    } 

    // update 
    { 
    while (timeSinceLastUpdate > timePerFrame) { 
     timeSinceLastUpdate -= timePerFrame; 
     manager.updateAllLayers(timePerFrame); 
    } 
    } 

    // render 
    { 
    _mainWindow.clear(); 
    // ... 
    _mainWindow.display(); 
    } 
} 

// ... 

, 이것이 영향을주지 않습니다 고정 된 업데이트 간격, 그래서 거기에 문제 없음). 이제 같이 사용하여 manager.updateAllLayers-sf::Time을 통과

당신의 elapsedTime (그것은 .asSeconds() 그래서 기본적으로 아무것도 변경 등의 기능을 가지고 있지만 분명히 speed의 값을 조정해야합니다) 다음, 경과 시간을 사용 해달라고하면

+0

Ur 업데이트는 고정 된 업데이트 방법에 대해서는 정확하지만, 초당 업데이트 수와는 독립적 인 솔루션을 얻으려고합니다. 나는 그것이 탁구와 같은 게임에 대해서는 중요하지 않지만 새로운 개념을 배우기 위해 그렇게하고 있음을 안다. –

관련 문제