Guardar valor de uma instancia de uma Classe

24 respostas
L

BOM DIAAAA

Venho a tentar tirar uma dúvida com vocês se possível,se puder me ajudar eu fico muito grato.

Eu estou criando um jogo em java de rpg porém me encontro em uma situação que não consigo sair dela,segue as informações a seguir…

O jogo tem:

Super Classe Heroi
int pontosDeVida
String Nome

Classe Mago extends Heroi
int pontosDeMagia

Classe Guerreiro extends Heroi
int forca

Classe Arqueiro extends Heroi

Depois que faço todos os procedimentos de gets sets e etc…
Aí vem a classe:

GeradorDeHerois

public Heroi retornarHeroi(ClassesEnum Classe){ // ClassesEnum Classe é um enumerador que usei para tentar deixar o código mais refinado.
Heroi retorne = null;

switch(Classe){
        case MAGO:
            retorne =  new Mago ();          // instancia um mago
            break;
            
        case GUERREIRO:
            retorne =  new Guerreiro();   // instancia um guerreiro
            break;
            
        case ARQUEIRO:
            retorne = new Arqueiro();   // instancia um arqueiro
            break;
    }
   
    return = retorne;
}

O problema​ vem agora…

Eu crio a classe Batalha

public class Batalha () {

public void EscolhaSuaClasse(){

escolha = SuaClasse();

Heroi retorne = null;
switch (escolha){

case 1:
           retorne = Mago;
          break;
          
      case 2:
          retorne = Guerreiro;
          break;
          
      case 3:
          retorne = Arqueiro;
          break;
          
      default:
             Imprime ("opção invalida")
          break;
          
  }

}

Ai eu dou a opção pro usuario escolher a classe que ele quer começar o jogo,
depois que o usuario escolhe a classe (mago,guerreiro ou arqueiro), a classe é instanciada automaticamente…
o problema de forma nítida vem agora…

como vou continuar o programa? acessar os metodos e atributos do heroi que foi instanciado,sendo que não sei qual classe o usuario escolheu?

por exemplo … digamos que vc entra nesse switch e escolhe mago…
o programa instancia o mago…

por eu programador não ter como saber se vc vai escolher mago,arqueiro ou guerreiro eu não consigo acessar os atributos e metodos depois que sai do escopo do switch

o que eu queria fazer era de alguma forma guardar essa instancia que o usuario vai gerar
e depois conseguir acessar os metodos e atributos dessa instancia.

mas até hoje eu não consegui achar nenhuma forma de fazer isso,jogar uma instancia em um lugar e resgatar ela depois para usar .

complementando… se fosse só uma classe,suponhamos,guerreiro!!

ai eu saberia que ele escolheria o guerreiro obrigatoriamente,ai depois era só continuar a batalha normalmente

exemplo:

public void luta () {

while (Guerreiro.getHp > 0 && InimigogetHp > 0){

/// comandos para a batalha acontecer

}

}

Se vocês souber a saída desse problema e puder me enviar o modelo do codigo/metodo que vou precisar eu agradeço muito.

24 Respostas

D

Tem várias opções:

Heroi heroi = null;
public class Batalha() {
 public void EscolhaSuaClasse() {
  escolha = SuaClasse();
  // Heroi retorne = null; //movido para fora do método
  switch (escolha) {
   case 1:
    heroi = Mago;
    //retorne = Mago;
    break;

   case 2:
    heroi = Guerreiro;
    //retorne = Guerreiro;
    break;

   case 3:
    heroi = Arqueiro;
    //retorne = Arqueiro;
    break;

   default:
    Imprime("opção invalida")
    break;

  }
 }
}

Agora estará acessível em toda classe.

Se o getHp for um método da classe Heroi:

while (heroi.getHp > 0 && InimigogetHp > 0){

E se precisar saber qual a classe do Heroi:

if(heroi instanceOf Mago) imprime("Mago");

Uma pergunta, o Mago tem pontos de força?

Se sim, não haveria necessidade de criar várias classes:

class Heroi {
  int pontosDeMagia;
  int pontosDeForca;
  /* ... */
  ClassesEnum classe;
  int obterPontosDeAtaque() {
    switch(classe) {
      MAGO: return pontosDeMagia;
      GUERREIRO: return pontosDeForca;
    }
  }
}
S

Suas classes não implementam a interface Heroi (ou extendem uma superclasse Heroi)?
Essa é a magia do polimorfismo, você vai manipular um objeto do tipo Heroi, sem precisar se preocupar se é um Mago, Guerreiro ou Arqueiro.

L

Bom dia , obrigado pela atenção e por tentar ajudar…

A hierarquia de classes está assim :

HERÓI ( classe genérica)
Que contém os atributos que todo herói tem;

Int PontosDeVida
String TipoHeroi // mágico ou físico

Classe MAGO herda de HEROI: logo ele vai ter
PontosDeVida (Herdado)
TipoHeroi (Herdado)

Int pontoDeMagia // característica só de heroi do tipo mágico.

classe GUERREIRO herda de HEROI; logo…
PontosDeVida (herdado)
Classe (Herdado)
PontosDeForça // característica que só classe de dano físico tem…

Logo , mago não tem o atributo pontos de força
Logo, Guerreiro não tem pontos de magia

Você poderia me dar um exemplo de como eu posso fazer isso que vc falou ?

Manipular a classe Heroi sem me preocupar se é um mago/guerreiro…

Digamos que vc instanciou mago ao escolher a opção 1 em switch case …

Como vc vai continuar o programa depois do switch ?

Digamos que vc quer exibir um método que imprimi na tela o status do mago

Públic void  status (){

Imprime Mago.getPontosDeVida

Imprime Mago.getPontosDeMagia

}

Como vc programador vai fazer isso,sendo que o usuário pode digitar 2 e instanciar um Guerreiro .

Obg novamente pela atencao, e caso tenha em mente uma ideia de código, escreve aqui por favor… ótimo dia

L

Diego…chegando em casa vou tentar ,obrigado pela atenção e por tentar me ajudar …

Se não fosse pedir muito teria como vc me dar um apoio via discord? Caso eu não consiga.Eu resolvendo essa situação eu já consigo terminar meu programa básico…

S

Ná prática, o que diferencia “ponto de magia” de “ponto de força” ou de “ponto de qualquer outro poder”?

Se esses pontos tem comportamentos diferentes, então sugiro que você crie uma classe Poder, com um atributo pontos
Aí na classe Heroi crie um atributo “poder” assim cada objeto Heroi poderá ter um poder específico. ( ou uma lista de poderes :smiley: )

E aí você cria subclasses de Poder, por exemplo Magia, Força, Velocidade

Nesse caso, a classe Heroi deveria fornecer um método pra isso, aí você especializa em cada caso.

L

DIego deu certo!!

agora só preciso saber como acessar os metodos da classe escolhida…

por exemplo…

switch (escolha){
        
    case 1:
        HeroiAtual = new Mago("ZEZAO",500,"MAGO",300);
        break;
        
    case 2:
        HeroiAtual = new Guerreiro();
        break;
        
    case 3: 
        HeroiAtual = new Arqueiro();
        
    default:
        System.out.println("OPÇÃO INVÁLIDA");
        break; 
       

    }

if (HeroiAtual.getClasse().equals("MAGO")) {
    System.out.println("MAGO CRIADO");
    HeroiAtual.StatusMago();  // eu n consigo ter acesso aos metodos do mago,da erro
}
D

Use cast

if (HeroiAtual.getClasse().equals("MAGO")) {
    System.out.println("MAGO CRIADO");
    Mago mago = (Mago) HeroiAtual;
    mago.StatusMago();
}

Seria melhor alterar a classe Heroi:

public void status() {
  switch(getClasse) {
    case "MAGO": System.out.println("MAGO CRIADO"); break;
    case "GUERREIRO": System.out.println("GUERREIRO CRIADO"); break;
  }
}

e depois para obter os status:

HeroiAtual.status();
S

Não seria melhor fazer um instanceof?

if (HeroiAtual instanceof Mago) {

Vocês estão dando à classe Heroi a responsabilidade de lidar com características específicas de cada subclasse.
Se o status varia de acordo com o tipo de Heroi, então esse método deveria ser implementado nas subclasses.

L

boA!! brigadao man…vcs estao me ajudando muito,to curtindo muito esse projeto do jogo

L

vou ler um pouco mais sobre instanceof, valeu mesmo staroski!!

Observe se minha linha de raciocínio esta razoável …

eu vou criar um metodo de ataque na classe heroi,como mago,guerreiro e arqueiro herdam de heroi
logo os tres vao ter esse metodo de ataque seguido de um @Override,certo?

exemplo…

public class heroi () {

public void atacar(){

}

public class Mago (){

@Override
public void atacar(){

}

imprima MAGO ATACOU

}

public class Guerreiro)(){

<a class="mention" href="/u/override">@Override</a>

public void atacar(){

IMPRIMA GUERREIRO ATACOU

}

ou seja… toda vez que eu chamar na batalha o heroi escolhido pelo usuario e chamar o metodo ataque

o ataque vai vir de acordo com a classe instanciada,certo?

suponhamos…
escolha = 1

switch (escolha){

case 1:

heroiescolhido = new mago

}
if (heroiescolhido.getclasse().equals(mago)){

heroiescolido.atacar();

}

MAGO ATACOU

L

Agora eu preciso pensar em uma forma de criar os ataques

vcs acham que fica muito feio criar um switch (escolhaSkil)
case 1 bomba de gelo
inimigo.hp -= 30

case2 bolsonario ice
inimigo.hp -= 2000

D

Eu usaria lista para os skills:

ArrayList<Skill> skills = new ArrayList<>();

Também pode usar Enum:

enum Skill {
    BOMBA_DE_GELO ("Bomba de Gelo", 30),
    BOLSONARIO_ICE ("Bolsonario Ice", 2000);
    String nome;
    int poder;
    Skill(String nome, int poder) {
      this.nome = nome;
      this.poder = poder;
    }
    int obterPoder() {return poder;}
}

inimigo.hp -= Skill.BOMBA_DE_GELO.obterPoder(); // exemplo
L

Eu criaria um array list em cada classe ? (mago,guerreiro e arqueiro) com as respectivas skills dele?

L

no caso desse Enum,

o certo seria eu criar um Enum pra cada classe né?

EnumSkiilMago
EnumSkillGuerreiro

eu preciso ver como ficaria o switch disso…

pq tenho que dar a opção pro usuario escolher…ele vai ler o nome da skil e escolher qual ele quer…

estilo pokemon/final fantasy

D

Sim mas não precisa de swich

exemplo:

class Mago {
    ArrayList<EnumSkiilMago> skills = new ArrayList<>();
}

public static void main() {
  Mago m = new Mago();
  m.skills.add(EnumSkiilMago.BOMBA_DE_GELO);
  m.skills.add(EnumSkiilMago.BOLSONARIO_ICE);
  // exemplo de usar magia
  int índice = scanner.nextInt();// entrada
  EnumSkiilMago skill = mago.skills.get(indice); // obtem o skill
  inimigo.hp -= skill.obterPoder(); // usa
}

pode exibir os skill assim:

for (int i = 0; i < m.skills.size(); i++) {
  System.out.println("" + i + "\t" + m.skills.get(i).obterNome());
}
L

Perfeitooooo… mas na hora que cheguei no for não consegui exibir a skill

public static void main(String[] args) {
    int indice;
    Scanner input = new Scanner(System.in);

Mago m = new Mago(“baba”,500,“bebe”,300);

m.skills.add(EnumSkiilMago.GELO_DIVINO);

m.skills.add(EnumSkiilMago.BOMBA_DE_GELO);

indice = input.nextInt();
EnumSkiilMago skill = Mago.skills.get(indice);

skill.obterpoder();

for (int i = 0; i < m.skills.size(); i++ {
        
        System.out.println("" + i + "\t" + m.skills.get(i).obterNome(); // da erro nessa linha
    }
L

@diego12 consegui … estava fazendo errado uma coisa aqui…brigadao man…

agora é só criar um desse para todas as classes né?

minha ideia é girar o jogo em um loop while

while (heroi.getHp > 0 && inimigo.getHp > 0){

/// comandos

aqui vai vir o array de lista de dano…

o do inimigo vai ser em random e o do heroi vai ser a escolha do usuario

}

S

Ainda não entendi pq você cismou com um switch para saber qual a classe de herói…

Seria só fazer assim:

heroiescolido.atacar();
println(heroiescolhido.getClasse());
L

Primeiramente,brigadão por estar tentando ajudar…

Eu consegui resolver o problema ,graças ao apoio de vocês…

O que eu me referi sobre switch dessa vez foi em relação aos ataques …

Exemplo…

Eu preciso montar um sistemas de ataque parecido com Pokémon ou final fantasy…

Aparece o nome da habilidade …
Você escolhe ela
E ela causa um dano …

Aí eu pensei o seguinte

Usar o método de ataque .
Detalhe, todas as classes (guerreiro,arqueiro e mago) herdam esse método(ataque) da classe genérica Herói .

O exemplo abaixo é só da classe guerreiro

Públic int Ataque (){

Imprime (1) Corte divino

Imprime (2) Corte duplo

Return input.nextInt

}

Na classe batalha …

Públic batalha (){
Int escolha;

Públic void Batalha (){

// supondo que o usuário ja instanciou um guerreiro.

Escolha = HeroiEscolhido.ataque ();

Switch (escolha) {

Case 1:

Imprime  CorteDivino;

Inimigo .getHp -=10;

break;

Case 2:

Imprime corte duplo;

Inimigo-= 50;

Break;

Default
Break

}
Porém não sei se isso é correto
Ou se está incoerente …

Boa noite =)))

L

@diego12… Como ficaria esse codigo pra remover hp do inimigo,se caso eu instanciasse o inimigo somente na classe batalha ?

Suponhamos que …
A classe Guerreiro tem o metodo de ataque…

public int atacar(){

System.out.println("================ ESCOLHA SEU ATAQUE =================");
        skills.add(EnumSkillGuerreiro.CORTE_DUPLO);
        skills.add(EnumSkillGuerreiro.CORTE_DIVINO);
        
        for (int i = 0; i < skills.size(); i++) {
            System.out.println("" + i + skills.get(i).name());
        }
        setIndice(input.nextInt());
        
        EnumSkillGuerreiro dano = skills.get(getIndice());
       
        Inimigo.hp -= skill.obterPoder(); // VAI DAR ERRO PORQUE  O INIMIGO So passa a existir na classe batalha.
       
     return getIndice();
}

}

L

Consegui aqui…obrigado mesmo assim …

L

@diego12 como ficaria esse mesmo codigo só que uma skill de cura pro mago? eu tentei mas não deu certo

D

Eu adicionaria mais um atributo ao EnumSkiilMago, e ficaria mais ou menos assim:

Mago m = new Mago();
  m.skills.add(EnumSkiilMago.BOMBA_DE_GELO);
  m.skills.add(EnumSkiilMago.CURA);
  // exemplo de usar magia
  int índice = scanner.nextInt();// entrada
  EnumSkiilMago skill = mago.skills.get(indice); // obtem o skill
  if (skill.obterTipo().equals("ataque"))
    inimigo.hp -= skill.obterPoder(); // usa
  if (skill.obterTipo().equals("cura"))
    herói.hp += skill.obterPoder(); // usa
  if (skill.obterTipo().equals("buff_def"))
    herói.defesa += skill.obterPoder(); // usa
S

A classe da Skill poderia ter um método aplicar(Personagem p)
Aí cada implementação saberia o que fazer e seu código não precisaria dessa montoeira de if.

Criado 25 de abril de 2018
Ultima resposta 6 de mai. de 2018
Respostas 24
Participantes 3