[RGSS3]Criar mais um atributo

16 Respostas   2011 Visualizações

0 Membros e 1 Visitante estão vendo este tópico.

Akira!

Tópico criado em: 13/12/2014 às 10:07

Olá jovens!
Tô precisando de uma forcinha aqui!
Tem como eu criar mais um atributo via script?

Exemplo: Meus jogadores vão sentir frio, então preciso de um atributo 'frio' para os heróis!
Logo esse atributo precisa diminuir e aumentar, como se fosse hp e mp!
Tem como fazer isso?
Espero que tenham entendido!
Até!

miguel8884

Resposta 1: 13/12/2014 às 13:08

Não é só criar uma variável e manipula-la  :hmm:? Se não não entendi muito bem, se estiver falando como ataque, defesa essas coisas, vou dar uma verificada aqui, se eu ver eu te falo!

Akira!

Resposta 2: 13/12/2014 às 13:18

Eu quero criar esse atributo 'frio', como se fosse hp e mp, que podem ser manipulados um em cada actor!
Tipo isso:
Código: (ruby) [Selecionar]
heroi1.frio = 100
heroi2.frio = 80

E manipular esses valores!
Sou péssimo em descrever coisas!

miguel8884

Resposta 3: 13/12/2014 às 13:57 - Última modificação por miguel8884 em 13/12/2014 às 14:05

Ahh isso é bem simples!

Vou explicar de dois jeitos, um mais fácil outro mais dificil!

Você pode criar um module para configurar o frio que cada um irá iniciar, não precisa ser o frio, pode ser todos, mas vou usar o frio como exemplo!

Código: [Selecionar]
module Tutorial
  Actor = Array.new
end

Eu criei essa array dentro do module  para manipularmos as características de cada herói a partir de sua id!

Código: [Selecionar]
module Tutorial
  Actor = Array.new
 
  Actor[1] = [
  Frio = 100,
  ]
 
  Actor[2] = [
  Frio = 120,
  ]
end

Aqui defini o frio inicial pro herói de id 1 e 2, os outros agente cria um predefinido aqui mesmo no module!

Código: [Selecionar]
module Tutorial
  Actor = Array.new
 
  Frio_Predefinido = 50
 
  Actor[1] = [
  Frio = 100,
  ]
 
  Actor[2] = [
  Frio = 120,
  ]
end

Beleza, agora vamos na classe Game_Actor que gerencia os membros e todos os personagens!
Usei um alias no método setup que possui um parâmetro.

Código: [Selecionar]
class Game_Actor < Game_Battler
  alias :gst_tutorial :setup
  def setup(actor_id)
    gst_tutorial(actor_id)
  end
end

Agora vou criar as variáveis que você quer, vou criar só o frio por que foi a que eu defini no module.

Código: [Selecionar]
class Game_Actor < Game_Battler
  alias :gst_tutorial :setup
  def setup(actor_id)
    gst_tutorial(actor_id)
    @frio = Tutorial::Actor[actor_id][0]
  end
end

Usei o nome do meu module acessei a array actor que é outra array, então para acessar a posição do actor que queremos usei o actor_id, o parâmetro do método, e na frente a posição do valor que queremos dessa array!

Agora vou simplesmente usar o attr_accessor na variável @frio, assim poderei altera-la como se ela fosse o@hp ou o @mp!

Ficou assim

Código: [Selecionar]
module Tutorial
  Actor = Array.new
 
  Frio_Predefinido = 50
 
  Actor[1] = [
  Frio = 100,
  ]
 
  Actor[2] = [
  Frio = 120,
  ]
end

class Game_Actor < Game_Battler
  attr_accessor :frio
  alias :gst_tutorial :setup
  def setup(actor_id)
    gst_tutorial(actor_id)
    @frio = Tutorial::Actor[actor_id][0]
  end
end

Mas ainda falta  frio predefinido, para isso vou usar uma condição!

Código: [Selecionar]
module Tutorial
  Actor = Array.new
 
  Frio_Predefinido = 50
 
  Actor[1] = [
  Frio = 100,
  ]
 
  Actor[2] = [
  Frio = 120,
  ]
end

class Game_Actor < Game_Battler
  attr_accessor :frio
  alias :gst_tutorial :setup
  def setup(actor_id)
    gst_tutorial(actor_id)
    if Tutorial::Actor[actor_id].nil?
      @frio = Tutorial::Frio_Predefinido
    else
      @frio = Tutorial::Actor[actor_id][0]
    end
  end
end

Pronto, assim caso a array actor do module não possua o id do actor em questão, ela cria a variável frio com  definido no module como predefinido!

Acho que é isso, se não entender alguma coisa só perguntar, não sou muito bom em explicar XD

Akira!

Resposta 4: 13/12/2014 às 14:38

Obrigado pela atenção @miguel!
Assim que chegar em casa vou conferir!

Akira!

Resposta 5: 14/12/2014 às 10:44

Opa! Muito obrigado @miguel! Funciona bem!
Mas como defino um frio máximo?
Pois quando vou somando na variável, queria que ela não passasse de '100'
É possível?

miguel8884

Resposta 6: 14/12/2014 às 11:34

Hum ok! Sim é possível, faremos mais algumas coisas, podemos fazer um uma condição no update da Scene_Map.

Primeiro vamos fazer uma configuração naquele module colocando o frio máximo e após um método no game_actor que retornará o frio máximo!

Código: [Selecionar]
module Tutorial
  Actor = Array.new
 
  Frio_Predefinido = 50
 
  Actor[1] = [
  Frio = 100,
  Frio_Max = 120,
  ]
 
  Actor[2] = [
  Frio = 120,
  Frio_Max = 150,
  ]
end

class Game_Actor < Game_Battler
  attr_accessor :frio
  alias :gst_tutorial :setup
  def setup(actor_id)
    gst_tutorial(actor_id)
    if Tutorial::Actor[actor_id].nil?
      @frio = Tutorial::Frio_Predefinido
    else
      @frio = Tutorial::Actor[actor_id][0]
    end
  end
  def frio_max
    return Tutorial::Actor[@actor_id][1]
  end
end

Agora vou criar verificação na classe Scene_Map, sempre que você estiver no mapa, ela estará verificando se o frio está ultrapssando o máximo, e caso esteja ela faz com que ele fique no máximo.

Não se esqueça de dar o alias, vou usar o método update dela, não recoloque o super, pois com o alias já estamos incluindo ele.

Como não existe apenas um membro na equipe, vamos utilizar isso aqui:

Código: [Selecionar]
$game_party.members.each do |act|
 
end

Acessamos os membros em $game_party.members e para cada um deles ele executa o que estiver dentro do bloco, talvez você já saiba isso mas né  :XD:, e na vez de cada um o que estiver entre || essa bagaça ae vai ser o que seria $game_party.members[0] ou $game_party.members[1].

Cada membro da equipe pertence a classe $game_actor, por isso o que criamos nele vai funcionar aqui.

Código: [Selecionar]
class Scene_Map < Scene_Base
  alias :tutorial_gst_map :update
  def update
    tutorial_gst_map
    $game_party.members.each do |act|
      if act.frio > act.frio_max
        act.frio = act.frio_max
      end
    end
  end
end

Essa foi a modificação na classe, agora o frio dele não ultrapassará o máximo definido no module, mas eu já ia me esquecendo, e caso não tenhamos no module a configuração de um actor da equipe? Portanto vamos colocar uma configuração predefinida para o frio máximo e depois uma condição no método frio_max:

Código: [Selecionar]
module Tutorial
  Actor = Array.new
 
  Frio_Predefinido = 50
  Frio_Max_Predefinido = 100
 
  Actor[1] = [
  Frio = 100,
  Frio_Max = 120,
  ]
 
  Actor[2] = [
  Frio = 120,
  Frio_Max = 150,
  ]
end

class Game_Actor < Game_Battler
  attr_accessor :frio
  alias :gst_tutorial :setup
  def setup(actor_id)
    gst_tutorial(actor_id)
    if Tutorial::Actor[actor_id].nil?
      @frio = Tutorial::Frio_Predefinido
    else
      @frio = Tutorial::Actor[actor_id][0]
    end
  end
  def frio_max
    if Tutorial::Actor[@actor_id].nil?
      return Tutorial::Frio_Max_Predefinido
    else
      return Tutorial::Actor[@actor_id][1]
    end
  end
end

Pronto, agora está tudo certo, tenho certeza que assim ficará tudo ok, se precisar de mais alguma coisa, e novamente se não entender também eu explico melhor!  :XD:

Akira!

Resposta 7: 14/12/2014 às 13:28

Perfeito @miguel! Obrigado mesmo!
Só mais uma coisinha, eu consigo alterar os valores de cada um assim por exemplo:
Código: (ruby) [Selecionar]
$game_actors[id].frio += 10Como faço pra usar um item?
Tipo, eu tenho um item tocha, quero aumentar o valor no personagem que usar a tocha sacou?!
Desculpe o incomodo!

miguel8884

Resposta 8: 14/12/2014 às 14:04

Sim você pode usar $game_actors para alterar só não sei se na equipe vai funcionar!

Acho melhor usar $game_party.members[id].frio

Só não entendi direito, você quer que quando use a tocha, o valor mude, ou apenas por possuir o item ele já altere?

Akira!

Resposta 9: 14/12/2014 às 14:16

Certo, tenho um item tocha, que ao usar vai chamar um evento comum, quero que o valor frio mude para o herói que usar o item!

miguel8884

Resposta 10: 14/12/2014 às 15:04

Ah acho que entendi, deixa eu ver aqui, na verdade, você pode fazer uma alteração em um método do game_actor ou battler não lembro qual vou ver aqui, é um pouco avançado, por isso não vou explicar, vou deixar  código pra você aí você só faz o que eu falar!

Código: [Selecionar]
module Tutorial
  Actor = Array.new
 
  Frio_Predefinido = 50
  Frio_Max_Predefinido = 100
 
  Actor[1] = [
  Frio = 100,
  Frio_Max = 120,
  ]
 
  Actor[2] = [
  Frio = 120,
  Frio_Max = 150,
  ]
end

class Game_Actor < Game_Battler
  attr_accessor :frio
  alias :gst_tutorial :setup
  def setup(actor_id)
    gst_tutorial(actor_id)
    if Tutorial::Actor[actor_id].nil?
      @frio = Tutorial::Frio_Predefinido
    else
      @frio = Tutorial::Actor[actor_id][0]
    end
  end
  def frio_max
    if Tutorial::Actor[@actor_id].nil?
      return Tutorial::Frio_Max_Predefinido
    else
      return Tutorial::Actor[@actor_id][1]
    end
  end
  alias :gst_tutorial_use_item :use_item
  def use_item(item)
    gst_tutorial_use_item
    if item.note.match(/Frio=(\d+)/im)
      @frio -= $1
    end
  end
end

class Scene_Map < Scene_Base
  alias :tutorial_gst_map :update
  def update
    tutorial_gst_map
    $game_party.members.each do |act|
      if act.frio > act.frio_max
        act.frio = act.frio_max
      end
    end
  end
end

Aí você vai colocar na nota do item assim

Frio=value

No lugar de value coloca quanto vai descer de frio ao usar o item!

Akira!

Resposta 11: 14/12/2014 às 16:48

Tá dando erro quando eu uso o item:
Código: (ruby) [Selecionar]
Script 'xxxxx' line 39: ArgumentError occurred.
Wrong number of arguments (0 for 1)
A linha é essa:
Código: (ruby) [Selecionar]
gst_tutorial_use_item use_item
Outra coisa, como coloco mais variáveis no Scene_Map que me passou?
Coloquei mais valores no array do módulo mas não consegui atualizar no Scene_Map!
Desculpe o incomodo e mais uma vez obrigado pela atenção!

miguel8884

Resposta 12: 16/12/2014 às 18:29

Deu esse erro pois acabei esquecendo de colocar o parametro no alias também  :facepalm:. Se me der um tempinho, eu faço aqui, coloque o script aí para eu ver por que não está atualizando direito.

Enter

  • *
  • Posts: 219
  • Ouros: 133
  • The Game Has Changed
Resposta 13: 05/02/2015 às 17:55

Oi. Eu queria entender por que tem que criar um frio pré-definido caso não seja encontrada a id do herói:
Citar
  if Tutorial::Actor[actor_id].nil?
      @frio = Tutorial::Frio_Predefinido
    else
      @frio = Tutorial::Actor[actor_id][0]
    end
Citar
Pronto, assim caso a array actor do module não possua o id do actor em questão, ela cria a variável frio com  definido no module como predefinido!

Acho que é isso, se não entender alguma coisa só perguntar, não sou muito bom em explicar XD
Como assim: caso não seja encontrada a id do herói? Tipo, todos os actors tem id, quando que da nil?

Obgd

Brandt

Resposta 14: 08/02/2015 às 06:14 - Última modificação por Masked em 08/02/2015 às 06:22

Tomei a liberdade de corrigir o script:
Código: [Selecionar]
module Tutorial
  Actor = []
 
  Frio_Predefinido = 50
  Frio_Max_Predefinido = 100
 
  Actor[1] = {
  :frio = 100,
  :max = 120,
  }
 
  Actor[2] = {
  :frio = 120,
  :max = 150,
  }
end

class Game_Actor < Game_Battler
  attr_reader :frio
  alias gst_tutorial setup
  def setup(actor_id)
    gst_tutorial(actor_id)
    unless Tutorial::Actor[actor_id]
      @frio = Tutorial::Frio_Predefinido
    else
      @frio = Tutorial::Actor[actor_id][:frio]
    end
  end

  def frio=(x)
    @frio = x
    @frio = frio_max if @frio > frio_max
    @frio = 0 if @frio < 0
  end

  def frio_max
    unless Tutorial::Actor[@actor_id]
      return Tutorial::Frio_Max_Predefinido
    else
      return Tutorial::Actor[@actor_id][:max]
    end
  end
  alias gst_tutorial_use_item use_item
  def use_item(item)
    gst_tutorial_use_item(item)
    if item.note =~ /Frio[ ]*=[ ]*(\d+)/i
      @frio -= $1
    end
  end
end

Miguel, tinha uns erros bem básicos aí cara, por exemplo as arrays que você usou pra configuração, se quiser dar nome aos valores use um Hash, que serve pra isso.

Tem também vários "if objeto.nil?", em vez disso, use "unless objeto", o primeiro só vai gastar tempo.

Tem também o jeito que você deu de evitar que o frio passasse do limite, que nem funciona se você estiver no menu, não evita valores negativos e gasta tempo da atualização da Scene_Map todo frame, em vez disso crie um método de atribuição para a variável e faça a validação lá, levando em conta os valores negativos.

Até mais, qualquer coisa avise, Arck!, não pude testar, então talvez algum erro apareça...



@Enter: é preciso criar um frio padrão pra quem for usar não ter que definir um frio específico para cada personagem, e ele quis dizer que talvez o ID do personagem não estivesse na Array de configuração, não que o personagem não tem ID.
~ Masked