để a viết cho e cái vòng lặp main loop của SDL :V :V
cấu trúc của vòng lặp chính của SDL2 là
// main loop
for (bool quit = false; !quit;) {
// handle events
// process game logic
// draw & display
}
có 3 phần chính:
-
- Xử lý events như gõ phím, bấm chuột, resize màn hình v.v…
-
- Xử lý logic của game như là update physics
-
- Vẽ và hiển thị ra màn hình
3 phần này để thứ tự thế nào cũng được :V vì khi vòng for lặp liên tục kia nó sẽ chạy theo thứ tự 123123123123 thì khi nhìn vào có thể thấy nó lặp là 123.123 hay 231.231 hay 312.312 gì cũng được :V
nếu 3 phần này xử lý nhanh quá, ví dụ mỗi phần 0.1ms thì 3 phần chỉ có 0.3ms, trong 1 giây chạy 3333 lần tổng cộng thì display 3333 lần/giây, tương đương với 3333fps :V Ngoài ra CPU xử lý events/logic liên tục thì nó chạy cpu lên tối đa 100% cpu, trong khi màn hình máy tính chỉ refresh 60/120/144Hz(fps) là hết :V vì vậy nên cần delay để giảm fps xuống.
gọi phần delay này là phần 4. Phần 4 này có thể thực hiện theo nhiều cách:
code cho vòng lặp main loop của SDL, nếu có xài vsync vài xài SDL_Renderer
:
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1,
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
// main loop
for (bool quit = false; !quit;) {
// handle events
for (SDL_Event evt; SDL_PollEvent(&evt);) {
if (evt.type == SDL_QUIT) {
quit = true;
break;
}
}
// process game logic
// (nothing to process)
// draw & display
SDL_RenderClear(renderer); // clear screen
// draw... (nothing to draw)
SDL_RenderPresent(renderer); // display
}
nếu ko xài vsync thì
const int kMaxFps = 60;
const int kMaxFrameTime = 1000 / kMaxFps;
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
// main loop
for (bool quit = false; !quit;) {
const auto startFrameTime = SDL_GetTicks64();
// handle events
for (SDL_Event evt; SDL_PollEvent(&evt);) {
if (evt.type == SDL_QUIT) {
quit = true;
break;
}
}
// process game logic
// (nothing to process)
// draw & display
SDL_RenderClear(renderer);
// draw... (nothing to draw)
SDL_RenderPresent(renderer);
// delay
const auto processTime = SDL_GetTicks64() - startFrameTime;
if (processTime < kMaxFrameTime)
SDL_Delay(kMaxFrameTime - processTime);
}