Я изучаю С# в течение лета, и теперь мне хочется сделать небольшой проект из того, что я сделал до сих пор. Я решил создать своего рода текстовую приключенческую игру.
Основная структура игры будет включать в себя несколько секторов (или комнат). При входе в комнату будет выведено описание и ряд действий и таких действий, которые вы можете предпринять; способность исследовать, подбирать, использовать материал в этой комнате; возможно, боевая система и т.д. Сектор может быть подключен до 4 других секторов.
Во всяком случае, набросанные на бумаге идеи о том, как разработать код для этого, я почесываю голову над структурой части моего кода.
Я выбрал класс игрока и класс уровня, который представляет уровень/подземелье/область. Этот класс уровней будет состоять из нескольких взаимосвязанных "секторов". В любой момент времени игрок будет присутствовать в одном определенном секторе на уровне.
Итак, вот путаница:
Логически, можно было бы ожидать такой метод, как player.Move(Dir d)
Такой метод должен изменить поле текущего сектора в объекте уровня. Это означает, что класс Player должен знать о уровне класса. Хммм.
И Level, возможно, придется манипулировать объектом Player (например, игрок входит в комнату, попадает в заложники чем-то, теряет что-то из инвентаря). Итак, теперь Level также должен содержать ссылку на объект Player?
Это не очень приятно; все должно содержать ссылку на все остальное.
В этот момент я вспомнил, как читал о делегатах из книги, которую я использую. Хотя я знаю о указателях функций из С++, в главе о делегатах были представлены примеры с своего рода "точки зрения на основе событий", с которой я не имел большого просветления.
Это дало мне идею разработать классы следующим образом:
Игрок:
class Player
{
//...
public delegate void Movement(Dir d); //enum Dir{NORTH, SOUTH, ...}
public event Movement PlayerMoved;
public void Move(Dir d)
{
PlayerMoved(d);
//Other code...
}
}
Уровень:
class Level
{
private Sector currSector;
private Player p;
//etc etc...
private void OnMove(Dir d)
{
switch (d)
{
case Dir.NORTH:
//change currSector
//other code
break;
//other cases
}
}
public Level(Player p)
{
p.PlayerMoved += OnMove;
currSector = START_SECTOR;
//other code
}
//etc...
}
Это хороший способ сделать это?
Если глава делегата не была представлена так, как это было, я бы не подумал использовать такие "события". Итак, что было бы хорошим способом реализовать это без использования обратных вызовов?
У меня есть привычка делать очень подробные сообщения... извините v__v