执行Pong时Allegro中的时间问题

Timing problems in Allegro while implementing Pong

本文关键字:时间 问题 Allegro Pong 执行      更新时间:2023-10-16

我正在尝试使用Allegro 4和C++实现Pong的一个非常基本的版本。然而,当我将计时机制与rest()调用结合使用时,我遇到了一个问题。我的比赛是为两名球员设置的,一旦球员得到7分,一名球员就赢得一盘,然后两人都从0开始。第一个赢得两盘的选手获胜。在一盘获胜后,我会显示获胜者的名字,并呼叫rest(2000),以便玩家可以看到消息。然而,在这之后,球似乎不知从哪里冒出来,导致其中一名球员在比赛开始时自动得分。之后,它会按照预期从中心恢复。当我删除计时机制或rest()调用时,不会发生这种情况。

我试过把比分和盘数的更新移到计时循环之外,但没有用。也不会在rest()调用之后立即调用ball的init()函数。对于如何解决这个问题,我非常感谢您的意见。

这是代码。我遗漏了不影响问题的基本部分和包含部分。 //includes...

Paddle p1, p2;  //paddles for player 1, player 2
Ball b;   //game ball
int main()
{
setupGame();   //setup allegro and bitmaps
init();    //initialize paddles and ball
bool done = false;
int win, game = 0;
//game loop
while(!done)    
{
if(key[KEY_X])   //quick exit for debugging
done = true;
//timing loop
while(counter > 0) {
movePaddles();   
moveAndCollideBall();
game = checkCondition(b, p1, p2);  //check if either player 1 or player 2 has won a point
updateScore(game);   //update score
updateSets();        //update set if score of either equals 7
counter --; 
}
draw();    //draw paddles and ball
displayScore();   
blit(buffer, screen, 0, 0, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);  //draw buffer to screen
clear_bitmap(buffer);   //clear buffer for next iteration
checkWinner(done);   //check if either player has won 2 sets, exit loop if so
}
exitGame();   //clear bitmaps and exit allegro
return 0;
}
END_OF_MAIN()
//Returns 1 if player 1 has won a point, 2 for player 2
int checkCondition(Ball b, Paddle p1, Paddle p2)
{
if(b.x < p1.x)
return 2;
else if(b.x > p2.x+PADDLE_WIDTH)
return 1;
return 0;
}
//setup allegro and timing variables, load bitmaps
void setupGame()
{
//allegro, screen setup, etc.
//timing mechanism
LOCK_VARIABLE(counter);
LOCK_FUNCTION(increment_counter);
install_int_ex(increment_counter, BPS_TO_TIMER(240));
srand(time(0));
//other setup stuff
}
//initialize paddles and ball
void init()
{
p1.init(10, 210);
p2.init(620, 210);
b.init();
}
//output score to buffer
void displayScore()
{
textprintf_ex(buffer, gamefont, SCREEN_WIDTH/4, 10, WHITE, -1, "%i", p1.score);
textprintf_ex(buffer, gamefont, SCREEN_WIDTH/2 - SCREEN_WIDTH/3, 450, WHITE, -1, "Sets: %i", p1.sets);
textprintf_ex(buffer, gamefont, SCREEN_WIDTH/2 + SCREEN_WIDTH/4, 10, WHITE, -1, "%i", p2.score);
textprintf_ex(buffer, gamefont, SCREEN_WIDTH/2 + SCREEN_WIDTH/6, 450, WHITE, -1, "Sets: %i", p2.sets);
}
//taking the winner of the point as parameter, update the corresponding player's score by 1, reset ball
void updateScore(int game)
{
if(game > 0)
{game == 1 ? ++p1.score : ++p2.score;
b.init();
game = 0;
}              
}

//update no of sets won if either player has score of 7, reset scores
void updateSets()
{
if(p1.score == 7 || p2.score == 7)
{
if(p1.score == 7)
{p1.sets++;
textprintf_ex(screen, gamefont, SCREEN_WIDTH/5, SCREEN_HEIGHT/2,WHITE, -1, "Player 1 wins the set!");
}         
else
{p2.sets++;
textprintf_ex(screen, gamefont, SCREEN_WIDTH/5, SCREEN_HEIGHT/2,WHITE, -1, "Player 2 wins the set!");
}
p2.score = 0;
p1.score = 0;
rest(2000);  //THIS SEEMS TO CAUSE THE PROBLEM, AFTER THE REST, THE BALL INSTEAD OF COMING FROM THE CENTER, QUICKLY COMES FROM SOMEWHERE CLOSE TO THE CORNER
}   
}     
//check if either player has won 2 sets, if so set done to true
void checkWinner(bool& done)
{
if(p1.sets == 2)
{textprintf_ex(screen, gamefont, SCREEN_WIDTH/4, SCREEN_HEIGHT/2 + 30,WHITE, -1, "Player 1 wins!!");
rest(2000);
done = true;
}
else if(p2.sets == 2)
{textprintf_ex(screen, gamefont, SCREEN_WIDTH/4, SCREEN_HEIGHT/2 + 30,WHITE, -1, "Player 2 wins!!");
rest(2000);
done = true;
}
}

rest(2000)之后,将计数器重置为0。在休息期间,它会持续两秒钟,所以在它完成后,当它试图追赶时,你会得到两秒钟的游戏爆发。

正确的解决方案是拥有组织得更好的代码。两秒钟的休息应该作为你常规时间循环的一部分。