Я работаю над «простой» игрой для развлечения, вроде Factorio, но не основанной на сетке. Теперь мне нужна какая-то система, чтобы отслеживать все мои различные типы зданий и позволять игроку выбирать тип в меню. Меню обрабатывается классом UI
, и этот класс вызывает методы класса Game
для проверки денег и прочего. Затем класс Game
вызывает класс World
, чтобы добавить любое здание, выбранное игроком. По крайней мере, это важный момент, я думаю.
Как у меня сейчас, для хранения различных типов зданий у меня есть класс с именем BuildInstruction
с подклассами BuildingBuildInstruction
и ConnectionBuildInstruction
. Эти классы просто содержат 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
с подклассами и статическим списком‹> объектов 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);
}
}
И, наконец, класс Game:
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