سؤال

أنا أقوم بتطوير لعبة ، اللعبة لها وضع مختلف. سهل ، طبيعي ، وصعب. لذلك ، أفكر في كيفية تخزين وضع اللعبة. فكرتي الأولى هي استخدام الرقم لتمثيل الصعوبة.

سهل = 0 عادي = 1 صعب = 2

لذلك ، سيكون رمز بلدي شيء مثل هذا:

switch(gameMode){

case 0:
//easy
break;

case 1:
//normal
break;

case 3:
//difficult
break;

}

لكنني أعتقد أن لديها بعض المشكلات ، إذا أضفت وضعًا جديدًا ، على سبيل المثال ، "متطرف" ، أحتاج إلى إضافة حالة 4 ... ... يبدو أنه ليس تصميم GD.

لذلك ، أفكر في صنع كائن GameMode ، و GameMode مختلف هو فئة فرعية من Super Class GameMode. كائن gamemode هو شيء من هذا القبيل:

    class GameMode{
    int maxEnemyNumber;
    int maxWeaponNumber;
      public static GameMode init(){
         GameMode gm = GameMode();
         gm.maxEnemyNumber = 0;
         gm.maxWeaponNumber = 0;
         return gm;
      }    

    }

class EasyMode extends GameMode{

      public static GameMode init(){
         GameMode gm = super.init();
         gm.maxEnemyNumber = 10;
         gm.maxWeaponNumber = 100;
         return gm;
      }    
}


class NormalMode extends GameMode{

      public static GameMode init(){
         GameMode gm = super.init();
         gm.maxEnemyNumber = 20;
         gm.maxWeaponNumber = 80;
         return gm;
      }    
}

لكنني أعتقد أنه يبدو أنه "ضخم للغاية" لإنشاء كائن لتخزين GameMode ، "GameMode" الخاص بي فقط تخزين متغيرات مختلفة لإعدادات اللعبة .... هل هذه طريقة بسيطة لتخزين البيانات فقط بدلاً من صنع كائن؟ thz u.

هل كانت مفيدة؟

المحلول

أعتقد أنك تحاول تمثيل جدول بيانات التكوين. إما وضع هذا في ملف التكوين إذا كنت تستخدم لغة تدعم ذلك ، أو تستخدم البيانات الحرفية في الكود الخاص بك.

على سبيل المثال ، يمكنك كتابة هذا في ج:

typedef enum difficulties {
  DIFFICULTY_EASY,
  DIFFICULTY_MEDIUM,
  DIFFICULTY_HARD
} difficulties;

struct {
  int max_enemies;
  int max_weapons;
} difficulty_settings[] = {
  {10, 4},
  {20, 5},
  {30, 6}
};

وعندما تريد قراءة إعداد معين ، على سبيل المثال max_enemies للمستوى السهل ، يمكنك الكتابةdifficulty_settings[DIFFICULTY_EASY].max_enemies

من السهل إضافة المزيد من التكوين (إما المزيد من المعلمات ، أو المزيد من مستويات الصعوبة) عن طريق تمديد الجدول.

نصائح أخرى

الهدف الغالب الذي يجب أن يكون لديك هنا هو مركزية المنطق لاسترداد القيم المتعلقة بمستويات مختلفة. من خلال توفير مكان واحد يتم فيه تخزين هذه القيم ، يمكنك تقليل عدد الأماكن الموجودة في الكود الذي تحتاج إلى تغييره إذا قمت بإضافة مستوى آخر ، وإضافة قيم أخرى ، إلخ.

واجهة الفصل هي خيار جيد لهذا الحل. ومع ذلك ، إذا كان لديك عدد محدود من خيارات التكوين التي يمثلها الفصل ، فلا يوجد سبب تحتاج إلى استخدام الميراث. يمكنك البدء بفئة واحدة تغلف المنطق. إذا كانت بقية الكود الخاص بك استرجاع إعداداتها عبر واجهة الفصل ، فيمكنك لاحقًا تقديم تصميم أكثر تعقيدًا ، مثل الفئات الفرعية لكل وضع ، إذا كان ذلك ضروريًا مع تعديلات محدودة لبقية لعبتك.

على سبيل المثال ، قد يكون التنفيذ الأول مثل

enum mode {
    MODE_EASY = 0,
    MODE_NORMAL = 1,
    MODE_DIFFICULT = 2,
};

class gameSettings {
    public gameSettings(mode GameMode) {
        m_mode = GameMode;
    }

    public int getMaxWeaponNumber() {
        int maxWeaponNumber;
        switch(m_mode) {
            case EASY_MODE:
                maxWeaponNumber = 100;
                break;

            // Other mode settings.               
         }

         return maxWeaponNumber;
    }

    // Other game settings....

    private mode m_mode;

}

هذا يجمع بين تصريح بيان التبديل () مع فوائد واجهة الفصل. يمكنك أيضًا تبديل بيان Switch () مع جدول بحث ، كما هو مقترح من قبل ملصق آخر ، أو بعض الآلية الأخرى كما هو مناسب لتطبيقك.

لا أعرف Java (وهو ما تبدو عليه أمثلةك) ، لذلك أقدم أفكاري في بعض C#.

هذه فكرة. استخدم وضع اللعبة الخاص بك كعلم بدلاً من ذلك. إذا بدأت بـ:

[Flags]
enum GameModes
{
    Unknown = 0,
    ModeA = 1,
    ModeB = 2,
    ModeC = 4,
}

الآن لديك مستويات 1-7 المتاحة.

GameModes Difficulty = GameModes.ModeA | GameModes.ModeB;    // difficulty = 3
GameModes Difficulty = GameModes.ModeB;    // difficulty = 2

بالإضافة إلى ذلك ، سيتطلب منك أي من الطريقة التي أظهرتها إضافة المزيد من الخيارات في حالة تغيير مستويات (أوضاع) ، وإضافتها ، إلخ صف دراسي. لا أعتقد أنك يجب أن تحتاج إلى فئة قاعدة تمتد لأي شيء.

استخدم نهج التبديل في مُنشئ فئة GameMode الخاصة بك.

إلى جانب بعض مشكلات بناء الجملة ، أعتقد أنك على المسار الصحيح. لا أعتقد أنك يجب أن تقلق بشأن الذاكرة ، مع الأخذ في الاعتبار وجود وضع واحد فقط في وقت واحد. هذا شكل من أشكال نمط الاستراتيجية. يمكنك تمديده حتى تفعل الأنماط أكثر. على سبيل المثال ، بدلاً من مجرد الاحتفاظ بالثوابت ، ربما يمكن أن تكون هناك طريقة generateenemies التي تنشئ بالفعل مجموعة أو قائمة من الأعداء. هذا ينتقل أكثر من الاستراتيجية إلى كائن الوضع. يمكن أن تساعد التخلف عن السداد العاقل في الطبقة الفائقة في تجنب الرمز الزائد.

من الصعب أن نقول نوع إعادة البناء التي يمكن القيام بها هنا ، حيث يوجد معلومات أقل حول الفصول الأخرى. لكن يمكنك التحقق من نمط الدولة الذي يلف سلوكيات مختلفة في كائنات حالة مختلفة. إن مقاربتك في توسيع فئة Gamemode الأساسية تشبه إلى حد كبير نمط الحالة. أعتقد أنه أفضل من كتلة المفتاح ... والأنماط هي طرق موثوقة للقيام بالأشياء ، إذا تم تطبيقها جيدًا.

لماذا تعتقد أن التبديل أصعب في Mantain؟ إذا قمت بإضافة وضع آخر ، فسيتعين عليك إضافة رمز ، بغض النظر عن الحل الذي تستخدمه.

الحالة الوحيدة التي يمكنني التفكير فيها في المكان الذي لا تضطر فيه لإضافة رمز إذا قمت بإضافة وضع آخر هي إذا قمت بإنشاء معلمات اللعبة من قيمة gameMode.

على سبيل المثال: maxenemy = 5 * gameMode;

أعتقد أنه ما لم يكن لديك تهيئة معقدة للغاية لأداء التبديل يكون أكثر من كافية. أعلم ، أنا أعلم ، أن الأشياء والفصول الدراسية لطيفة وكل موسيقى الجاز ، ولكن إذا كان عليك فقط تحديد عدد قليل من المتطلبات والشيء الذي يعمل ، فإن استثمار الوقت في تطوير فئة معقدة في وضع اللعبة قد لا يكون حلاً مجزيًا بعد كل شيء (أنا (أنا يعني ، كم عدد أوضاع اللعبة التي تخطط لإضافتها؟).

الاستفادة من نمط الاستراتيجية.

في شروط جافا:

public interface Strategy {
    void execute();
}

public class SomeStrategy implements Strategy {
    public void execute() {
        System.out.println("Some logic.");
    }
}

الذي تستخدمه على النحو التالي:

Map<String, Strategy> strategies = new HashMap<String, Strategy>();
strategies.put("strategyName1", new SomeStrategy1());
strategies.put("strategyName2", new SomeStrategy2());
strategies.put("strategyName3", new SomeStrategy3());

// ...

strategies.get(s).execute();
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top