কীভাবে আমি সাফল্যগুলি পরিচালনা করার জন্য নমনীয় কাঠামো সেট আপ করতে পারি?


54

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

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

উত্তর:


39

আমি মনে করি এক ধরণের দৃ solution় সমাধান হ'ল অবজেক্ট ওরিয়েন্টেড পথে যাওয়া।

আপনি কোন ধরণের অর্জনকে সমর্থন করতে চান তার উপর নির্ভর করে আপনার গেমের বর্তমান অবস্থা এবং / অথবা গেমের অবজেক্টগুলি (প্লেয়ারের মতো) যে ক্রিয়াকলাপ / ইভেন্টগুলির ইতিহাস তৈরি করেছে সে সম্পর্কে আপনার জিজ্ঞাসা করার একটি উপায় প্রয়োজন।

ধরা যাক আপনার একটি বেস অ্যাচিভমেন্ট ক্লাস রয়েছে যেমন:

class AbstractAchievement
{
    GameState& gameState;
    virtual bool IsEarned() = 0;
    virtual string GetName() = 0;
};

AbstractAchievementগেমের অবস্থা সম্পর্কে একটি উল্লেখ রয়েছে। এটি ঘটছে এমন জিনিসগুলি জিজ্ঞাসা করার জন্য ব্যবহৃত হয়।

তারপরে আপনি কংক্রিট বাস্তবায়ন করুন। আসুন আপনার উদাহরণগুলি ব্যবহার করুন:

class MasterSlicerAchievement : public AbstractAchievement
{
    string GetName() { return "Master Slicer"; }
    bool IsEarned()
    {
        Action lastAction = gameState.GetPlayerActionHistory().GetAction(0);
        Action previousAction = gameState.GetPlayerActionHistory().GetAction(1);
        if (lastAction.GetType() == ActionType::Slice &&
            previousAction.GetType() == ActionType::Slice &&
            lastAction.GetObjectType() == ObjectType::Watermelon &&
            previousAction.GetObjectType() == ObjectType::Strawberry)
            return true;
        return false;
    }
};
class InvinciblePipeRiderAchievement : public AbstractAchievement
{
    string GetName() { return "Invincible Pipe Rider"; }
    bool IsEarned()
    {
        if (gameState.GetLocationType(gameState.GetPlayerPosition()) == LocationType::OVER_PIPE &&
            gameState.GetPlayerState() == EntityState::INVINCIBLE)
            return true;
        return false;
    }
};

তারপরে IsEarned()পদ্ধতিটি ব্যবহার করে কখন চেক করবেন তা সিদ্ধান্ত নেওয়া আপনার পক্ষে । আপনি প্রতিটি গেম আপডেটে পরীক্ষা করতে পারেন।

আরও কার্যকর উপায় হ'ল উদাহরণস্বরূপ, কোনও ধরণের ইভেন্ট ম্যানেজার থাকা। এবং তারপর (যেমন ঘটনা রেজিস্টার করো PlayerHasSlicedSomethingEventঅথবা PlayerGotInvicibleEventঅথবা শুধুমাত্র PlayerStateChangedএকটি পদ্ধতি যে প্যারামিটারে কৃতিত্ব নিতে হবে)। উদাহরণ:

class Game
{
    void Initialize()
    {
        eventManager.RegisterAchievementCheckByActionType(ActionType::Slice, masterSlicerAchievement);
        // Each time an action of type Slice happens,
        // the CheckAchievement() method is invoked with masterSlicerAchievement as parameter.
        eventManager.RegisterAchievementCheckByPlayerState(EntityState::INVINCIBLE, invinciblePiperAchievement);
        // Each time the player gets the INVINCIBLE state,
        // the CheckAchievement() method is invoked with invinciblePipeRiderAchievement as parameter.
    }
    void CheckAchievement(const AbstractAchievement& achievement)
    {
        if (!HasAchievement(player, achievement) && achievement.IsEarned())
        {
            AddAchievement(player, achievement);
        }
    }
};

13
শৈলী nitpick: if(...) return true; else return false;হিসাবে একইreturn (...)
ড্যানি Pflughoeft - BlueRaja

2
এটি একটি কৃতিত্ব সিস্টেম বাস্তবায়নের জন্য খুব ভাল টেম্পলেট। তদুপরি, এটি এখনও এই ধারণাটি দেখায় যে আপনার গেম-স্টেটগুলি ট্র্যাক করার একটি উপায় থাকতে হবে। আমি সম্ভবত এটি সবচেয়ে জটিল ধারণা খুঁজে পাই।
ব্রায়ান হ্যারিংটন

@ এসপিও আপনি একজন মাস্টার ম্যান ...! : ডি সহজ এবং মার্জিত সমাধান। Congrat।
দিয়েগো পালোমার

+1 আমি মনে করি কোনও সমস্যা নির্গমন / সংগ্রহ সিস্টেম হ'ল এই সমস্যাটি পরিচালনা করার দুর্দান্ত উপায়।
ashes999

14

ভাল, সংক্ষেপে, একটি নির্দিষ্ট শর্ত পূরণ হলে কৃতিত্বগুলি আনলক করা হয়। সুতরাং আপনার যে শর্তটি চান তা যাচাই করার জন্য যদি বিবৃতিগুলি উত্সাহিত করতে সক্ষম হয়।

উদাহরণস্বরূপ, আপনি যদি জানতে চান যে একটি স্তর সমাপ্ত হয়েছে বা বসকে পরাজিত করা হয়েছে, এই ঘটনাগুলি ঘটলে আপনার বুলিয়ান পতাকা সত্য হওয়া উচিত।

তারপর:

if(GlobalFlags.MasterBossDefeated == true && AchievementClass.MasterBossDefeatedAchievement == false)
{
    AchievementClass.MasterBossDefeatedAchievement = true;
    showModalPopUp("You defeated the Master Boss!  30 gamerscore");
}

আপনি যে শর্তটি চান তার সাথে মেলে তুলতে আপনি এটিকে জটিল বা সরলতর করতে পারেন।

এক্সবক্স 360 সাফল্যের কিছু তথ্য এখানে পাওয়া যাবে


2
+1 দুর্দান্ত নিবন্ধ এবং মূলত আমি কী প্রস্তাব দিচ্ছি। যদিও আমি মোডালটিকে তার পাঠ্যটি অর্জন থেকে নিজেই পেয়ে যাব ... আপনি যদি কিছু পরিবর্তন করতে চান তবে কেবল পাঠ্য শিকার এড়ানোর জন্য।
জেসি ডর্সি

@ নোট্রাইন - ভুলে যাবেন না যে এখানে পোস্ট করা কোনও কোড সিউডো কোড হিসাবে বিবেচনা করা উচিত - প্রায়শই পয়েন্টটি পেতে সরলিকৃত কোড ব্যবহার করা প্রয়োজন।
ক্রিসএফ

1
এক্সবক্স 360 সাফল্যের লিঙ্কটি মারা গেছে।
ঝুলন্ত


8

আপনি যদি প্রতিটি ক্রিয়া খেলোয়াড় পোস্টে একটি বার্তা গ্রহণ করেন AchievementManager? তারপরে ব্যবস্থাপক নির্দিষ্ট শর্ত পূরণ করেছেন কিনা তা অভ্যন্তরীণভাবে পরীক্ষা করতে পারেন। প্রথম বার্তা পোস্ট বার্তা:

AchievementManager::PostMessage("Jump", "162");

AchievementManager::PostMessage("Slice", "Strawberry");
AchievementManager::PostMessage("Slice", "Watermelon");

AchievementManager::PostMessage("Kill", "Goomba");

এবং তারপরে AchievementManagerকিছু করার দরকার আছে কিনা তা যাচাই করে নিন:

if (!strcmp(m_Message.name, "Slice") && !strcmp(m_LastMessage.name, "Slice"))
{
    if (!strcmp(m_Message.value, "Watermelon") && !strcmp(m_LastMessage.value, "Strawberry"))
    {
        // achievement unlocked!
    }
}

আপনি সম্ভবত স্ট্রিংগুলির পরিবর্তে গণনা দিয়ে এটি করতে চাইবেন। ;)


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

2
এটা কি পারে? গেমটিতে যা ঘটেছিল তা ট্র্যাক করার কোনও উপায় না থাকলে আপনি বাইরের স্ক্রিপ্টে শর্ত রাখতে পারেন।
নাইট 666

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

4

আমি ব্যবহার করা সর্বশেষ নকশাটি প্রতি ব্যবহারকারীর ধ্রুবক কাউন্টারগুলির একটি সেট থাকার আশেপাশে তৈরি হয়েছিল এবং তারপরে একটি নির্দিষ্ট মানকে আঘাত করা একটি নির্দিষ্ট কাউন্টার থেকে অর্জনের কী রয়েছে key বেশিরভাগটি একক অর্জন / কাউন্টার জুটি ছিল যেখানে কাউন্টারটি কেবল সর্বদা 0 বা 1 হবে (এবং অর্জনটি> = 1 তে ট্রিগার হয়েছিল) তবে আপনি এটি "মেরে যাওয়া এক্স ডিউডস" বা "পাওয়া এক্স বুকে" জন্যও ব্যবহার করতে পারেন can এর অর্থ হ'ল আপনি এমন কোনও কিছুর জন্য কাউন্টার সেটআপ করতে পারেন যার কোনও সাফল্য নেই এবং এটি ভবিষ্যতে ব্যবহারের জন্য ট্র্যাক করা হবে।


3

আমি যখন আমার শেষ খেলায় সাফল্য বাস্তবায়ন করেছি, তখন আমি এগুলি সমস্ত পরিসংখ্যান ভিত্তিক করে দিয়েছি। আমাদের পরিসংখ্যান একটি নির্দিষ্ট মান পর্যন্ত পৌঁছে গেলে অর্জনগুলি আনলক করা হয়। আধুনিক যুদ্ধ 2 বিবেচনা করুন: গেমটি প্রচুর পরিসংখ্যান ট্র্যাক করছে! আপনি SCAR-H এর সাথে কতগুলি শট নিয়েছেন? লাইটওয়েট পার্ক ব্যবহার করার সময় আপনি কত মাইল ছড়িয়েছেন?

সুতরাং আমার বাস্তবায়নে, আমি কেবল একটি পরিসংখ্যান ইঞ্জিন তৈরি করেছিলাম, তারপরে একটি কৃতিত্ব ম্যানেজার তৈরি করেছি যা গেমপ্লে জুড়ে সাফল্যের স্থিতি পরীক্ষা করতে সত্যিই সাধারণ অনুসন্ধানগুলি চালায়।

যদিও আমার বাস্তবায়ন বেশ সরল, এটি কাজটি করে। আমি এটি সম্পর্কে লিখেছি এবং আমার প্রশ্নের ভাগ এখানে


2

ইভেন্ট ক্যালকুলাস ব্যবহার করুন । তারপরে কিছু পূর্বশর্ত এবং ক্রিয়াকলাপ তৈরি করুন যা পূর্বশর্তগুলি পূরণ করার পরে প্রয়োগ করা হয়:

  • পূর্বশর্ত: আপনি 1000 শত্রুকে হত্যা করেছেন, আপনার দুটি পা রয়েছে
  • ক্রিয়া: আমাকে ললিপপ দিন, আমাকে সুপার-ডুপার-শটগান -13 দিন
  • প্রথমবারের ক্রিয়া: বলুন "আপনি এত দুর্দান্ত!"

এটির মতো ব্যবহার করুন (গতির জন্য অপ্টিমাইজড!):

  • সমস্ত পরিসংখ্যান সংরক্ষণ করুন।
  • পূর্বশর্তগুলির জন্য কোয়েরি পরিসংখ্যান।
  • ক্রিয়া প্রয়োগ করুন।
  • একবারে এককালীন ক্রিয়া প্রয়োগ করুন।

আপনি যদি এটি দ্রুত করতে চান:

  • আপনি যা চান ক্যাশে করুন, এর কিছু অংশ কিছু গাছ, হ্যাশে সংরক্ষণ করুন ...
  • পরিবর্তনগুলি বর্ধনশীল করুন যাতে আপনি সমস্ত ক্রিয়া সমস্ত সময় প্রয়োগ করেন না তবে এগুলি নতুন যা ...)

বিঃদ্রঃ

সর্বোত্তম পরামর্শ দেওয়া শক্ত কারণ যেহেতু সবকিছুরই পক্ষে মতামত রয়েছে।

  • "সেরা ডেটাস্ট্রাকচার কী?" বোঝায় "আপনি এর সাথে সবচেয়ে বেশি কী অপারেশন করতে চান? অনুসন্ধান করা, সরানো, যুক্ত করা ..."
  • আপনি মূলত এই বৈশিষ্ট্যগুলিতে ভাবেন: কোডিংয়ের সহজতা, গতি, স্পষ্টতা, আকার ...

0

কৃতিত্বের ইভেন্টটি হওয়ার পরে যদি কোনও আইএফ চেক করে ভুল হয়?

if (Cinimatics.done)
   Achievement.get(CINIMATICS_SEEN);

if (EnemiesKiled > 200)
   Achievement.get(KILLER);

if (Damage > 2000 && TimeSinceFirstDamage < 2000)
   Achievement.get(MEAT_SHIELD);

InvitationAccepted = Invite.send(BestFriend);
if (InvitationAccepted)
   Achievement.get(A_FRIEND_IN_NEED);

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