Componente de Personagem de Jogo
Parte da seção Programação Orientada a Objetos do Journey de C# da Coddy. Lição 69 de 70.
Desafio
FácilVamos criar um sistema de personagens de jogo usando o padrão de arquitetura baseado em componentes! Em vez de criar hierarquias rígidas de herança, você vai compor personagens anexando componentes independentes que lidam com comportamentos específicos — uma abordagem flexível amplamente usada no desenvolvimento de jogos.
Você vai organizar seu código em cinco arquivos:
IComponent.cs: Defina uma interfaceIComponentno namespaceGame.Components. Todo componente deve ter um métodoUpdate()que imprime o que o componente está fazendo.HealthComponent.cs: Crie uma classeHealthComponentque implementeIComponent. Ela deve acompanhar os pontos de vida atuais e máximos, com métodosTakeDamage(int amount)eHeal(int amount). A vida nunca deve ficar abaixo de 0 nem acima do máximo. Inclua umevent Action<int> HealthChangedque seja acionado sempre que a vida mudar, passando o novo valor de vida. O métodoUpdate()deve imprimir o status atual da vida.InventoryComponent.cs: Crie uma classeInventoryComponentque implementeIComponent. Ela gerencia uma lista de nomes de itens com os métodosAddItem(string item)eRemoveItem(string item)(retornaboolindicando o sucesso). O métodoUpdate()deve imprimir o conteúdo do inventário.Character.cs: Crie uma classeCharacterno namespaceGameque mantenha uma coleção de componentes. Seu personagem precisa de uma propriedadeNamee destes métodos:AddComponent(IComponent component)- anexa um componente ao personagemGetComponent<T>()where T : IComponent - retorna o primeiro componente do tipo T ou null se não for encontradoUpdateAll()- chamaUpdate()em cada componente anexado
Program.cs: Reúna tudo criando um personagem, anexando componentes e processando comandos.
Você receberá as seguintes entradas:
- Nome do personagem
- Vida máxima inicial do HealthComponent
- Número de comandos a serem processados
- Para cada comando: a ação seguida dos dados relevantes
Formatos dos comandos:
damage
{amount}
heal
{amount}
add_item
{itemName}
remove_item
{itemName}
updateFormatos da saída:
- Quando a vida mudar (por meio do evento):
Health changed: {newHealth} - Ao adicionar um item:
Added: {itemName} - Ao remover um item:
Removed: {itemName}ouItem not found: {itemName} Update()de HealthComponent:Health: {current}/{max}Update()de InventoryComponent:Inventory: {item1}, {item2}, ...ouInventory: empty
Por exemplo, se as entradas forem:
Hero
100
7
add_item
Sword
add_item
Shield
damage
30
heal
10
remove_item
Potion
remove_item
Sword
updateA saída deverá ser:
Added: Sword
Added: Shield
Health changed: 70
Health changed: 80
Item not found: Potion
Removed: Sword
Health: 80/100
Inventory: ShieldObserve como o personagem não herda de nada especial — ele simplesmente mantém componentes que fornecem comportamentos. O método GetComponent<T>() usa genéricos para uma recuperação segura quanto ao tipo, e os eventos notificam quando a vida muda. Essa abordagem de composição permite combinar componentes livremente!
Experimente você mesmo
using System;
using Game;
using Game.Components;
class Program
{
public static void Main(string[] args)
{
// Lê o nome do personagem
string characterName = Console.ReadLine();
// Lê a vida máxima inicial
int maxHealth = Convert.ToInt32(Console.ReadLine());
// Lê o número de comandos
int numCommands = Convert.ToInt32(Console.ReadLine());
// TODO: Criar um Character com o nome fornecido
// TODO: Criar HealthComponent com maxHealth e InventoryComponent
// TODO: Inscrever-se no evento HealthChanged para imprimir: Health changed: {newHealth}
// TODO: Adicionar ambos os componentes ao personagem
// TODO: Processar cada comando
for (int i = 0; i < numCommands; i++)
{
string command = Console.ReadLine();
// TODO: Lidar com cada tipo de comando:
// - "damage": ler a quantidade, chamar TakeDamage no componente de saúde
// - "heal": ler a quantidade, chamar Heal no componente de saúde
// - "add_item": ler o nome do item, chamar AddItem no componente de inventário
// - "remove_item": ler o nome do item, chamar RemoveItem no componente de inventário
// - "update": chamar UpdateAll no personagem
}
}
}
Todas as lições de Programação Orientada a Objetos
1Fundamentos de POO
Arquivos ExternosNamespaces e DiretivasIntrodução a Classes e ObjetosA Palavra-chave 'this'Métodos e ParâmetrosCampos vs PropriedadesConstrutoresInicializadores de ObjetosRecapitulação - Calculadora Simples4Herança
Sintaxe Básica de Herança (:)A Palavra-chave 'base'Palavras-chave Virtual e OverrideClasses SeladasA Classe Base 'object'Recapitulação - Hierarquia de Funcionários7Recursos Avançados
Sobrecarga de OperadoresIndexadores (this[])Sobrescrita de ToString()Métodos de ExtensãoRecapitulação - Lista Personalizada10Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoSingleton Thread-SafePadrão FactoryPadrão Observer (Eventos)Padrão Strategy13Desafios Finais
Plataforma de E-learningComponente de Personagem de JogoServiço de Aluguel de Veículos2Propriedades e Membros Estáticos
Propriedades AutoimplementadasPropriedades de Apenas Leitura/EscritaCampos e Métodos EstáticosClasses EstáticasMembros com Corpo de Expressão5Polimorfismo e Interfaces
Polimorfismo: Compilação vs ExecuçãoInterface vs Classe AbstrataMúltiplas InterfacesInterfaces ExplícitasUpcasting e DowncastingRecapitulação - Calculadora de Formas8Conceitos Avançados de POO
Composição sobre HerançaGenerics (Classes e Métodos)Delegates e EventosAtributos e ReflectionIDisposable e a Instrução usingFundamentos de Injeção de Dependência11Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão Composite3Arquitetura de Classes
Dados de Instância vs EstáticosPalavras-chave 'readonly' e 'const'Campos de SuporteRecapitulação - Gerenciador de Conta Bancária6Encapsulamento
Modificadores de AcessoPropriedades para EncapsulamentoImplementação de Ocultação de DadosPadrões de ImutabilidadeRecapitulação - Registros de Estudantes9Argumentos Variáveis
A Palavra-chave 'params'Parâmetros OpcionaisArgumentos NomeadosSobrecarga de MétodosPratique por conta própria: Compilador de C# online