Пятница, 19 Апреля 2024, 03:05

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Форум игроделов » Конструкторы игр и лёгкие в освоении системы разработки игр » Game Maker » Принятие координат клиентами(39dylib)
Принятие координат клиентами(39dylib)
zzzzzaДата: Среда, 19 Июня 2013, 02:01 | Сообщение # 1
участник
Сейчас нет на сайте
Сделал передачу координат от клиента серверу и от сервера всем остальным клиентам. Проблема заключается в том, что приходят эти координаты c большим запозданием(приходят другим клиентам. На сервер все передается без тормозов), причем, как я заметил, тому кто подключился последним, приходят быстрее. Попытался избавиться от всех возможных циклов, остался только один - отвечающий за отправку координат каждому клиенту. Может быть из-за этого цикла, но я думаю вряд ли. Потом узнал про алгоритм Нейгла(Nagle's algorithm), нашел какой функцией его можно отключить("setnagle(client, false)"), но все равно не помогло, лично я разницы не заметил, но возможно я что-то не правильно сделал.
Если есть мысли в чем может быть проблема, пишите.
BasicMMORPG, как пример не давайте))


Сообщение отредактировал zzzzza - Среда, 19 Июня 2013, 02:46
royalfintДата: Среда, 19 Июня 2013, 09:30 | Сообщение # 2
частый гость
Сейчас нет на сайте
ты нам код покажи чтоли как узнать где там у тебя дырка
zzzzzaДата: Среда, 19 Июня 2013, 22:45 | Сообщение # 3
участник
Сейчас нет на сайте
server-obj_system-step:
Код
     case 6:
       //Ïðèíèìàåì êîîðäèíàòû êëèåíòà.
       ini_open('register.ini');
       k = ini_read_real('K','k', '');
       name=readstring(0);
       for(iii=0;iii<=k;iii+=1)
        {
         if (name=ini_read_string('Name','name'+'['+string(iii)+']',''))
          {
           player_id=ini_read_real('ID','id'+'['+string(iii)+']','');
           player_id.x=readshort(0);
           player_id.y=readshort(0);
               clearbuffer(1);
               writebyte(7,1);
               writestring(name,1);
               writeshort(player_id.x,1);
               writeshort(player_id.y,1);
               send_to_all_but_one(current_client);
           iii=k;
          }
        }
        ini_close();
        clearbuffer(0);
      break;

Отправка координат всем клиентам вот:
Код
              clearbuffer(1);
               writebyte(7,1);
               writestring(name,1);
               writeshort(player_id.x,1);
               writeshort(player_id.y,1);
               send_to_all_but_one(current_client);


client-obj_system-step:
Код
   case 7:
     if (room_r[1]=1)
      {
       take_player_name=readstring(0);
       for(i=0;i<=number_other_player;i+=1)
        {
         if (take_player_name!=player_name[i+1]) and (i=number_other_player)
          {
           player_name[i+2]='';
           player_name[i+1]=take_player_name;
           other_player_id[i+1]=global.max_id+1;
           instance_create(0,0,obj_other_player);
           other_player_id[i+1].x=readshort(0);
           other_player_id[i+1].y=readshort(0);
          }
         if (take_player_name=player_name[i+1])
          {
           other_player_id[i+1].x=readshort(0);
           other_player_id[i+1].y=readshort(0);
           i=number_other_player;
          }
        }
      }
     clearbuffer(0);
    break;

Добавлено (19.06.2013, 22:45)
---------------------------------------------
Если пояснить что нужно, то говорите)

XDominatorДата: Четверг, 20 Июня 2013, 12:19 | Сообщение # 4
постоянный участник
Сейчас нет на сайте
Подозреваю что у тебя просто напросто за 1 степ обрабатывается 1 клиент. А они должны обрабатываться в цикле, все за 1 степ. Учитывая такой симптом что первым приходят быстрее пакеты - я прав с 95%-ной вероятностью. Кури степ отправки, сравнивай с тем же мморпг - ищи 5 отличий. Все это мое субъективное мнение, и не есть истина в последней ипостаси.

Ghaarp

The soul lighter(Android, logic)

Zzzzombie RAGE!!!(For android)
zzzzzaДата: Четверг, 20 Июня 2013, 14:50 | Сообщение # 5
участник
Сейчас нет на сайте
XDominator, так у меня же вроде все клиенты обрабатываются за 1 шаг.
Код
     case 6:  
        //Ïðèíèìàåì êîîðäèíàòû êëèåíòà.  
        ini_open('register.ini');  
        k = ini_read_real('K','k', '');  
        name=readstring(0);  
        for(iii=0;iii<=k;iii+=1)  
         {  
          if (name=ini_read_string('Name','name'+'['+string(iii)+']',''))  
           {  
            player_id=ini_read_real('ID','id'+'['+string(iii)+']','');  
            player_id.x=readshort(0);  
            player_id.y=readshort(0);  
                clearbuffer(1);  
                writebyte(7,1);  
                writestring(name,1);  
                writeshort(player_id.x,1);  
                writeshort(player_id.y,1);  
                send_to_all_but_one(current_client);  
            iii=k;  
           }  
         }  
         ini_close();  
         clearbuffer(0);  
       break;

Добавлено (20.06.2013, 14:43)
---------------------------------------------
XDominator, ааа, я кажется понял в чем ошибка. Надо вот эту часть

Код
                clearbuffer(1);   
                 writebyte(7,1);   
                 writestring(name,1);   
                 writeshort(player_id.x,1);   
                 writeshort(player_id.y,1);   
                 send_to_all_but_one(current_client);  
вынуть из условия, но оставить в цикле))
Сейчас попробую)

Добавлено (20.06.2013, 14:50)
---------------------------------------------
Сделал во так:

Код
     case 6:
       //Ïðèíèìàåì êîîðäèíàòû êëèåíòà.
       ini_open('register.ini');
       k = ini_read_real('K','k', '');
       name=readstring(0);
       for(iii=0;iii<=k;iii+=1)
        {
         if (name=ini_read_string('Name','name'+'['+string(iii)+']',''))
          {
           player_id=ini_read_real('ID','id'+'['+string(iii)+']','');
           player_id.x=readshort(0);
           player_id.y=readshort(0);
           iii=k;
          }
        }
               clearbuffer(1);
               writebyte(7,1);
               writestring(name,1);
               writeshort(player_id.x,1);
               writeshort(player_id.y,1);
               send_to_all_but_one(current_client);
        ini_close();
        clearbuffer(0);
      break;

стало побыстрее, но все равно есть задержка примерно в 3 секунды(2 клиента).
Надо еще что-нибудь придумать:)
XDominatorДата: Четверг, 20 Июня 2013, 15:24 | Сообщение # 6
постоянный участник
Сейчас нет на сайте
ты приводишь только код одного кейса. Та ошибка которую я тебе описал, не может быть в кейсе, если я прав то она находится части, которая располагается НАД ВСЕМИ кейсами smile

Ghaarp

The soul lighter(Android, logic)

Zzzzombie RAGE!!!(For android)
zzzzzaДата: Пятница, 21 Июня 2013, 16:12 | Сообщение # 7
участник
Сейчас нет на сайте
XDominator, теперь понял про что ты.
Создал еще один шаг(он без кейса), но все равно ничего не изменилось.

Добавлено (20.06.2013, 21:58)
---------------------------------------------
XDominator,
Выглядит новый код так же:

Код
                clearbuffer(1);    
                  writebyte(7,1);    
                  writestring(name,1);    
                  writeshort(player_id.x,1);    
                  writeshort(player_id.y,1);    
                  send_to_all_but_one(current_client);  

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

Добавлено (21.06.2013, 16:12)
---------------------------------------------
XDominator, наконец-то доперло как правильно сделать, только проблема появилась:)
Почему-то сообщение из server-obj_player-alarm[0] отправляться не хочет, хотя из server-obj_system-'любое событие' отправляется. Из client-'любой объект'-'любое событие' все прекрасно отправляется.
Часа полтора пытался выяснить в чем проблема, но так и не понял(

XDominatorДата: Пятница, 21 Июня 2013, 17:45 | Сообщение # 8
постоянный участник
Сейчас нет на сайте
вообще то что ты используешь отправку в аларм-ивенте это немного странно, потому что это само по себе задает задержку...Но раз уж тебе действительно так надо и ты в упор не понимаешь в чем дело - то просто попробуй обойти проблему. Скажем вместо кода отправки в аларме, пропиши просто а=0, а потом в любом степе пиши что то вроде:

Код

if a = 1
{
   a = 0
   //Код отправки
}


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

Приведи проблемный код полностью, с первой строки. Ты копируешь непосредственно код отправки, а дело не в самом коде отправки, а втом как ты вообще на этот код выходишь.


Ghaarp

The soul lighter(Android, logic)

Zzzzombie RAGE!!!(For android)
zzzzzaДата: Воскресенье, 23 Июня 2013, 01:53 | Сообщение # 9
участник
Сейчас нет на сайте
XDominator, Я отправку сначала в степ игрока написал, но после запуска, сервер не отвечал, пришлось в будильник засунь.
С блокиратором(а=0), это понятно, но я не хочу так делать.
Алгоритм, который пришел мне в голову, на мой взгляд самый удобный и простой, но появилась эта проблема. Я еще поколдую, может получится)
Я по другому написал, по сравнению с предыдущими кодами. Как пример, отправка теперь не в obj_system-step-'case...', а в будильнике obj_player.
Я тебе исходник попозже в личку кину, может поймешь в чем дело.

Добавлено (23.06.2013, 01:53)
---------------------------------------------
Попробовал вставить вот этот код:
Код
clearbuffer(1);
writebyte(7,1);
writeshort(id,1);
writeshort(x,1);
writeshort(y,1);
send_to_all();

в нажатие мыши на obj_player, все передалось.
Если в будильник ставлю, то, то что в будильнике, выполняется один раз(в будильнике в конце стоит alarm[0]=1), не знаю почему так(
Если в шаг запихнуть, то сервер не отвечает(
В чем может быть проблема?


Сообщение отредактировал zzzzza - Воскресенье, 23 Июня 2013, 01:55
XDominatorДата: Понедельник, 24 Июня 2013, 08:55 | Сообщение # 10
постоянный участник
Сейчас нет на сайте
У тебя отправка происхоидт не в аларме, а в скрипте send_to_all(). Приведи его.

Попутно, приведи код, где у тебя конкретно вот этот кусок вызывается.

Добавлено (24.06.2013, 08:55)
---------------------------------------------
Исходники вечером поковыряю если будет время...


Ghaarp

The soul lighter(Android, logic)

Zzzzombie RAGE!!!(For android)
zzzzzaДата: Вторник, 25 Июня 2013, 15:19 | Сообщение # 11
участник
Сейчас нет на сайте
Код
var i;
for (i=0;i<ds_list_size(client_list);i+=1)
  {
   sendmessage(ds_list_find_value(client_list,i),0,'',1);
  }

Добавлено (25.06.2013, 15:19)
---------------------------------------------
Наконец-то нашел ошибку:

Код
writeshort(id,1);

А заключается она в том, что во writeshort можно записывать значения от -32768 до +32767, а все id больше 100000 smile


Сообщение отредактировал zzzzza - Понедельник, 24 Июня 2013, 13:08
XDominatorДата: Вторник, 25 Июня 2013, 18:31 | Сообщение # 12
постоянный участник
Сейчас нет на сайте
Самое интересное, что по сути то иды ты должен задавать свои, а не использовать программные...Очень советую тебе от этой системы избавиться.

Ghaarp

The soul lighter(Android, logic)

Zzzzombie RAGE!!!(For android)
zzzzzaДата: Среда, 26 Июня 2013, 02:44 | Сообщение # 13
участник
Сейчас нет на сайте
XDominator, У меня система своя. Заключается в том, что в клиентах и в сервере каждый шаг вычисляется максимальный id существующий в игре и когда присоединяется игрок, ему присваивается максимальный id + 1 и потом создается объект с этим же id.
Ну надеюсь ты понял:D

Добавлено (26.06.2013, 02:44)
---------------------------------------------
XDominator, Сделал передачу клиентам по-другому(не как в начале писал). Теперь сервер отправляет координаты всем клиентам(кроме одного, понятно какого) каждый шаг. И клиенты принимают их:

Код
   case 7:
     if (room_r[1]=1)
      {
       other_player_id=readshort(0);
       if (create[other_player_id]=false)
        {
         player=instance_create(0,0,obj_other_player);
         players_id[other_player_id]=player;
         player.name=players_name[other_player_id];
         create[other_player_id]=true;
        }
         else
        {
         player=players_id[other_player_id];
         player.x=readshort(0);
         player.y=readshort(0);
        }
      }
     clearbuffer(0);
    break;

. Избавился от всех циклов и на сервере и в клиентах, но почему-то в этом варианте тоже есть приличная задержка. Почему, даже представить не могу(
Для пробы сделал так:
Код
        else
        {
         show_message('УРА');
         player=players_id[other_player_id];
         player.x=readshort(0);
         player.y=readshort(0);
        }

то есть вставил show_message. При запуске, show_message приходит постоянно(меньше секунды), то есть задержки никакой. А вот присвоение координат почему-то с задержкой, хотя идет на следующих строчках.
Есть конечно вариант почему это может происходить(только что в голову пришел:D). Перенесу этот код в шаг obj_other_player.
XDominator, У тебя есть какие-нибудь мысли?
XDominatorДата: Среда, 26 Июня 2013, 09:14 | Сообщение # 14
постоянный участник
Сейчас нет на сайте
Во первых, предлагаю тебе не перемешивать теплое с мягким, и отделить id гроков от идов их объектов на сервере. Эти иды нужны не только на сервере, но и на клиенте, и перебираются все игроки по идам от 0 до n.

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


Ghaarp

The soul lighter(Android, logic)

Zzzzombie RAGE!!!(For android)
zzzzzaДата: Среда, 26 Июня 2013, 14:08 | Сообщение # 15
участник
Сейчас нет на сайте
XDominator, ахаха, ок:D
Форум игроделов » Конструкторы игр и лёгкие в освоении системы разработки игр » Game Maker » Принятие координат клиентами(39dylib)
  • Страница 1 из 1
  • 1
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг