Приветствую Вас Гость
Регистрация | Вход
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]

  • Главная страница
  • Форум (Новoe на форуме)
  • Быстрый старт
  • Блог
  • Видео уроки
  • Каталог файлов
  • Статьи и уроки
  • Юзербары
  • FAQ
  • Обратная связь
  • Для начинающих [9]
    Заморочки [4]
    Для немного понимающих 39длл [9]
    Сложный уровень [4]

    Онлайн всего: 1
    Гостей: 1
    Пользователей: 0

    [ Кто нас сегодня посетил ]
    Главная » Статьи » Статьи » Для начинающих

    Онлайн без DLL
    Я думаю многие когда нибудь хотели создать онлайн игру для большого количества игроков. Здесь я опишу как создать простую игру, состоящую из севера и клиента без использования каких либо dll библиотек и пакетов расширений. Для того что бы понять про что я тут буду писать, вы должны:

    1)Разбираться в gml
    2)Знать операторы if, for
    3)Понимать что такое сервер и клиент.

    Открываем game maker. Начнем создавать сервер.
    Итак для начала создайте объект controller и комнату rm_server, поставьте объект в комнату
    В событии создания напишите код:

    Gml:

    str=get_string('Введите IP адрес или пустую строку для игры по лок. сети','')
    if(!mplay_init_tcpip(str))
    {
    show_message('Невозможно установить TCP/IP соединение.')
    game_end()
    }

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

    Gml:

    if(mplay_session_create('',100,''))
    global.master = true
    else
    {
    show_message('Невозможно создать соединение.')
    game_end()
    }

    Следующий код проверяет возможность создания соединение, если оно возможно, то переменная global.master становится правдой. Эта переменная показывает сервер мы или нет. Если соединение невозможно – то выдаем ошибку и выходим из игры

    Gml:

    for(i=1 i<101 i+=1)
    global.players[i]=0

    Этим кодом мы заполняем массив players нулями, т.е. игроков на сервере нет.

    Gml:

    global.playernumb=0

    Устанавливаем количество игроков на 0.

    Gml:

    alarm[[0]=2

    Ставим таймер.

    Gml:

    global.serverid=mplay_player_id(0)

    И устанавливаем id сервера.

    Итак мы создали соединение и установили значение переменных

    В события таймера 0 напишем:

    Gml:

    for(i=1 i<101 i+=1)
    {
    if(global.players[i]=1)
    mplay_message_send(0,50,'global.players['+string(i)+']=1')
    }

    mplay_message_send(0,50,'global.playernumb='+string(global.playernumb))

    alarm[0]=2

    Мы отправляем игрокам данные о количестве игроков, и о массиве players.

    Теперь откроем game maker еще раз. Начем создавать клиента.
    Создадим объект controller и rm_client, поставим объект в комнату.
    В создании у объекта пишем:

    Gml:

    str=get_string('Введите IP адрес или пустую строку для игры по лок. сети','');
    if(!mplay_init_tcpip(str))
    {
    show_message('Невозможно установить TCP/IP соединение')
    game_end()
    }

    Подключаемся.

    Gml:

    if(mplay_session_find() > 0)
    {
    if(mplay_session_join(0,''))
    global.master = false
    else
    {
    show_message('Невозможно подключиться.')
    game_end()
    }
    }
    else
    {
    show_message('Некуда подключаться.')
    game_end()
    }

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

    Gml:

    mplay_message_send(0,101,mplay_player_id(0))

    Посылаем на сервер сообщение с индексом 101 и в текте сообщения записываем наш ид как клиента

    Gml:

    global.ind=0

    Устанавливаем наш индекс, как игрока на 0.

    Gml:

    for(i=1 i<101 i+=1)
    global.players[i]=0

    Задаем массив players

    Gml:

    global .playernumb=0
    global.serverid=0

    Устанавливаем ид сервера на 0 и количество игроков на 0.

    Откроем сервер.
    У объекта controller в событии шага пишем код:

    Gml:

    while(mplay_message_receive(0))
    {

    Проверям получены ли новые сообщения.

    Gml:

    if(mplay_message_id()=101)
    {
    var pl;
    pl=mplay_message_value()

    Если ид сообщения равен 101, то считываем текст сообщения в переменную pl, а в тексте сообщения записан ид игрока корый нам его отправил.

    Gml:

    for(i=1 i<101 i+=1)
    {
    if(global.players[i]!=0)
    mplay_message_send(pl,50,'global.players['+string(i)+']=1')
    }

    Массивом проверям есть ли другие игроки на сервере, если есть то отправляем сообщение, в котором написан код, котрый устанавливает массив players с определенным идексом на правду, то есть записываем что игрок с определенным индексом есть на сервере.

    Gml:

    mplay_message_send(pl,50,'global.playernumb='+string(global.playernumb))
    mplay_message_send(pl,50,'global.serverid='+string(mplay_player_id(0)))

    Тут мы отправляем сообщения с количеством игроков и ид сервера.

    Gml:

    for(i=1 i<101 i+=1)
    {
    if(global.players[i]=0)
    {
    global.players[i]=1
    global.playernumb+=1
    with(instance_create(32,32,player))
    ind=other.i
    mplay_message_send(pl,100,'global.ind='+string(i))
    mplay_message_send(0,175,i)
    exit;
    }
    }
    }
    }

    Этим массивом мы ищем свободный ид, если ид найден, то устанавливаем массив players с этим ид на 1 то есть игрок с таким индексом есть на сервере. Далее увеличиваем количество игроков на 1, создаем объект игрока на сервере и устанавливаем ему индекс на тот ид который мы нашли. Отправляем игроку сообщение с его индексом и отправляем всем игрокам сообщение с индексом этого игрока. У сообщений разные ид.

    Теперь снова клиент: создадим объекты player и otherplayer.
    В событии шага:

    Gml:

    while(mplay_message_receive(0))
    {

    Принимаем сообщения

    Gml:

    if(mplay_message_id()=50)
    execute_string(mplay_message_value())

    Если ид сообщения – 50 то просто выполняем код, который сервер записал в это сообщение(а сервер нам отправил 3 сообщения со своим ид, с количество игроков, и с массивом players)

    Gml:

    else
    if(mplay_message_id()=100)and(global.ind=0)
    {
    execute_string(mplay_message_value())
    instance_create(32,32,player)
    for(i=1 i<101 i+=1)
    {
    if(global.players[i]=1)and(global.ind!=i)
    {
    with(instance_create(32,32,otherplayer))
    ind=other.i
    }
    }
    }

    Если ид сообщения не 50, то если ид сообщения 100 и если наш индекс еще не установлен, то:
    Выполняем код, который записан в сообщении, а там записан код установления ид.
    Потом создаем объект игрока, которым мы будем управлять.
    Далее смотрим массив players, который был нам отправлен с сервера ранее, и создаем объекты otherplayer, которые показывают где стоят другие игроки. Устанавливаем объектам otherplayer индексы соответствующие индексам игроков, которые уже есть на сервере.

    Gml:

    else
    if(mplay_message_id()=175)
    {
    if(global.ind!=mplay_message_value())
    {
    with(instance_create(32,32,otherplayer))
    ind=mplay_message_value()
    }
    }

    Напоминание: в сообщении с ид 175 записан индекс игрока который только что присоединился.

    Итак нам приходит сообщение с ид 175, мы проверяем не равен ли индекс игрока который присоединился на сервер нашему индексу (т.е. если он равен, то мы и есть тот игрок который присоединился к серверу), если он не равен, то создаем otherplayer с индексом равным индексу этого игрока.

    Теперь нам надо сделать так, чтоб при выходе игрока из игры он удалялся из игры и на сервере и у всех клиентов.
    В событии game_end у контроллера пишем:

    Gml:

    mplay_message_send(global.serverid,201,global.ind)
    mplay_session_end()
    mplay_end()

    Мы посылаем на сервер сообщение с ид 201 и записываем в него наш индекс.
    Далее завершаем подключение.

    Заходим в сервер,
    Создадим скрипт scr_destroy, напишем в нем:

    Gml:

    with(player)
    {
    if(ind=argument0)
    instance_destroy()
    }

    Этот скрипт проверяет не равен ли индекс игрока аргументу 0, если равен то удаляем обьект.

    В событии шага у controller перед последней скобкой - } пишем:

    Gml:

    else
    if(mplay_message_id()=201)
    {
    global.players[mplay_message_value()]=0
    global.playernumb-=1
    scr_destroy(mplay_message_value())
    mplay_message_send(0,200,mplay_message_value())
    }

    Так как в начале кода, который написан в шаге мы проверяли равен ли ид принятого сообщения 101, то в этом коде мы смотрим, что если ид не равен 101 то равен ли он 201.

    Если он равен, то:
    Напоминание: в сообщение с ид 201 записан индекс игрока, вышедшего из игры
    Устанавливаем игрока с индексом, который записан в сообщение на 0, т.е игрок отключился. Уменьшаем число игроков посылаем клиентам сообщение с ид 200, в котром записан индекс вышедшего игрока.

    Так же мы выполняем scr_destroy с аргументом 0 который равен индексу этого игрока.

    Откроем клиента, создадим скрипт scr_destroy():
    Скрипт такой же как и в сервере, но вместо player пишем otherplayer

    В событии шага перед последней скобкой допишем код:

    Gml:

    else
    if(mplay_message_id()=200)
    {
    global.players[mplay_message_value()]=0
    global.playernumb-=1
    scr_destroy(mplay_message_value())
    }

    Работает также, как и на сервере. Удаляет игрока из массива, уменьшает число игроков, выполняет скрипт.

    Мы сделали возможность игрокам заходить на сервер и также выходить с него, и между игроками синхронизируются количество игроков и их индексы.

    Теперь добавим игрокам возможность двигаться, и синхронизировать свои координаты.
    Откроем клиента, у объекта player добавим движение(какое угодно, что бы изменялись координаты)
    В создании player установим таймер 0 на 2

    Gml:

    alarm[0]=2

    На событие сигнала 0 напишем код:

    Gml:

    mplay_message_send(global.serverid,151,'scr_playerlocation('+string(global.ind)+','+string(x)+','+string(y)+')')
    alarm[0]=2

    Код отправляет на сервер сообщение с ид 151 в, сообщении записан скрипт scr_playerlocation.

    Заходим в сервер. Создаем скрипт scr_playerlocation:

    Gml:

    with(player)
    {
    if(ind=argument0)
    {
    x=argument1
    y=argument2
    }
    }

    Мы проверяем у объектов player, равен ли их индекс аргументу 0 и тогда устанавливаем координаты на argument 1 и argument 2
    Работает это так: нам от клиента пришло сообщение с текстом: scr_playerlocation(1,25,45)
    Объект player с индексом 1 переместится в координаты 25,45.

    В шаге у controller, перед последней скобкой пишем:

    Gml:

    else
    if(mplay_message_id()=151)
    {
    execute_string(mplay_message_value())
    mplay_message_send(0,150,mplay_message_value())
    }

    Мы принимаем сообщение выполняем, то что там написано(а там написан scr_playerlocation) и отправляем это сообщение всем игрокам.

    И наконец заходим опять в клиент и добавляем scr_playerlocation, но вместо player пишем otherplayer.
    В шаге у объекта controller перед последней скобкой пишем код:

    Gml:

    else
    if(mplay_message_id()=150)
    {
    execute_string(mplay_message_value())
    }

    Вы выполняем то, что записано в сообщение, т.е скрипт scr_playerlocation

    Надеюсь я ничего не забыл Если все правильно сделаете то вы получите сервер к котрому могу присоединяться игроки.

    Да и вот ссылка на пример: http://rghost.ru/2335204

    Категория: Для начинающих | Добавил: ADSU1231 (15.09.2010)
    Просмотров: 1579 | Комментарии: 11 | Рейтинг: 5.0/2
    Всего комментариев: 10
    10  
    Там куча ошибок было, когда я еще только онлайн осваивал...

    9  
    http://www.filedropper.com/server-klient

    8  
    Написал бы в [code] GML, а то сплошным текстом читать херово!

    7  
    Исходник дайте пож , по ссылке файл удалеен)))

    6  
    блин. ADSU1231, тебе самому удобно читать такой код?
    http://gml2color.indented.net/index.php?page=html&action=process
    крась его здесь, через bb коды. Выделяй код
    Code
    [quote][/quote]

    Надо как-нибудь ввести обязательные требования к статьям по оформлению...


    5  
    Но играть только через хамачи

    4  
    Перезалейте, плиз, пример

    3  
    Я тоже когда-то этим занимался, когда ещё не подозревал о существование 39dll.

    2  
    Спс за положительный отзыв=)

    1  
    Я когда то занимался стандартным подключением, мне как то его мало было...
    Хорошая статья...

    Добавлять комментарии могут только зарегистрированные пользователи.
    [ Регистрация | Вход ]
    -->


    Логин:
    Пароль:

    Хостинг от uCoz