Ở bài trước chúng ta đã tìm hiểu sơ qua Vòng lặp thông điệp chính với hàm GetMessage. Hôm nay, chúng ta sẽ đi tìm hiểu kỹ hơn vấn đề này.

Vấn đề đặt ra:

Khi game của chúng ta có các đối tượng di chuyển trên màn hình như nấm độc, rùa, đạn bắn, cháy nổ…ta sẽ cần mọi thứ chuyển động liên tục cho dù có hay không có thông điệp nào trong hàng đợi. Vòng lặp thông điệp ở bài trước sẽ không còn phù hợp với game vì nó sẽ dừng lại (không làm gì cả) ngay tại hàm GetMessage khi không có thông điệp nào (khi người dùng không đụng tới chuột, bàn phím…). Yêu cầu lúc này là phải có một vòng lặp chạy liên tục đảm bảo:

  • Giữ mọi thứ chuyển động.
  • Đồng thời phải nhận và xử lý thông điệp trong hàng đợi (nếu có).

Cách giải quyết: Sử dụng hàm PeekMessage thay cho GetMessage.

PeekMessage

PeekMessage sẽ kiểm tra xem có thông điệp trong hàng đợi hay không. Nếu có thì lấy thông điệp ra y như GetMessage. Nếu không có, thay vì đứng đợi như GetMessage thì PeekMessage sẽ thoát ra để mọi thứ tiếp tục chạy. Khai báo:

BOOL PeekMessage(
	LPMSG lpMsg, //con trỏ đến nơi lưu trữ MSG
    HWND hWnd,
    UNIT wMsgFilterMin, //thông điệp đầu tiên
    UNIT wMsgFilterMax, //thông điệp cuối cùng
    UNIT wRemoveMsg);

Trong đó:

  • Tương tự với GetMessage, hai tham số wMsgFilterMinwMsgFilterMax được gán giá trị bằng 0.
  • wRemoveMsg nhận một trong hai hằng số PM_NOREMOVE và PM_REMOVE tương ứng với việc gỡ thông điệp ra hàng đợi hay không khi nó đã đọc thông điệp từ hàng đợi vào lpMsg.

Đoạn code với PeekMessage sẽ trông như sau:

//khởi tạo game
Game_Init();

//vòng lặp thông điệp chính
while (!done)
{
	if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
    	//kiểm tra xem có phải thông điệp thoát?
        if(msg.message == WM_QUIT)
        	done = 1;
        //Giải mã và truyền thông điệp cho WndProc
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    
    //process game loop
    Game_Run();
}

Lưu đồ ý tưởng của PeekMessage:

Tổng kết

Chúng ta đã cùng nhau tìm hiểu về cấu trúc của một chương trình Windows và vòng lặp thông điệp cho game…Bài sau chúng ta sẽ bước vào làm việc với DirectX.😉 Hãy truy cập vào Series Make Game - TuiTuCodeđể học tiếp những bài thú vị khác nữa. Nếu có thắc mắc các bạn cứ bình luận bên dưới hoặc gửi thắc mắc về page TuiTuCode để các ad giải đáp. Pie~