Menu
Coddy logo textTech

Componente de personaje de juego

Parte de la sección Programación Orientada a Objetos del Journey de C# de Coddy. Lección 69 de 70.

challenge icon

Desafío

Fácil

¡Construyamos un sistema de personajes para un juego usando el patrón de arquitectura basado en componentes! En lugar de crear jerarquías de herencia rígidas, compondrás personajes adjuntando componentes independientes que gestionan comportamientos específicos: un enfoque flexible muy utilizado en el desarrollo de juegos.

Organizarás tu código en cinco archivos:

  • IComponent.cs: Define una interfaz IComponent en el espacio de nombres Game.Components. Cada componente debe tener un método Update() que muestre lo que está haciendo el componente.
  • HealthComponent.cs: Crea una clase HealthComponent que implemente IComponent. Debe realizar un seguimiento de los puntos de salud actuales y máximos, con métodos TakeDamage(int amount) y Heal(int amount). La salud nunca debe ser inferior a 0 ni superior al máximo. Incluye un event Action<int> HealthChanged que se active cada vez que cambie la salud, pasando el nuevo valor de salud. El método Update() debe mostrar el estado actual de la salud.
  • InventoryComponent.cs: Crea una clase InventoryComponent que implemente IComponent. Gestiona una lista de nombres de objetos con los métodos AddItem(string item) y RemoveItem(string item) (devuelve bool para indicar si la operación tuvo éxito). El método Update() debe mostrar el contenido del inventario.
  • Character.cs: Crea una clase Character en el espacio de nombres Game que contenga una colección de componentes. Tu personaje necesita una propiedad Name y estos métodos:
    • AddComponent(IComponent component): adjunta un componente al personaje
    • GetComponent<T>() donde T : IComponent: devuelve el primer componente de tipo T, o null si no se encuentra
    • UpdateAll(): llama a Update() en cada componente adjunto
  • Program.cs: Une todo creando un personaje, adjuntando componentes y procesando comandos.

Recibirás las siguientes entradas:

  • Nombre del personaje
  • Salud máxima inicial para el HealthComponent
  • Número de comandos que se procesarán
  • Para cada comando: la acción seguida de los datos relevantes

Formatos de los comandos:

damage
{amount}

heal
{amount}

add_item
{itemName}

remove_item
{itemName}

update

Formatos de salida:

  • Cuando cambie la salud (mediante un evento): Health changed: {newHealth}
  • Al añadir un objeto: Added: {itemName}
  • Al eliminar un objeto: Removed: {itemName} o Item not found: {itemName}
  • Update() de HealthComponent: Health: {current}/{max}
  • Update() de InventoryComponent: Inventory: {item1}, {item2}, ... o Inventory: empty

Por ejemplo, si las entradas son:

Hero
100
7
add_item
Sword
add_item
Shield
damage
30
heal
10
remove_item
Potion
remove_item
Sword
update

La salida debería ser:

Added: Sword
Added: Shield
Health changed: 70
Health changed: 80
Item not found: Potion
Removed: Sword
Health: 80/100
Inventory: Shield

Observa que el personaje no hereda de nada especial; simplemente contiene componentes que proporcionan comportamiento. El método GetComponent<T>() utiliza genéricos para obtener componentes de forma segura según el tipo, y los eventos notifican cuando cambia la salud. ¡Este enfoque de composición te permite combinar componentes libremente!

Pruébalo tú mismo

using System;
using Game;
using Game.Components;

class Program
{
    public static void Main(string[] args)
    {
        // Leer el nombre del personaje
        string characterName = Console.ReadLine();
        
        // Leer la salud máxima inicial
        int maxHealth = Convert.ToInt32(Console.ReadLine());
        
        // Leer el número de comandos
        int numCommands = Convert.ToInt32(Console.ReadLine());
        
        // TODO: Crear un Character con el nombre dado
        
        // TODO: Crear HealthComponent con maxHealth e InventoryComponent
        
        // TODO: Suscribirse al evento HealthChanged para imprimir: Health changed: {newHealth}
        
        // TODO: Agregar ambos componentes al personaje
        
        // TODO: Procesar cada comando
        for (int i = 0; i < numCommands; i++)
        {
            string command = Console.ReadLine();
            
            // TODO: Manejar cada tipo de comando:
            // - "damage": leer la cantidad, llamar a TakeDamage en el componente de salud
            // - "heal": leer la cantidad, llamar a Heal en el componente de salud
            // - "add_item": leer el nombre del objeto, llamar a AddItem en el componente de inventario
            // - "remove_item": leer el nombre del objeto, llamar a RemoveItem en el componente de inventario
            // - "update": llamar a UpdateAll en el personaje
        }
    }
}

Todas las lecciones de Programación Orientada a Objetos

Practica por tu cuenta: Compilador de C# online