Тетрис и красивая графика - PullRequest
2 голосов
/ 21 мая 2009

Скажем, вы строите игру Тетрис. Как любой хороший программист, у вас есть логика представления с одной стороны, а бизнес-логика - с другой; вероятно, происходит полноценный MVC.

Когда модель отправляет update(), представление перерисовывается, как и ожидалось.

Но тогда ... если вы хотите добавить, скажем, анимацию для исчезновения строки, как бы вы реализовали это в представлении?

Делайте любые предположения, которые хотите, за исключением того, что «Все правильно инкапсулировано».

Ответы [ 5 ]

4 голосов
/ 21 мая 2009

Лично я бы отдельно рисовал экран как можно чаще, даже если не было обновления положения блока. Так что у меня был бы где-нибудь цикл с "update" и "render" частью. Обновление играет в логику с логикой, которая выполняет или не обновляет позиции и / или удаляет блоки. Render играет мяч в графической части, которая рисует блоки, где они должны быть.

Теперь, если есть строки, которые нужно стереть, логика знает и может пометить эти строки, которые нужно удалить. Здесь я предполагаю, что каждая часть состоит из 4 отдельных блоков, и любой из этих блоков является одним объектом. Теперь, когда этот блок имеет установленный флаг «die», вы можете взять некоторые части рендера, чтобы исчезнуть из блока (скажем, 500 мс, чтобы взорваться). По истечении этого времени объект может быть ликвидирован, и блок на линии выше падает. Почему 500мс? Что ж, вам определенно следует использовать основанное на времени движение , поскольку на разных компьютерах скорость игры остается одинаковой.

Кстати, уже есть так называемые игровые движки, которые обеспечивают такой цикл обновления-рендеринга. Например, XNA, если вы идете по линии .NET. Вы также можете закодировать свой собственный движок, но будьте осторожны, это не простая задача и очень много времени. Я сделал это однажды и не ожидаю, что это будет движок, подобный движку Source; -)

2 голосов
/ 21 мая 2009

Большинство игр выполняют цикл, который постоянно перерисовывает вид игры как можно быстрее, вместо того, чтобы ждать изменения состояния модели и затем обновлять вид.

Если вам нравится шаблон представления модели, то он может хорошо работать, когда представление продолжает рисовать некоторые типы объектов после их удаления из модели, затухая в течение нескольких миллисекунд.

1 голос
/ 31 мая 2009

Интересно думать об игре как о MVC. Это перспектива, которую я никогда не принимал (по какой-то странной причине), но определенно интригующая, которая имеет большой смысл. Предполагая, что вы реализуете свою игру «Тетрис» с помощью MVC, я думаю, что вы можете принять во внимание две вещи, касающиеся связи между вашим контроллером и вашим представлением: есть состояние и есть события.

Ваш контроллер, очевидно, является центральной точкой взаимодействия для пользователя. Когда они выдают команды клавиатуры, ваш контроллер будет интерпретировать их и вносить соответствующие корректировки состояния. Однако иногда игра входит в состояние, которое совпадает с определенным событием ... например, заполнение строки блоками, которые теперь должны быть удалены.

Scoregraphic дал вам хорошую основу. Ваше представление должно работать в фиксированном цикле, чтобы поддерживать постоянную скорость на разных компьютерах. Но помимо обновления экрана для отображения нового состояния, он также должен иметь очередь событий, на которые он может выполнять анимацию в ответ. В случае заполнения строк в Tetris ваш контроллер может выдавать строго типизированные объекты событий, которые являются производными от какого-либо базового типа событий, в очередь событий представления, которая затем может использоваться представлением для выполнения соответствующих анимированных ответов.

1 голос
/ 31 мая 2009

Я часто задавался этим вопросом сам.

Мои мысли были такими:

1) Представлению задается состояние блоков (форма, яда-яда), но с дополнительными «переходными» данными:

2) Тот факт, что строка должна быть удалена, кодируется в состоянии, а НЕ вычисляется в представлении.

3) Теперь представление умеет рисовать переходы:

  • Без изменений: состояние для этого конкретного блока одинаковое
  • Изменить с «падения» на «заблокировано»: состояние «заблокировано» (с помощью сбрасываемого блока)
  • Изменить с «заблокировано» на «удалить»: состояние «удалено» (при завершении строки)
  • Изменить с «падения» на «удалить»: состояние «удалено», но старое состояние «падает»
1 голос
/ 21 мая 2009

Другим подходом было бы объединение класса MVC с чем-то вроде дифференциального выполнения - «представление» - это модель того, что представлено, но код рисования сравнивает поток событий, которые «представление» создает, с потоком из предыдущего рендеринга. , Таким образом, если в одном потоке есть строка, а в следующем нет, код рисования может анимировать разницу. Это позволяет абстрагировать чертеж от вида. Часто «представление» в MVC представляет собой набор виджетов, а не то, что непосредственно рисует отображение, поэтому в любом случае вы получаете вложенные иерархии MVC: приложение - это MVC (модель данных, объекты представления, контроллер приложения), где объект представления имеет коллекцию виджетов, каждый из которых имеет вид MVC (состояние виджета (например, нажатие кнопки), привязка внешнего вида и инструментария, отображение событий инструментария -> состояние виджета).

...