Menu
Coddy logo textTech

Desarrollo de personajes de videojuegos

Parte de la sección Programación Orientada a Objetos del Journey de Java de Coddy. Lección 86 de 87.

Este desafío te pide construir un sistema de desarrollo de personajes de juego que muestre el poder de la POO para modelar entidades complejas e interactivas.

Diseña una jerarquía de personajes en la que una clase base Character defina atributos comunes como salud, nombre y nivel. Las clases especializadas, como Warrior, Mage y Archer, extienden esta base con habilidades únicas y estilos de combate.

Las interfaces funcionan de forma natural aquí: Attackable podría definir métodos de combate, mientras que Healable gestiona las habilidades de restauración. Un Mage podría implementar ambas, mientras que un Warrior se centra únicamente en atacar.

Considera usar el patrón Strategy para diferentes comportamientos de ataque, lo que permite que los personajes cambien dinámicamente de estilo de combate. El patrón State podría gestionar condiciones de los personajes, como los estados normal, envenenado o aturdido, que afectan al comportamiento.

Piensa en la composición para sistemas de equipamiento donde los personajes «tienen» armas y armaduras en lugar de heredar de ellas. Usa enumeraciones para las clases de personajes o los tipos de daño, y aplica la encapsulación para proteger las estadísticas de modificaciones no válidas.

challenge icon

Desafío

Fácil

¡Construyamos un sistema de desarrollo de personajes de juego que muestre el poder de la POO para modelar entidades de juego complejas e interactivas! Crearás una jerarquía de personajes con diferentes estilos de combate, habilidades especiales y un sistema de estados que afecta a la forma en que se comportan los personajes.

Organizarás tu código en siete archivos:

  • DamageType.java: Crea un enum que represente diferentes tipos de daño en el juego. Incluye los valores PHYSICAL, MAGICAL y RANGED. Añade un campo privado description (String), un constructor que lo establezca y un getter. El daño físico debe tener la descripción "brute force", el daño mágico debe tener "arcane energy" y el daño a distancia debe tener "precision strike".
  • Attackable.java: Crea una interfaz que defina las capacidades de combate. Declara los métodos attack(Character target), que devuelve un String que describe el ataque, y getDamageType(), que devuelve un DamageType.
  • Healable.java: Crea una interfaz para las habilidades de restauración. Declara un método heal(int amount) que devuelva un String que describa la acción de curación.
  • Character.java: Crea una clase base abstracta para todos los personajes del juego. Incluye campos privados para name (String), health (int), maxHealth (int) y level (int). El constructor recibe name, maxHealth y level, y establece inicialmente health igual a maxHealth. Incluye getters para todos los campos. Añade un método protegido setHealth(int health) que garantice que health se mantenga entre 0 y maxHealth. Crea un método takeDamage(int damage) que reduzca health y devuelva "[name] takes [damage] damage! Health: [health]/[maxHealth]". Añade un método isAlive() que devuelva true si health es mayor que 0. Declara un método abstracto getCharacterClass() que devuelva un String.
  • Warrior.java: Crea una clase que extienda Character e implemente Attackable. Añade un campo privado strength (int). El constructor recibe name, maxHealth, level y strength. Implementa getCharacterClass() para que devuelva "Warrior". Implementa getDamageType() para que devuelva PHYSICAL. Implementa attack(Character target) para infligir un daño igual a strength más level, llamar al método takeDamage del objetivo y devolver "[name] strikes with [damageType description] for [damage] damage!", seguido de un salto de línea y del resultado de takeDamage.
  • Mage.java: Crea una clase que extienda Character e implemente tanto Attackable como Healable. Añade los campos privados intelligence (int) y mana (int). El constructor recibe name, maxHealth, level, intelligence y mana. Implementa getCharacterClass() para que devuelva "Mage". Implementa getDamageType() para que devuelva MAGICAL. Implementa attack(Character target) para infligir un daño igual a intelligence multiplicado por 2, siguiendo el mismo formato que Warrior. Implementa heal(int amount) para restaurar health (usando setHealth) y devolver "[name] channels healing magic! Health: [health]/[maxHealth]".
  • Main.java: ¡Da vida a tu sistema de juego! Recibirás un String de comandos separados por comas:
    • CREATE_WARRIOR:name:maxHealth:level:strength
    • CREATE_MAGE:name:maxHealth:level:intelligence:mana
    • ATTACK:attackerName:targetName
    • HEAL:mageName:amount
    • STATUS:characterName

    Mantén una colección de personajes. Procesa cada comando e imprime:

    • CREATE_WARRIOR/CREATE_MAGE: [name] the [characterClass] joins the battle!
    • ATTACK: Imprime el resultado del ataque (el String devuelto por el método attack)
    • HEAL: Imprime el resultado de la curación, o [name] cannot heal si el personaje no es un Mage
    • STATUS: [name] ([characterClass]) - Level [level] - Health: [health]/[maxHealth] - [Alive/Defeated]

    Después de todos los comandos, imprime --- Battle Summary --- seguido del estado de cada personaje.

Recibirás una entrada: el String de comandos separados por comas.

Por ejemplo, con la entrada CREATE_WARRIOR:Thorin:100:5:15,CREATE_MAGE:Gandalf:80:7:12:50,ATTACK:Thorin:Gandalf,HEAL:Gandalf:25,STATUS:Gandalf, tu salida sería:

Thorin the Warrior joins the battle!
Gandalf the Mage joins the battle!
Thorin strikes with brute force for 20 damage!
Gandalf takes 20 damage! Health: 60/80
Gandalf channels healing magic! Health: 80/80
Gandalf (Mage) - Level 7 - Health: 80/80 - Alive
--- Battle Summary ---
Thorin (Warrior) - Level 5 - Health: 100/100 - Alive
Gandalf (Mage) - Level 7 - Health: 80/80 - Alive

¡Este desafío combina la herencia (jerarquía de Character), la implementación de múltiples interfaces (Mage implementa tanto Attackable como Healable), los enums con métodos (DamageType), el polimorfismo (tratar de forma uniforme distintos tipos de personajes) y la encapsulación (gestión protegida de health) en un sistema de juego atractivo!

Pruébalo tú mismo

import java.util.Scanner;
import java.util.HashMap;
import java.util.Map;
import java.util.LinkedHashMap;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String input = scanner.nextLine();
        
        // TODO: Usa una colección para mantener los personajes (LinkedHashMap preserva el orden de inserción)
        // LinkedHashMap<String, Character> characters = new LinkedHashMap<>();
        
        // TODO: Divide la entrada por comas para obtener los comandos individuales
        // String[] commands = input.split(",");
        
        // TODO: Procesa cada comando:
        // - CREATE_WARRIOR:name:maxHealth:level:strength
        //   Print: "[name] the Warrior joins the battle!"
        // 
        // - CREATE_MAGE:name:maxHealth:level:intelligence:mana
        //   Print: "[name] the Mage joins the battle!"
        // 
        // - ATTACK:attackerName:targetName
        //   Imprime el resultado del ataque del método attack
        // 
        // - HEAL:mageName:amount
        //   Imprime el resultado de la curación, o "[name] cannot heal" si no es un Mage
        // 
        // - STATUS:characterName
        //   Imprime: "[name] ([characterClass]) - Level [level] - Health: [health]/[maxHealth] - [Alive/Defeated]"
        
        // TODO: After all commands, print "--- Battle Summary ---"
        // Luego imprime el estado de cada personaje
    }
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos

Practica por tu cuenta: Compilador de Java online