দুটি গেমের মধ্যে কীভাবে বিভক্ত হবে?


24

এমন একটি সিস্টেম তৈরি করার জন্য সেরা প্যাটার্নটি কী যা সমস্ত অবজেক্টের অবস্থান দুটি আপডেটের মধ্যবর্তী স্থানে বিভক্ত হয়?

আপডেটটি সর্বদা একই ফ্রিকোয়েন্সিতে চলবে তবে আমি কোনও এফপিএসে রেন্ডার করতে সক্ষম হতে চাই। সুতরাং রেন্ডারিং যতটা সম্ভব মসৃণ হবে যতক্ষণ না প্রতি সেকেন্ডের ফ্রেমগুলি বিবেচনা করুন না কেন তা আপডেটের ফ্রিকোয়েন্সি থেকে কম বা বেশি।

আমি বর্তমান ফ্রেম থেকে ভবিষ্যতের ফ্রেমে ভবিষ্যতের ইন্টারপোলেটে 1 ফ্রেম আপডেট করতে চাই। এই উত্তরের একটি লিঙ্ক রয়েছে যা এটি করার বিষয়ে কথা বলে:

সেমি-ফিক্সড বা ফুল-ফিক্সড টাইমস্টেপ?

সম্পাদনা করুন: আমি কীভাবে ইন্টারপোলেশনে শেষ এবং বর্তমান গতি ব্যবহার করতে পারি? উদাহরণস্বরূপ, কেবল লিনিয়ার অন্তরঙ্গকরণের সাথে এটি অবস্থানের মধ্যে একই গতিতে অগ্রসর হবে। এটি দুটি পয়েন্টের মধ্যে অবস্থানটি বিভক্ত করার জন্য আমার একটি উপায় প্রয়োজন, তবে প্রতিযোগিতার জন্য প্রতিটি পয়েন্টের গতি বিবেচনা করুন। এটি কণার প্রভাবের মতো কম হারের সিমুলেশনের জন্য সহায়ক হবে।


2
টিক্স হচ্ছে যুক্তি টিক্স? সুতরাং আপনার আপডেট fps <রেকর্ডিং এফপিএস?
কম্যুনিস্ট হাঁস

আমি শব্দটি পরিবর্তন করেছি। তবে হ্যাঁ লজিক টিক্স এবং না, আমি আপডেটটি থেকে সম্পূর্ণ রেন্ডারিং মুক্ত করতে চাই, সুতরাং গেমটি 120HZ বা 22.8HZ এ রেন্ডার করতে পারে এবং আপডেট করার পরেও একই গতি চলবে, যদি ব্যবহারকারী সিস্টেমের প্রয়োজনীয়তা পূরণ করে meets
অ্যাটাকিংহোব

এটি সত্যই জটিল হতে পারে যেহেতু আপনার সমস্ত বস্তুর অবস্থানের রেন্ডার করার সময় স্থির থাকা উচিত (রেন্ডার প্রক্রিয়া চলাকালীন এগুলি পরিবর্তন করা কিছু অস্বচ্ছল আচরণের কারণ হতে পারে)
Ali1S232

ইতিমধ্যে 2 গণনা করা আপডেট ফ্রেমগুলির মধ্যে এক সময়ে ইন্টারপোলেশন রাষ্ট্রের গণনা করবে। এই প্রশ্নটি কি এক্সট্রাপোলেশন সম্পর্কে নয়, সর্বশেষ আপডেটের ফ্রেমের পরে কিছু সময়ের জন্য রাষ্ট্রকে গণনা করছে ? পরের আপডেটটি এখনও ক্যাপুলেট করা হয়নি।
মাইক সেমদার

আমি মনে করি যে তার যদি কেবল একটি থ্রেড আপডেট / রেন্ডারিং থাকে তবে কেবল রেন্ডারিং পজিশনে পুনরায় আপডেট করা এটি ঘটতে পারে না। আপনি কেবল জিপিইউতে অবস্থানগুলি প্রেরণ করুন এবং তারপরে পুনরায় আপডেট করুন।
জ্যাকারমার্জ

উত্তর:


22

আপনি পৃথক আপডেট (লজিক টিক) এবং অঙ্কন (টিক রেন্ডার) হারগুলি করতে চান।

আপনার আপডেটগুলি বিশ্বব্যাপী সমস্ত বস্তুর অবস্থান আঁকতে হবে।

আমি এখানে দুটি পৃথক সম্ভাবনা কভার করব, আপনি যেটি অনুরোধ করেছেন, তা এক্সট্রাপোলেশন এবং আরও একটি পদ্ধতি, অন্তরঙ্গকরণ।

1।

এক্সট্রোপোলেশন হল যেখানে আমরা পরের ফ্রেমে অবজেক্টের (পূর্বাভাসিত) অবস্থান গণনা করব এবং তারপরে বর্তমান বস্তুর অবস্থানের মধ্যে এবং বস্তুটি পরবর্তী ফ্রেমের অবস্থানের মধ্যে বিভক্ত করব।

এটি করতে, আঁকতে হবে প্রতিটি বস্তুর অবশ্যই একটি যুক্ত velocityএবং থাকতে হবে position। পরের ফ্রেমটিতে velocity * draw_timestepঅবজেক্টের অবস্থানের অবস্থানটি অনুসন্ধান করতে আমরা পরবর্তী ফ্রেমের পূর্বাভাসিত অবস্থানটি সন্ধান করতে কেবল অবজেক্টের বর্তমান অবস্থানটি যুক্ত করব। draw_timestepপূর্ববর্তী রেন্ডার টিক (ওরফে আগের ড্র কল) এর পরে যে সময় কেটে গেছে তা হ'ল।

আপনি যদি এটি এ ছেড়ে চলে যান, যখন তাদের ভবিষ্যদ্বাণী করা অবস্থানটি পরবর্তী ফ্রেমে প্রকৃত অবস্থানের সাথে মেলে না তখন আপনি সেই বস্তুগুলি "ঝাঁকুনি" খুঁজে পাবেন। ঝাঁকুনি অপসারণ করতে, আপনি পূর্বাভাসিত অবস্থানটি সংরক্ষণ করতে পারেন এবং পূর্ববর্তী পূর্বাভাসিত অবস্থান এবং প্রতিটি অঙ্কিত ধাপে নতুন পূর্বাভাসিত অবস্থানের মধ্যে লার্প করতে পারেন, পূর্ববর্তী আপডেটটিকে লার্প ফ্যাক্টর হিসাবে টিকিয়ে রাখার পর থেকে অতিবাহিত সময়টি ব্যবহার করে। এটি যখন দ্রুত চলমান বস্তুগুলি হঠাৎ করে অবস্থান পরিবর্তন করে, তখন এটি খারাপ আচরণে পরিণত হয় এবং আপনি সম্ভবত এই বিশেষ কেসটি পরিচালনা করতে চাইতে পারেন। এই অনুচ্ছেদে যা বলা হয়েছে তা হ'ল আপনি বহিঃপ্রকাশ ব্যবহার করতে চান না তার কারণ ।

2।

ইন্টারপোলেশন হল যেখানে আমরা শেষ দুটি আপডেটের স্থিতি সংরক্ষণ করি এবং সর্বশেষের আপডেটের পরে গত সময়ের যে পরিমাণ সময় পেরিয়ে গেছে তার উপর ভিত্তি করে তাদের মধ্যে বিভক্ত করা। এই সেটআপে, প্রতিটি বস্তুর অবশ্যই একটি সম্পর্কিত positionএবং থাকতে হবে previous_position। এই ক্ষেত্রে, আমাদের অঙ্কন বর্তমান গেমস্টেটের পিছনে সবচেয়ে খারাপ এক আপডেট টিকে উপস্থাপন করবে এবং সর্বোপরি বর্তমান আপডেটের টিকের মতো ঠিক একই স্থানে।


আমার মতে, আপনি সম্ভবত বর্ণনাকেন্দ্রটি চান যা আমি বর্ণনা করেছি, কারণ প্রয়োগ করা দু'জনের পক্ষে সহজতর এবং আপনার বর্তমান আপডেট হওয়া রাষ্ট্রের পিছনে একটি সেকেন্ডের (উদাহরণস্বরূপ 1/60 সেকেন্ড) একটি ক্ষুদ্র ভগ্নাংশ অঙ্কন করা ভাল।


সম্পাদনা:

উপরেরগুলি আপনাকে বাস্তবায়ন করার অনুমতি দেওয়ার পক্ষে পর্যাপ্ত পরিমাণে না হলে, আমি বর্ণিত অন্তরঙ্গ পদ্ধতিটি কীভাবে করব তার একটি উদাহরণ এখানে। আমি এক্সট্রাপোলেশনটি কভার করব না, কারণ এমন কোনও বাস্তব-জগতের পরিস্থিতি সম্পর্কে আমি ভাবতে পারি না যেখানে আপনাকে এটি পছন্দ করা উচিত।

আপনি যখন একটি অঙ্কনযোগ্য অবজেক্ট তৈরি করেন, এটি আঁকার জন্য প্রয়োজনীয় বৈশিষ্ট্যগুলি সংরক্ষণ করবে (অর্থাত, এটি আঁকার জন্য প্রয়োজনীয় রাষ্ট্রীয় তথ্য)।

এই উদাহরণস্বরূপ, আমরা অবস্থান এবং আবর্তন সংরক্ষণ করব। আপনি অন্যান্য বৈশিষ্ট্য যেমন রঙ বা টেক্সচার সমন্বয় অবস্থানের (যেমন যদি কোনও টেক্সচার স্ক্রোলগুলি) সঞ্চয় করতেও পারেন।

থ্রেড রেন্ডার করার সময় ডেটা সংশোধন করা থেকে রোধ করতে, (যেমন রেন্ডার থ্রেড আঁকানোর সময় একটি অবজেক্টের অবস্থান পরিবর্তন করা হয়েছে, তবে অন্য সমস্ত এখনও আপডেট হয়নি), আমাদের কিছু ধরণের ডাবল বাফারিং প্রয়োগ করতে হবে।

একটি বস্তু এটির দুটি অনুলিপি সঞ্চয় করে previous_state। আমি এগুলিকে একটি অ্যারে রাখব previous_state[0]এবং তাদের হিসাবে এবং হিসাবে উল্লেখ করব previous_state[1]। এটি একইভাবে এটির দুটি অনুলিপি প্রয়োজন current_state

ডাবল বাফারটির কোন অনুলিপি ব্যবহার করা হয় তার উপর নজর রাখতে আমরা একটি ভেরিয়েবল সঞ্চয় করি state_index, যা আপডেট এবং আঁকার উভয় ক্ষেত্রেই উপলভ্য।

আপডেট থ্রেড প্রথমে তার নিজস্ব ডেটা ব্যবহার করে কোনও বস্তুর সমস্ত বৈশিষ্ট্য গণনা করে (আপনি যে কোনও ডেটা স্ট্রাকচার চান)। তারপর, এটি কপি current_state[state_index]করার previous_state[state_index]কপি, এবং অঙ্কন, জন্য নতুন তথ্য প্রাসঙ্গিক positionএবং rotationমধ্যে current_state[state_index]। তারপরে এটি state_index = 1 - state_indexডাবল বাফারের বর্তমানে ব্যবহৃত অনুলিপিটি ফ্লিপ করতে।

উপরের অনুচ্ছেদে সমস্ত কিছুই লক আউট নিয়ে শেষ করতে হবে current_state। আপডেট এবং আঁকার থ্রেড উভয়ই এই লকটি নিয়ে যায়। লকটি কেবলমাত্র রাষ্ট্রীয় তথ্যের অনুলিপি করার সময়কালে নেওয়া হয়, যা দ্রুত।

রেন্ডার থ্রেডে আপনি এর পরে অবস্থান এবং আবর্তনের ক্ষেত্রে রৈখিক প্রবৃত্তি করেন:

current_position = Lerp(previous_state[state_index].position, current_state[state_index].position, elapsed/update_tick_length)

কোথায় elapsedযে থ্রেড রেন্ডার পাস হয়েছে, সর্বশেষ আপডেট টিক যেহেতু পরিমাণ, এবং update_tick_lengthযে আপনার নির্দিষ্ট আপডেট হার টিক প্রতি লাগে (যেমন 20FPS আপডেট এ সময় পরিমাণ update_tick_length = 0.05)।

Lerpউপরের ফাংশনটি কী তা আপনি যদি না জানেন , তবে উইকিপিডিয়া সম্পর্কিত প্রবন্ধটি চেকআউট করুন: লিনিয়ার ইন্টারপোলেশন । তবে, যদি আপনি জানেন না যে লার্পিং কী, তবে আপনি সম্ভবত ডিসপ্লেড আপডেট / ইন্টারপোল্টেড অঙ্কন সহ অঙ্কন কার্যকর করতে প্রস্তুত নন।


1
+1 টি একই ওরিয়েন্টেশন / ঘুর্ণন এবং অন্যান্য সব রাজ্যের জন্য অবশ্যই করতে হবে সময়ের পরিবর্তন, অর্থাত কণা সিস্টেম ইত্যাদি উপাদান অ্যানিমেশন মত
Maik Semder

1
ভাল কথা মাইক, আমি উদাহরণ হিসাবে শুধু অবস্থান ব্যবহার করেছি। যদি আপনি এক্সট্রাপোলেশন ব্যবহার করতে চান তবে আপনার যে কোনও সম্পত্তির এক্সট্রোপোলেট করতে চান তার "বেগ" সংরক্ষণ করতে হবে (অর্থাত্ সেই সম্পত্তির সময়ের পরিবর্তনের হার)। শেষ পর্যন্ত, আমি সত্যিই এমন পরিস্থিতির কথা ভাবতে পারি না যেখানে এক্সটার্পোলেশন অন্তরঙ্গকরণের চেয়ে ভাল, আমি কেবল এটি অন্তর্ভুক্ত করেছি কারণ প্রশ্নকারীর প্রশ্ন এটির অনুরোধ করেছিল। আমি বিরক্তি ব্যবহার করি। বিভক্তকরণের সাথে, আমাদের যে কোনও বৈশিষ্ট্যের বর্তমান এবং পূর্ববর্তী আপডেটের ফলাফলগুলি বিভক্ত করতে সঞ্চয় করতে হবে, যেমনটি আপনি বলেছেন।
ওলোভস্কি

এটি সমস্যার পুনরুদ্ধার এবং অন্তরঙ্গ এবং এক্সট্রাপোলেশন মধ্যে পার্থক্য; এটি কোনও উত্তর নয়।

1
আমার উদাহরণে আমি রাজ্যে অবস্থান এবং আবর্তন সংরক্ষণ করি। আপনি কেবল রাজ্যে বেগ (বা গতি) সঞ্চয় করতে পারেন। তারপরে আপনি ঠিক একই উপায়ে ( Lerp(previous_speed, current_speed, elapsed/update_tick_length)) গতির মাঝে লার্প করুন । আপনি রাজ্যে যে কোনও নম্বর সংরক্ষণ করতে চান তা দিয়ে এটি করতে পারেন। লিર્পিং আপনাকে একটি দুটি সংখ্যার মধ্যে একটি মান দেয়, একটি লিপ ফ্যাক্টর দেওয়া হয়।
ওলহোভস্কি

1
কৌণিক চলাফেরার বিচ্ছুরণের জন্য এটি লার্পের পরিবর্তে স্লিপ ব্যবহার করার পরামর্শ দেওয়া হয় । উভয় রাজ্যের চৌকোণগুলি সংরক্ষণ করা এবং তাদের মধ্যে স্লিপ করা সহজ হবে। অন্যথায় একই নিয়ম কৌণিক বেগ এবং কৌণিক ত্বরণের জন্য প্রযোজ্য। কঙ্কাল অ্যানিমেশনের জন্য আপনার কাছে একটি পরীক্ষা-মামলা রয়েছে?
মাইক সেমদার

-2

এই সমস্যাটির জন্য আপনার শুরু সম্পর্কে আপনার সংজ্ঞাগুলি সম্পর্কে চিন্তা করা এবং কিছুটা আলাদাভাবে শেষ করা দরকার। প্রারম্ভিক প্রোগ্রামাররা প্রায়শই ফ্রেম প্রতি অবস্থানের পরিবর্তনের কথা ভাবেন এবং এটি শুরুতে যাওয়ার একটি দুর্দান্ত উপায়। আমার প্রতিক্রিয়ার স্বার্থে, আসুন একটি মাত্রিক উত্তর বিবেচনা করুন।

ধরা যাক এক্স পজিশনে আপনার একটি বানর রয়েছে। এখন আপনার কাছে একটি "অ্যাডএক্স" রয়েছে যা আপনি কীবোর্ড বা অন্য কোনও নিয়ন্ত্রণের উপর ভিত্তি করে ফ্রেমের প্রতি বানরের অবস্থানে যুক্ত হন। আপনার গ্যারান্টিযুক্ত ফ্রেমের হার যতক্ষণ থাকবে এটি কাজ করবে। ধরা যাক যে আপনার এক্সটি 100 এবং আপনার অ্যাডএক্স 10 টি 10 ​​ফ্রেমের পরে, আপনার x + = অ্যাডএক্স 200 এ জমা হওয়া উচিত।

এখন, অ্যাডএক্সের পরিবর্তে, যখন আপনার ভেরিয়েবল ফ্রেম রেট থাকে, আপনার বেগ এবং ত্বরণের দিক দিয়ে চিন্তা করা উচিত। আমি আপনাকে এই পাটিগণিতের সমস্ত মধ্য দিয়ে চলব তবে এটি অত্যন্ত সাধারণ। আমরা যা জানতে চাই তা হ'ল আপনি প্রতি মিলিসেকেন্ডে কত দূর ভ্রমণ করতে চান (এক সেকেন্ডের 1/1000 তম)

আপনি যদি 30 এফপিএসের জন্য শুটিং করছেন, তবে আপনার ভেলএক্সটি এক সেকেন্ডের 1 / তৃতীয় হওয়া উচিত (30 এফপিএসের শেষ উদাহরণ থেকে 10 ফ্রেম) এবং আপনি জানেন যে আপনি সেই সময় 100 'এক্স' ভ্রমণ করতে চান সুতরাং আপনার ভেলেক্সটি সেট করুন 100 দূরত্ব / 10 এফপিএস বা ফ্রেম প্রতি 10 দূরত্ব। মিলি সেকেন্ডে, এটি প্রতি 3.3 মিলি সেকেন্ডে প্রতি 1 দূরত্ব x বা মিলসেকেন্ডে 0.3 'x' পর্যন্ত কাজ করে।

এখন, যতবার আপনি আপডেট করবেন, আপনার যা করতে হবে তা হল সময় অতিবাহিত হওয়া। ৩৩ এমএস পাস হয়েছে (এক সেকেন্ডের 1/30 তম) বা যাই হোক না কেন, আপনি কেবল দূরত্ব 0.3 কে মিলিসেকেন্ডের সংখ্যায় গুণ করে। এর অর্থ হল আপনার এমন একটি টাইমার দরকার যা আপনাকে এমএস (মিলিসেকেন্ড) নির্ভুলতা দেয় তবে বেশিরভাগ টাইমার আপনাকে এটি দেয়। এই জাতীয় কিছু করুন:

var startTime = getTimeInMillisecond ()

... পরে ...

বিভিন্ন সময় = getTimeInMillisecond ()

var elapsedTime = সময়-সূচনাকালীন

শুরুর সময় = সময়

... এখন আপনার সমস্ত দূরত্ব গণনা করতে এই অতিবাহিত সময় ব্যবহার করুন।


1
তার কোনও পরিবর্তনশীল আপডেটের হার নেই। তার একটি নির্দিষ্ট আপডেটের হার রয়েছে। সত্যি কথা বলতে কী, আপনি এখানে কী বিন্দুটি তৈরি করতে চাইছেন তা আমি সত্যিই জানি না: /
ওলহোভস্কি

1
??? -1। এটিই সম্পূর্ণ পয়েন্ট, আমার একটি গ্যারান্টিযুক্ত আপডেট রেট রয়েছে তবে একটি পরিবর্তনশীল রেন্ডার রেট রয়েছে এবং আমি চাই যে এটি কোনও স্টাটারিংয়ের সাথে মসৃণ হোক।
অ্যাটাকিংহোব

পরিবর্তনশীল আপডেটের হার নেটওয়র্ক গেমস, প্রতিযোগিতামূলক গেমস, রিপ্লে সিস্টেম বা অন্য যে কোনও কিছু গেম-প্লেতে ডিস্ট্রিমেন্টিক হওয়ার উপর নির্ভর করে with
আক্রমণ

1
স্থির আপডেট ছদ্ম-ঘর্ষণ সহজে সংহত করার অনুমতি দেয়। উদাহরণস্বরূপ, আপনি যদি প্রতিটি গতি আপনার ফ্রেমকে ০.৯ দিয়ে গতিতে চান, আপনি যদি দ্রুত বা ধীর ফ্রেমটি দিয়ে কতগুলি গুণতে চান তা কীভাবে নির্ধারণ করবেন? ফিক্সড আপডেটটি মাঝে মাঝে ব্যাপকভাবে পছন্দ করা হয় - কার্যত সমস্ত পদার্থবিজ্ঞানের সিমুলেশনগুলি একটি নির্দিষ্ট আপডেটের হার ব্যবহার করে।
ওলহোভস্কি

2
যদি আমি একটি পরিবর্তনশীল ফ্রেম রেট ব্যবহার করি এবং প্রচুর বস্তু একে অপরের সাথে ঝাঁপিয়ে পড়ে একটি জটিল প্রাথমিক অবস্থা সেট আপ করি তবে কোনও গ্যারান্টি নেই যে এটি ঠিক একইরকম অনুকরণ করবে। প্রকৃতপক্ষে এটি প্রতিবার সিমুলেশন রানের মধ্যবর্তী সময়ে সম্পূর্ণ পৃথক রাজ্যে সংক্ষিপ্ত সময়ের সাথে সংক্ষিপ্ত আকারের ছোট ছোট পার্থক্যের সাথে প্রতিবার কিছুটা আলাদাভাবে অনুকরণ করবে।
অ্যাটাকিংহোব
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.