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 |
|
| |