Я делаю упрощенную пошаговую космическую игру. Игрок взаимодействует с 2D-картой, которая представляет галактику / игровую область. Карта состоит из секторов, и каждый сектор может содержать несколько планет. Игроки могут взаимодействовать с картой, перемещая космический корабль в каждый сектор и колонизируя по желанию.
Итак, часть моего слоя модели выглядит так (я здесь для краткости упрощаю):
function Map() {
// An array of Sectors
this.sectors = [];
. . .
}
function Sector() {
// Array of Planets
this.planets = [];
// Array of player built space stations
. . .
this.spaceStations = [];
}
function Planet() {
// Array of player built buildings
this.structures = []
. . .
}
В настоящее время в игре есть два представления: MapView, отображающий видимую вселенную:
function MapView() {
// @param _map The game Map object
this.render = function(_map) {
this.canvas = new Canvas();
// Camera can examine the Map to find the part that is currently visible on screen
this.camera = new Camera();
. . .
foreach(_map.sectors as sector) {
LOTS of code and drawImage commands here to . . .
-ask camera if each sector is in currently in view (no point drawing the entire map)
-draw each sector background image (star field or nebula or whatever helps make the game look more natural)
-draw sector boundary lines so we end up with a nice nasty grid over the whole map
-determine what planet sprite image to draw depending on planet type (i.e ROCK, EARTH, GAS)
-draw every planet in each sector (the player can watch these planet sprites ‘orbit’ their sun)
-draw any player created structures in each sector
-draw any ships currently in each sector
}
}
}
и ExamineSectorView, который отображает выбранный сектор:
function ExamineSectorView() {
// @param _sector A game Sector object
this.render = function(_sector) {
this.canvas = new AnotherCanvas();
. . .
not-so-much-but-growing-suspiciously-large-amount-of-code here to . . .
- foreach { draw planets in currently selected sector (selected from Map) }
- draw space stations
- you get the idea
}
}
У меня сейчас только один контроллер, MapController. Он создает прослушиватели событий на клавиатуре / мыши, чтобы игрок мог взаимодействовать с картой, то есть:
- игрок нажимает на сектор в MapView -> просматривать этот сектор в ExamineSectorView
- игрок использует клавиши со стрелками -> прокрутите карту камеры.
При запуске контроллер вызывает методы на карте (для ее создания), создает представления и запускает таймер setInterval для визуализации представления.
Я бы хотел помочь с моими двумя взглядами.
Я чувствую, что они оба слишком много делают.
Они действительно содержат логику, но это относится только к просмотру и требуется для рендеринга - например, оператор с 10 переключателями для определения типа планеты и рисования соответствующего изображения или небольшого умножения свойства планеты '.size' для решения насколько большой его нарисовать. Так что я думаю, что логика находится в правильном месте в представлении.
Проблема в том, что вся эта логика, зависящая от представления, дает очень много. Моя точка зрения выходит из-под контроля, и я хотел бы как-то разделить рендеринг каждого аспекта представлений. Например, вот так:
function MapView() {
this.render = function() {
this.canvas = new Canvas();
// Camera can examine the Map to find the part that is currently visible on screen
this.camera = new Camera();
. . .
foreach(_map.sectors as sector) {
mapSectorView = new MapSectorView();
mapSectorView.render(sector);
}
}
}
function MapSectorView() {
this.render = function(_sector) {
this.canvas = new Canvas();
. . .
foreach(sector.planets as planet) {
planetView = new MapSectorPlanetView();
planetView.render(planet);
}
}
}
function MapSectorPlanetView() {
this.render = function(_planet) {
this.canvas = new Canvas();
. . .
foreach(planet.structure as structure) {
structureView = new StructureView();
structureView.render(structure);
}
}
}
. . .
Я читал другие сообщения на этом сайте, в которых говорится, что представления не должны создавать друг друга. Если это так, альтернативой вышесказанному было бы создание всех необходимых представлений в контроллере и начало их передачи; т.е.
mapView.render(mapModelObject, mapSectorView, mapPlanetView);
Я тоже не уверен, что это способ решения этой проблемы.
Я могу представить, что эта игра станет большой довольно быстро, и я знаю, что представление станет намного сложнее по мере разработки игры, поэтому я был бы признателен за любые советы о том, как управлять рендерингом в такой игре MVC, особенно в отношении разделения проблемы в среде JS / холста.
Я только что нашел: MVC: модели данных и модели представления
Мне интересно, возможно ли это здесь; создать несколько моделей просмотра, то есть MapViewModel, который содержит все необходимые представления и отображает каждое из них.
Спасибо!