6 de dezembro de 2014

Como Criar Inventário - Volumétrico

Inventários estão presentes em diversos jogos, principalmente em RPGs. Seja para equipar um item ou apenas armazená-lo, a importância dos inventários é tanta que é quase impossível encontrar um jogo que não faça uso deles, desde os mais simples aos mais complexos. Neste tutorial explicarei como criar um inventário baseado no volume dos itens.

A ideia do inventário volumétrico é de aproximar ainda mais o jogo da realidade. Caso já tenha jogado Age of Empires, é possível que tenha passado por uma situação em que era possível colocar 10 elefantes dentro de um barco, mas não 11 arqueiros. Também temos os inventários de slots, por exemplo:

Inventário Diablo 2
Inventário do Diablo 2

Apesar de ser uma proposta interessante, não vejo muito sentido. Como um pequeno anel pode ocupar 1/6 do espaço que uma armadura pesada ocupa? Por quê uma caixa que ocupa 4 slots possui 12 slots em seu interior? Por esses e outros motivos, vamos criar nosso invetário volumétrico. Para este tipo inventário decidi que o melhor é criar um slot onde os itens são colocados e transferidos para onde poderão ser vistos e retirados.

Para este tutorial vou considerar o código utilizado no Tutorial sobre Drag'n'Drop para pegar itens. Se não utiliza este código, o sistema de inventário pode facilmente ser adaptado ao seu jogo. É importante ter conhecimento sobre DS Lists e Arrays para entender os códigos usados neste tutorial.

obj_jogador

Create Event

//Cria e desativa o inventário.

inventario = instance_create(x, y, obj_inventario)
instance_deactivate_object(inventario)

Press I-Key Event

//Cria a tecla de atalho "I" para ativar e desativar o inventário e seus componentes.

if instance_exists(inventario)
{
   instance_deactivate_object(inventario)
   instance_deactivate_object(inventario.slot_inserir)
   instance_deactivate_object(inventario.seta_cima)
   instance_deactivate_object(inventario.seta_baixo)
   var i = 8;
   repeat (9)
   {
      instance_deactivate_object(inventario.slot[i])
   i--
   }
}
else
{
   instance_activate_object(inventario)
   instance_activate_object(inventario.slot_inserir)
   instance_activate_object(inventario.seta_cima)
   instance_activate_object(inventario.seta_baixo)
   var i = 8;
   repeat (9)
   {
      instance_activate_object(inventario.slot[i])
   i--
   }
}

obj_inventario

Create Event

itens_armazenados = ds_list_create()

volume_maximo = 100
volume = 0

//Define os offsets das posições dos slots.

linha1 = -80
linha2 = 0
linha3 = 80
coluna1 = 0
coluna2 = 80
coluna3 = 160

slot_inserir = instance_create(x, y, obj_slot_inserir)
slot_inserir.inventario = id
instance_deactivate_object(slot_inserir)

seta_cima = instance_create(x, y, obj_setacima)
seta_cima.inventario = id
instance_deactivate_object(seta_cima)

seta_baixo = instance_create(xyobj_setabaixo)
seta_baixo.inventario = id
instance_deactivate_object(seta_baixo)

//Criar os slots e define suas variáveis.

slot[8] = 0

var i = 8;
repeat (9)
{
   slot[i] = instance_create(xyobj_slot)
   slot[i].item_armazenado = noone
   slot[i].index = i
   slot[i].inventario = id
   instance_deactivate_object(slot[i])
   i--
}

Step Event

x = view_wview[0]/5
y = view_hview[0]/2

slot_inserir.x = x
slot_inserir.y = y - sprite_height/3

seta_cima.x = x + sprite_width
seta_cima.yy - sprite_height/10

seta_baixo.x = x + sprite_width
seta_baixo.y = y + sprite_height/10

slot[0].x = x + coluna1
slot[0].y = y + linha1

slot[1].x = x + coluna2
slot[1].y = y linha1

slot[2].x = x + coluna3
slot[2].y = y + linha1

slot[3].x = x + coluna1
slot[3].y = y + linha2

slot[4].x = x + coluna2
slot[4].y = y + linha2

slot[5].x = x + coluna3
slot[5].y = y + linha2

slot[6].x = x + coluna1
slot[6].y = y + linha3

slot[7].x = x + coluna2
slot[7].y = y + linha3

slot[8].x = x + coluna3
slot[8].y = y + linha3

Draw Event

//Desenha os sprites de todos componentes do inventário para que se comportem como um único objeto sem se preocupar com a "depth" individual. Lembrar de tornar todos objetos invisíveis, com exceção do inventário.

draw_self()
draw_sprite(slot_inserir.sprite_index, slot_inserir.image_index, slot_inserir.x, slot_inserir.y)
draw_sprite(seta_cima.sprite_index, seta_cima.image_index, seta_cima.x, seta_cima.y)
draw_sprite(seta_baixo.sprite_index, seta_baixo.image_index, seta_baixo.x, seta_baixo.y)

//Desenha os slots e o que estiver armazenado neles logo em seguida, para ficar por cima.

var i = 8;
repeat (9)
{
    draw_sprite(slot[i].sprite_index, slot[i].image_index, slot[i].x, slot[i].y)
    if slot[i].item_armazenado != 0
    {
        draw_sprite(slot[i].item_armazenado.sprite_index, slot[i].item_armazenado.image_index, slot[i].x, slot[i].y)
    }
    i--
}

obj_slot_inserir

Left Pressed Event

item = obj_cursor.item_segurado

if item != noone && (inventario.volume + item.volume) < inventario.volume_maximo
{
   ds_list_insert(inventario.itens_armazenados, 0, item)
   instance_deactivate_object(item)
   obj_cursor.item_segurado = noone
}

obj_slot

Step Event

item_armazenado = inventario.itens_armazenados[| index]

if item_armazenado != 0
{
   item_armazenado.x = x
   item_armazenado.y = y
}

Left Pressed Event

if obj_cursor.item_segurado = noone
{
   instance_activate_object(item_armazenado)
   obj_cursor.item_segurado = item_armazenado
   ds_list_delete(inventario.itens_armazenados, index)
}

obj_setacima

//Diminui o index dos slots para mostrar 3 posições anteriores, fazendo a terceira linha sumir e dar espaço para a segunda. Só funciona se a seta pra baixo já tiver sido apertada.

if inventario.slot[0].index != 0
{
   var i = 8;
   repeat (9)
   {
      inventario.slot[i].index -= 3
      i--
   }
}

obj_setabaixo

//Aumenta o index dos slots para mostrar 3 posições a frente, fazendo a primeira linha sumir para dar espaço para a segunda.

if inventario.item_list[| (inventario.slot[8].index + 1)] != 0
{
   var i = 8;
   repeat (9)
   {
      inventario.slot[i].index += 3
      i--
   }
}

Com as adaptações necessárias esse inventário pode servir para mochilas e também pode ser usado em qualquer jogo. Se encontrou algum erro ou ficou com alguma dúvida deixe seu comentário que responderei assim que possível.
   

9 comentários :

  1. Parabéns pelo tuto! Não pare viu? Ainda vai ajudar muitas pessoas o/

    ResponderExcluir
  2. Sinceramente, seu tutorial é ótimo..mas o que eu acho que falltou foi mais explicações, principalmente para iniciantes, estou no gamemaker a 2 anos mas acho que seu tutorial ta muito bom. PARABENS

    ResponderExcluir
    Respostas
    1. Obrigado pelo elogio e feedback. Fico feliz que tenha gostado :) Tentarei comentar mais os códigos daqui pra frente.

      Excluir
  3. Olá eu usei os códigos no game maker studio mais não funcionou, os códigos só funciona no game maker 8.0?

    ResponderExcluir
    Respostas
    1. Qual o erro que deu? Esse código é pra funcionar no Studio mesmo, não no 8.

      Excluir
  4. ola, gostaria de saber como adicionar um item

    ResponderExcluir