根据菜单

时间:2018-01-26 15:09:37

标签: c# class oop instantiation

我在"简单"有趣的游戏有点像Factorio,但不是基于网格的。 现在我需要某种系统来跟踪我所有不同的建筑类型,并让玩家在菜单中选择一种类型。该菜单由UI类处理,该类调用Game类中的方法来检查钱和诸如此类的东西。然后Game类调用World类来添加玩家选择的任何构建。至少那是相关的一点,我想。

正如我现在所知,为了存储不同的建筑类型,我有一个名为BuildInstruction的类,其中包含子类BuildingBuildInstructionConnectionBuildInstruction。这些类只包含Action<> thingamabobs在给定世界坐标/两个连接点时返回建筑物/连接。

我已经在Game - 和IU - 类中遇到过这种方法的一些问题。我似乎无法以合乎逻辑的方式在课程之间划分工作......

我知道这是一个荒谬模糊的问题,但我很难制定。基本上,如果有人知道这类事情的某种常见做法会很棒......我对所有建议持开放态度。

谢谢!

顺便说一下,如果它有助于理解,可以使用一些代码:

这是我用来将一种层次结构中的选项传递给菜单:

public class Category<T>
{
    public string Label { get; private set; }

    public T Me { get; private set; }

    List<Category<T>> children = new List<Category<T>>();

    public IEnumerable<Category<T>> Children => children;

    public bool HasChildren => children.Count() > 0;

    public Category(string label, List<Category<T>> _children)
    {
        Label = label;
        children = _children;
    }

    public Category(string label, T me)
    {
        Label = label;
        Me = me;
    }
}

这是带有子类的BuildInstruction类和静态列表&lt;&gt;然后我将BuildInstruction个对象提供给菜单。

public abstract class BuildInstruction
{
    public static Category<BuildInstruction> BuildInstructions;

    static BuildInstruction()
    {
        BuildInstructions = new Category<BuildInstruction>("Build", new List<Category<BuildInstruction>>()
        {
            new Category<BuildInstruction>("Powergrid", new List<Category<BuildInstruction>>()
            {
                new Category<BuildInstruction>("Powerline", new ConnectionBuildInstruction(
                    (start, end) =>
                    new Powerline(start as IPowerlineConnectable, end as IPowerlineConnectable)
                ))
            }),
            new Category<BuildInstruction>("Logistics", new List<Category<BuildInstruction>>()
            {
                new Category<BuildInstruction>("Pipeline", new ConnectionBuildInstruction(
                    (start, end) =>
                    new Pipeline(start as IPipelineConnectable, end as IPipelineConnectable)
                )),
                new Category<BuildInstruction>("Stockpile", new BuildingBuildInstruction(
                    (worldPos) =>
                    new Stockpile(worldPos)
                ))
            })
        });
    }

    public string Name { get; protected set; }
}

public class BuildingBuildInstruction : BuildInstruction
{
    Func<PointF, Building> BuildFunction;

    public BuildingBuildInstruction(Func<PointF, Building> buildFunction)
    {
        BuildFunction = buildFunction;

    }

    public Building Build(PointF worldPos)
    {
        return BuildFunction(worldPos);
    }
}

public class ConnectionBuildInstruction : BuildInstruction
{
    Func<IConnectable, IConnectable, Connection> BuildFunction;

    public ConnectionBuildInstruction(Func<IConnectable, IConnectable, Connection> buildFunction)
    {
        BuildFunction = buildFunction;
    }

    public Connection Build(IConnectable start, IConnectable end)
    {
        return BuildFunction(start, end);
    }
}

最后,游戏类:

public class Game
{
    World World = new World();

    public Game()
    {

    }

    public void Update()
    {

    }

    public void Draw(Graphics g)
    {
        World.Draw(g);
    }

    //-----------------------------------------------------

    public void BuyBuilding(Building building)
    {
        if (true) //Check money and whatnot...
        {
            if (ConstructBuilding(building))
            {
                //Success, use money and stuff
            }
            else
            {
                //Fail. Feedback!
            }
        }
        else
        {
            //Not enough money or whatnot. Feedback!
        }
    }

    bool ConstructBuilding(Building building)
    {
        return World.AddWorldObject(new ConstructionSite(building));
        //This ConstructionSite class is just a thing that makes it so that 
        //the actual building-process takes some time in-game
    }
}

我认为UI类只会让人感到困惑和代码太多(已经很多了?)但它只调用BuyBuilding()中的Game方法。现在,我使用BuyBuilding()方法获取了Building个对象,但我不知道这是否是一个很好的方法...

PS。 如果这太模糊和太荒谬,那就不要犹豫了,我只是想看看某个地方是否有人有任何建议或想法...

再次感谢你! :d

1 个答案:

答案 0 :(得分:0)

有很多方法可以做到这一点

一个选项是Build Class

public class BuildBuilding
{
    public Point Location{get;set;}
    public BuildingType Type{get;set;}

    public void Create(){
        ///logic for creation here
    }
}

这可以让你连接INotifyPropertyChanged或其他一些监控功能,你的UI可以用来设置类的属性,比如鼠标到位置和菜单键入

如果您不需要这种复杂程度,那么简单的静态创建函数就可以正常运行,这就是您所尝试的

public abstract class BuildingType 
{

    public static Building Create(Point location, BuildingType type){
        ///logic for creation here
    }
}

这里UI必须立即提供所有参数,但只要你没有太复杂的东西就可以使用

或者您可以定义和界面或虚拟函数来完成子类中的工作

public abstract class BuildingType 
{
    public abstract Building Create(Point location);//logic in child
}

public interface IBuildable
{
    void Create(Point location)
}

这些中的任何一个都会强制执行一个抽象句柄,你可以使用它来定义一个没有行为的方法句柄,你可以将UI连接到每个类型,然后在激活时调用公共函数