xaitMap اکنون از Unity پشتیبانی می کند                          نسخه جدید موتور NeoAxis منتشر شد                          پیام نوروزی محمد غضنفری به تمام علاقه مندان به دانش ساخت بازی در سال 91                          معرفی کتاب 1001 video games you must play before you die                          رونمایی از دو کتاب با محوریت تولید ابزارهای ساخت بازی                          مستند بنیاد بازی یا بازی بنیاد                          مستند معرفی اسکنر سه بعدی
 
 
 
بازی ساز تخصصی ترین تارنمای آموزش ساخت بازی دو بعدی سه بعدی و طراحی بازی در ایران: تالار گفتمان

 
بازی ساز تخصصی ترین تارنمای آموزش ساخت و طراحی بازی :: نمايش موضوعات - اتاق کار شماره 04 برنامه نویسی win32

اتاق کار شماره 04 برنامه نویسی win32

 

اين انجمن قفل شده است . شما مجاز به ارسال مطلب يا جوابيه و ويرايش مطالب نمي باشيد.   اين مطلب قفل شده است . شما مجاز به ويرايش آن و يا ارسال جوابيه نمي باشيد .    

   بازی ساز تخصصی ترین تارنمای آموزش ساخت و طراحی بازی صفحه اول انجمن -> برنامه نویسی به زبان ++C -> اتاق کارهای Workshop Win32

نمايش موضوع قبلي :: نمايش موضوع بعدي  
نويسنده پيغام

admin
مدیر سایت
مدیر سایت

وضعيت: آفلاين
9 مهر ماه ، 1387
تعداد ارسالها: 455
امتياز: 0
تشکر کرده: 88
تشکر شده 154 بار در 98 پست

محل سكونت: درون قلب شما

ارسالارسال شده در: يكشنبه، 7 آذر ماه ، 1389 20:04:58    موضوع مطلب: اتاق کار شماره 04 برنامه نویسی win32 پاسخ همراه با اعلان

بسم الله الرحمن الرحیم

اتاق کار شماره 04 برنامه نویسی Win32

حلقه RealTime

مقدمه: در این اتاق کار می خواهیم یک حلقه پیام به شکل Real Time را بررسی کنیم. ما به بررسی یک تابع با نام PeekMessage و به بررسی تفاوت آن با تابع GetMessage می پردازیم.
به طور کلی استفاده از تابع GetMessage اشتباه نیست امّا این تابع نمی تواند یک نتیجه بسیار خوب را برای بازی ها و صحنه های شبیه ساز تعاملی را بدهد. پس بهترین راه استفاده از PeekMessage است که در این اتاق کار چگونگی کار با این تابع را آموزش می دهیم.

ساختار حلقه GetMessage

در اتاق کار قبلی ما با استفاده از تابع GetMessage یک نمونه پنجره کاربردی را ایجاد کردیم. ما از تابع GetMessage و دو تابع دیگر برای ساختن یک حلقه که در ارسال پیام های تمام پنجره ها به کار می رفت. البته ما نمی خواهیم دوباره درباره اتاق کار قبلی صحبت کنیم پس اگر کمی برایتان این موضوعات مبهم بود حتماً اتاق کارهای قبلی را یک بار دیگر با دقت بخوانید. در نمودار زیر به شما نحوه کار حلقه رویدادها را که نوشتیم نشان می دهیم.


یکبار که ما یک پنجره را ایجاد می کنیم ما آنرا در یک حلقه رویداد قرار می دهیم. جایی که ما تابع GetMessage را می بینیم. GetMessage برای یک پیام صبر می کند و آن را می گیرد و به مرحله بعد می دهد. TranslateMessage هم کاملاً منطقی و روشن برای برنامه نویسی ویندوز است. زیرا به شکل طبیعی با برنامه کاربردی تحت ویندوز صحبت می کند. درست مثل همین نرم افزار Word که تا شما حرکتی نکنید آن هم کاری نمی کند و منتظر حرکتتان می شود.
هرچند ما به این کارها نیازی نداریم. ما تنها به 36 تصویر سه بعدی به شکل تمام رندرشده در هر ثانیه نیاز داریم که در صحنه گذاشته شود بدون هیچ تاخیری. و ما همچنین باید برای رویارویی با یک مشکل آماده شویم. اگر ویندوز برای هر پیام بخواهد صبر کند به طور قطع ما نمی توانیم 30 تا در هر ثانیه بفرستیم.

تابع جدید PeekMessage

ما برای حل این مشکل به جای استفاده از تابع GetMessage از یک تابع جدید با نام PeekMessage استفاده می کنیم. این تابع در اصل مشابه تابع قبلی می باشد. امّا یک تفاوت خیلی مهم دارد و آن تفاوت این است که نمی تواند برای هر چیزی صبر کند. PekkMessage فقط به صف پیامها نگاهی می اندازد و بررسی می کند و اگر پیامی بود اجرا می کند و اگر نبود برنامه می تواند ادامه پیدا کند. این برای چیزی که ما می خواهیم خیلی کاربردی است یک نگاهی به نمودار زیر بیاندازید تا بیشتر متوجه بشوید البته حین نگاه کردن نیم نگاهی هم برای مقایسه به نمودار بالا بیاندازید مطمئناً فرق این دو تابع را متوجه خواهید شد.


از شروع بهتر است نگاهی کوچک و ساده به ساختار تابع PeekMessage بیاندازیم.

                           
:كد

BOOL PeekMessage(LPMSG lpMsg,
                 HWND hWnd,
                 UINT wMsgFilterMin,
                 UINT wMsgFilterMax,
                 UINT wRemoveMsg);

چهار پارامتر اوّلیه این تابع مسلماً برای شما آشنا است. این چهار پارامتر در تابع GetMessage هم مورد استفاده قرار می گرفت. امّا پنجمین پارامتر wRemoveMsg جدید است.
در هر صورت پیامهای دریافت شده از صف رویدادها یا متوقف شده یا انجام می شود. ما می توانیم PM_REMOVE یا PM_NOREMOVE را بگذاریم. اوّلین پیامی که از صف رویدادها برای خواندن خارج می شود در آن ثانیه یک پیام برای بازیابی بعد آماده می شود. ما می توانیم در اینجا از مقدار PM_REMOVE استفاده کنیم.
خوب حالا این سوال مطرح می شود که ما چگونه اینها را در برنامه اجرا کنیم. در حلقه اصلی آخرین برنامه ای که نوشتیم باید ما آن را تغییر می دهیم و این بار از PeekMeesage می باشد.

                           
:كد

// Enter the infinite message loop
while(TRUE)
{
    // Check to see if any messages are waiting in the queue
    while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
        // Translate the message and dispatch it to WindowProc()
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    // If the message is WM_QUIT, exit the while loop
    if(msg.message == WM_QUIT)
        break;

    // Run game code here
    // ...
    // ...
}


اکنون برنامه ما می تواند بارها اجرا شود بدون هیچ ترسی از ویندوز و پیامهای خسته کننده اش. خوب بریم و یک نگاه سریع به تغییراتمان بکنیم.

                           
:كد

while(TRUE)
به طور طبیعی یک حلقه نامحدود می سازد. هنگام خروج از بازی می توانیم از این حلقه خارج شویم.
                           
:كد

while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
این را استفاده کردیم چون نمی خواهیم برای پیام های ویندوز صبر کنیم امّا یک زیرچشمی هم به پیام های ویندوز داریم. ما در اینجا می خواهیم از PeekMessage استفاده کنیم. PeekMessage مقدار TRUE را درصورتی که پیامی دریافت کند برمی گرداند و FALSE را اگر دریافت نکند و همچنین محتویات حلقه while را اجرا می کند که کدهای بازی ما در آن قرار دارد.
                           
:كد

if(msg.message == WM_QUIT)
این خط کد این معنی را دارد که اگر پیام ما WM_QUIT بود زمانی است که ما باید از حلقه پنجره مان خارج شویم. به یاد بیاورید که ما همچنین چیزی را در GetMessage نداشتیم زیرا در آن تابع ما مقدار 0 را در هنگام بسته شدن برمی گردانیم. امّا در اینجا باید از حلقه خارج شویم و یک مقدار اصول کار فرق دارد.
اینجا کدهای جدیدمان قرار دارد.

                           
:كد

// include the basic windows header file
#include <windows.h>
#include <windowsx.h>

// the WindowProc function prototype
LRESULT CALLBACK WindowProc(HWND hWnd,
                         UINT message,
                         WPARAM wParam,
                         LPARAM lParam);

// the entry point for any Windows program
int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow)
{
    // the handle for the window, filled by a function
    HWND hWnd;
    // this struct holds information for the window class
    WNDCLASSEX wc;

    // clear out the window class for use
    ZeroMemory(&wc, sizeof(WNDCLASSEX));

    // fill in the struct with the needed information
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
    wc.lpszClassName = L"WindowClass1";

    // register the window class
    RegisterClassEx(&wc);

    // create the window and use the result as the handle
    hWnd = CreateWindowEx(NULL,
                          L"WindowClass1",    // name of the window class
                          L"Our First Windowed Program",    // title of the window
                          WS_OVERLAPPEDWINDOW,    // window style
                          300,    // x-position of the window
                          300,    // y-position of the window
                          500,    // width of the window
                          400,    // height of the window
                          NULL,    // we have no parent window, NULL
                          NULL,    // we aren't using menus, NULL
                          hInstance,    // application handle
                          NULL);    // used with multiple windows, NULL

    // display the window on the screen
    ShowWindow(hWnd, nCmdShow);

    // enter the main loop:

    // this struct holds Windows event messages
    MSG msg;

    // Enter the infinite message loop
    while(TRUE)
    {
        // Check to see if any messages are waiting in the queue
        while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            // translate keystroke messages into the right format
            TranslateMessage(&msg);

            // send the message to the WindowProc function
            DispatchMessage(&msg);
        }

        // If the message is WM_QUIT, exit the while loop
        if(msg.message == WM_QUIT)
            break;

        // Run game code here
        // ...
        // ...
    }

    // return this part of the WM_QUIT message to Windows
    return msg.wParam;
}

// this is the main message handler for the program
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    // sort through and find what code to run for the message given
    switch(message)
    {
        // this message is read when the window is closed
        case WM_DESTROY:
            {
                // close the application entirely
                PostQuitMessage(0);
                return 0;
            } break;
    }

    // Handle any messages the switch statement didn't
    return DefWindowProc (hWnd, message, wParam, lParam);
}

هنگامی که شما برنامه تان را اجرا می کنیم می بینید که در خروجی این دو تابع GetMessage و PeekMessage هیچ تفاوت چندانی با هم ندارد. در حقیقت شما تفاوت این دو را در برنامه نویسی بازی مشاهده خواهید کرد.
خوب من خیلی خوشحالم که به لطف خداوند توانستم در چهار اتاق کار برنامه نویسی لازم تحت ویندوز برای ساخت بازی را به شکل کامل به شما یاد دادم و این اتاق کار پایان برنامه نویسی تحت ویندوز برای ساخت بازی می باشد. درست در ظاهر کار ممکن است یک مقدار پیچیده باشد امّا مطمئن باشید با کمی تمرین تمام این توابع و کارکرد آنها را یاد خواهید گرفت. اگر تا اکنون تمام اتاق کارها را تمرین و یاد گرفته اید کاملاً برای یادگیری DirectX آماده اید پس من به شما پیشنهاد می کنم بعد از اتمام این چهار اتاق کار آموزش های ما در اتاق کارهای DirectX را پی گیری کنید.
نویسنده این اتاق کارها خادم همیشگی شما جویندگان علم و دانش محمد غضنفری می باشد.

_________________
هدف ما پیشرفت صنعت بازی های رایانه ای در ایران است.
امام باقر (علیه السلام): دانشمندی که از علمش استفاده شود از هفتاد هزار عابد بهتر است.

بازگشت به بالا

رويت مشخصات كاربر ارسال پيغام شخصي بازديد از سايت ارسال كننده مطلب شناسه Yahoo
کاربرانی که برای این ارسال از admin تشکر کرده اند smoke
تمامي مطالب ارسال شده:   
اين انجمن قفل شده است . شما مجاز به ارسال مطلب يا جوابيه و ويرايش مطالب نمي باشيد.    اين مطلب قفل شده است . شما مجاز به ويرايش آن و يا ارسال جوابيه نمي باشيد .   

   بازی ساز تخصصی ترین تارنمای آموزش ساخت و طراحی بازی صفحه اول انجمن -> برنامه نویسی به زبان ++C -> اتاق کارهای Workshop Win32

زمان پيشفرض سايت: ساعت گرينويچ + 3.5 ساعت
صفحه 1 از 1
  

پاسخ سريع در دسترس نميباشد

  


 


Powered by phpBB © 2001, 2008 phpBB Group
تبلیغات شما در اینجا


Powered By PHPNuke All Right Reserved bazisaz Team