Как я делал MMO-игру 5 (Отрисовка мира)

Движок для игры я сделал следующим образом: игрок посылает команды на сервер, кликая мышью по элементам интерфейса, но изменения игрового мира производятся специальным потоком сервера с определенной периодичностью. Чтобы игрок видел изменения следует обновлять в браузере игрока картинку. Сначала я сделал перезагрузку фрейма раз в 10 секунд с помощью метатэга Refresh: "<meta http-equiv="refresh" content="10">". Тестирование показало, что тогда картинка некрасиво моргает. Обратившись к помощи AJAX, удалось сделать более красивое обновление и при этом сократился объем трафика. Сделано это было следующим образом:

function f1(){ var v1=window.XMLHttpRequest?new XMLHttpRequest():new ActiveXObject("Microsoft.XMLHTTP"); v1.open("POST","server"); v1.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); v1.onreadystatechange=function() { if (v1.readyState==4&&v1.status==200) eval(v1.responseText); }; v1.send('...');}

Что делает этот код? Когда загружается эта HTML-страница, тут же срабатывает функция f1(). Эта функция обращается к серверу через AJAX и получает код, написанный на JavaScript. Благодаря функции eval() (см. 11 строку), этот код выполняется браузером. Сервер передает код вида: "setTimeout('f1();',10000); document.getElementById('i1').innerHTML='Этот текст появится внутри тэга BODY';". Т.е. запускается таймер для повторного обращения к серверу и полностью перерисовывается содержимое фрейма. Таким образом каждые 10 секунд игрок будет видеть изменения игрового мира.

Итак, та часть движка, которая работает на стороне игрока, готова. Какие-либо изменения можно легко сделать, передавая в качестве ответа на AJAX-запрос как HTML-, так и JavaScript-код.

Комментарии

А есть ли смысл изобретать велосипед? Может проще и удобнее воспользоваться тем же самым RichFaces-ем или GWT?

Submitted by Victor on

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

Это оно пока сотня байт, пока еще к этому не прикручена посылка и обработка событий, очередь сообщений, генерация innerHTML для 'Этот текст появится внутри тэга BODY' и других часто используемых в AJAX-е вещей.

Имхо - рискуешь в дальнейшем закопаться, хотя для обучающих целей, пример хороший.

P.S.: Кстати что планируешь делать с реакцией на кнопки браузера (вперед, назад, обновить, стоп).

Submitted by Victor on

Посылка событий будет реализована в виде множества DIV, которые шлют AJAX-запрос с кодом операции. По сути это вызов той же функции f1(), только надо добавить 1 параметр. Для отрисовки мира f1() вызывается таймером, а тут будет вызываться через событие onclick. Обработка реакции на команду не нужна, результат реакции будет визуализироваться функцией f1(), когда сработает таймер. Очередь сообщений не нужна. Механика игры такова, что за 1 тик (10 секунд) будет обрабатываться только самая последняя команда. Оно и удобно - если кликнул атаковать одного, а потом все-таки решил другого ударить, то надо просто кликнуть на новую цель.

Это конечно теория, как оно будет на самом деле - увидим во время бета-теста.

PS: Я уже проверил реакцию в IE8. "Вперед" неактивна. "Назад" возвращает на страницу регистрации/авторизации. "Обновить" просто перерисовывает содержимое фреймов с предварительным запросом на повторный посыл POST-данных, это не влияет на таймер отрисовки мира, потому что он завязан на часах на сервере. "Стоп" ничего не делает, страница же не перезагружается.

GameDev.by