এক্সএনএ কল করা বন্ধ করে Update
এবং Draw
গেমের উইন্ডোটি পুনরায় আকার দেওয়া বা সরানোর সময় বন্ধ করে দেয় ।
কেন? এই আচরণ রোধ করার কোনও উপায় আছে?
(এটি আমার নেটওয়ার্ক কোডটি বিচ্ছিন্ন করে দেয়, কারণ নেটওয়ার্ক বার্তাগুলি পাম্প করা হচ্ছে না))
এক্সএনএ কল করা বন্ধ করে Update
এবং Draw
গেমের উইন্ডোটি পুনরায় আকার দেওয়া বা সরানোর সময় বন্ধ করে দেয় ।
কেন? এই আচরণ রোধ করার কোনও উপায় আছে?
(এটি আমার নেটওয়ার্ক কোডটি বিচ্ছিন্ন করে দেয়, কারণ নেটওয়ার্ক বার্তাগুলি পাম্প করা হচ্ছে না))
উত্তর:
হ্যাঁ. এটিতে এক্সএনএর ইন্টার্নালগুলির সাথে অল্প পরিমাণে গণ্ডগোল জড়িত। আমি এই ভিডিওর দ্বিতীয়ার্ধে একটি স্থির একটি প্রদর্শনী পেয়েছি ।
পটভূমি:
এটি হওয়ার কারণটি হ'ল XNA তার গেমের ঘড়ি স্থগিত করে যখন Game
অন্তর্নিহিত Form
আকারটি পুনরায় আকার দেওয়া হয় (বা সরানো হয়, ইভেন্টগুলি একই হয়)। এটি, পরিবর্তে, কারণ এটি তার গেম লুপটি চালাচ্ছে Application.Idle
। যখন উইন্ডোটির আকার পরিবর্তন করা হয়, উইন্ডোজ কিছু ক্রেজি উইন 32 মেসেজ লুপ স্টাফ করে যা Idle
গুলি চালানো থেকে বাধা দেয় ।
সুতরাং, যদি Game
এটির ঘড়িটি স্থগিত না করা হয় তবে একটি আকার পরিবর্তন করার পরে এটি একটি প্রচুর পরিমাণে সঞ্চিত হয়ে যায় যে এটির পরে এটি একটি ফাটলে আপডেট করতে হবে - স্পষ্টভাবে কাম্য নয়।
কিভাবে ঠিক হবে এটা:
এক্সএনএ-তে ইভেন্টগুলির একটি দীর্ঘ শৃঙ্খলা রয়েছে (যদি আপনি এটি ব্যবহার Game
করেন তবে এটি কাস্টম উইন্ডোতে প্রযোজ্য নয়) যা গেমের ঘড়ির জন্য মূলত অন্তর্নিহিত ইভেন্টের আকার পরিবর্তন Form
করে Suspend
এবং Resume
পদ্ধতিগুলি সংযুক্ত করে ।
এগুলি ব্যক্তিগত, তাই ইভেন্টগুলি আনহুক করার জন্য আপনাকে প্রতিবিম্বটি ব্যবহার করতে হবে (যেখানে this
রয়েছে Game
):
this.host.Suspend = null;
this.host.Resume = null;
প্রয়োজনীয় আবশ্যকতা এখানে:
object host = typeof(Game).GetField("host", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this);
host.GetType().BaseType.GetField("Suspend", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(host, null);
host.GetType().BaseType.GetField("Resume", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(host, null);
(আপনি চেইনটি অন্য কোথাও সংযোগ বিচ্ছিন্ন করতে পারেন, এটি সনাক্ত করার জন্য আপনি আইএলএসপি ব্যবহার করতে পারেন But তবে উইন্ডোর আকারের পরিবর্তে আর কিছু নেই যা টাইমারকে স্থগিত করে - তাই এই ইভেন্টগুলি যে কোনওটির মতোই দুর্দান্ত))
তারপরে আপনাকে নিজের টিক উত্স সরবরাহ করতে হবে, যখন XNA কখন থেকে টিক দিচ্ছে না Application.Idle
। আমি কেবল একটি ব্যবহার করেছি System.Windows.Forms.Timer
:
timer = new Timer();
timer.Interval = (int)(this.TargetElapsedTime.TotalMilliseconds);
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
এখন, timer_Tick
শেষ পর্যন্ত কল করবে Game.Tick
। এখন যেহেতু এই ঘড়িটি স্থগিত করা হয়নি, আমরা কেবল এক্সএনএর নিজস্ব টাইমিং কোডটি ব্যবহার করা মুক্ত। সহজ! একেবারেই নয়: এক্সএনএ-র অন্তর্নির্মিত টিকিংটি না ঘটে কেবল তখনই আমরা আমাদের ম্যানুয়াল টিকিংটি ঘটতে চাই। এটি করার জন্য এখানে কিছু সাধারণ কোড দেওয়া হল:
bool manualTick;
int manualTickCount = 0;
void timer_Tick(object sender, EventArgs e)
{
if(manualTickCount > 2)
{
manualTick = true;
this.Tick();
manualTick = false;
}
manualTickCount++;
}
এবং তারপরে, Update
এক্সএনএ সাধারণত টিক দিচ্ছে তবে এই কোডটি কাউন্টারটিকে পুনরায় সেট করতে রাখুন।
if(!manualTick)
manualTickCount = 0;
নোট করুন যে এই টিকিংটি XNA এর যথেষ্ট কম নির্ভুল। তবে এটি রিয়েল টাইমটির সাথে কমবেশি আবদ্ধ থাকা উচিত।
এই কোডটিতে এখনও একটি ছোট ত্রুটি রয়েছে। উইন 32, এর নির্বোধ কুরুচিপূর্ণ মুখকে আশীর্বাদ করুন, মাউসটি আসলে চলার আগে আপনি উইন্ডোর শিরোনাম-বারটিতে ক্লিক করার পরে কয়েক শত মিলি সেকেন্ডের জন্য সমস্ত বার্তা বন্ধ করে দেয় ( আবার সেই একই লিঙ্কটি দেখুন )। এটি আমাদের Timer
(যা বার্তা-ভিত্তিক) টিক দেওয়া থেকে বাধা দেয় ।
যেহেতু আমরা এখন এক্সএনএর গেম ক্লকটি স্থগিত করি না, যখন আমাদের টাইমার অবশেষে আবার টিক দেওয়া শুরু করে, আপনি আপডেটগুলি দেখতে পাবেন। এবং দুর্ভাগ্যক্রমে, এক্সএনএ আপনি শিরোনাম বারটি ক্লিক করার সময় উইন্ডোজ বার্তা থামিয়ে দেওয়ার সময়ের চেয়ে সামান্য কম পরিমাণে জমে থাকা সময়ের পরিমাণকে ক্যাপ করে রাখে । সুতরাং যদি কোনও ব্যবহারকারী আপনার শিরোনাম-বারটি সরিয়ে না রেখে ক্লিক করে ধরে রাখার ঘটনা ঘটে তবে আপনি আপডেটের একটি বিস্ফোরণ পেয়ে যাবেন এবং রিয়েল টাইম থেকে কিছু ফ্রেম হ্রাস পাবে।
(কিন্তু এই এখনও হওয়া উচিত যথেষ্ট অধিকাংশ ক্ষেত্রে জন্য। XNA'S টাইমার ইতিমধ্যে উত্সর্গমূলক তোতলামি প্রতিরোধ সঠিকতা, তাই যদি আপনি প্রয়োজন নিখুঁত টাইমিং, আপনি অন্য কিছু করা উচিত।)