| mehanic | Дата: Четверг, 09 Июля 2015, 14:01 | Сообщение # 1 |  
 
был не раз 
Сейчас нет на сайте 
 
 | Читаем ниже.   
   Добавлено (09 июля 2015, 14:01)   ---------------------------------------------   Решил переписать эту статью ещё и сюда.:)   2 часть - 3 часть на другом сайте(примеры тут же) - 4 часть на другом сайте(примеры тут же)   Всем привет, если вы знаете больше половины отсюда Справка GAME MAKER онлайн то продолжаем читать, давно хотел написать статью на тему создания мультиплеера в гмс, ДЛЯ ПОЛУПРОФИ, ну вообщем наконец руки до этого дошли... Смотрим и делаем. 
   Мультиплеер в GMS #1 Основы, сервер и клиент. 
   Приступаем. В сервере и в клиенте создаём спрайт spr_player в котором будут два квадратика размером 32x32 пикселя залитые красным, а другой зелёным цветом, ставим центр. Теперь создаём объект и в сервере и в клиенте obj_player которому присваиваем созданный раньше спрайт, и объект и в сервере и в клиенте obj_controller в котором будут происходить основные события. sm:cool На всякий случай добавим в наш проект в сервер и в клиент шрифт с диапазоном от 1 до 1105 и назовём его font_text. 
   Приступаем к самому интересному, кодингу. 
   СЕРВЕР: obj_controller в Create:   Код Server = network_create_server( network_socket_tcp , 63258 , 32 );//создаём сам сервер(тип советую использовать как тут, порт, максимум игроков)   Buffer = buffer_create( 1024 , buffer_fixed , 1 );//создание буфера(размер, размер не меняется, тут не знаю...)   SocketList = ds_list_create();//сюда будем заносить всех игроков   global.max_players=0//всего игроков было на сервер      
   СЕРВЕР: obj_controller в Asynchronouos в Networking:   Код                   var type_event = ds_map_find_value( async_load , "type" );/*получаем тип пришедших данных, в данном случаи это network_type_connect и другие...*/                               switch( type_event ) {                     case network_type_connect://если игрок вошёл...                        var socket = ds_map_find_value( async_load , "socket" );//получаем его сокет                        ds_list_add( SocketList , socket );//заносим новый сокет в наш лист                     break;                     case network_type_disconnect://если игрок вышел...                        var socket = ds_map_find_value( async_load , "socket" );                        var findsocket = ds_list_find_index( SocketList , socket );//получаем индекс сокета из нашего списка который пришёл                                                 if ( findsocket >= 0 ) {//если есть...                           ds_list_delete( SocketList , findsocket );//удаляем                        }                     break;                     case network_type_data://если пришли данные...                        var buffer = ds_map_find_value( async_load , "buffer" );//получаем буффер                        var socket = ds_map_find_value( async_load , "id" );//получаем айди сокета                        buffer_seek( buffer , buffer_seek_start , 0 );/*ставим курсор в начало буфера(буффер, отсчитывать с начала буффера, отступаем с начала 0 знаком)*/                        ReceivedPacket( buffer , socket );//скрипт который принимает два аргумента, сейчас займёмся...                     break;                  }      
   СЕРВЕР: Создадим скрипт ReceivedPacket:   Код                   var buffer = argument[ 0 ];//всё понятно                  var socket = argument[ 1 ];                  var msgid = buffer_read( buffer , buffer_u8 );//читаем из buffer байт, который может быть от 0 до 255                  switch( msgid ) {                     case 1://если байт который мы прочитали равен 1, то...                        global.max_players+=1//всего игроков было на сервере увеличиваем на один                        buffer_seek( Buffer , buffer_seek_start , 0 );//уже писал выше                        buffer_write( Buffer , buffer_u8 , 1 );/*записываем в Buffer значение 1(значение должно быть уникальным для разных данных, допустим что бы отправить координаты надо будет писать 2, а что бы получить ник игрока 3 и т.д) и указываем что оно от 0 до 255 (ниже приведу таблицу из справки GM:S)*/                        buffer_write( Buffer , buffer_u16,  global.max_players);//записываем уникальный айди для клиента в будущем                        network_send_packet( socket , Buffer , buffer_tell( Buffer ) );/*отправляем буффер клиенту который послал запрос на получение этих данных (собственно сам игрок, буффер, размер отправляемого буффера). Отправляет клиенту уникальный айди*/                     break;                  }      
   Так... выключение сервера...   СЕРВЕР: obj_controller в Other в Game End:   Код                   network_destroy( Server );//собственно выключить наш сервер                  buffer_delete( Buffer );//удалить буффер                  ds_list_destroy( SocketList );//удалить лист с пользователями      
   Добавим пожалуй немного статистики: количество игроков на сервере, сколько всего было игроков на сервере и был ли создан сервер.   СЕРВЕР: obj_controller в Draw:   Код                   draw_set_font(font_text);                  draw_set_color( c_white );                  draw_text( 16 , 16, "Сервер создан: " + string( Server >= 0 ) );                  draw_text( 16 , 32, "Сейчас на сервере игроков: " + string( ds_list_size( SocketList ) ) );                  draw_text( 16 , 48, "Всего было игроков на сервере: " + string( global.max_players) );      
   Хух... устал... а мы закончили только сервер... приступаем к клиенту... :facepalm_2: 
   КЛИЕНТ: obj_controller в Create:   Код                   ip=get_string("Айпи: ","127.0.0.1");                  Socket = network_create_socket( network_socket_tcp );//создаём наш сокет                  isConnected = network_connect( Socket , ip , 63258 );//подключаемся к серверу                  Buffer = buffer_create( 1024 , buffer_fixed , 1 );//уже проходили.:)                  global.myid=0//наш уникальный в будущем айди клиента                  alarm[0]=2//надо ставить, что бы работало.:)                  Result=0//проверка на подсоединение к серверу      
   КЛИЕНТ: obj_controller в Alarm0:   Код                    buffer_seek( Buffer , buffer_seek_start , 0 );                   buffer_write( Buffer , buffer_u8 , 1 );//записываем в буфер, тут уникальный айди(значение) тоже один, так как отсылаем уже серверу                   Result = network_send_packet( Socket , Buffer , buffer_tell( Buffer ) );/*отсылаем информацию серверу, что бы он прислал нам наш уникальный айди.*/      
   КЛИЕНТ: obj_controller в Asynchronouos в Networking:   Код    var type_event = ds_map_find_value( async_load , "type" );                  switch( type_event ) {                     case network_type_data:                        var buffer = ds_map_find_value( async_load , "buffer" );                        buffer_seek( buffer , buffer_seek_start , 0 );                        ReceivedPacket( buffer );                     break;                  }      
   КЛИЕНТ: Создадим скрипт ReceivedPacket:   Код    //получаем и присваиваем наш уникальный айди                  var buffer = argument[ 0 ];                  var msgid = buffer_read( buffer , buffer_u8 );                  switch( msgid ) {                     case 1:                        global.myid = buffer_read( buffer , buffer_u16 );                     break;                  }      
   Конец игры...   КЛИЕНТ: obj_controller в Other в Game End:   Код                   network_destroy( Socket );                  buffer_delete( Buffer );      
   Создался ли клиент выводим информацию...   КЛИЕНТ: obj_controller в Draw:   Код                  draw_set_font(font_text)                 draw_set_color(c_white);                 draw_text(16, 16, "Присоединён: " + string( Result >= 0 ) );                 draw_text(16, 32, "Мой айди: "+string(global.myid))      
   buffer_u8 - положительные числа от 0 до 255   buffer_s8 - число от -128 до 127   buffer_u16 - положительные числа от 0 до 65535   buffer_s16 - число от -32768 до 32767   buffer_u32 - положительные числа от 0 до 4294967295   buffer_s32 - число от -2147483648 до 2147483647   buffer_f32 - число от -16777216 до 16777216 с плавающей запятой(например число 643,32)   buffer_f64 - число с плавающей запятой от -(2^52) до (2^52)-1   buffer_bool - логическое значение, может быть только 1 или 0 (истина или ложь)   buffer_string - текстовая строка не ограниченная размером бит 
   Создаём комнаты на сервере и клиенте под названием Test_Room, ставим размеры 480х480 и ставим в них объект obj_controller.   ТЕСТИРУЕМ!!! 
   Пишем недочёты, ошибки, и стоит ли продолжать... А то замучался. sm:) Насчёт obj_player не беспокоимся... просто на дальнейший урок сделали, если вам он будет нужен.;] Может кому-то да понадобится такое.:) если нужно ещё больше помощи, смотрим небольшая справка по GM:S networking 
   P.s. За основу взял какой-то пример который нашёл... забыл где, что бы всё не переписывать.Х) Но вроде авторские права не нарушает...
  http://forum.hellroom.ru/index.php?topic=21720   Мультиплеер GMS(Game Maker Studio networking) туториал на русском создание игры:}
 
 Сообщение отредактировал mehanic - Вторник, 28 Июля 2015, 20:30  |  
| 
 | 
 |    |