Guardar valor de uma instancia de uma Classe

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.

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;
    }
  }
}
1 curtida

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.

1 curtida

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

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…

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.

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
}

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();
1 curtida

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.

1 curtida

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

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)(){

@Override
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

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

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

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

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

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());
}
1 curtida

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
    }

@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

}

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());
1 curtida

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 =)))