Problema com métodos de atualização (GameTime) e implementação de pausa

7

Eu tenho a função de pausa implementada e funciona corretamente, pois escurece a tela do jogador e para de atualizar a jogabilidade.

O problema é que o GameTime continua a aumentar enquanto está pausado, então meu método que verifica gameTime versus anteriorSpawnTime antes de gerar outro inimigo fica confuso e, se o jogo for pausado por muito tempo, é perceptível que o próximo inimigo desenha muito cedo.

Aqui está o meu código para a atualização do inimigo.

private void UpdateEnemies(GameTime gameTime)
    {
        // Spawn a new enemy every 1.5 seconds
        if (gameTime.TotalGameTime - previousSpawnTime > enemySpawnTime)
        {
            previousSpawnTime = gameTime.TotalGameTime;

            // Add an Enemy
            AddEnemy();
        }
...

Eu também tenho outros métodos que dependem do gameTime. Tentei obter o tempo total de pausa e subtraí-lo do tempo total do jogo, mas não consigo fazê-lo funcionar corretamente se é assim que devo resolver isso.

Se você precisar ver outro código, me avise. Obrigado.

Adam LaBranche
fonte

Respostas:

8

Em vez de usar TotalGameTimeuse ElapsedGameTimee acumule o total em execução em alguma variável. Então, quando você pausa o jogo, tudo o que você precisa fazer é parar de adicionar o tempo decorrido à variável. Aqui está um exemplo:

float spawnTimer = 0.0f;
float timeBetweenSpawns = 1.5f;

private void Update(GameTime gameTime)
{
    // Perform actions that should only happen when the game is not paused
    if(!isPaused)
    {
        // Add time elapsed since previous frame to running timer
        spawnTimer += (float) gameTime.ElapsedGameTime.TotalSeconds;

        // Check if enough time has passed to spawn a new enemy
        if(spawnTimer >= timeBetweenSpawns)
        {
            AddEnemy();

            // Decrement the timer to prepare it for the next spawn
            spawnTimer -= timeBetweenSpawns;
        }
    }

    // Perform any actions that should happen all the time
}
David Gouveia
fonte
3
Chamar UpdateEnemies com um delta de tempo de 0,0 é uma opção mais agradável, pois permite que os inimigos processem atividades incidentais ou de sabor, como bater os pés no tédio, sem afetar o jogo. Se você simplesmente parar de chamar atualizações, perderá opções interessantes como essa.
Patrick Hughes
@PatrickHughes Sim, eu gosto da idéia de muitos caras no meio da batalha batendo os pés esperando que você faça uma pausa.
Michaelhouse
11
@PatrickHughes A maneira como escolhi demonstrar a pausa foi meramente ilustrativa, pois a questão estava principalmente relacionada ao gerenciamento do tempo. No entanto, eu ainda não passaria um delta de tempo zero por dois motivos: GameTimeé calculado e gerenciado automaticamente pela estrutura; portanto, para passar um delta zero seria necessário instanciar um GameTimeobjeto separado ou alterar a assinatura para usar um float; e mesmo com um delta zero, ele ainda executaria as verificações de adição e temporizador desnecessariamente. Se necessário, basta agrupar parte do método em uma verificação de pausa, para que a outra metade possa continuar atualizando.
David Gouveia
2
@PatrickHughes O que você está descrevendo é claramente um conceito de visualização. Quando o jogo está em pausa, renderize modelos com animações "ociosas". Isso deve ser tratado nas chamadas do Draw, NÃO nas chamadas de atualização.
22412 Daniel Carlsson
11
@PatrickHughes Sim, é um pouco estranho, e é por isso que, em todos os meus projetos, a primeira coisa que faço no topo do meu loop de atualização é converter o GameTimeobjeto em um float simples e usar esse valor. Eu nunca tive a necessidade, mas isso facilita a implementação de câmera lenta - basta dimensionar o valor do tempo decorrido de alguma forma constante. Quanto à pausa do jogo, acho que é mais uma questão de preferência pessoal - eu gosto de tratar a pausa como um botão liga / desliga, em vez de um delta zero, para pular explicitamente os cálculos dependentes do tempo, mas ambos são soluções perfeitamente válidas :)
David Gouveia