jburn7
jburn7

Reputation: 125

C++ Setting a frame rate in a game like Tetris

So this question is a little more abstract than some. Say I have a game that I only want to render once per second, such as a Tetris clone. I only want to process one input per second, then render the new frame accordingly. Tetris is a grid-based game, so I can't just move the game piece by a certain amount times the timeDelta float that people usually use for frame rate examples. How do I go about only rendering one frame per second in a grid-based game? Here's what code I have so far, but it's wrong:

void Engine::Go(){
    while(window.isOpen()){
        if(timeElapsed >= 1000){
            timeElapsed = clock.restart().asMilliseconds();;
            ProcessInput();
        }
        UpdateCPU();
        Render();
        timeElapsed = clock.getElapsedTime().asMilliseconds();
        time += timeElapsed;
    }
}

void Engine::ProcessInput(){
    while(window.pollEvent(event)){
        if(event.type == (sf::Event::Closed))
            window.close();
    }
    //process movement detection of piece
    int temp = level.GetGamePieces().size();
    if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left)){
        level.GetGamePieces().at(temp - 1).GetPieceSprite().move(-10, 0);
        std::cout << "left";
        moved = true;
    }
    else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right)){
        level.GetGamePieces().at(temp - 1).GetPieceSprite().move(10,0);
        std::cout << "right";
        moved = true;
    }
    else{
        level.GetGamePieces().at(temp - 1).GetPieceSprite().move(0,10);
        std::cout << "down";
        moved = true;
    }
}

I only want to move the gamepiece one sqaure at a time, once per second, but I just don't know how to do this.

Edit: Here's the code that renders the frames

void Engine::Render(){
    window.clear();
    //draw wall tiles
    for(int i = 0; i < 160; i++){
        if(i < 60){
            level.GetWallTile().setPosition(0, i * 10);
            window.draw(level.GetWallTile());
        }
        if(i >= 60 && i < 100){
            level.GetWallTile().setPosition((i - 60) * 10, 590);
            window.draw(level.GetWallTile());
        }
        if(i >= 100){
            level.GetWallTile().setPosition(390, (i - 100) * 10);
            window.draw(level.GetWallTile());
        }
    }

    //draw BG tiles
    for(int i = 1; i < 39; i++){
        for(int j = 0; j < 59; j++){
            level.GetBGTile().setPosition(i * 10, j * 10);
            window.draw(level.GetBGTile());
        }
    }

    for(int i = 0; i < level.GetGamePieces().size(); i++){
        window.draw(level.GetGamePieces()[i].GetPieceSprite());
    }

    window.display();
}

Upvotes: 0

Views: 596

Answers (1)

pyj
pyj

Reputation: 1499

You are not accounting for the fact that a user may want to move a shape in between movements of the shape.

You should allow the user to move the shape left, right, and down whenever he/she wants to, but not force the downward movement until after the elapsed time has completed.

When I made a block-based game, here's what I did

void updateSeconds( double deltaTime ) {
// If timer until shape falls runs out, move the shape down.
    timeUntilShapeDrop -= deltaTime;
    if ( timeUntilShapeDrop > 0 || currentFallingShape->isAnimating() ) {
        return;
    }

    // If ( shape collides with map when moved down )
    currentFallingShape->move(-1,0);
    if ( currentFallingShape->isCollisionWithMap ( * map ) ) {
        currentFallingShape->move(1,0);

        // Lock shape in place on the map
        currentFallingShape->setBlocksOnMap( * map );
        lastUpdateLinesCleared = clearFullLines();
    }
    timeUntilShapeDrop = calculateShapeDropTimeInterval();

I also included gradual shape animation if you're interested one way of how to do it. I built a graphical game map on top of the logical map and used the logical map to start the graphical interpolation. I broke the graphics library I was using, but the logic code is still good for reference or use if you'd like.

Upvotes: 1

Related Questions