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
Buffers, tudo sobre.
5 participantes
GMBR :: Ensine & Aprenda :: Tutoriais :: Game Maker
Página 1 de 1
Buffers, tudo sobre.
- 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:
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:
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:
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. Mais sobre eles podem ser vistos no tutorial do Fred:
https://gmbr.forumeiros.com/t27638-tutorial-de-multiplayer-networking-nativo-gms
Boa leitura!
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: Buffers, tudo sobre.
Não sabia que o GMS já trabalhava com buffers de uma forma tão completa. É bom saber, me bati muito com os jogos online no tempo do GM8.
Gabreel- Data de inscrição : 02/10/2009
Reputação : 52
Número de Mensagens : 2232
Prêmios :
x 0 x 0 x 0
x 0 x 0 x 0
x 0 x 0 x 0
Plataformas :- Game Maker 8.0 ou 8.1
- Game Maker Studio 1.4
- Game Maker Studio 2.0
- Javascript
- Outros
Re: Buffers, tudo sobre.
Excelente, este é um assunto que faltava um tuto.
Vou até fazer referência a este tutorial no meu tuto de networking.
Obrigado, Pedro!
Vou até fazer referência a este tutorial no meu tuto de networking.
Obrigado, Pedro!
fredcobain- Games Ranking :
Data de inscrição : 14/04/2011
Reputação : 163
Número de Mensagens : 692
Prêmios :
x 0 x 3 x 0
x 0 x 0 x 0
x 0 x 0 x 0
Re: Buffers, tudo sobre.
É ficou muito bom, mas poderia me dizer para que serve buffer_seek, seus arguments e suas constantes "
No tutorial de fredcobain falou somente que serve para preparar o pacote.
No tutorial de fredcobain falou somente que serve para preparar o pacote.
- Código:
buffer_seek(buffer,base,offset)
Constantes:
buffer_seek_start
buffer_seek_end
buffer_seek_relative
Re: Buffers, tudo sobre.
Talvez esse tutorial ajude:
https://gmbr.forumeiros.com/t29549-exemplos-de-buffer
Adiantando, buffer_seek serve para definir a posição do buffer em que deve começar a escrita/leitura.
https://gmbr.forumeiros.com/t29549-exemplos-de-buffer
Adiantando, buffer_seek serve para definir a posição do buffer em que deve começar a escrita/leitura.
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: Buffers, tudo sobre.
Não nesse tuto a unica referencia com explicação é esta:
e qual é mesma a plicação deste recurso
- Código:
buffer_seek(buff, buffer_seek_start, 0); // vamos para o começo do buffer
e qual é mesma a plicação deste recurso
Re: Buffers, tudo sobre.
@Witen: Tendo a estrutura do seu buffer em mente, as vezes você pode querer abrir o buffer só para pegar um dado em específico. Não se esqueça de que essa posição é por bytes, não por número de elementos. Então, por exemplo, se você quer acessar o terceiro dado e os dois primeiros são do tipo buffer_u16 (16 bits = 2 bytes), então você vai querer acessar a posição 4 do buffer: 0+2+2. Daí, você dá um buffer_read com o tipo adequado do terceiro dado. buffer_seek_start lerá do começo, relative da posição atual, e end do fim. Mas ué, porque raios eu poderia ler algo do fim? Acontece que você também pode atribuir um valor negativo para a posição, então se quisesse pegar o 4 últimos bytes do buffer em um buffer_u32 por exemplo, só era dar:
O problema é que o alinhamento é um fator que pode influenciar na determinação da posição correta. Um alinhamento de 1 vai funcionar tranquilo nessa lógica, mas outros valores será preciso calcular melhor. Detalhe que, um alinhamento diferente de 1 só deve ser usado se o buffer apenas contiver dados de um tipo, se você escrever vários tipos de dados então use alinhamento 1 mesmo.
A parada não é tão simples assim, para entender melhor sobre buffers você teria que entender sobre como funcionam os tipos de dados e sua estrutura na memória. Mas sem dúvida a aplicação mais usada (na programação em geral) é lidar com um "arquivo empacotado", formatos que utilizam ponteiros para dado no arquivo, como em muitos arquivos de jogos.
Bom, é isso. Espero que tenha ficado claro pra você e para alguém com a mesma duvida.
Abraços o/
- Código:
buffer_seek(buffer, buffer_seek_end, -4);
dado = buffer_read(buffer, buffer_u32);
O problema é que o alinhamento é um fator que pode influenciar na determinação da posição correta. Um alinhamento de 1 vai funcionar tranquilo nessa lógica, mas outros valores será preciso calcular melhor. Detalhe que, um alinhamento diferente de 1 só deve ser usado se o buffer apenas contiver dados de um tipo, se você escrever vários tipos de dados então use alinhamento 1 mesmo.
Caso não saiba, signed e unsigned são duas formas de leitura de um dado, é algo determinado pela especificação do formato. O primeiro tipo é um número inteiro, positivo e negativo, e diz que o bit mais significante (o último bit, vai depender do tamanho do dado e de coisas como endianess) irá determinar se o valor é positivo e negativo - por esse motivo, o intervalo numérico é diminuido para a metade do alcance de um unsigned, que é justamente um número natural, de números apenas positivos (incluindo o zero). Leia isso aqui da Wikipedia.
A escolha entre signed e unsigned vai depender do uso que você quer para o dado em questão. Para posições de objetos, por exemplo, os valores podem ser negativos ou positivos, daí você usa signed. E também, uma room provaelmente não vai ser 255x255 (bom, você pode fazer um jogo assim mas, não é comum), então você poderia utilizar um de 16 bits. Se você não coloca nada fora da tela em seu projeto e possui um vasto espaço de room, então é mais viável usar o tipo unsigned para obter um range maior.
Muita coisa em relação a isso já está escrita no próprio tópico.
A parada não é tão simples assim, para entender melhor sobre buffers você teria que entender sobre como funcionam os tipos de dados e sua estrutura na memória. Mas sem dúvida a aplicação mais usada (na programação em geral) é lidar com um "arquivo empacotado", formatos que utilizam ponteiros para dado no arquivo, como em muitos arquivos de jogos.
Vamos dizer que você estivesse gerando um formato e no cabeçalho dele iria conter um endereço para os textos do jogo, não dá pra colocar o valor de cara se a lista de textos não for o primeiro conjunto depois do cabeçalho. Então, você salva a posição atual no cabeçalho (no GM, com buffer_tell), escreve um dado qualquer e quando chegar a hora de escrever os textos você pega a posição atual novamente, dá um seek para a posição salva no cabeçalho (buffer_seek(buffer, buffer_seek_start, posicao), iniciando do começo), e escreve por cima essa outra posição que você acabou de pegar com buffer_write. Daí você dá um seek de volta para a posiçao dos textos e começa a colocar os dados.
Bom, é isso. Espero que tenha ficado claro pra você e para alguém com a mesma duvida.
Abraços o/
Markituh- Games Ranking :
Data de inscrição : 11/10/2009
Reputação : 106
Número de Mensagens : 2184
Prêmios :
x 0 x 1 x 0
x 0 x 0 x 0
x 0 x 0 x 0
Re: Buffers, tudo sobre.
Nossa quando você explica explica muito bem, em fim de forma geral do que eu entendi foi que buffer_seek e como um ponteiro que vai determinar o lugar da leitura e escrita dos bytes.
No signed e unsigned deu pra entender bem, por exemplo nas próprias constantes buffer_ são representadas com a primeira letra de signed e unsigned de pois do _,são estas as letras s(signed) e o u(unsigned).
Como por exemplo:
buffer_u8 (unsigned)
buffer_s16 (signed)
No signed e unsigned deu pra entender bem, por exemplo nas próprias constantes buffer_ são representadas com a primeira letra de signed e unsigned de pois do _,são estas as letras s(signed) e o u(unsigned).
Como por exemplo:
buffer_u8 (unsigned)
buffer_s16 (signed)
Última edição por Witen em Sex 20 Jun 2014, 14:11, editado 1 vez(es)
Re: Buffers, tudo sobre.
Exato. Quanto mais informação numérica você precisar armazenar, mais bits você usa. Para armazenar booleans (true e false), você usa um buffer_u8, pois é uma informação simples e não precisa de muita coisa. Se quiser fazer a parada do "jeito dos mano", dava pra você armazenar uns 8 valores boolean em um byte: lia esse byte e usava um script pra extrair cada bit. A questão é a endianess que falei antes que pode influenciar um pouco, mas já que o buffer foi escrito no próprio PC então não haverá problemas. Depois que você se acostumar a usar buffers não vai querer mais saber de INIs, hehe
Entendeu bem o conceito de signed, né? Boa dedução! A diferença mesmo como pode ver no tópico é o intervalos de valores que a "bitagem" pode trabalhar. O esquema do buffer_seek não é algo tão crucial não, só em aplicações onde há partes no buffer interligadas como no exemplo anterior no meu último post. Uma vez eu fiz um extrator de recursos de .gmk e além de dar bastante seek para ir para o começo de cada entrada, alguns eu precisava descompactar e deixar as paradas alinhadas Quer uma outra aplicação de seek? Pra pular dados que não precisam ser alterados num savegame, em vez de reescrever tudo denovo.
(eu sei, escrevo muito rsrs)
Abraços o/
Entendeu bem o conceito de signed, né? Boa dedução! A diferença mesmo como pode ver no tópico é o intervalos de valores que a "bitagem" pode trabalhar. O esquema do buffer_seek não é algo tão crucial não, só em aplicações onde há partes no buffer interligadas como no exemplo anterior no meu último post. Uma vez eu fiz um extrator de recursos de .gmk e além de dar bastante seek para ir para o começo de cada entrada, alguns eu precisava descompactar e deixar as paradas alinhadas Quer uma outra aplicação de seek? Pra pular dados que não precisam ser alterados num savegame, em vez de reescrever tudo denovo.
(eu sei, escrevo muito rsrs)
Abraços o/
Markituh- Games Ranking :
Data de inscrição : 11/10/2009
Reputação : 106
Número de Mensagens : 2184
Prêmios :
x 0 x 1 x 0
x 0 x 0 x 0
x 0 x 0 x 0
Tópicos semelhantes
» [ResolGms online dúvida simples sobre buffers pls!
» [ SoftinGames ] Tudo Sobre.
» tudo sobre GAME MAKER
» tudo o que voce gostaria de saber sobre a carreira de game desing
» como fazer movimento tipo do asteroids só que isométrico?
» [ SoftinGames ] Tudo Sobre.
» tudo sobre GAME MAKER
» tudo o que voce gostaria de saber sobre a carreira de game desing
» como fazer movimento tipo do asteroids só que isométrico?
GMBR :: Ensine & Aprenda :: Tutoriais :: Game Maker
Página 1 de 1
Permissões neste sub-fórum
Não podes responder a tópicos