Gần đây tôi đã đọc bài viết này về Vòng lặp trò chơi: http://www.koonsolo.com/news/dewitters-gameloop/
Và đề nghị thực hiện cuối cùng là làm tôi bối rối. Tôi không hiểu làm thế nào nó hoạt động, và nó trông giống như một mớ hỗn độn.
Tôi hiểu nguyên tắc: Cập nhật trò chơi với tốc độ không đổi, với bất cứ điều gì còn lại sẽ khiến trò chơi diễn ra nhiều lần nhất có thể.
Tôi lấy nó bạn không thể sử dụng một:
- Nhận đầu vào cho 25 tick
- Kết xuất trò chơi cho 975 tick
Cách tiếp cận vì bạn sẽ nhận được đầu vào cho phần đầu tiên của phần thứ hai và điều này sẽ cảm thấy kỳ lạ? Hay đó là những gì đang diễn ra trong bài viết?
Bản chất:
while( GetTickCount() > next_game_tick && loops < MAX_FRAMESKIP)
Làm thế nào là thậm chí hợp lệ?
Hãy giả sử giá trị của anh ấy.
MAX_FRAMESKIP = 5
Giả sử next_game_tick, được chỉ định các khoảnh khắc sau khi khởi tạo, trước khi vòng lặp trò chơi chính có nghĩa là ... 500.
Cuối cùng, khi tôi đang sử dụng SDL và OpenGL cho trò chơi của mình, với OpenGL chỉ được sử dụng để kết xuất, hãy giả sử rằng GetTickCount()
sẽ trả về thời gian kể từ khi SDL_Init được gọi, như vậy.
SDL_GetTicks -- Get the number of milliseconds since the SDL library initialization.
Nguồn: http://www.libsdl.org/docs/html/sdlgetticks.html
Tác giả cũng giả định điều này:
DWORD next_game_tick = GetTickCount();
// GetTickCount() returns the current number of milliseconds
// that have elapsed since the system was started
Nếu chúng tôi mở rộng while
tuyên bố, chúng tôi nhận được:
while( ( 750 > 500 ) && ( 0 < 5 ) )
750 vì thời gian đã trôi qua kể từ khi next_game_tick
được chỉ định. loops
bằng không như bạn có thể thấy trong bài viết.
Vì vậy, chúng tôi đã bước vào vòng lặp while, hãy thực hiện một số logic và chấp nhận một số đầu vào.
Yada yada yada.
Ở cuối vòng lặp while, tôi nhắc bạn ở trong vòng lặp trò chơi chính của chúng tôi là:
next_game_tick += SKIP_TICKS;
loops++;
Chúng ta hãy cập nhật lần lặp tiếp theo của mã while như thế nào
while( ( 1000 > 540 ) && ( 1 < 5 ) )
1000 bởi vì thời gian đã trôi qua khi nhận đầu vào và thực hiện công cụ trước khi chúng tôi đạt được thông số tiếp theo của vòng lặp, trong đó GetTickCount () được gọi lại.
540 bởi vì, trong mã 1000/25 = 40, do đó, 500 + 40 = 540
1 vì vòng lặp của chúng tôi đã lặp lại một lần
5 , bạn biết tại sao.
Vì vậy, vì vòng lặp While này không phụ thuộc vào RAR RÀNG MAX_FRAMESKIP
và không có ý định TICKS_PER_SECOND = 25;
làm thế nào trò chơi được cho là chạy chính xác?
Không có gì ngạc nhiên với tôi khi tôi triển khai mã này vào mã của mình, tôi có thể thêm chính xác khi tôi đổi tên các chức năng của mình để xử lý đầu vào của người dùng và vẽ trò chơi theo những gì tác giả của bài viết có trong mã ví dụ của mình, trò chơi không làm gì cả .
Tôi đã đặt một fprintf( stderr, "Test\n" );
vòng lặp bên trong mà không được in cho đến khi trò chơi kết thúc.
Làm thế nào để vòng lặp trò chơi này chạy 25 lần một giây, được đảm bảo, trong khi kết xuất nhanh nhất có thể?
Đối với tôi, trừ khi tôi thiếu một cái gì đó LỚN, có vẻ như ... không có gì.
Và không phải cấu trúc này, của vòng lặp while này, được cho là chạy 25 lần một giây và sau đó cập nhật trò chơi chính xác những gì tôi đã đề cập trước khi bắt đầu bài viết?
Nếu đó là trường hợp tại sao chúng ta không thể làm một cái gì đó đơn giản như:
while( loops < 25 )
{
getInput();
performLogic();
loops++;
}
drawGame();
Và tính cho nội suy một số cách khác.
Tha thứ cho câu hỏi cực kỳ dài của tôi, nhưng bài viết này đã gây hại nhiều hơn là tốt cho tôi. Bây giờ tôi rất bối rối - và không biết làm thế nào để thực hiện một vòng lặp trò chơi thích hợp vì tất cả những câu hỏi phát sinh này.