Entrar
Últimos assuntos
» player não consegue andarpor lovn7 Qui 21 Nov 2024, 13:33
» É possível fazer istó no game maker
por William Lima Qui 21 Nov 2024, 10:56
» Rio Rise - novo launcher do Gta San Andreas SAMP Brasil
por Lua Sáb 16 Nov 2024, 20:22
» (Resolvido) Cenario longo x Texture Pages
por josuedemoraes Sáb 16 Nov 2024, 15:31
» Kids' band
por Adilson Lucindo Santos Sex 15 Nov 2024, 12:23
» (RESOLVIDO) Engasgos-Troca de Sprites/animações
por josuedemoraes Ter 12 Nov 2024, 01:49
» Block Room - DEMO
por Joton Qua 06 Nov 2024, 22:58
» Game Infinito vertical (subindo)
por macmilam Sáb 26 Out 2024, 12:36
» Retorno da GMBR!!!
por Dancity Ter 22 Out 2024, 16:36
» Máquina de estados
por aminaro Qui 10 Out 2024, 13:33
» como faço pra um objeto colidir com o outro e diminuir a vida do player ?
por josuedemoraes Qui 03 Out 2024, 16:51
» RESOLVIDO: Colisão com objetos moveis
por josuedemoraes Qua 02 Out 2024, 20:28
» Crypt of the Blood Moon
por divin sphere Qua 11 Set 2024, 18:18
» como fazer um objeto seguir?
por divin sphere Dom 18 Ago 2024, 18:08
» Procuro de alguém para Modelar/Texturizar/Animar objetos 3D
por un00brn Dom 11 Ago 2024, 11:10
» Destruição de cenário (estilo DD Tank)
por CoronelZeg Sex 09 Ago 2024, 17:16
» RESOLVIDO-Como destruir uma instancia especifica de um objeto
por josuedemoraes Ter 23 Jul 2024, 00:40
» Automatizar a coleta de id
por GabrielXavier Seg 22 Jul 2024, 18:01
» Preciso de ajuda para concluir um pequeno projeto
por lmoura Qui 27 Jun 2024, 15:45
» ANGULO ACOMPANHAR O OBJETO
por Klinton Rodrigues Qui 27 Jun 2024, 08:34
» Musica reinicia quando sala reinicia
por GabrielXavier Ter 18 Jun 2024, 07:28
» como fazer uma copia de gd
por generico_cube Sex 14 Jun 2024, 15:48
» Square Adventure
por guilherme551 Ter 11 Jun 2024, 09:54
» como posso definir limite de uma variavel
por GabrielXavier Sex 07 Jun 2024, 14:14
» [Resolvido] Dúvida, colisão única de objeto
por vdm842 Sex 24 maio 2024, 09:50
Networking
4 participantes
GMBR :: Ensine & Aprenda :: Tutoriais :: Game Maker
Página 1 de 1
Networking
Tradução livre do tutorial: http://gmc.yoyogames.com/index.php?showtopic=582029
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:
obj_client.create:
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:
E isso ao obj_client.create:
Para que cada jogador saiba de quem é qual mensagem, o nome de cada um será único.
Adicione isso ao obj_client.create:
Crie dois eventos (alarm0 e alarm1) no obj_client.
Ao alarm0, adicione:
Importante: podemos enviar mensagens em qualquer evento, mas, para receber, há um evento específico.
Adicione isso a obj_server.networking:
"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:
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:
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:
Para enviar o "status" visto acima, adicione no obj_client.step:
Agora que o servidor recebe as mensagens, vamos compartilhá-las com todos os jogadores:
No obj_server.End Step:
Troque o conteúdo de obj_client.networking por:
No obj_client.draw:
Troque o conteúdo de obj_server.networking por:
Ruben -> Artigo original
PedroX -> Tradução (e um pouco de adaptação)
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:
Re: Networking
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?
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- Data de inscrição : 17/06/2012
Reputação : 7
Número de Mensagens : 112
Prêmios :
x 0 x 0 x 0
x 0 x 0 x 0
x 0 x 0 x 0
Re: Networking
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).Quais as mudanças do Client/Server do GM8 para o GM:S
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:
Re: Networking
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!
Flw!
Misterioso- Games Ranking :
Data de inscrição : 01/08/2012
Reputação : 0
Número de Mensagens : 44
Prêmios :
x 0 x 0 x 0
x 0 x 0 x 0
x 0 x 0 x 0
Re: Networking
PedroX escreveu: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).Quais as mudanças do Client/Server do GM8 para o GM:S
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- Data de inscrição : 17/06/2012
Reputação : 7
Número de Mensagens : 112
Prêmios :
x 0 x 0 x 0
x 0 x 0 x 0
x 0 x 0 x 0
Re: Networking
@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.
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:
Re: Networking
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.
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.
Re: Networking
Qual acha mais fácil? Acho que é uma questão de resposta pessoal.facilidade no desenvolvimento
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.performance
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:
Tópicos semelhantes
» Networking
» Chat Networking
» [Dúvida] Networking.
» Ajuda com Networking
» [Tutorial]Experimental Micro web Networking GM:S
» Chat Networking
» [Dúvida] Networking.
» Ajuda com Networking
» [Tutorial]Experimental Micro web Networking GM:S
GMBR :: Ensine & Aprenda :: Tutoriais :: Game Maker
Página 1 de 1
Permissões neste sub-fórum
Não podes responder a tópicos