[ENGINE - SCRIPT] Método de draw_sprite_part

Ver o tópico anterior Ver o tópico seguinte Ir em baixo

Qualidade [ENGINE - SCRIPT] Método de draw_sprite_part

Mensagem por Mr.Rafael em Seg 19 Ago 2013, 12:07

Método de draw_sprite_part:
(Com o CQ #16 encerrado, nada mais justo do que eu compartilhar meu segredo, né?)

Estava eu todo empolgado com o CQ #16, até que, em um momento muito antes de começar a fazer meu jogo, pensei: "Como eu poderia manter múltiplas imagens no jogo usando só um sprite?". A resposta de usar subimages e o "image_index" era óbvia. No entanto, eu quis ser Do Contra, igual ao CQ de formas (todo mundo usando Surface e eu fiz meu jogo inteiro em Drag n' Drop Laughing).

Então, comecei a queimar alguns neurônios pensando em como eu poderia fazer isso sem me perder com trocentas ID's de subimages e sendo diferente da possível maioria. Achei uma função do draw chamada draw_sprite_part, e lá estava a resposta para tudo. Cool

Entendendo um pouco:

Este método que eu vou apresentar para vocês é um pouquinho diferente do que eu fiz para o CQ em si. Enquanto para o meu jogo do CQ eu utilizei a função draw_sprite_part, nesse aqui eu usei o draw_sprite_part_ext. Isso deixou a engine consideravelmente mais difícil de mexer, pois agora você tem a oportunidade de mexer em mais parâmetros, além de não precisar modificar quase nada para mexer com outras coisas (como alpha e image_xscale). Além disso, eu também fiz algumas pequenas alterações para que ela se tornasse pelo menos um "alterador-de-valores". Ou seja, você só precisará alterar os valores de algumas variáveis no Create para mudar cada simples parâmetro.

Uma coisa muito interessante é que ela é muito semelhante ao formato CHR, usado em jogos antigos. O CHR funciona(va) basicamente como um WinRAR, só que utilizando imagens: cada figura era indexada em uma determinada posição, e o software (jogo) apenas precisava "recortá-la" e exibir aquele pedaço. Os tilesets também funcionam assim.

Como implementar:

Bom, a primeira coisa é criarmos a nossa spritesheet. Nesse caso, tenho aqui uma imagem que servirá muito bem de explicação:

O método gira em torno de Slots e Subs. Calma, eu vou explicar:
- Os Slots são um pedaço horizontal, e consomem uma parte inteira. Basicamente, funciona da mesma maneira de quando você salva um sprite animado em PNG no GM. No caso, temos 4 subs, então pode-se dizer que isso seria o equivalente a figura_strip4.
- As Subs são as suas subimages normais. Leve em consideração que eu estou usando 16x16 para explicar, mas é possível alterar o tamanho ao seu gosto. No caso, temos 4 subimages, que eu posso utilizar como animação de algum objeto ou como itens separados. Explicarei isso no script.
- O Slot 0 sempre é reservado para indicar a máscara. Você deverá criar um quadrado/retângulo preto e então definir apenas esta parte como máscara do sprite. Você fará isso clicando no botão "Modify Mask" e mexendo apenas nos valores do Right e do Bottom.
- Por conta do motivo acima: Os Slots das suas figuras sempre começarão a partir do 1. As Subs podem começar naturalmente do 0, mas como eu desenhei aquelas letras ali para indicar, acabaremos tendo que usar 1 também. Very Happy

Scripts:

Feito isso, agora criamos nosso objeto. Uma coisa importante: não coloque nenhum sprite diretamente nele. Não que tenha problemas, mas você vai se perder todo. --\'

Mas espere: primeiro, vamos criar logo os scripts. Por favor, use os nomes sugeridos Rolling Eyes:

sa_scp (Sub Animation):
Spoiler:

Código:
/*---------------------------------------------------------------------*/
/*                       sa_scp: Sub Animation                         */
/*---------------------------------------------------------------------*/

/*--------------SCRIPT DE ANIMAÇÃO POR DRAW_SPRITE_PART----------------*/
/*                           (By: Mr.Rafael)                           */
/*   (2013 - GMBR | Direitos reservados a mim e ao meu cachorro! :D)   */
/*                                                                     */
/*               VISITE MEU PERFIL NA GAME MAKER BRASIL:               */
/*                   http://gmbr.forumeiros.com/u3158)                 */
/* (http://gamemakerbrasil.com.br/forum/index.php?action=profile;u=12) */
/*                                                                     */
/*  E eu sei que uma boa galera vai falar que eu podia ter optimizado  */
/*  Isso, aquilo e aquilo outro. Vão me fazer parecer um noob. ;-;     */
/*---------------------------------------------------------------------*/

if (run_spd == 0)
    {
    // Voltar a posição original de contagem
    run_spd = sub_spd;
    
    if (sub_actual == sub_end)
        {
        // Retornar ao início
        sub_actual = sub_start;
        }
    else
        {
        // Mover a figura
        sub_actual += width_slot;
        }
    }
else
    {
    // Diminuir contagem do tempo
    run_spd -= frame_vel;
    }

rp_scp (Receive Parameters):
Spoiler:

Código:
/*---------------------------------------------------------------------*/
/*                     rp_scp: Receive Parameters                      */
/*---------------------------------------------------------------------*/

/*--------------SCRIPT DE ANIMAÇÃO POR DRAW_SPRITE_PART----------------*/
/*                           (By: Mr.Rafael)                           */
/*   (2013 - GMBR | Direitos reservados a mim e ao meu cachorro! :D)   */
/*                                                                     */
/*               VISITE MEU PERFIL NA GAME MAKER BRASIL:               */
/*                   http://gmbr.forumeiros.com/u3158)                 */
/* (http://gamemakerbrasil.com.br/forum/index.php?action=profile;u=12) */
/*                                                                     */
/*  E eu sei que uma boa galera vai falar que eu podia ter optimizado  */
/*  Isso, aquilo e aquilo outro. Vão me fazer parecer um noob. ;-;     */
/*---------------------------------------------------------------------*/

// Receber parâmetros (PELAMORDEDEUS NÃO MEXA NISSO! Ò_Ó):
sprite_index = choose_spr;
mask_index = choose_msk;
image_index = choose_sub;
image_speed = choose_spd;
sub_start = width_slot * frame_start;
sub_actual = sub_start;
sub_end = width_slot * (frame_start + frame_end);
sub_spd = frame_spd;
run_spd = sub_spd;

di_scp (Draw Image):
Spoiler:

Código:
/*---------------------------------------------------------------------*/
/*                          di_scp: Draw Image                         */
/*---------------------------------------------------------------------*/

/*--------------SCRIPT DE ANIMAÇÃO POR DRAW_SPRITE_PART----------------*/
/*                           (By: Mr.Rafael)                           */
/*   (2013 - GMBR | Direitos reservados a mim e ao meu cachorro! :D)   */
/*                                                                     */
/*               VISITE MEU PERFIL NA GAME MAKER BRASIL:               */
/*                   http://gmbr.forumeiros.com/u3158)                 */
/* (http://gamemakerbrasil.com.br/forum/index.php?action=profile;u=12) */
/*                                                                     */
/*  E eu sei que uma boa galera vai falar que eu podia ter optimizado  */
/*  Isso, aquilo e aquilo outro. Vão me fazer parecer um noob. ;-;     */
/*---------------------------------------------------------------------*/

// Desenhar figura (Não precisa entender... apenas deixe isso aí. ._.):
draw_sprite_part_ext(choose_spr,choose_sub,sub_actual,top_slot,width_slot,height_slot,self.x,self.y,sub_xscale,sub_yscale,sub_color,sub_alpha);

Ok, estes são os scripts. Agora, no Create de cada objeto que você queira colocar, use isto:
Código:
choose_spr = all_spr; // [X] Definir sprite real (caso haja mudanças)
choose_msk = all_spr; // [X] Definir máscara real (obrigatório para colisões)
choose_sub = 0;       // [X] Definir subimage do sprite real (para múltiplos tilesets)
choose_spd = 0;       // [X] Definir velocidade do sprite real (para possíveis "swaps" de animação)

sub_xscale = 1;       // [X] Definir Xscale da figura (use "1" ou "-1" | caso não queira usar, deixe "1")
sub_yscale = 1;       // [X] Definir Yscale da figura (use "1" ou "-1" | caso não queira usar, deixe "1")
sub_color = c_white;  // [X] Definir coloração da figura (use c_algumacoisa | caso não queira usar, deixe "c_white")
sub_alpha = 1;        // [X] Definir alpha da figura (entre 0 e 1 } caso não queira usar, deixe "1")

width_slot = 16;      // [X] Definir largura da figura
height_slot = 16;     // [X] Definir altura da figura
top_slot = 16 * 1;    // [X] Definir slot das figuras em Top

frame_start = 1;      // [X] Definir em qual subimage a animação inicia (caso haja)
frame_end = 0;        // [X] Definir em qual subimage a animação termina (frame_start + frame_end)
frame_spd = 0;        // [X] Definir a velocidade da subimage (deixe 0 para estático)
frame_vel = 0;        // [X] Quantos segundos para completar cada "ciclo de frame". (deixe 0 para estático)

// Receber parâmetros:
script_execute(rp_scp);
Aqui você definirá absolutamente TODOS os parâmetros da figura: quanto ela tem de largura, quanto ela tem de altura, em que Sub ela inicia, de qual Slot faz parte, qual a velocidade dela, etc. Uma observação básica: o script utilizado por mim para meu jogo do CQ é mais básico que isso. No entanto, eu fiz umas melhorias para que ele ficasse mais fácil de ser compreendido e que mais coisas pudessem ser feitas na imagem.

Bom: feito isso, agora só precisamos executar os scripts apropriados no Draw. Na engine de exemplo, usei este código aqui:
Código:
// Script de animação:
script_execute(sa_scp);

// Desenhar figura:
script_execute(di_scp);
Bem pequeno, não é? Sim, tanto na parte do código do Draw como nos próprios scripts em si.
Mas algumas coisas importantes: apesar de parecer legal, este recurso usa e abusa do Draw. Então pode ser que seu jogo fique meio pesado. Para finalizar, veja uma diferença entre a room no modo edição e o jogo rodando:

Mas as coisas podem ficar bem divertidas, dependendo do tamanho do seu jogo. Senhoras e senhores: apresentamos os... GLITCHES GRÁFICOS:

Eles representam mais ou menos a forma que os jogos que usavam CHR (jogos em cartucho, principalmente) se comportavam quando seus gráficos corrompiam. Você pode conseguir estes efeitos rabiscando a sua spritesheet ou trocando Slots ou Subs de lugar. Very Happy

Teste a engine:

Ficou curioso para ver esta linda e maravilhosa gambiarra engine? Pode baixá-la:

DOWNLOAD DA ENGINE AQUI!

o/

Mr.Rafael

Ranking : Nota A
Número de Mensagens : 383
Data de inscrição : 05/10/2010
Notas recebidas : A-C-B-A
Reputação : 57
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 0
   : 1
   : 2

Voltar ao Topo Ir em baixo

Qualidade Re: [ENGINE - SCRIPT] Método de draw_sprite_part

Mensagem por Kapoty em Seg 19 Ago 2013, 19:34

Realmente muito bom, meio que em outras linguagens teríamos que fazer isso, desenhar partes da imagem (que é o seu caso), ou desenhar frame por frame (como funciona no Game Maker).

Kapoty

Ranking : Nota B
Número de Mensagens : 635
Data de inscrição : 05/11/2011
Notas recebidas : E + D + C + B + D +B + A
Reputação : 22
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 1
   : 0
   : 1

Voltar ao Topo Ir em baixo

Qualidade Re: [ENGINE - SCRIPT] Método de draw_sprite_part

Mensagem por Livsk em Seg 19 Ago 2013, 20:00

Gostei do método que você utilizou, não é muito difícil e enquanto a maioria iria utilizar image_index você pensou em algo diferente. Parabéns.

Flw.

Livsk

Ranking : Nota C
Número de Mensagens : 364
Idade : 19
Data de inscrição : 02/06/2011
Notas recebidas : C + C + D + D + D + D + B + B + A + C + B
Reputação : 13
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 1
   : 0
   : 1

Voltar ao Topo Ir em baixo

Qualidade Re: [ENGINE - SCRIPT] Método de draw_sprite_part

Mensagem por Conteúdo patrocinado Hoje à(s) 08:36


Conteúdo patrocinado


Voltar ao Topo Ir em baixo

Ver o tópico anterior Ver o tópico seguinte Voltar ao Topo

- Tópicos similares

 
Permissão deste fórum:
Você não pode responder aos tópicos neste fórum