2012-11-14 54 views
0

我试图用Allegro 4和C++实现Pong的一个非常基本的版本。但是,当我将计时机制与rest()调用结合使用时,我遇到了一个问题。我的比赛是为2名球员设置的,一名球员获得7分后赢得一套,然后两名球员都从0重新开始。首先赢得2套的球员获胜。获胜后,我会显示获胜者的名字并致电休息(2000年),以便玩家可以看到消息。然而,在此之后,这个球似乎不知从何而来,并导致了一个球员在开始时的自动点。之后,它会继续从中心回来,因为它应该是。当我删除定时机制或rest()调用时,不会发生这种情况。Allegro实施Pong时的时序问题

我试过移动分数和定时循环外的集合的更新,但它不起作用。在rest()调用之后,也不会调用球的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; 
    } 
} 
+0

Allegro 4几乎不赞成使用。它不再处于积极的发展阶段,因为旧的API很老,并没有真正反映更现代的方法。我推荐你使用Allegro 5. – Cubic

+0

是的,我知道,但我已经非常熟悉Allegro 4,因此想在开始使用Allegro 5之前完成一些游戏。 – theSuperiorVenacava

回答

0

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

正确的解决方法是有更好的组织代码。两秒的休息时间应该是您常规时间循环的一部分。

+0

非常感谢。减少柜台解决了问题。但其余()确实发生在定时循环内部,因为包含rest()调用的updateSets()函数在定时循环内。无论如何,非常感谢您的帮助。它终于正常工作。 – theSuperiorVenacava

+0

我的观点是你应该像'remaining_pause = 240 * 2;'那样做,然后在你的循环里面'remaining_pause - '。在暂停模式下,您不会处理输入,但您仍然可以像平常一样更新图形等。使用小型游戏时,所有内容都应该很好地适合单个游戏循环,而无需在各种功能中使用特殊处理程序。 – Matthew