Насколько я понял, все удовольствие от игры получаешь, когда пишешь для нее бота. Для этого я выбрал один из самых своих любимых языков — javascript. Также я решил визуализировать карту, чтобы видеть как мои кораблики летают и захватываюи вражеские планеты. Много кода и SQL запросов я приводить не буду чтобы не раздувать статью, вы всегда можете посмотреть их в репозитории.
Алгоритм поведения бота я выбрал очень простой — построить добытчиков, построить захватчиков, и когда захватчиков станет достаточно — лететь захватывать. Еще, по ходу, строятся инженеры, которые ремонтируют корабли и, если хватает денег, я провожу апгрейд флота.
С самого начала я решил по минимуму использовать сторонние библиотеки. Итак, сначала устанавливаем соединение с базой.
var config = require('./config.js'); // Postgres connection var pg = require('pg'), conn = "pg://"+config.username+":"+config.password+"@db.schemaverse.com:5432/schemaverse"; var UserModel = require('./models/user'); var CommandProcessor = require('./command_processor'); pg.connect(conn, function(err, client) { if (!err){ var userModel = new UserModel.constructor(client); CommandProcessor(userModel); } else { console.log(err); } });
После установки соединения инициализируется пользователь и чтобы можно было смотреть некоторую статистику в консоле и запускать визуализатор я добавил обработчик команд.
При инициализации пользователя собирается информация о его планетах. Посройка добытчиков/захватчиков/инженеров производит каждая планета сама для себя. А заправка/апгрейд для всех кораблей.
Это пошаговая стратегия, причем зависимость длительности хода я так и не смог проследить. Поэтому я проверяю, завершился ли ход, в зависимости от длительности предыдущего хода. В начале нового хода, проверяется состояние кораблей и вызываются обработчики, что подписались на событе «tic». Информация о захвате новой планеты получается из списка ивентов. Для того, чтобы захватить планету достаточно успешно добыть из нее топливо. Это единственный ресурс игры. Также при каждом ходе поправляется курс и скорость всех летящих кораблей.
При захвате новой планеты, она добавляется в список планет и подписывается на событие «tic».
var tick = function(){ repair_damaged(); create_miners(); create_attackers(); go_to_conqueror(); } //constructor user.on(tick);
Следить за всем этим по выводу консоли не очень интересно. Я добавил модуль CommandProcessor с помощью которого можно в любой момент проверить состояние игры. В любой момент можно расширить список поддерживаемых команд. Но более подробно я хочу расказать о визуализаторе и о проблемах, с которыми мне пришлось столкнутся.
После ввода команды «map» первым делом создаются веб и websocket серверы.
var app = require('http').createServer(handler), io = require('socket.io').listen(app, { log: false });
Визуализатор также подписывается на событие «tic» и передает сообщение клиентам, что можно обновить карту.
По сути веб-сервер нужен только для передачи статики, тоесть websocket клиента.
Существующие визуализаторы отображают только общую карту. Моей же целью было отображение, также, флота.
Выглядит это примерно так:
Я сделал при приближении кружочки планет больше, потому что они закрывались кораблями.
В наибольшем масштабе карта очень долго обновляется. Если ее перемещать или увеличивать тоже приходится долго ждать. Я не обновляю карту при каждом чихе, а жду, пока пользователь введет новые желаемые координаты. Карта реагирует на колесо мыши и перемешение. Клиент передает степень увеличения, смещение и размер требуемого рисунка. Сервер, на основе этих данных, запрашивает с базы обьекты, рисует их на canvas и передает обратно клиенту.
get_map_base64( data.x, data.y, data.w, data.h, data.zoom, data.render_planets, data.render_ships, function(img){ socket.emit('draw', img); } );
В теории сервер может рисовать только корабли или только планеты, но я пока это не использую.
Можно было оптимизировать скорость обновления карты, если: хранить список планет локально и изменять отдельние планеты по событию «conquer», и если брать не все карты из базы, а разбить на квадраты и брать по одной с квадрата.
Но их очень много чтобы хранить локально, я решил сэкономить память, а если брать по одной с квадрата, то при большом масштабе можно не увидеть свою начальную планету. Поэтому я решил пока не оптимизировать процес. К тому же, при большом увеличении все обновляется довольно быстро.
Ссылка за репозиторий проекта — https://github.com/peinguin/schemaverse_bot
ссылка на оригинал статьи http://habrahabr.ru/post/195322/
Добавить комментарий