গেম স্টেট 'স্ট্যাক'?


52

আমি কীভাবে আমার গেমগুলিতে গেমের রাজ্যগুলি বাস্তবায়িত করব তা নিয়ে ভাবছিলাম। আমি এটির জন্য প্রধান জিনিসগুলি হ'ল:

  • আধা-স্বচ্ছ শীর্ষস্থানীয় রাষ্ট্রগুলি - গেমটির পিছনে বিরতি মেনুর মাধ্যমে দেখতে সক্ষম হচ্ছে

  • ওও-আমি কিছু পিছনে তত্ত্বটি ব্যবহার করা এবং বুঝতে এটি আরও সহজ মনে করি পাশাপাশি অরগানাইজড রাখা এবং আরও যুক্ত করে।



আমি একটি লিঙ্কযুক্ত তালিকা ব্যবহার করার পরিকল্পনা করছিলাম এবং এটিকে স্ট্যাক হিসাবে গণ্য করব। এর অর্থ আমি আধা স্বচ্ছতার জন্য নীচে রাজ্যে অ্যাক্সেস করতে পারি।
পরিকল্পনা: রাজ্য স্ট্যাকটিকে আইগেমস্টেস্টের পয়েন্টারের লিঙ্কযুক্ত তালিকাগুলি হিসাবে রাখুন। শীর্ষস্থানীয় রাষ্ট্রটি তার নিজস্ব আপডেট এবং ইনপুট কমান্ডগুলি পরিচালনা করে এবং তারপরে রাজ্যটির নীচে আঁকতে হবে কিনা তা সিদ্ধান্ত নিতে স্বতন্ত্র সদস্য রয়েছে a
তখন আমি করতে পারি:

states.push_back(new MainMenuState());
states.push_back(new OptionsMenuState());
states.pop_front();

প্লেয়ার লোড উপস্থাপন করতে, তারপরে বিকল্পগুলিতে এবং তারপরে প্রধান মেনুতে।
এটি কি একটি ভাল ধারণা, বা ...? আমি কি অন্য কিছু তাকান?

ধন্যবাদ।


আপনি কি বিকল্পমেনুস্টেটের পিছনে মেইনমেনস্টেট দেখতে চান? বা অপশনমেনুস্টেটের পিছনে কেবল গেমের পর্দা?
স্কিজ

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

আমি জানি যে এটি দেরিতে হয়ে গেছে, তবে ভবিষ্যতের পাঠকদের কাছে: newনমুনা কোডে দেখানো উপায়ে ব্যবহার করবেন না , এটি কেবল মেমরি ফাঁস বা অন্যান্য, আরও গুরুতর ত্রুটিগুলির জন্য জিজ্ঞাসা করছে।
ফারাপ

উত্তর:


44

আমি কোডরঞ্জার হিসাবে একই ইঞ্জিনে কাজ করেছি। আমার ভিন্ন দৃষ্টিভঙ্গি রয়েছে। :)

প্রথমত, আমাদের কাছে এফএসএমের স্ট্যাক ছিল না - আমাদের স্ট্যাক স্টেট ছিল। একটি স্ট্যাক রাজ্য একটি একক এফএসএম করে। আমি জানি না এফএসএমগুলির একটি স্ট্যাক কেমন লাগবে। ব্যবহারিক কিছু করার জন্য সম্ভবত খুব জটিল।

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

দুটি উদাহরণ হিসাবে এটি কুৎসিত হয়েছে:

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

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

যেটি ভাল ছিল তা অবকাঠামোগত প্রোগ্রামারদের কোড সংহত করার জন্য কাজগুলি বিচ্ছিন্ন করা যা গেমের প্রবাহটি আসলে কীভাবে কাঠামোবদ্ধ ছিল তা জানত না, তাই আপনি প্যাচার লেখককে "ক্লায়েন্ট_প্যাচ_উপডেটে আপনার কোডটি রেখেছিলেন" এবং গ্রাফিক লেখার লোকটিকে বলতে পারেন "আপনার কোডটি ক্লায়েন্ট_ম্যাপট্যান্সফার_অননেটারে রাখুন" লোড করা হচ্ছে এবং আমরা কোনও সমস্যা ছাড়াই কিছু নির্দিষ্ট যুক্তির প্রবাহকে অদলবদল করতে পারি।

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

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


দুর্দান্ত উত্তর, ধন্যবাদ! আমি মনে করি আপনার পোস্ট এবং আপনার অতীতের অভিজ্ঞতা থেকে আমি অনেক কিছু নিতে পারি। : ডি + 1 / টিক
কমিউনিস্ট হাঁস

শ্রেণিবিন্যাস সম্পর্কে দুর্দান্ত জিনিস হ'ল আপনি ইউটিলিটি স্টেটগুলি তৈরি করতে পারবেন যা কেবল শীর্ষে ঠেলে দেওয়া হয়েছে এবং অন্য কী চলছে তা নিয়ে চিন্তা করার দরকার নেই।
কোডরেঞ্জার

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

UIs আসলে যে পয়েন্টটি ডিএজি হ'ল তা সঠিকভাবে গ্রহণ করা হয়েছে তবে আমি এটির সাথে একমত নই যে এটি অবশ্যই একটি স্ট্যাকের মধ্যে উপস্থাপিত হতে পারে। যে কোনও সংযুক্ত নির্দেশিত অ্যাসাইক্লিক গ্রাফ (এবং আমি এটির ক্ষেত্রে কোনও সংযুক্ত ডিএজি হবে না এমন কোনও ক্ষেত্রে ভাবতে পারি না) গাছ হিসাবে প্রদর্শিত হতে পারে এবং স্ট্যাক মূলত একটি গাছ।
এড রপ্পল

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

11

এখানে গেমস্টেট স্ট্যাকের একটি উদাহরণ বাস্তবায়ন যা আমি খুব দরকারী বলে মনে করেছি: http://creators.xna.com/en-US/sams/gamestatemanagement

এটি সি # তে লিখিত এবং এটি সংকলন করতে আপনার এক্সএনএ কাঠামো প্রয়োজন, তবে আপনি ধারণা পেতে কোড, ডকুমেন্টেশন এবং ভিডিওটি কেবল পরীক্ষা করে দেখতে পারেন।

এটি রাষ্ট্রের স্থানান্তর, স্বচ্ছ রাষ্ট্রগুলি (যেমন মডেল বার্তাগুলি বাক্স) এবং লোডিং রাজ্যগুলিকে সমর্থন করে (যা বিদ্যমান রাজ্যগুলির আনলোডিং এবং পরবর্তী রাষ্ট্রের লোডিং পরিচালনা করে)।

আমি এখন আমার (নন-সি #) শখ প্রকল্পগুলিতে একই ধারণাগুলি ব্যবহার করি (মঞ্জুর করা হয় এটি বৃহত্তর প্রকল্পগুলির জন্য উপযুক্ত নাও হতে পারে) এবং ছোট / শখের প্রকল্পগুলির জন্য আমি অবশ্যই পদ্ধতির প্রস্তাব দিতে পারি can


5

এটি আমরা যা ব্যবহার করি তার অনুরূপ, এফএসএমগুলির একটি স্ট্যাক। মূলত প্রতিটি রাজ্যকে একটি প্রবেশ, প্রস্থান এবং টিক ফাংশন দিন এবং ক্রম হিসাবে তাদের কল করুন। লোড করার মতো জিনিসগুলি পরিচালনা করার জন্য খুব সুন্দরভাবে কাজ করে।


3

"গেম প্রোগ্রামিং রত্ন" ভলিউমগুলির মধ্যে একটিতে গেমের রাজ্যগুলির উদ্দেশ্যে এটিতে একটি রাষ্ট্রীয় মেশিন বাস্তবায়ন ছিল; http://emersnt.net/Global/Documents/textbook/Chapter1_GameAppFramework.pdf এ কীভাবে এটি একটি ছোট গেমের জন্য ব্যবহার করতে হয় তার একটি উদাহরণ রয়েছে এবং এটি পড়ার জন্য খুব গেমব্রায়ো-নির্দিষ্ট হওয়া উচিত নয়।


"ডাইরেক্টএক্স সহ প্রোগ্রামিং রোল প্লে গেমস" এর প্রথম বিভাগটি একটি রাষ্ট্র ব্যবস্থা (এবং একটি প্রক্রিয়া সিস্টেম - খুব আকর্ষণীয় পার্থক্য) প্রয়োগ করে।
রিকিট

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

3

আলোচনায় কেবল সামান্য মানক যোগ করার জন্য, এই জাতীয় ডেটা স্ট্রাকচারের জন্য ক্লাসিক সিএস শব্দটি একটি পুশডাউন অটোমেটন


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

1
"আমি নিশ্চিত নই যে রাষ্ট্রীয় স্ট্যাকগুলির কোনও বাস্তব-বিশ্বের বাস্তবায়ন একটি পুডডাউন অটোমেটনের সমান equivalent" পার্থক্য কি? উভয়েরই একটি সীমাবদ্ধ রাজ্যগুলির একটি সেট রয়েছে, রাজ্যের একটি ইতিহাস এবং ধাক্কা দেওয়ার জন্য এবং পপ রাষ্ট্রগুলিতে আদিম ক্রিয়াকলাপ। আপনি যে অপারেশনগুলি উল্লেখ করেছেন তার কোনওটিই তহবিলের থেকে পৃথক নয়। "পপ টু স্টেটস" কেবল দু'বার পপিং করছে। "অদলবদল" একটি পপ এবং একটি পুশ। পাসিং ডেটা মূল ধারণার বাইরে, তবে "এফএসএম" ব্যবহার করে এমন প্রতিটি গেম নামের মতো অনুভূতি ছাড়াই অতিরিক্ত ডেটা প্রয়োগ করে।
munificent

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

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

1
গুড পয়েন্ট, স্থির!
উপুড়হস্ত

1

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

আমি যখন রাজ্যটি বের হয় তখন আমি কেবল তার অনুসরণ করতে রাজ্যটিকে নির্দিষ্ট করব।

যে পরিস্থিতি আপনি বর্তমান অবস্থার আগের রাজ্যে ফিরে আসতে চান, উদাহরণস্বরূপ "প্রধান মেনু-> বিকল্পগুলি-> প্রধান মেনু" এবং "বিরতি-> বিকল্পগুলি-> বিরতি", কেবলমাত্র স্টার্টআপ পরামিতি হিসাবে রাজ্যে প্রবেশ করুন ফিরে যেতে রাষ্ট্র।


আমি হয়ত প্রশ্নটা ভুল বুঝি?
Skizz

না আপনি করেননি. আমি মনে করি ডাউন ভোটাররা তা করেছে।
কমিউনিস্ট হাঁস

স্ট্যাক ব্যবহার করা সুস্পষ্ট রাষ্ট্রীয় রূপান্তরগুলির ব্যবহারকে বিরত রাখে না।
ড্যাশ-টম-ব্যাং

1

ট্রানজিশন এবং এই জাতীয় অন্যান্য জিনিসগুলির জন্য আরেকটি সমাধান হ'ল গন্তব্য এবং উত্সের রাজ্য সরবরাহ করা, রাষ্ট্রীয় মেশিনের সাথে, যা "ইঞ্জিন" এর সাথে সংযুক্ত হতে পারে, যাই হোক না কেন। সত্যটি হ'ল বেশিরভাগ রাষ্ট্রীয় মেশিনগুলি সম্ভবত হাতে প্রকল্পের জন্য উপযুক্ত হতে হবে। একটি সমাধান এই বা সেই খেলায় উপকৃত হতে পারে, অন্যান্য সমাধানগুলি এতে বাধা দিতে পারে।

class StateMachine
{
public:
    StateMachine(Engine *);
    void Push(State *);
    State *Pop();
    void Update();
    Engine *GetEngine();

private:
    std::stack<State *> _states;
    Engine *_engine;
};

রাজ্যগুলি বর্তমান অবস্থা এবং মেশিনকে পরামিতি হিসাবে ঠেলে দেওয়া হয়।

void StateMachine::Push(State *state)
{
    State *from = 0;
    if (!_states.empty()) from = _states.top();
    _states.push(state);
    state->Enter(this, from);
}

রাজ্যগুলি একই ফ্যাশনে পপড। আপনি নীচে কল Enter()করুন কিনা Stateতা বাস্তবায়ন প্রশ্ন।

State *StateMachine::Pop()
{
    _ASSERT(!_states.empty());
    State *state = _states.top();
    State *to = 0;
    _states.pop();
    if (!_states.empty()) to = _states.top();
    state->Exit(this, to);
    return state;
}

প্রবেশ করার সময়, আপডেট করার সময় বা প্রস্থান করার সময়, Stateএটি প্রয়োজনীয় সমস্ত তথ্য পেয়ে যায়।

void SomeGameState::Enter(StateMachine *sm, State *from)
{
    Engine *eng = sm->GetEngine();
    eng->GetKeyboard()->KeyDown.Bind(this, &SomeGameState::KeyDown);
    LoadLevelState *state = new LoadLevelState();
    state->SetLevel(eng->GetSaveGame()->GetLevelName());
    state->Load.Bind(this, &SomeGameState::OnLevelLoaded);
    sm->Push(state);
}

void SomeGameState::Update(StateMachine *sm)
{
    Engine *eng = sm->GetEngine();
    float time = eng->GetFrameTime();
    if (shouldExit)
        sm->Pop();
}

void SomeGameState::Exit(StateMachine *sm, State *from)
{
    Engine *eng = sm->GetEngine();
    eng->GetKeyboard()->KeyDown.UnsubscribeAll(this);
}

0

আমি বেশ কয়েকটি গেম জুড়ে একটি খুব অনুরূপ সিস্টেম ব্যবহার করেছি এবং দেখেছি যে বেশ কয়েকটি ব্যতিক্রম ব্যতীত এটি একটি দুর্দান্ত ইউআই মডেল হিসাবে কাজ করে।

কেবলমাত্র আমরা যে সমস্যার মুখোমুখি হয়েছি সেগুলি হ'ল নতুন রাজ্যকে ধাক্কা দেওয়ার আগে একাধিক রাজ্যের পপ ফিরিয়ে আনার ক্ষেত্রে কিছু ক্ষেত্রে এটির ইচ্ছা ছিল (আমরা সাধারণত ইউআইআই-র প্রতীক হিসাবে প্রয়োজনীয়তা সরিয়ে দিতে ইউআই পুনরায় প্রবাহিত করেছি) এবং উইজার্ড-স্টাইল তৈরি করি রৈখিক প্রবাহ (পরবর্তী অবস্থার সাথে ডেটা পাস করার মাধ্যমে সহজেই সমাধান করা হয়)।

আমরা ব্যবহৃত বাস্তবায়নটি স্ট্যাকটি মোড়ানো এবং আপডেট এবং রেন্ডারিংয়ের পাশাপাশি স্ট্যাকের ক্রিয়াকলাপের জন্য যুক্তি পরিচালনা করে। স্ট্যাকের প্রতিটি ক্রিয়াকলাপ রাজ্যগুলিতে ঘটনার সূত্রপাত ঘটায় এবং তাদের অপারেশন সম্পর্কে অবহিত করা হবে।

কিছু সাধারণ কাজ যেমন সরলকরণের জন্য অদলবদল (লিনিয়ার প্রবাহের জন্য পপ এবং পুশ) এবং রিসেট (মূল মেনুতে ফিরে যাওয়ার জন্য বা কোনও প্রবাহ শেষ করার জন্য) হিসাবে কিছু সহায়ক ফাংশন যুক্ত করা হয়েছিল।


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

0

আমি আমার প্রায় সমস্ত প্রকল্পের জন্য এটি গ্রহণ করি, কারণ এটি অবিশ্বাস্যভাবে ভাল কাজ করে এবং অত্যন্ত সহজ।

আমার অতি সাম্প্রতিক প্রকল্প, শার্পলক , নিয়ন্ত্রণ প্রবাহকে এই সঠিকভাবে পরিচালনা করে। আমাদের রাজ্যগুলি ইভেন্ট ক্রিয়াকলাপগুলির একটি সেট দিয়ে সমস্ত সংযুক্ত থাকে যা রাজ্যগুলি পরিবর্তনের সময় ডাকা হয় এবং এটিতে একটি "নামযুক্ত স্ট্যাক" ধারণার বৈশিষ্ট্য রয়েছে যাতে আপনি একই রাজ্যের মেশিনে এবং শাখার মধ্যে একাধিক স্ট্যাকের রাজ্য থাকতে পারেন - একটি ধারণাগত সরঞ্জাম, এবং প্রয়োজনীয় নয়, তবে ব্যবহার করা সহজ।

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


0

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

ডিএজি দ্বারা উপস্থাপিত ইন-গেম মেনুটি "আরও ভাল" হতে পারে তবে একটি অন্তর্নিহিত রাষ্ট্রীয় মেশিনের সাথে (অন্য মেনু অপশনে যা অন্য স্ক্রিনে যায় সেখানে কীভাবে যেতে হয় তা জানে এবং পিছনের বোতামটি টিপলে সর্বদা শীর্ষস্থানটি পপ করে) প্রভাবটি ছিল ঠিক একই.

এই অন্যান্য সিস্টেমগুলির মধ্যে কিছুতে "শীর্ষস্থানীয় স্থিতি প্রতিস্থাপন" কার্যকারিতা ছিল, তবে এটি সাধারণত StatePop()অনুসরণ হিসাবে প্রয়োগ করা হয়েছিল StatePush(x);

মেমোরি কার্ড হ্যান্ডলিংটি একই রকম ছিল যেহেতু আমি আসলে অপারেশন কাতারে একটি টন "অপারেশন" ধাক্কা দিয়েছি (যা কার্যত স্ট্যাকের মতো একই কাজ করেছিল, যেমন LIFO এর চেয়ে FIFO এর মতো); আপনি একবার এই ধরণের কাঠামো ব্যবহার শুরু করলে ("এখন একটি জিনিস ঘটছে, এবং এটি হয়ে গেলে এটি নিজেই পপ হয়") এটি কোডের প্রতিটি ক্ষেত্রকে সংক্রামিত করতে শুরু করে। এমনকি এআইও এরকম কিছু ব্যবহার শুরু করেছে; এআই "ক্লুলেস" তখন প্লেয়ারকে গোলমাল করলেও দেখা যায়নি, তখন "সাবধানে" রূপান্তরিত হয় এবং শেষ পর্যন্ত তারা যখন খেলোয়াড়কে দেখেন তখন "অ্যাক্টিভ" উন্নীত হয় (এবং সেই সময়ের কম গেমগুলির বিপরীতে, আপনি লুকিয়ে রাখতে পারবেন না) পিচবোর্ডের বাক্সে এবং শত্রুকে আপনার সম্পর্কে ভুলে যেতে! এটি আমি তিক্ত নয় ...))

GameState.h:

enum GameState
{
   k_frontend,
   k_gameplay,
   k_inGameMenu,
   k_moviePlayback,
   k_numStates
};

void GameStatePush(GameState);
void GameStatePop();
void GameStateUpdate();

GameState.cpp:

// k_maxNumStates could be bigger, but we don't need more than
// one of each state on the stack.
static const int k_maxNumStates = k_numStates;
static GameState s_states[k_maxNumStates] = { k_frontEnd };
static int s_numStates = 1;

static void (*s_startupFunctions)()[] =
   { FrontEndStart, GameplayStart, InGameMenuStart, MovieStart };
static void (*s_shutdownFunctions)()[] =
   { FrontEndStop, GameplayStop, InGameMenuStop, MovieStop };
static void (*s_updateFunctions)()[] =
   { FrontEndUpdate, GameplayUpdate, InGameMenuUpdate, MovieUpdate };

static void GameStateStart(GameState);
static void GameStateStop(GameState);

void GameStatePush(GameState gs)
{
   Assert(s_numStates < k_maxNumStates);
   GameStateStop(s_states[s_numStates - 1])
   s_states[s_numStates] = gs;
   s_numStates++;
   GameStateStart(gs);
}

void GameStatePop()
{
   Assert(s_numStates > 1);  // can't pop last state
   s_numStates--;
   GameStateStop(s_states[s_numStates]);
   GameStateStart(s_states[s_numStates - 1]);
}

void GameStateUpdate()
{
   GameState current = s_states[s_numStates - 1];
   s_updateFunctions[current]();
}

void GameStateStart(GameState gs)
{
   s_startupFunctions[gs]();
}

void GameStateStop(GameState gs)
{
   s_shutdownFunctions[gs]();
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.