Obrigado por visitar a The Game Makers Brasil 😁 Use o fórum de Dúvidas para fazer perguntas. Se está em busca de aprender dê uma olhada nos tutoriais.

[PROG] Buffers, tudo sobre.

Tutoriais, videoaulas, guias e downloads para te ajudar nos estudos.
Avatar do usuário
Tutoriais & Aulas
Colaborador
Colaborador
Reações: 0
Mensagens: 110

[PROG] Buffers, tudo sobre.

Mensagem por Tutoriais & Aulas » Sex Abr 29, 2016 10:04 am

Autor original: PedroX
  • Título: Tudo sobre Buffers
  • Versão do GM: Game Maker Studio 1.2 ou superior
  • Dificuldade: Média
  • Link para download da Engine: Não tem
  • Requer Extensões: Não
  • Requer DLLs: Não
  • Tags: studio, buffers, online, multiplayer
O que são buffers?

Buffers são regiões da memória física usadas para guardar temporariamente dados enquanto esses estão sendo movidos de um lugar para outro ou manipulados de alguma maneira. Por exemplo, você pode usá-los para guardar dados de packets que serão enviados ou recebidos.

O GM:S tem funções para criar, modificar, carregar e salvar buffers, mas antes de usá-las, note os pontos a seguir.

Teoria.

       - Quando um buffer é criado, ele é automaticamente limpo e preenchidoit com 0.
       - "size" é o tamanho (em bytes) de um buffer.
       - "Alignment" indica como os dados são guardados dentro de um buffer. Se o "alignment" é, digamos, 4, e você escreve 1 byte no buffer e usa buffer_tell, você terá o valor 1 como retorno. No entanto, se você escrever mais um byte e usar buffer_tell, você terá o valor 5 como retorno, visto que são usados blocos de 4. "Alignment" é valido somente na escrita em um buffer, então se você usar buffer_tell depois de escrever algo, terá como retorno a posição de escrita atual que vem lodo depois dos dados escritos. Então, se  você escrever algo novamente, a posição desses novos dados será um múltiplo de 4 (ou do valor usado).

A imagem a seguir ilustra mais ou menos como um buffer é alinhado:
Imagem

Como já vimos, se o alinhamento for de 1, os dados são jogados um logo após o outro. Já se for maior que um, os novos dados ficarão numa posição múltipla do valor de alinhamento.

       - "offset" é o valor (em bytes) para rechear/preencher/completar os dados escritos no buffer.
       - Algumas funções de buffer também criam um novo buffer (por exemplo, buffer_load). Lembre-se de remover esses buffers da memória depois de usá-los pela última vez (ou no final do jogo), usando a função buffer_delete.
       - A memória usado pelos buffers é a do sistema; mesmo que o jogo não esteja em foco (por exemplo, numa ligação no celular), os dados escritos nele vão estar seguros. Mas se o app for fechado ou reiniciado, os dados serão perdidos.

Usando buffers.

É muito rápido acessar buffers, porém seu uso deve ser curto (a menos que seja muito necessário prolongá-lo), porque a memória do sistema está envolvida. Geralmente usamos buffers para guardar um checkpoint no jogo ou para guardar dados que são enviados ou recebidos num jogo online.

NOTA: Ao reiniciar o jogo, os buffers não serão apagados, mas você não conseguirá acessá-los. Isso causa um vazamento de memória (ou seja, o buffer ficará lá até o dispositivo ser reiniciado), e seu jogo poderá encerrar sozinho (dar crash). Sempre delete os buffers usados.

Tipos de buffer

Existem 4 tipos no GM:S.

buffer_fixed
Tamanho constante (significa que não pode ser modificado).

buffer_grow
Tamanho dinâmico (que aumenta conforme necessário).

buffer_wrap
Quando o buffer encher, os dados começarão a ser escritos no começo, criando um loop. Por exemplo, restam 2 bytes e você escreve 3. Então 2 serão colocados no final e o outro vai substituir o primeiro byte do buffer.

buffer_fast
Um buffer especial, super rápido de se ler e escrever. Porém, você pode escrever somente dados dos tipos buffer_u8 e buffer_s8, e o 'alignment' precisa ser 1.

Se tiver dúvidas quanto a quantos bytes vai precisar, use o buffer do tipo grow.

Tipos de dados

Ao ler ou escrever em um buffer, você pode usar diferentes tipos de dados. Os dados são sequenciais. E você sempre deve saber que tipo de dados usou. Por exemplo, escreveu um número, um nome (string), um número, um nome (string). Então você não pode querer ler um nome (string) antes de ler o número.

buffer_u8 (1 byte)
Um inteiro de 0 a 255.

buffer_s8 (1 byte)
Um inteiro de -128 a 127.

buffer_u16 (2 bytes)
Um inteiro de 0 a 65.535.

buffer_s16 (2 bytes)
Um inteiro de -32.768 a 32.767.

buffer_u32 (4 bytes)
Um inteiro de 0 a 4.294.967.295.

buffer_s32 (4 bytes)
Um inteiro de -2.147.483.648 a 2.147.483.647.

buffer_f16 (2 bytes)
Um número (não precisa ser inteiro) de -65504 a 65504. (Ainda não está disponível.)

buffer_f32 (4 bytes)
Um número (não precisa ser inteiro) de -16777216 a 16777216.

buffer_f64 (8 bytes)
Um número (não precisa ser inteiro) de -(2^52) a 2^52 - 1. (Números muito grandes)

buffer_bool (1 byte)
1 ou 0 (true ou false)

buffer_string
Uma string UTF-8 terminada com 'null' (0x00). Um 0 é colocado depois da string para determinar quando ela acaba.

Então, suponde que escreva no buffer:

Código: Selecionar todos

buffer_write(buff, buffer_bool, global.Sound);
buffer_write(buff, buffer_bool, global.Music);
buffer_write(buff, buffer_s16, obj_Player.x);
buffer_write(buff, buffer_s16, obj_Player.y);
buffer_write(buff, buffer_string, global.Player_Name);
Você deve ler na mesma ordem, assim:

Código: Selecionar todos

global.Sound = buffer_read(buff, buffer_bool);
global.Music = buffer_read(buff, buffer_bool);
obj_Player.x = buffer_read(buff, buffer_s16);
obj_Player.y = buffer_read(buff, buffer_s16);
global.Player_Name = buffer_read(buff, buffer_string);
Esse é o básico sobre buffers.

Boa leitura!

Responder

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 0 visitante