А чем обусловлен выбор DirectX? При портировании всё равно ведь пришлось от него отказываться. Не думали написать игру на чем-нибудь кросс-платформенном и запуститься в том числе и на мобильных устройствах? Игра, судя по геймплейным видео, отлично бы игралась на планшетах и больших телефонах.
Предложения не выделяются автоматически, а берутся из файла титров (*.srt). Автоматическое распознавание речи задачка, конечно, интересная, но опыт того же Youtube показывает, что очень велика вероятность ошибок, а для обучающего проекта это неприемлемо.
И еще, видна пикселизация в контролах Play, Next, Prev, Volume.
Да, с графикой я пока не заморачивался: стандартные контролы проигрывателя были слишком маленькими и я просто увеличил картинки в графическом редакторе.
Вообще, цель статьи не в том, чтобы сравнить Zend с другими фреймворками, а в том, чтобы дать разработчикам, начинающим работать с фреймворком, ответы на вопросы: что такое ServiceManager, как работать с формами, БД и т.п. Соглашусь, читать лучше на свежую голову, но текста примерно с такой структурой мне не хватало когда я начал свое знакомство с этим фреймворком.
Николай, я правильно из вашего комментария понял, что в Zend'е при помощи классов Zend\Config\Reader можно не только читать настройки своих кастомных модулей, но и прикрутить как замену application.config.php, *global.php, *local.php и конфигов модулей?
1) Зачем в каждом экшене делать?.. В зенд же есть хуки перед вызовом экшена?
3) Разве это нельзя сделать в хуках доктрины prePersist?
Не готов ответить на вопросы, попробую изучить его и переделать этот кусок.
2) Почему в мире php не принято следовать REST? Ведь очень некрасиво выглядят эти постоянные проверки на то, что запрос POST?
Наверняка это возможно, изучу этот вопрос и переделаю этот кусок кода.
4) что это за магия?
Пока в проекте нет работы с пользователями, по этому тут хардкодится ноль, в третьей части я прикручу юзеров и эта строчка будет заменена на айдишник текущего пользователя.
7) Что за магическая 1?
Это статус. 0 — не опубликовано, 1 — опубликовано. У вас есть предложение как убрать эту магическую константу?
Кирилл, а вы можете привести практический пример использования DI в этом контексте? Честно говоря, дальше доки, в которой класс А зависит от класса Б я пока не продвинулся.
Хех, хороший вопрос :) Это наследие одного из предыдущих алгоритмов, когда мне нужно было сравнивать состояния игровых миров двух пользователей. Логично, что сравнивать надо было два дата-фрейма с одинаковыми номерами. В текущем рабочем алгоритме информация о номере дата-фрейма не нужна.
что используется в качестве транспорта? голый TCP?
Да, голый TCP.
как осуществляется фрагментация сообщений?
Каждый дата-фрейм это преобразованный в JSON-массив с данными, описание массива в соседнем комментарии.
было бы разумно использовать какие-нибудь WebSockets + JSON для этого
Согласен, но сейчас у меня нет возможности допилить еще и HTML5-клиент. Для того и выложил на гитхабе, чтобы желающие смогли усовешенствовать клиент :)
При инициализации игры сервер передает клиенту массив с данными:
0 'left or right'
1 координаты шарика по оси Х;
2 координаты шарика по оси У;
3 дельта шарика по оси Х по отношению к предыдущему дата фрейму;
4 дельта шарика по оси Y по отношению к предыдущему дата фрейму;
5 счет левого игрока;
6 счет правого игрока;
7 координата У левой доски;
8 координата У правой доски;
9 дельта У левой доски;
10 дельта У правой доски;
11 номер «дата фрейма» (не номер отрендеренного флешом кадра, а номер передачи данных); 12 клиент добавляет к этому массиву время, за которое кадр должен быть отрендерен (1 / число дата фреймов в секунду)
Серевер клиенту во время игрового процесса
При игре сервер передает клиенту аналогичные данные, для сохранения совместимости с данными инициализации первый элемент передается пустым:
0 ''
1 координаты шарика по оси Х;
2 координаты шарика по оси У;
3 дельта шарика по оси Х по отношению к предыдущему дата фрейму;
4 дельта шарика по оси Y по отношению к предыдущему дата фрейму;
5 счет левого игрока;
6 счет правого игрока;
7 координата У левой доски;
8 координата У правой доски;
9 дельта У левой доски;
10 дельта У правой доски;
11 номер «дата фрейма» (не номер отрендеренного флешом кадра, а номер передачи данных); 12 клиент добавляет к этому массиву время, за которое кадр должен быть отрендерен (1 / число дата фреймов в секунду)
Клиент серверу во время игры
0 'left or right'
1 изменение положения своей доски
2 номер отправленного фрейма. Нужен чтобы сервер не обрабатывал дважды один и тот же фрейм.
Да, клиент несовершенен. Если нажать тильду, то можно будет увидеть отладочную информацию и положение доски, там где она должна находиться по мнению клиента. Эта доска двигается плавно. При желании можно допилить клиента так, чтобы движения досок были более плавными.
Так а в чем проблема? Поставьте Буст, запустите краулер, когда он обойдет весь сайт и сгенерирует html, можете скопировать файлы. Чтобы их отдавать нужно будет также скопировать правила для .htaccess.
Для Друпала есть модуль Boost, который сгенерированные страницы складывает в файловую систему в виде html-файлов. По умолчанию этот процесс запускается для запрошенных юзером страниц, но есть в модуле и краулер, который может обойти весь сайт и сгенерировать для него статику.
Руководствуясь статьей собрал почти такого же робота: www.youtube.com/watch?v=EKOa53JaOAg. Мой управляется через Андроид-смартфон или через десктопный гуй.
Собственно, мы ровно так и используем: на фронтенде Нжинкс, отдающий статику (js, css, картинки), на бэкенде Варниш + Апач (от него в нашем приложении отказаться сложно) + PHP-приложение. Архитектура не окончательная и, честно говоря, одно из двух: Варниш или Нжинкс, мне в ней кажется лишним, по-этому подумываю об эксперименте, в котором хочу попробовать отказаться от сначала от Нжинкса (то есть оставить только Варниш + Апач), потом от Варниша (Нжинкс + Апач) и сравнить что же работает быстрее.
Предложения не выделяются автоматически, а берутся из файла титров (*.srt). Автоматическое распознавание речи задачка, конечно, интересная, но опыт того же Youtube показывает, что очень велика вероятность ошибок, а для обучающего проекта это неприемлемо.
И еще, видна пикселизация в контролах Play, Next, Prev, Volume.
Да, с графикой я пока не заморачивался: стандартные контролы проигрывателя были слишком маленькими и я просто увеличил картинки в графическом редакторе.
Почему некошерны? На битбакете можно бесплатно создавать приватные репозитории, а на гитхабе — нет.
Проверил, вот такая конструкция в Твиг шаблоне работает:
Но вариант с view-плагином мне все же нравится больше:
3) Разве это нельзя сделать в хуках доктрины prePersist?
Не готов ответить на вопросы, попробую изучить его и переделать этот кусок.
2) Почему в мире php не принято следовать REST? Ведь очень некрасиво выглядят эти постоянные проверки на то, что запрос POST?
Наверняка это возможно, изучу этот вопрос и переделаю этот кусок кода.
4) что это за магия?
Пока в проекте нет работы с пользователями, по этому тут хардкодится ноль, в третьей части я прикручу юзеров и эта строчка будет заменена на айдишник текущего пользователя.
7) Что за магическая 1?
Это статус. 0 — не опубликовано, 1 — опубликовано. У вас есть предложение как убрать эту магическую константу?
Да, против первых двух пунктов есть тестирование и код ревью, но мне удобнее недопустить появления этих проблем.
Да, голый TCP.
как осуществляется фрагментация сообщений?
Каждый дата-фрейм это преобразованный в JSON-массив с данными, описание массива в соседнем комментарии.
было бы разумно использовать какие-нибудь WebSockets + JSON для этого
Согласен, но сейчас у меня нет возможности допилить еще и HTML5-клиент. Для того и выложил на гитхабе, чтобы желающие смогли усовешенствовать клиент :)
Серевер клиенту при инициализации (первый пакет)
При инициализации игры сервер передает клиенту массив с данными:
0 'left or right'
1 координаты шарика по оси Х;
2 координаты шарика по оси У;
3 дельта шарика по оси Х по отношению к предыдущему дата фрейму;
4 дельта шарика по оси Y по отношению к предыдущему дата фрейму;
5 счет левого игрока;
6 счет правого игрока;
7 координата У левой доски;
8 координата У правой доски;
9 дельта У левой доски;
10 дельта У правой доски;
11 номер «дата фрейма» (не номер отрендеренного флешом кадра, а номер передачи данных);
12 клиент добавляет к этому массиву время, за которое кадр должен быть отрендерен (1 / число дата фреймов в секунду)
Серевер клиенту во время игрового процесса
При игре сервер передает клиенту аналогичные данные, для сохранения совместимости с данными инициализации первый элемент передается пустым:
0 ''
1 координаты шарика по оси Х;
2 координаты шарика по оси У;
3 дельта шарика по оси Х по отношению к предыдущему дата фрейму;
4 дельта шарика по оси Y по отношению к предыдущему дата фрейму;
5 счет левого игрока;
6 счет правого игрока;
7 координата У левой доски;
8 координата У правой доски;
9 дельта У левой доски;
10 дельта У правой доски;
11 номер «дата фрейма» (не номер отрендеренного флешом кадра, а номер передачи данных);
12 клиент добавляет к этому массиву время, за которое кадр должен быть отрендерен (1 / число дата фреймов в секунду)
Клиент серверу во время игры
0 'left or right'
1 изменение положения своей доски
2 номер отправленного фрейма. Нужен чтобы сервер не обрабатывал дважды один и тот же фрейм.
Перед отправкой данных и клиент, и сервер конвертируют их в JSON и в таком виде передают. Вот тут код отвечающий за передачу данных сервером:
github.com/romka/quickpong/blob/master/quickpong/quickpong.py#L179
github.com/romka/quickpong/blob/master/quickpong/protocol.py#L72