GMBR
Gostaria de reagir a esta mensagem? Crie uma conta em poucos cliques ou inicie sessão para continuar.
Entrar

Esqueci-me da senha

Últimos assuntos
» Preciso de ajuda
por AftonDuGrau Dom 21 Abr 2024, 20:18

» Como faz o evento drawn GUI, não se repetir?
por aminaro Sex 19 Abr 2024, 20:30

» Como ajustar velocidade de cada frame da animação no game maker
por Ralphed Qui 18 Abr 2024, 18:28

» PROBLEMAS COM FÍSICAS DE ÁGUA
por aminaro Ter 16 Abr 2024, 10:07

» Retorno da GMBR!!!
por Ralphed Sex 12 Abr 2024, 22:45

» JOGADOR PARANDO NO AR QUANDO ATACA
por aminaro Qua 10 Abr 2024, 13:51

» Problemas com texto interativo
por Kaaru72 Dom 07 Abr 2024, 11:31

» Erro escondido e indecifrável
por dev_gabize.azv Qui 04 Abr 2024, 10:11

» Mudar cor de apenas uma palavra
por Ralphed Sáb 30 Mar 2024, 00:39

» Procuro Programador de game maker
por Wou Sex 15 Mar 2024, 10:27

» Mod APK
por gamerainha Qua 13 Mar 2024, 06:30

» Aceito pedidos de sprites (Com exemplos meus)
por Sevilha Qua 28 Fev 2024, 12:17

» Inventário simples
por Isquilo_Roedor Qui 22 Fev 2024, 15:18

» Problemas na programaçnao de inimigo [jogo DOOM LIKE]
por Black Mirror Dom 11 Fev 2024, 13:34

» ANDROID MULTI TOUCH
por DiegoBr Dom 04 Fev 2024, 12:13

» Servidor de Discord do fórum?
por Lighter Sáb 27 Jan 2024, 17:18

» Save e Load Json
por Klinton Rodrigues Qui 25 Jan 2024, 11:12

» Colisão com mais de um objeto
por aminaro Seg 22 Jan 2024, 15:02

» Oi sou novo aqui
por Thiago Silveira Alexandre Sáb 20 Jan 2024, 20:55

» Como acessar conteudo comprado no marketplace
por macmilam Sex 19 Jan 2024, 07:42

» Devlogs em vídeos do Block Room
por Joton Seg 15 Jan 2024, 16:56

» Alguém aqui já ganha dinheiro com seus games?
por Joton Seg 15 Jan 2024, 16:49

» ACERVO GMBR MAGAZINE
por Joton Qui 11 Jan 2024, 19:21

» como aumentar o obj sem aumentar a colisão??
por GabrielXavier Qua 10 Jan 2024, 07:21

» Asteroid Core - Early Acesse Update [0.2.0.0]
por JOZ. Seg 08 Jan 2024, 14:39


Networking

4 participantes

Ir para baixo

Networking Empty Networking

Mensagem por PedroX Sex 31 maio 2013, 17:19

Tradução livre do tutorial: http://gmc.yoyogames.com/index.php?showtopic=582029

Networking tutorial, step by step.

Descrição: Tutorial que ensina como o Networking funciona e como criar um servidor e um cliente simples.

Dificuldade: Mediana

Para GM:Studio registrado.
Não requer nada além do Game Maker : Studio.

Crie dois projetos. Um será o servidor e o outro o cliente.

No projeto do cliente, crie um objeto obj_client; no projeto do servidor, crie um objeto obj_server; coloque ambos (em cada projeto) em uma room (que criar).

obj_server.create:
Código:
server = network_create_server(network_socket_tcp, 6510, 32)
buff = buffer_create(16384, buffer_fixed, 1);

obj_client.create:
Código:
client = network_create_socket (network_socket_tcp)
network_connect( client, "127.0.0.1", 6510)
buff = buffer_create( 256, buffer_grow, 1)

O número "6510" é a porta usado pelo jogo para acessar o servidor. O "32" é o número máximo de clientes que o servidor pode gerenciar ao mesmo tempo. O "127.0.0.1" é o ip do servidor; este número indica que o servidor se encontra no mesmo pc.

A função buffer_create() irá criar um buffer tanto no cliente quanto no server. O buffer é como uma folha, em que você escreve as mensagens que irá enviar para os outros jogadores.

O buffer do servidor é maior, pois sua folha irá guardar mensagens de todos os jogadores. O argumento "buffer_grow" indica que o buffer pode crescer.

Adicione isso ao obj_server.create:
Código:
clients_sockets = ds_list_create() //guardará o socket de cada jogador
clients_name = ds_list_create() //guardará o nome de cada jogador
clients_x = ds_list_create() //guardará o valor de x de cada jogador
clients_y = ds_list_create() //guardará o valor de y de cada jogador

E isso ao obj_client.create:
Código:
clients_name = ds_list_create()
clients_x = ds_list_create()
clients_y = ds_list_create()

Para que cada jogador saiba de quem é qual mensagem, o nome de cada um será único.

Adicione isso ao obj_client.create:
Código:
randomize()
setup=1
login=0
name_creation_phrase="Insert your character name :"
alarm[0]=10

Crie dois eventos (alarm0 e alarm1) no obj_client.

Ao alarm0, adicione:
Código:
client_name=get_string(name_creation_phrase, "player"+string(round(random(9999))))
buffer_seek(buff, buffer_seek_start, 0) //garantir que escreverá no inicio da folha
buffer_write(buff , buffer_string, "check_name") //escreve na folha 'buff' uma 'string' com valor "check_name", que é o assunto
buffer_write(buff , buffer_string, client_name)
buffer_size = buffer_tell(buff) //pega o tamanho da mensagem (ou seja, onde ela termina)
network_send_packet( client, buff, buffer_size ) //envia a 'carta'

Importante: podemos enviar mensagens em qualquer evento, mas, para receber, há um evento específico.

Adicione isso a obj_server.networking:
Código:
net_buff = ds_map_find_value(async_load, "buffer")
buff_info = buffer_read(net_buff , buffer_string )  //pega o assunto
sock = ds_map_find_value(async_load, "id") //pega o id do player

if buff_info="check_name" //se o assunto é "check_name"
    {
    b_name=buffer_read(net_buff , buffer_string )
    count=ds_list_size(clients_name)
    name_exists=0 //ainda não há um nome igual ao enviado
for(i=0;i<count;i++)
{
if b_name=ds_list_find_value(clients_name, i) name_exists=1 //se tiver um nome igual, a variável fica com o seu valor igual a 1
}

buffer_seek(buff, buffer_seek_start, 0) 
buffer_write(buff, buffer_string, "name_exists")
buffer_write(buff, buffer_bool, name_exists) //resultado do teste (true ou false)
var buffer_size = buffer_tell(buff);
network_send_packet( sock, buff, buffer_size );
}

"async_load" é um mapa padrão do networking. O evento Networking é disparado quando chega uma nova mensagem ou conexão.

Importante: a parte que você lê do buffer é deletada, então não é possível ler duas vezes a mesma informação (a menos que você tenha a escrito duas ou mais vezes).

Agora adicione isso ao obj_client.networking:
Código:
if ds_map_exists(async_load, "buffer")
    {
net_buff = ds_map_find_value(async_load, "buffer")
    buff_info = buffer_read(net_buff, buffer_string )

if buff_info="name_exists"
        {
        setup=buffer_read(net_buff , buffer_bool )
        if setup = 1
            {
            name_creation_phrase="Name already beeing used, please insert another name :"
            alarm[0]=1
            }
else
            {
            alarm[1]=1
            show_message("Welcome "+client_name+"!")
            }
        }
}

A parte do login não é especial, é apenas um pacote que repassa o nome e a posição do cliente.

Evento obj_client.alarm 1:
Código:
buffer_seek(buff, buffer_seek_start, 0)
buffer_write(buff , buffer_string, "client_setup")
buffer_write(buff , buffer_string, client_name)
buffer_write(buff , buffer_s16, x)
buffer_write(buff , buffer_s16, y)
buffer_size = buffer_tell(buff)
network_send_packet( client, buff, buffer_size )
login=1

Como pode ver, foram escritos quatro dados, e então devem ser lidos quatro dados, na mesma ordem de escrita.

Troque o contéudo de obj_server.networking por isto:
Código:
net_buff = ds_map_find_value(async_load, "buffer")
    buff_info = buffer_read(net_buff , buffer_string )
    sock = ds_map_find_value(async_load, "id")
   
    if buff_info="client_status"//client stats
        {
        index=ds_list_find_index( clients_sockets, sock)
        b_x=buffer_read(net_buff , buffer_s16 )
        b_y=buffer_read(net_buff , buffer_s16 )
        ds_list_replace(clients_x, index, b_x)
        ds_list_replace(clients_y, index, b_y)
        }
   
    else if buff_info="check_name"//check if name exists
        {
        b_name=buffer_read(net_buff , buffer_string )
        count=ds_list_size(clients_name)
        name_exists=0
        for(i=0;i<count;i++)
            {
            if b_name=ds_list_find_value(clients_name, i) name_exists=1
            }
        buffer_seek(buff, buffer_seek_start, 0) 
        buffer_write(buff, buffer_string, "name_exists")
        buffer_write(buff, buffer_bool, name_exists)
        var buffer_size = buffer_tell(buff);
        network_send_packet( sock, buff, buffer_size );
        }
       
       
    else if buff_info="client_setup"//client setup
        {
        b_name=buffer_read(net_buff , buffer_string )
        b_x=buffer_read(net_buff , buffer_s16 )
        b_y=buffer_read(net_buff , buffer_s16 )
        ds_list_add(clients_sockets,sock)
        ds_list_add(clients_name,b_name)
        ds_list_add(clients_x,b_x)
        ds_list_add(clients_y,b_y)
        //show_message(b_name+" joined at pos x:"+string(b_x)+" y:"+string(b_y))
        //show_message("list sizes, socket="+string(ds_list_size(clients_sockets))+" name="+string(ds_list_size(clients_name))+" x="+string(ds_list_size(clients_x))+" y="+string(ds_list_size(clients_y)))
        }

Para enviar o "status" visto acima, adicione no obj_client.step:
Código:
if login=1 //só manda se já logou
    {
    buffer_seek(buff, buffer_seek_start, 0)
    buffer_write(buff , buffer_string, "client_status")
    buffer_write(buff , buffer_s16, mouse_x)
    buffer_write(buff , buffer_s16, mouse_y)
    buffer_size = buffer_tell(buff)
    network_send_packet( client, buff, buffer_size )
    }

Agora que o servidor recebe as mensagens, vamos compartilhá-las com todos os jogadores:

No obj_server.End Step:
Código:
count = ds_list_size(clients_sockets)
if count>0
    {
    buffer_seek(buff, buffer_seek_start, 0)
    buffer_write(buff, buffer_string, "all_clients")
    buffer_write(buff, buffer_s16, count)
    for(i=0;i<count;i++)
        {
        buffer_write(buff, buffer_string, string(ds_list_find_value(clients_name,i)) )//clients_name
        buffer_write(buff, buffer_s16, ds_list_find_value(clients_x,i))//clients_x
        buffer_write(buff, buffer_s16, ds_list_find_value(clients_y,i) )//clients_y
        }
    var buffer_size = buffer_tell(buff);
       
    // Enviar para todos os jogadores
    for(i=0;i<count;i++)
        { 
        sock = ds_list_find_value(clients_sockets,i);
        network_send_packet( sock, buff, buffer_size );
        }
    }

Troque o conteúdo de obj_client.networking por:
Código:
if ds_map_exists(async_load, "buffer")
    {
    net_buff = ds_map_find_value(async_load, "buffer")
    buff_info = buffer_read(net_buff, buffer_string )
   
    if buff_info="all_clients"
        {
        count=buffer_read(net_buff , buffer_s16 )
        ds_list_clear(clients_name)
        ds_list_clear(clients_x)
        ds_list_clear(clients_y)
        for(i=0;i<count;i++)
            {
            ds_list_add(clients_name,buffer_read(net_buff , buffer_string ))
            ds_list_add(clients_x,buffer_read(net_buff , buffer_s16 ))
            ds_list_add(clients_y,buffer_read(net_buff , buffer_s16 ))
            }
        }
   
    else if buff_info="name_exists"
        {
        setup=buffer_read(net_buff , buffer_bool )
        if setup = 1
            {
            name_creation_phrase="Name already beeing used, please insert another name :"
            alarm[0]=1
            }
        if setup = 0
            {
            alarm[1]=1
            show_message("Welcome "+client_name+"!")
            }
        }
    }

No obj_client.draw:
Código:
count = ds_list_size(clients_name)
if count>0
    {
    for(i=0;i<count;i++)
            {
            name=ds_list_find_value(clients_name,i)//name
            xx=ds_list_find_value(clients_x,i)//x
            yy=ds_list_find_value(clients_y,i)//y
            if name != client_name
                {
                draw_circle(xx,yy,10,true)
                draw_set_halign(fa_center)
                draw_set_valign(fa_middle)
                draw_text(xx,yy-32,name)
                }
            }
    }
draw_circle(mouse_x,mouse_y,10,false)

Troque o conteúdo de obj_server.networking por:
Código:
eventid = ds_map_find_value(async_load, "id")
if server = eventid
    {
    //disconnect of a client
    t = ds_map_find_value(async_load, "type");
    sock = ds_map_find_value(async_load, "socket");


    if( t!=network_type_connect)
        {
        index=ds_list_find_index( clients_sockets, sock)
        //show_message(ds_list_find_value(clients_name, index)+" disconected")
        ds_list_delete(clients_sockets,index)
        ds_list_delete(clients_name, index)//name
        ds_list_delete(clients_x, index )//x
        ds_list_delete(clients_y, index )//y
        }
    }
else
    {
    net_buff = ds_map_find_value(async_load, "buffer")
    buff_info = buffer_read(net_buff , buffer_string )
    sock = ds_map_find_value(async_load, "id")
   
    if buff_info="client_status"//client stats
        {
        index=ds_list_find_index( clients_sockets, sock)
        b_x=buffer_read(net_buff , buffer_s16 )
        b_y=buffer_read(net_buff , buffer_s16 )
        ds_list_replace(clients_x, index, b_x)
        ds_list_replace(clients_y, index, b_y)
        }
   
    else if buff_info="check_name"//check if name exists
        {
        b_name=buffer_read(net_buff , buffer_string )
        count=ds_list_size(clients_name)
        name_exists=0
        for(i=0;i<count;i++)
            {
            if b_name=ds_list_find_value(clients_name, i) name_exists=1
            }
        buffer_seek(buff, buffer_seek_start, 0) 
        buffer_write(buff, buffer_string, "name_exists")
        buffer_write(buff, buffer_bool, name_exists)
        var buffer_size = buffer_tell(buff);
        network_send_packet( sock, buff, buffer_size );
        }
       
       
    else if buff_info="client_setup"//client setup
        {
        b_name=buffer_read(net_buff , buffer_string )
        b_x=buffer_read(net_buff , buffer_s16 )
        b_y=buffer_read(net_buff , buffer_s16 )
        ds_list_add(clients_sockets,sock)
        ds_list_add(clients_name,b_name)
        ds_list_add(clients_x,b_x)
        ds_list_add(clients_y,b_y)
        //show_message(b_name+" joined at pos x:"+string(b_x)+" y:"+string(b_y))
        //show_message("list sizes, socket="+string(ds_list_size(clients_sockets))+" name="+string(ds_list_size(clients_name))+" x="+string(ds_list_size(clients_x))+" y="+string(ds_list_size(clients_y)))
        }       
    }

Ruben -> Artigo original
PedroX -> Tradução (e um pouco de adaptação)

_________________


Leia o Manual do Iniciante e a Lista de Tutoriais, para aprender bastante sobre o GM.
Recomendo o Manual completo das colisões, bem útil.
O exemplo Criar um chat (banir, kickar, etc) é interessante.

Para seu jogo ficar rápido e legal, aprenda a Aumentar o desempenho do seu jogo.

Aprenda a calcular a velocidade de suas animações


Entre para o Clube do Inglês:
PedroX
PedroX

Games Ranking : Nota B

Notas recebidas : C+B
Data de inscrição : 26/07/2008
Reputação : 311
Número de Mensagens : 6087
Prêmios : Networking Empty

Medalhas x 0 Tutoriais x 17 Moedas x 0

Ouro x 0 Prata x 0 Bronze x 0

Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0

https://web.whatsapp.com/send?phone=5519995935953&text=Pedro

Ir para o topo Ir para baixo

Networking Empty Re: Networking

Mensagem por soueunox Sex 31 maio 2013, 17:50

Bom, pelo que to vendo é tipo que um jogo online simples.
Com sistemas de nomes e coordenadas do jogadores.

Agora uma pergunta, Quais as mudanças do Client/Server do GM8 para o GM:S
Em relação a esse topico?
soueunox
soueunox

Data de inscrição : 17/06/2012
Reputação : 7
Número de Mensagens : 112
Prêmios : Networking Empty

Medalhas x 0 Tutoriais x 0 Moedas x 0

Ouro x 0 Prata x 0 Bronze x 0

Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0

Ir para o topo Ir para baixo

Networking Empty Re: Networking

Mensagem por PedroX Sex 31 maio 2013, 18:04

Quais as mudanças do Client/Server do GM8 para o GM:S
Muitas. Agora você não precisa de DLLs. Há sistemas de buffers e sockets mais personalizáveis. Os tipos de dados também são mais abrangentes. Não pega no HTML5 (pena).

_________________


Leia o Manual do Iniciante e a Lista de Tutoriais, para aprender bastante sobre o GM.
Recomendo o Manual completo das colisões, bem útil.
O exemplo Criar um chat (banir, kickar, etc) é interessante.

Para seu jogo ficar rápido e legal, aprenda a Aumentar o desempenho do seu jogo.

Aprenda a calcular a velocidade de suas animações


Entre para o Clube do Inglês:
PedroX
PedroX

Games Ranking : Nota B

Notas recebidas : C+B
Data de inscrição : 26/07/2008
Reputação : 311
Número de Mensagens : 6087
Prêmios : Networking Empty

Medalhas x 0 Tutoriais x 17 Moedas x 0

Ouro x 0 Prata x 0 Bronze x 0

Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0

https://web.whatsapp.com/send?phone=5519995935953&text=Pedro

Ir para o topo Ir para baixo

Networking Empty Re: Networking

Mensagem por Misterioso Sex 31 maio 2013, 19:11

Sockets e mais sockets mas no final sempre tem uma situação complicada, o IP da pessoa teria que ser único na rede de internet dela, e que as portas do seu Modem e do seu Firewall fossem abertas. E no meio dessa confusão, Hamachi não seria uma boa opção, e alem do mais mesmo que haja uma pessoa sendo o servidor, uma hora ou outra ela vai ter que desligar o computador, Pra jogos desse tipo é recomendado VirtualServer só que não é de graça, seria legal um sistema tipo requisições sem lag, né PedroX.

Flw!
Misterioso
Misterioso

Games Ranking : Sem avaliações

Data de inscrição : 01/08/2012
Reputação : 0
Número de Mensagens : 44
Prêmios : Networking Empty

Medalhas x 0 Tutoriais x 0 Moedas x 0

Ouro x 0 Prata x 0 Bronze x 0

Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0

Ir para o topo Ir para baixo

Networking Empty Re: Networking

Mensagem por soueunox Sex 31 maio 2013, 20:32

PedroX escreveu:
Quais as mudanças do Client/Server do GM8 para o GM:S
Muitas. Agora você não precisa de DLLs. Há sistemas de buffers e sockets mais personalizáveis. Os tipos de dados também são mais abrangentes. Não pega no HTML5 (pena).

Bom, pena mesmo que não pegue no HTML5.
Mais o melhor modulo e tecnica facil de ultizar é a dll mesmo ne?
Pois ja tem as scripts e tudo mais...
a não ser que as script possam ser executadas sem a dll também :p
Muito bom, não sabia dessa função do GM:S
Ela pega em android, iOS?
soueunox
soueunox

Data de inscrição : 17/06/2012
Reputação : 7
Número de Mensagens : 112
Prêmios : Networking Empty

Medalhas x 0 Tutoriais x 0 Moedas x 0

Ouro x 0 Prata x 0 Bronze x 0

Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0

Ir para o topo Ir para baixo

Networking Empty Re: Networking

Mensagem por PedroX Sex 31 maio 2013, 22:20

@Kimimaro
Sim. Mas se for um jogo muito 'ativo', requests não adiantariam muito. Mesmo assim, seu projeto sobre isso poderia ser postado aqui para estudos...

@soueunox
Sim, pega em todos menos HTML5 (segundo o que já li até o momento).

Melhor para GM:S: o modo desse tutorial (interno)
Melhor para GM:8: DLLs.

_________________


Leia o Manual do Iniciante e a Lista de Tutoriais, para aprender bastante sobre o GM.
Recomendo o Manual completo das colisões, bem útil.
O exemplo Criar um chat (banir, kickar, etc) é interessante.

Para seu jogo ficar rápido e legal, aprenda a Aumentar o desempenho do seu jogo.

Aprenda a calcular a velocidade de suas animações


Entre para o Clube do Inglês:
PedroX
PedroX

Games Ranking : Nota B

Notas recebidas : C+B
Data de inscrição : 26/07/2008
Reputação : 311
Número de Mensagens : 6087
Prêmios : Networking Empty

Medalhas x 0 Tutoriais x 17 Moedas x 0

Ouro x 0 Prata x 0 Bronze x 0

Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0

https://web.whatsapp.com/send?phone=5519995935953&text=Pedro

Ir para o topo Ir para baixo

Networking Empty Re: Networking

Mensagem por machosupremo Sáb 01 Jun 2013, 13:58

Uma pergunta sobre a estrutura ai abordada.
O desenvolvedor da engine escolheu uma série de listas (ds_list_create) para cada tipo de informação.

Eu ja aprendi a usar objetos para cada novo jogador e a este objeto eu atribuiria as devidas variáveis.

Qual método seria mais adequado quanto a performance e/ou facilidade no desenvolvimento.
machosupremo
machosupremo

Data de inscrição : 10/10/2012
Reputação : 2
Número de Mensagens : 99
Prêmios : Networking Empty

Medalhas x 0 Tutoriais x 0 Moedas x 0

Ouro x 0 Prata x 0 Bronze x 0

Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0

http://www.dinoup.com

Ir para o topo Ir para baixo

Networking Empty Re: Networking

Mensagem por PedroX Sáb 01 Jun 2013, 14:28

facilidade no desenvolvimento
Qual acha mais fácil? Acho que é uma questão de resposta pessoal.

performance
Usar listas gasta menos memória e talvez seja mais rápido. Instâncias gastam mais memória, por terem muitas informações (image_index, por exemplo, vai ficar aumentando automaticamente) e talvez sejam mais lentas.

Minha opinião:

No server, usar listas. No cliente, usar instâncias (desde que essas sejam visíveis, pois o GM por padrão desenha mais rápido do que códigos do Draw).

_________________


Leia o Manual do Iniciante e a Lista de Tutoriais, para aprender bastante sobre o GM.
Recomendo o Manual completo das colisões, bem útil.
O exemplo Criar um chat (banir, kickar, etc) é interessante.

Para seu jogo ficar rápido e legal, aprenda a Aumentar o desempenho do seu jogo.

Aprenda a calcular a velocidade de suas animações


Entre para o Clube do Inglês:
PedroX
PedroX

Games Ranking : Nota B

Notas recebidas : C+B
Data de inscrição : 26/07/2008
Reputação : 311
Número de Mensagens : 6087
Prêmios : Networking Empty

Medalhas x 0 Tutoriais x 17 Moedas x 0

Ouro x 0 Prata x 0 Bronze x 0

Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0

https://web.whatsapp.com/send?phone=5519995935953&text=Pedro

Ir para o topo Ir para baixo

Networking Empty Re: Networking

Mensagem por Conteúdo patrocinado


Conteúdo patrocinado


Ir para o topo Ir para baixo

Ir para o topo

- Tópicos semelhantes

 
Permissões neste sub-fórum
Não podes responder a tópicos