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