C++

Арена

Начал делать реализацию боев на арене с противником человеком.
Алгоритм делаю следующим:

  • Игрок заходит на арену, и если стэк заявок пуст, то регистрируется новая заявка
  • Если стэк заполнен - то двое переносятся в лабиринт
  • Далее думаю сделать следующую проверку - победителем будет тот, кто останется в лабиринте один, т.е. второй игрок (а может еще и третий с четвертым и пятым) может попросту выйти из лабиринта - и того победа засчитывается последнему.
    Ну и противника можно вывести из лабиринта против его воли :)

    Изменения в игровой механике - минимальные:

    Опыт

    - Погляди какой толстый монстр
    - Не-не, это просто кучка опыта

    Опыт приобретается путем истребления монстров и прочих путников в лабиринтах/аренах/подвалах.
    Чаще всего в различных играх - количество опыта необходимое для получения следующего уровня измеряется по логорифмической шкале.
    Что дает игрокам быстро получить первые уровни, и запас времени на получение высших уровней.
    А еще есть например такое, в Diablo II, за истребления монстров не своего уровня, количество опыта режется.

    Инвентарь. Заключительная часть

    В Flash передача оказалась (как и предполагалась) ерундовым делом:
    Кнопка, на кнопке onPress.
    on (press) {
    btn_apply._visible = false;
    var inv='';for(var i=0;i<_root.itemsList.length;i++) {
    var tmp = itemsList[i].id.toString(16);
    if (tmp.length<6) { var i=6-tmp.length; for(var j=0;j<i;j++) {tmp='0'+tmp;} }
    inv+=itemsList[i].place.toString(16)+tmp;
    }
    loadVariablesNum(_root.host+"/maze?action=set_inv&inv="+inv+"&sessionid="+_root.session,0);
    }

    Ну да в Flash'ку пришлось передавать host, ну думаю может и не надо.

    На стороне сервера :

    Загоняем монстров в XML

    А вернее изгоняем из исходного кода, в принципе "изгоняем монстров из исходного кода" звучит более брутально, да?
    На текущий момент у нас есть следующие структурки:

    TCreatureParams basicCreatureParams[TP_CREATURE_LAST + 1]=
    {
    {10,10,10,10,-1}, //human
    {5,20,10, 0,-1}, //spider
    };
    char *creaturesNames[TP_CREATURE_LAST + 1] = {"","Паук-мохнач"};

    а также кусок кода при вызова action = get_info (там char *nick = new char[ strlen(creaturesNames[c->Type])*6];URLencoding( convertToUtf8(creaturesNames[c->Type],strlen(creaturesNames[c->Type])).c_str(), nick);)

    Ответный удар

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

    В клиентской флэшке изменений по минимуму - в функции обработки мышки:
    Ранее было:
    if (tx==_root.heroX && ty==_root.heroY)
    _root.showBook(1);
    else
    _root.moveHero(tx, ty);

    стало:
    if (tx==_root.heroX && ty==_root.heroY)
    _root.showBook(1);
    else
    if (_root.enemySquare(tx,ty) && dx<=1 && dy<<1)
    _root.strikeHero(tx,ty);
    else
    _root.moveHero(tx, ty);

    Атака паука

    Собственно не только паука, а любого враждебного существа.
    Для ее реализации переписываем функцию bool computerTurnCreature(TMazeMap *m,int creatureid)
    {
    logaccess(16,"computerTurnCreature(%d)",creatureid);
    TMazeCreature *c = getCreature(m,creatureid);
    if (!c) return false;
    vector<TMazeCreature *> crt;
    if (findCreature(m,c,&crt)) {
    float iam = Fast_Distance( c->x,c->y);
    float min;
    int index=0;
    for(int i=0;i<(int)crt.size();i++) {
    float tmp=Fast_Distance(crt[i]->x,crt[i]->y) - iam;
    if (tmp<0) tmp*=-1.0;
    if (i==0) min=tmp;

    И тут пришел паук

    Почти как в фильме, паука нарисовал не я – а неплохой художник ForEveR aka Сергей, причем совершено добровольно, за это ему респект и уважуха.

    И собственно было решено паучка протестить его и запустили в маленький лабиринт с игроком. Тут возникла проблема номер №1, для тестовой арены генерился маленький лабиринтик 10x10, и он не сгенерился, загружая проц на 90-100% комп задумался.

    Правки

    Избавился от пересчета нужно ли обновлять карту – теперь при открытии карты с сервера, запоминаются координаты, что с этого положения карта уже запрашивалась.
    Пометка сохраняется в массиве watchmap.

    На сервере связи с этим сделал, чтобы карта открывалась только по обозреваемой территории – алгоритм тут.

    Интеграция

    Нарисовал героя и даже сделав для него анимацию, попытался прикрутить его в основной проект.
    Для начала пришлось все-таки переписать загрузчик для SWF, теперь он сразу создает нужный клип, название которого приходит ему качестве параметра: function loadclipfromserver(path, loadname,nameclip).

    Затем пришлось в структуру(объект) creature добавить mcname,dx,dy,и все другие параметры для анимации
    Теперь в функции moveCreature не сразу присваиваются _x и _y, а выполняется ряд действий (может и избыточных, но пока нужных)

    Устанавливаем ловушки и мелкие правки

    Сократил массив city_mazeid[] который указывал на города на карте мира, теперь
    и города и лабиринты хранятся в структуре world_mazeid, но города имеют id меньше чем MAX_CITYID,
    а лабиринты больше. Зачем придумывал два массива мне сейчас и непонятно.

    Связи с изменениями слегка поправился код в int makeMaze(int width,int height,int *id,char *data,int wx,int wy,char *dmap)

    Также поправил код makeAction(TMazeMap *m,int creatureid,int what,int *ap),
    теперь после хода существа (действия ACT_STEP_*) вызывается checkForObject(TMazeCreature *c,TMazeMap *m) - т.е.

    RSS-материал