Инструменты пользователя

Инструменты сайта


lm3:ce:t_godot_multiplayer

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
lm3:ce:t_godot_multiplayer [2020/12/03 20:32]
ruben
lm3:ce:t_godot_multiplayer [2020/12/04 14:48] (текущий)
ruben
Строка 65: Строка 65:
  
 Запрос присвоения типа (3D / VR): Запрос присвоения типа (3D / VR):
-%%(lua)+<code lua>
 { "clients" = { "type" : <type:string> } } { "clients" = { "type" : <type:string> } }
 </code> </code>
Строка 91: Строка 91:
 *<data> различается для 3D и VR *<data> различается для 3D и VR
  
 +==== Файловая структура проекта ====
 +
 +{{ :lm3:ce:godot_mp_files.png?direct |}}
 +
 +==== Взаимосвязи ====
 +
 +Объекты основной логической машины:
 +  * TCP-server server: прием и передача данных клиенту
 +  * DataPack packer: распаковка и запаковка данных клиенту
 +  * Clients clients: взаимодействие клиентов
 +
 +Диаграмма связей:
 +
 +{{ :lm3:ce:godot_mp_lm.png?direct |}}
 +
 +==== Скрипты ====
 +
 +**main / start.lua**
 +
 +<code lua>
 +lm3:Include("mp_lib.lua")
 +lm3:LoadLibrary( {Alias = "sys", FileName = "lm3system"} )
 +
 +lm3:CreateLObject( { LibAlias = "sys", Type = "TCPServer", Name = "server" } )
 +server:SetAttr("SocCount", lmconf.MaxClientCount)
 +server:SetAttr("Port", lmconf.TCPVRPort)
 +
 +lm3:CreateLObject( { LibAlias = "sys", Type = "DataPack", Name = "packer" } )
 +packer:SetAttr("BufCount", lmconf.MaxClientCount)
 +
 +init_Clients("clients")
 +
 +init_Telemetry("telemetry")
 +
 +-- связи объектов
 +server:Connect("OnConnect", "clients", "DoConnect")
 +server:Connect("OnDisconnect", "clients", "DoDisconnect")
 +server:Connect("OnIncoming", "packer", "DoUnpack")
 +packer:Connect("OnPack", "server", "DoSend")
 +clients:Connect("OnSend", "packer", "DoPackTagged")
 +
 +-- распределим данные
 +packer:AddHandler("OnUnpack", function(o, ev)
 +    for obj_name, obj_data in pairs(ev.Data) do
 +        if obj_name == "clients" then
 +            for attr_name, attr_value in pairs(obj_data) do
 +                if attr_name == "Type" then
 +                    clients:Type( { Tag = ev.Tag, Type = attr_value} )
 +                end
 +            end
 +        elseif obj_name == "telemetry" then
 +            clients:Telemetry( {Tag = ev.Tag, Data = obj_data} )
 +        end
 +    end
 +end)
 +</code>
 +
 +**main / mp_lib.lua**
 +
 +<code lua>
 +function init_Clients(_name)
 +    local obj = lm3:CreateObject( { Type = "Base", Name = _name } )
 +
 +    -- структура данных о клиентах
 +    obj.ClientList = {}
 +    for i = 1, lmconf.MaxClientCount do
 +        obj.ClientList[i] = {
 +            isConnected = false,
 +            Type = ""
 +        }
 +    end
 +
 +    -- подключение клиента
 +    obj:AddInEvent("DoConnect", "int", function(o, ev)
 +        lm3:Log("New client connected:"..tostring(ev))
 +
 +        obj.ClientList[ev].isConnected = true
 +        obj.ClientList[ev].Type = "NA"
 +
 +        local sendData = { }
 +        local needSend = false
 +        for i = 1, lmconf.MaxClientCount do
 +            if i ~= ev and obj.ClientList[i].isConnected == true then
 +                sendData["Player"..tostring(i)] = { Type = obj.ClientList[i].Type  }
 +                needSend = true
 +            end
 +        end
 +
 +        if needSend == true then
 +            obj:OnSend( { Tag = ev, Data = sendData } )
 +        end
 +    end)
 +
 +    -- отключение клиента
 +    obj:AddInEvent("DoDisconnect", "int", function(o,ev)
 +        lm3:Log("Client disconnected:"..tostring(ev))
 +        obj.ClientList[ev].isConnected = false
 +        local sendData = { }
 +        sendData["Player"..tostring(ev)] = { Type = "NA"  }
 +        for i = 1, lmconf.MaxClientCount do
 +            if obj.ClientList[i].isConnected == true then
 +                obj:OnSend( { Tag = i, Data = sendData } )
 +            end
 +        end
 +    end)
 +
 +    -- присвоение типа
 +    obj:AddInEvent("Type", "table[Tag:int,Type:string]", function(o, ev)
 +        if obj.ClientList[ev.Tag].isConnected == true then
 +            obj.ClientList[ev.Tag].Type = ev.Type
 +            local sendData = { }
 +            sendData["Player"..tostring(ev.Tag)] = { Type = ev.Type  }
 +            -- lm3:Log("Set player type:"..lm3:DataToString(sendData))
 +            for i = 1, lmconf.MaxClientCount do
 +                if i ~= ev.Tag and obj.ClientList[i].isConnected == true then
 +                    obj:OnSend( { Tag = i, Data = sendData } )
 +                end
 +            end
 +        end
 +    end)
 +
 +    -- присвоение положения
 +    obj:AddInEvent("Telemetry", "table[Tag:int,Data:any]", function(o, ev)
 +        local sendData = {}
 +        sendData["Player"..ev.Tag] = ev.Data
 +        for i = 1, lmconf.MaxClientCount do
 +            if i ~= ev.Tag and obj.ClientList[i].isConnected == true then
 +                obj:OnSend( { Tag = i, Data = sendData } )
 +            end
 +        end
 +    end)
 +
 +    obj:AddOutEvent("OnSend", "table[Tag:int,Data:any]")
 +
 +    return obj
 +end
 +
 +function init_Telemetry(_name)
 +    local obj = lm3:CreateObject( { Type = "Base", Name = _name } )
 +
 +
 +    return obj
 +end
 +</code>
 +
 +==== Скриншоты ====
 +
 +С пультом управления:
 +
 +{{ :lm3:ce:godot_mp_test1.png?direct&400 |}}
 +
 +Без:
  
 +{{ :lm3:ce:godot_mp_test2.png?direct&400 |}}
lm3/ce/t_godot_multiplayer.1607016760.txt.gz · Последнее изменение: 2020/12/03 20:32 — ruben