Application.Runकॉल ड्राइव आपके Windows संदेश पंप है, जो अंततः है क्या शक्तियों सभी घटनाओं आप पर हुक कर सकते हैं Formवर्ग (और अन्य)। इस पारिस्थितिकी तंत्र में गेम लूप बनाने के लिए, आप तब सुनना चाहते हैं जब एप्लिकेशन का संदेश पंप खाली हो, और जब वह खाली रहता है, तो विशिष्ट "प्रक्रिया इनपुट स्थिति, गेम लॉजिक को अपडेट करें, दृश्य के रेंडर के चरण" को प्रोटोटाइपिकल गेम लूप प्रदान करें। ।
Application.Idleघटना आग हर बार एक बार आवेदन के संदेश कतार खाली कर दिया जाता है और आवेदन एक निष्क्रिय अवस्था में संक्रमण है। आप अपने मुख्य फॉर्म के निर्माणकर्ता में घटना को हुक कर सकते हैं:
class MainForm : Form {
public MainForm () {
Application.Idle += HandleApplicationIdle;
}
void HandleApplicationIdle (object sender, EventArgs e) {
//TODO: Implement me.
}
}
अगला, आपको यह निर्धारित करने में सक्षम होना चाहिए कि क्या एप्लिकेशन अभी भी निष्क्रिय है। Idleघटना केवल एक बार आग, जब आवेदन हो जाता है बेकार। यह तब तक फिर से निकाल नहीं दिया जाता है जब तक कि एक संदेश कतार में नहीं जाता है और फिर कतार फिर से खाली हो जाती है। Windows प्रपत्र संदेश कतार की स्थिति को क्वेरी करने के लिए एक विधि को उजागर नहीं करता है, लेकिन आप क्वेरी को एक देशी Win32 फ़ंक्शन को सौंपने के लिए प्लेटफ़ॉर्म आमंत्रण सेवाओं का उपयोग कर सकते हैं जो उस प्रश्न का उत्तर दे सकते हैं । इसके PeekMessageऔर इसके सहायक प्रकारों के आयात की घोषणा इस प्रकार है:
[StructLayout(LayoutKind.Sequential)]
public struct NativeMessage
{
public IntPtr Handle;
public uint Message;
public IntPtr WParameter;
public IntPtr LParameter;
public uint Time;
public Point Location;
}
[DllImport("user32.dll")]
public static extern int PeekMessage(out NativeMessage message, IntPtr window, uint filterMin, uint filterMax, uint remove);
PeekMessageमूल रूप से आपको कतार में अगले संदेश को देखने की अनुमति देता है; यह सच है अगर कोई मौजूद है, तो अन्यथा। इस समस्या के उद्देश्यों के लिए, कोई भी पैरामीटर विशेष रूप से प्रासंगिक नहीं है: यह केवल वापसी मूल्य है जो मायने रखता है। यह आपको एक फ़ंक्शन लिखने की अनुमति देता है जो आपको बताता है कि क्या एप्लिकेशन अभी भी निष्क्रिय है (अर्थात, कतार में अभी भी कोई संदेश नहीं हैं):
bool IsApplicationIdle () {
NativeMessage result;
return PeekMessage(out result, IntPtr.Zero, (uint)0, (uint)0, (uint)0) == 0;
}
अब आपके पास अपना पूरा गेम लूप लिखने की जरूरत है:
class MainForm : Form {
public MainForm () {
Application.Idle += HandleApplicationIdle;
}
void HandleApplicationIdle (object sender, EventArgs e) {
while(IsApplicationIdle()) {
Update();
Render();
}
}
void Update () {
// ...
}
void Render () {
// ...
}
[StructLayout(LayoutKind.Sequential)]
public struct NativeMessage
{
public IntPtr Handle;
public uint Message;
public IntPtr WParameter;
public IntPtr LParameter;
public uint Time;
public Point Location;
}
[DllImport("user32.dll")]
public static extern int PeekMessage(out NativeMessage message, IntPtr window, uint filterMin, uint filterMax, uint remove);
}
इसके अलावा, यह दृष्टिकोण संभव के रूप में करीब से मेल खाता है (पी / इनवोक पर न्यूनतम निर्भरता के साथ) विहित देशी विंडोज गेम लूप के साथ, जो इस तरह दिखता है:
while (!done) {
if (PeekMessage(&message, window, 0, 0, PM_REMOVE)){
TranslateMessage(&message);
DispatchMessage(&message);
}
else {
Update();
Render();
}
}