2010-07-22 14 views
8

मैं एक पुराना स्कूल ASCII डॉस-प्रॉम्प्ट गेम लिख रहा हूं। ईमानदारी से मैं गेम डिजाइन के इस ब्रांड के बारे में अधिक जानने के लिए जेडजेडटी का अनुकरण करने की कोशिश कर रहा हूं (भले ही यह पुरातन है)एएससीआईआई डॉस गेम्स - रेंडरिंग विधियां

मैं अच्छा कर रहा हूं, काम करने के लिए मेरा पूर्ण-स्क्रीन टेक्स्ट मोड मिला और मैं दुनिया बना सकता हूं और स्थानांतरित कर सकता हूं समस्याओं के बिना चारों ओर लेकिन मुझे अपने प्रस्तुतकर्ताओं के लिए एक सभ्य समय विधि नहीं मिल रही है।

मैं जानता हूँ कि मेरी प्रतिपादन और पूर्व प्रतिपादन कोड तेजी से है, क्योंकि अगर मैं किसी भी देरी() s या नहीं जोड़ते हैं (घड़ी() - renderBegin)/से time.h renders CLK_TCK चेकों blazingly तेजी से कर रहे हैं।

मैं देरी() का उपयोग नहीं करना चाहता क्योंकि यह मेरे ज्ञान प्लेटफार्म के लिए विशिष्ट है और इसके शीर्ष पर मैं देरी के दौरान कोई कोड नहीं चला सकता (उपयोगकर्ता इनपुट और प्रसंस्करण की तरह)। तो मैंने ऐसा कुछ करने का फैसला किया:

do { 
    if(kbhit()) { 
     input = getch(); 
     processInput(input); 
    } 

    if(clock()/CLOCKS_PER_SEC-renderTimer/CLOCKS_PER_SEC > RenderInterval) { 
     renderTimer = clock(); 
     render(); 
     ballLogic(); 
    } 
}while(input != 'p'); 

"सिद्धांत" में कौन सा होना चाहिए ठीक है। समस्या यह है कि जब मैं इस कोड को चलाता हूं (RenderInterval को 0.0333 या 30fps पर सेट करता है) मुझे 30fps के करीब कोई भी नहीं मिलता है, मुझे अधिकतम 18 की तरह मिलता है।

मैंने सोचा कि शायद मैं रेंडरइंटरवाल को 0.0 पर सेट करने का प्रयास करूँगा यह देखने के लिए कि क्या प्रदर्शन खराब हो गया है ... ऐसा नहीं हुआ। मैं (0.0 के रेंडर इंटरवल के साथ) अधिकतम ~ 18-20fps पर प्राप्त कर रहा था।

हालांकि शायद मैं इन सभी घड़ी() को लगातार कॉल कर रहा हूं और "इसे उस से विभाजित कर सकता हूं" तरीकों से मैं सीपीयू को कुछ डरावना कर रहा था, लेकिन जब मैंने रेंडर और बॉल लॉजिक को कथन के ब्रैकेट से बाहर ले लिया और रेंडरइंटरवाल को 0.0 तक सेट करें, मैं फिर से, तेजी से तेजी से प्रस्तुत करता हूं।

यह मेरे लिए बाध्य नहीं करता है क्योंकि अगर मैंने चेक किया है, तो क्या यह धीमी गति से नहीं चलना चाहिए? मेरा मतलब है कि यह अभी भी सभी गणना करने के लिए

BTW मैं Borland के टर्बो सी के साथ संकलन कर रहा हूँ ++ V1.01 है

+1

Zzt! मुझे वह खेल पसंद आया। – caf

+0

आप और मैं दोनों, कैफ। ('# थ्रोस्टार खोज ')। @ Parad0x13: यदि आप डॉस से दूर जाने से परहेज नहीं करते हैं, तो मैं एक पुस्तकालय लिखा एसडीएल द्वारा समर्थित किसी भी मंच पर इस ग्राफिक शैली का अनुकरण करने: http://libfake437.googlecode.com –

+0

आप 'घड़ी से परिणाम बंद संग्रहीत करते हैं () '(घड़ी (यह और संग्रहीत मूल्य) सबसे तेजी से कोड कोड आप कॉल नहीं करते है और इसे और अधिक सटीक हो जाएगा (अन्यथा आप जब आप पहली बार कहा जाता है के बीच के समय को खोना) असाइन करते हैं, आप इसे करने के लिए एक कॉल की बचत होगी' ' , सभी गणित किया और शाखा संभाला)। सटीकता का यह नुकसान गेम को धीमा कर देगा जो आप चाहते हैं, भले ही आप अब सीपीयू उपयोग को अधिकतम नहीं कर रहे हों। (संपादित करें: हाहा, बस इस तारीख को देखा, ओह ठीक है) –

उत्तर

1
clock()-renderTimer > RenderInterval * CLOCKS_PER_SEC 

तेजी से थोड़ा परिकलित किया जाएगा, संभवतः भी तेजी से करता है, तो आप पहले से गणना RenderInterval * CLOCKS_PER_SEC हिस्सा ।

+0

आपकी प्रतिक्रिया के लिए धन्यवाद, मैं अनुकूलन देखता हूं। इसके बावजूद भी मुद्दा अभी भी मौजूद है। बस हालांकि – Parad0x13

+0

इसे करने की कोशिश करता है संकलक छोरों पर अनुकूलन के सभी तरह है, जो विशेषताओं बना सकते हैं (खासकर अगर वे शाखाओं होते हैं) - दोनों ही मामलों में तैयार किए गए कोड को देखने के लिए प्रयास करें। वास्तव में, प्रोसेसर कुछ समान काम करता है (शाखा भविष्यवाणी देखें)। – Ofir

+0

मैंने प्री-प्रोसेसर की जांच की लेकिन मुझे पता नहीं लगा कि कौन से अनुकूलन सक्षम हैं – Parad0x13

0

इसके बारे में क्या: आप एक्स (= घड़ी()) y (= renderTimer) से घट रहे हैं। दोनों x और y CLOCKS_PER_SEC से विभाजित किया जा रहा है:

(clock() - renderTimer) > RenderInterval 

पहले ही समस्या मैं विभाजन के साथ देखा है कि आप नहीं जा रहे हैं था:

clock()/CLOCKS_PER_SEC-renderTimer/CLOCKS_PER_SEC > RenderInterval 

यह मोर efficiente लिखने के लिए नहीं होगा इससे वास्तविक संख्या प्राप्त करने के लिए, क्योंकि यह दो लंबी स्याही के बीच होता है। सेकेंड समस्या यह है कि यह रेंडरइंटरवाल * CLOCKS_PER_SEC गुणा करने के लिए अधिक कुशल है और इस तरह से इसे छुटकारा पाएं, ऑपरेशन को सरल बनाते हैं।

ब्रैकेट जोड़ना इससे अधिक सुगमता प्रदान करता है। और शायद इस फ़ार्मूला को सरल बनाकर आप आसानी से क्या गलत हो रहे हैं।

+0

के बजाय मैंने इन सूत्र अनुकूलन की कोशिश की लेकिन मुझे एक ही परिणाम जारी रहे। – Parad0x13

+0

क्या होगा यदि आप RenderInterval = 1 को मजबूर करते हैं? – Baltasarq

0

जैसा कि आपने अपने सबसे हालिया प्रश्न के साथ देखा है, आप केवल CLOCKS_PER_SEC द्वारा सीमित हैं जो केवल 18 वर्ष के हैं। आपको घड़ी के प्रति अलग मूल्य एक फ्रेम मिलता है, यही कारण है कि आप 18fps तक सीमित हैं।

आप समय के लिए स्क्रीन ऊर्ध्वाधर रिक्त अंतराल इस्तेमाल कर सकते हैं, यह खेल के लिए पारंपरिक है टाल के रूप में यह "फाड़" (जहां आधी स्क्रीन एक फ्रेम से पता चलता है और आधा एक और पता चलता)

0

मैं पता लगा क्यों यह नहीं था अभी प्रतिपादन, टाइमर है कि मैं बनाया समस्या यह है कि वास्तविक clock_t .054547XXX या तो और इसलिए मैं केवल 18fps पर प्रस्तुत कर सकता है के लिए एक ही सटीक है है ठीक है। जिस तरह से मैं इसे ठीक हैं एक और अधिक सटीक घड़ी ... जो एक पूरी अन्य कहानी

2

सबसे अच्छा गेमिंग अनुभव आमतौर पर नजर रखने के ऊर्ध्वाधर retrace के साथ सिंक्रनाइज़ द्वारा हासिल की है है का उपयोग करना है। समय प्रदान करने के अलावा, यह स्क्रीन पर गेम को आसान बना देगा, कम से कम यदि आपके पास कंप्यूटर से जुड़े सीआरटी मॉनीटर हैं।

80x25 पाठ मोड में, ऊर्ध्वाधर retrace (वीजीए पर) 70 बार/सेकंड होता है। मुझे याद नहीं है कि आवृत्ति ईजीए/सीजीए पर समान थी, लेकिन मुझे पूरा यकीन है कि यह हरक्यूलिस और एमडीए पर 50 हर्ट्ज था। कहें, 20 फ्रेम की अवधि को मापकर, आपके पास पर्याप्त आवृत्ति होनी चाहिए कि आप किस आवृत्ति से निपट रहे हैं।

मुख्य लूप someting तरह करते हैं:

while (playing) { 
    do whatever needs to be done for this particular frame 
    VSync(); 
    } 

    ... /* snip */ 

    /* Wait for vertical retrace */ 
    void VSync() { 
    while((inp(0x3DA) & 0x08)); 
    while(!(inp(0x3DA) & 0x08)); 
    } 
संबंधित मुद्दे