मैं सोच रहा था कि क्या कोई संभावित नुकसान हो सकता है जब मेरा गेम लूप जितनी तेजी से चलता है उतना ही सिस्टम अनुमति देता है?
मेरे पास वर्तमान में एक लूप है, जो नैनोसेकंड में पारित समय को मापकर, गेम लॉजिक चलाता है और बिना किसी समस्या के पूर्वनिर्धारित गति से तर्क प्रदान करता है। वास्तव में लूप में मैं जो भी तर्क करता हूं, उसे प्रत्येक सेकंड में एक निश्चित मात्रा में कॉल किया जाता है।
लूप अपने आप में केवल उतना ही तेज चलता है जितना कि यह पसंद करता है कि मेरी मशीन पर लगभग 11.7 मिलियन लूप एक सेकंड में आता है।
पाश (सरल छद्मकोश):
while(!isGameOver){
if(canPollInputs){
pollInputs()
}
while(canStepLogic){
stepLogic()
}
if(canRender){
render()
}
}
मेरा सवाल मूल रूप से है कि अगर साधारण लूप, यदि इसकी नियंत्रित गति से नहीं चल रहा है, तो क्या सिस्टम को कोई नुकसान पहुंचा सकता है?
संपादित करें: इसका मतलब है कि मेरा तर्क 30 बार (30 tps) सेकंड में चल रहा है, मेरा रेंडर 60 एफपीएस पर चल रहा है, मैं एक सेकंड में 100 बार इनपुट कर रहा हूं और तर्क के साथ सामना करने के लिए कुछ तर्क भी है या अपेक्षा से अधिक समय तक प्रतिपादन करना । लेकिन लूप खुद थ्रोटल नहीं है।
संपादित करें: Thread.sleep()
उदाहरण के लिए थ्रॉटल को मुख्य लूप से 250 लूप प्रति सेकेंड तक कम करने का उपयोग करने से घटता है, लेकिन लूप वांछित 250 के बजाय लगभग 570 लूप प्रति सेकंड पर चलता है (जब मैं अपने डेस्कटॉप मशीन पर कोड डालूंगा ..)
संपादित करें: यहां हम जाते हैं, चीजों को स्पष्ट करने के लिए एक कामकाजी जावा गेमेलोप। इसका उपयोग करने के लिए भी स्वतंत्र महसूस करें, लेकिन इसका दावा न करें;)
private void gameLoop() {
// Time that must elapse before a new run
double timePerPoll = 1000000000l / targetPPS;
double timePerTick = 1000000000l / targetTPS;
double timePerFrame = 1000000000l / targetFPS;
int maxFrameSkip = (int) ( (1000000000l / MINIMUM_FPS) / timePerTick);
int achievedPPS = 0;
int achievedFPS = 0;
int achievedTPS = 0;
long timer = TimeUtils.getMillis();
int loops = 0;
int achievedLoops = 0;
long currTime = 0l;
long loopTime = 0l;
long accumulatorPPS = 0l;
long accumulatorTPS = 0l;
long accumulatorFPS = 0l;
long lastTime = TimeUtils.getNano();
while(!isRequestedToStop) {
currTime = TimeUtils.getNano();
loopTime = currTime - lastTime;
lastTime = currTime;
loops = 0;
accumulatorPPS += loopTime;
accumulatorTPS += loopTime;
accumulatorFPS += loopTime;
if(accumulatorPPS >= timePerPoll) {
pollInputs();
playerLogic();
achievedPPS++;
accumulatorPPS -= timePerPoll;
}
while(accumulatorTPS >= timePerTick && loops < maxFrameSkip) {
tick();
achievedTPS++;
accumulatorTPS -= timePerTick;
loops++;
}
// Max 1 render per loop so player movement stays fluent
if(accumulatorFPS >= timePerFrame) {
render();
achievedFPS++;
accumulatorFPS -= timePerFrame;
}
if(TimeUtils.getDeltaMillis(timer) > 1000) {
timer += 1000;
logger.debug(achievedTPS + " TPS, " + achievedFPS + " FPS, "
+ achievedPPS + " Polls, " + achievedLoops + " Loops");
achievedTPS = 0;
achievedFPS = 0;
achievedLoops = 0;
}
achievedLoops++;
}
}
जैसा कि आप देख सकते हैं कि प्रत्येक लूप पर लगभग कोई कोड रन नहीं है लेकिन हमेशा एक निश्चित चयन होता है कि वास्तविक समय कितना बीत चुका है। यह सवाल उस 'वर्कर लूप' का जिक्र कर रहा है और यह सिस्टम को कैसे प्रभावित करता है।