Так что этот вопрос немного более абстрактный, чем некоторые. Скажем, у меня есть игра, которую я хочу рендерить только один раз в секунду, например, клон тетриса. Я хочу обрабатывать только один ввод в секунду, а затем соответственно рендерить новый кадр. Тетрис — это игра на основе сетки, поэтому я не могу просто переместить часть игры на определенное количество раз timeDelta
float, который люди обычно используют для примеров частоты кадров. Как я могу сделать только один кадр в секунду в игре на основе сетки? Вот то, что у меня есть код, но это неправильно:
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;
}
}
Я хочу перемещать игру по одному квадрату за раз, раз в секунду, но я просто не знаю, как это сделать.
Изменить: вот код, который отображает кадры
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();
}
Вы не учитываете тот факт, что пользователь может перемещать фигуру между движениями фигуры.
Вы должны позволить пользователю перемещать фигуру влево, вправо и вниз, когда он / она хочет, но
не заставляйте движение вниз, пока не истечет истекшее время.
Когда я сделал игру на основе блоков, вот что я сделал
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();
Я также включил постепенную анимацию формы, если вам интересен один из способов, как это сделать. Я построил графическую карту игры поверх логической карты и использовал логическую карту для запуска графической интерполяции. Я сломал графическую библиотеку, которую использовал, но логический код все еще хорош для справки или использования, если хотите.