#actionscript-3 #oop
#actionscript-3 #ооп
Вопрос:
Я немного новичок в разработке игр на as3, но я хочу создать несколько гибкую базу для игры Connect Four. Я бы хотел иметь возможность обтягивать игровое поле и игровые фигуры. Вот о чем я пока думаю. Если у кого-нибудь есть предложения, я был бы очень признателен:
GameController расширяет EventDispatcher — содержит все методы манипулирования сеткой игры. — Включает 2D массив для отслеживания местоположения игрового поля — Отправляет события после проверки при вызове методов
GameClass расширяет Sprite: — Содержит визуальные элементы игрового поля — Прослушиватели MouseEvent, прикрепленные к визуальным элементам, которые вызывают методы контроллера — (Пользовательские) прослушиватели ControllerEvent для обновления визуального вида при отправке GameController
Класс GamePiece расширяет Sprite: — Содержит расположение столбца / строки элемента — Содержит индекс текущего игрока — Загружает URL в формате PNG в качестве обложки
Это приблизительный план. Любые красные флажки или другие предложения очень ценятся.
Ответ №1:
Похоже, что GridController будет страдать от смешанных обязанностей; в архитектурах MVC ответственность контроллера заключается в перетасовке данных взад и вперед из модели в представление. Лично я бы рассмотрел возможность использования GridModel, которая содержала бы базовый многомерный массив, представляющий сетку, и методы добавления элементов, например:
public class GridModel extends EventDispatcher {
private var _grid : Array;
public function GridModel(rows : uint, cols : uint) : void {
// Create the data structure which represents the Grid.
_grid = initialiseGrid(rows, cols);
}
public function addPiece(player : uint, col : uint) : void {
if (isValidMove(col)) {
// Update the datastructure, determine which row the piece ended
// up residing in.
const row : uint = // method omitted
// Notify the rest of the system that a move has been made.
dispatchEvent(new GridUpdateEvent(GridUpdateEvent.MOVE, player, col, row, _grid.concat());
}
else {
// Illegal Move, datastructure stays the same, notify the rest
// of the system.
dispatchEvent(new IllegalMoveEvent(IllegalMoveEvent.COLUMN_FULL, player, col, _grid.concat()));
}
}
}
Основная роль вашего контроллера теперь будет заключаться в прослушивании событий, отправляемых моделью, а затем в соответствующем обновлении представления (DisplayList). Аналогично, ваше представление должно отправлять события на основе взаимодействия с пользователем (например: игрок номер один указал, что он хочет поместить фигуру во 2-й столбец); затем контроллер может вызвать соответствующий метод в модели.
Следующий фрагмент должен дать вам некоторое представление о том, каковы обязанности контроллера; не забывайте, что вы можете (и должны!) разделите свои обязанности, используя несколько моделей, представлений и, при необходимости, контроллеров.
public class GameController {
private var _gridModel : GridModel;
private var _stateModel : GameStateModel;
private var _gridView : GridView;
public function GameController(gridModel : GridModel, gameStateModel : GameStateModel, gridView : GridView) {
_gridModel = gridModel;
_gameStateModel : gameStateModel;
_gridView = gridView;
addEventListeners();
}
private function addEventListeners() : void {
_gridModel.addEventListener(GridUpdateEvent.MOVE, onGridUpdateMoveEvent);
_gridView.addEventListener(ColumnSelectionEvent.SELECTED, onColumnSelectedEvent);
}
private function onColumnSelectedEvent(event : ColumnSelectionEvent) : void {
// Query the GameStateModel to find out whos turn it currently is.
const activePlayer : uint = _gameStateModel.activePlayer;
// Ask the GridModel to update.
_gridModel.addPiece(activePlayer, event.column);
}
private function onGridUpdateMoveEvent(event : GridUpdateEvent) : void {
// Update the view.
_gridView.insertPiece(event.player, event.row, event.col);
// Update the GameState to indicate it's the next player turns.
_gameSate.completeTurn();
}
}
Комментарии:
1. Это фантастика, благодаря тому, что я полностью следую логике. Я думал о создании отдельных классов для GridModel и GameState, но я попал в старую ловушку, будучи ленивым и спрашивая: «действительно ли ему нужен свой собственный класс?» Я, конечно, вижу силу разделения этих отношений даже на этом уровне.
2. Одной из причин отделения GameStateModel от GridModel было бы изменение количества игроков; GridModel не волнует, сколько людей играет в игру, это ответственность GameStateModel. Используя полиморфизм, вы могли бы легко переключаться между двухпользовательской и трехпользовательской моделями.