首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >存储多种类型的数据

存储多种类型的数据
EN

Stack Overflow用户
提问于 2017-01-26 15:16:49
回答 4查看 150关注 0票数 1

我在试着创建一个任务系统。我有继承接口的QuestCreator、Quest和多个目标类(TalkObjective、LocationObjective等)。

在Quest类的构造函数中,我创建了一个类似List<IObjective>的列表。它没有起作用。

然后我创建了一个类来保存所有不同类型的列表。但我失去了对目标进行排序的能力。

我的问题是:有没有更好的方法/设计来做到这一点?

编辑

我很抱歉我没有详细描述它。因为我更改了我的代码,所以我不能在这里发布它。我试图创建相同的代码,但这一次代码没有给我错误。所以我自己解决了这个问题。

我使用的是一个没有完成/废弃的教程。Here is the link to github

我用抽象类构建了我的商品/库存系统,这是我想到的第一件事。但我的意图是按照教程的创建者设计的方式创建这个任务系统,这样我就可以学习他的方式。

我希望将不同对象类的对象放在一个列表中,并使用它们共同使用的接口。

代码语言:javascript
复制
public class QuestCreator : MonoBehaviour {
#region fields
private List<IQuestObjective> objectives;
private GameObject itemManager;
private ItemDatabase itemdb;
private Location location;
private Quest quest;

//For Saving Quest
private Quest_data quests;
#endregion


void Update()
{
    //Just for the test purpose
    if (Input.GetKeyDown (KeyCode.E)) 
    {
        itemManager = GameObject.Find ("GameManager");
        itemdb = itemManager.GetComponent<ItemDatabase>();
        Item item = new Item ();
        Item item2 = new Item ();
        item = itemdb.weapon_database[0];
        item2 = itemdb.weapon_database [1];

        CollectionObjective collectionObjective = new CollectionObjective ("Find", 3, item, "Find this precious item");
        CollectionObjective collectionObjective2 = new CollectionObjective ("Find", 1, item2, "Find Sword of Warrior from Dark Passage");
        LocationObjective locationObjective = new LocationObjective ("Go to Green Valley", "Go to " + location, location, false);
        objectives = new List<IQuestObjective> ();
        objectives.Add(collectionObjective);
        objectives.Add (collectionObjective2);
        objectives.Add (locationObjective);

        QuestText questText = new QuestText ();
        QuestIdentifier questIdentifier = new QuestIdentifier();
        questText.Title = "Finding Sword of Warrior";
        questText.DescriptionSummary = "Summary...";
        questText.Hint = "Hint...";
        questIdentifier.QuestID = 1;
        questIdentifier.SourceID = 1;
        quest = new Quest (questIdentifier, questText, objectives);
        Debug.Log (quest.Objectives[1].Description);
        Debug.Log (quest.Objectives.Count);

    }
}
EN

回答 4

Stack Overflow用户

发布于 2017-01-26 15:43:43

您需要研究继承和多态性。

在您的示例中,您将拥有一个包含所有常见逻辑的IObjective类:

代码语言:javascript
复制
public abstract IObjective : MonoBehaviour
{
     public abstract void CommonMethod();
     public virtual void OverrideIfNeeded(){}
     public void UseAsIs(){}
}

CommonMethod必须被子类重写。OverrideIfNeeded可以被覆盖或按原样使用。UseAsIs不能被覆盖(但它可以被隐藏)。

然后你就有了一个集合:

代码语言:javascript
复制
IEnumerable<IObjective> collection;

它包含各种不同的对象,这些对象都是IObjective,您可以迭代和调用IObjective中的所有方法:

代码语言:javascript
复制
   foreach(IObjective obj in collection)
   {
        obj.CommonMethod(); 
        obj.UseAsIs();
        ...
   }
票数 1
EN

Stack Overflow用户

发布于 2017-01-26 15:27:19

首先,对于所有的游戏编程,我强烈建议通过这本网络书籍- http://gameprogrammingpatterns.com/contents.html (它也提供PDF/书籍的变体为一些钱)。它会帮助你做一些游戏模式的例子,你会对游戏是如何制作的有一个概念。

你的问题有点宽泛,涉及到每个人的观点,不应该被列为Q on SO,但是:

逻辑上对我来说是这样的:有一个Quest (由工厂QuestCreator创建),它包含List<Objectives>

Objectives应该是一个抽象的类,包含一些变量和方法( Objective完成了吗?-所有objective都有的其他东西)。

在此之后,您应该继承较小的对象(如TalkObjectiveItemObjective),并覆盖-> IsObjectiveDone方法的内部实现。

老实说,在游戏编程中,开发人员正在尽可能地避免继承。创建继承树然后遍历代码太难了。取而代之的是,他们试图依赖像Component这样的模式(与上面的源代码相同)。

添加一些示例:

代码语言:javascript
复制
public abstract class Objective
{
    public bool IsObjectiveDone { get; private set; }

    public virtual void CheckIfDone();
}

public class ObjectiveGroup
{
    public bool AllObjectivesDone => SubObjectives.All(a => a.IsObjectiveDone);
    public Objective[] SubObjectives { get; private set; }

    public static ObjectiveGroup Create(TypeOfQuest aType, Requirements[] aReq)
    { /* factory implementation */ }
}

一旦你有了上面的例子,你就可以定义每种类型的“特殊”目标:

代码语言:javascript
复制
public class ItemObjective : Objective
{
    public Item RequiredItem { get; private set; }

    override public void CheckIfDone()
    {
        this.IsObjectiveDone = Player.GetInstance().Inventory.Contains(RequiredItem);
    }
}

一旦你想要开始新的任务,你将呼叫工厂,它将创建任务,包含一组目标。在每个目标上,您将在用户每次执行某些操作/获取新项目时执行CheckIfDone操作。

代码语言:javascript
复制
public class Quest
{
    public ObjectiveGroup { get; private set; }

    public Quest(TypeOfQuest aType, Requirements[] aReq)
    {
        this.ObjectiveGroup = ObjectiveGroup.Create(aType, aReq);
    }
}

public class Player
{
    public List<Quest> Quests = new List<Quest>();
    public List<Item> Inventory = new List<Item>();
}


public void Main(/* ... */)
{
    Player player = new Player();
    player.Quests.Add(new Quest(TypeOfQuest.ItemObtain, new Requirements[] { Item["Sword of Conan"] });

    while(true)
    {
        player.Quests.ObjectiveGroup.ForEach(a => a.SubObjectives.ForEach(b => b.CheckIfDone()));

        foreach(var objGrp in player.Quests.ObjectiveGroup)
            if(objGrp.IsObjectiveDone) Console.WriteLine("Quest completed");
    }
}
票数 0
EN

Stack Overflow用户

发布于 2017-01-26 15:35:26

以下是您可能针对您的问题而编写的代码示例。

代码语言:javascript
复制
public class Program
{
    public struct Location
    {
        // Assumes 2D game location
        public int X;
        public int Y;
    }

    public struct Character
    {
        public int GameCharId;
    }

    public class BaseObjective
    {
        public string Title;
        public string Description;
    }

    public class TalkObjective : BaseObjective
    {
        public Character TargetCharacter; 
    }

    public class LocationObjective : BaseObjective
    {
        public Location TargetLocation;
    }

    public static void Main(string[] args)
    {
        List<BaseObjective> currentObjectives = new List<BaseObjective>();

        TalkObjective obj1 = new TalkObjective(){ Title = "Talk to Bob", Description = "Bob has some useful information for you", TargetCharacter = new Character(){GameCharId = 87}};
        LocationObjective obj2 = new LocationObjective(){ Title = "Find the thing", Description = "Bob informed you of a thing, go and find it", TargetLocation = new Location(){ X = 33, Y=172}};


        currentObjectives.Add(obj1);
        currentObjectives.Add(obj2);
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41868468

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档