Menu
Coddy logo textTech

Oyun Karakteri Geliştirme

Coddy'nin Java Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 86 / 87.

Bu meydan okuma, karmaşık ve etkileşimli varlıkları modellemede OOP'nin gücünü sergileyen bir Oyun Karakteri Geliştirme sistemi oluşturmanızı sağlıyor.

Temel bir Character sınıfının sağlık, isim ve seviye gibi ortak nitelikleri tanımladığı bir karakter hiyerarşisi tasarlayın. Warrior, Mage ve Archer gibi özelleşmiş sınıflar, bu temeli benzersiz yetenekler ve dövüş stilleriyle genişletir.

Arayüzler burada doğal bir şekilde çalışır: Attackable savaş yöntemlerini tanımlayabilirken, Healable iyileştirme yeteneklerini yönetir. Bir Mage her ikisini de uygulayabilir, buna karşın bir Warrior yalnızca saldırmaya odaklanır.

Farklı saldırı davranışları için Strategy desenini kullanmayı düşünün; bu, karakterlerin dövüş stillerini dinamik olarak değiştirmesine olanak tanır. State deseni, davranışı etkileyen normal, zehirlenmiş veya sersemlemiş gibi karakter durumlarını yönetebilir.

Karakterlerin silahlardan ve zırhlardan miras almak yerine onlara "sahip olduğu" ekipman sistemleri için kompozisyon (composition) kullanmayı düşünün. Karakter sınıfları veya hasar türleri için enum'ları kullanın ve istatistikleri geçersiz değişikliklerden korumak için kapsülleme (encapsulation) uygulayın.

challenge icon

Görev

Kolay

Karmaşık ve etkileşimli oyun varlıklarını modellemede OOP'nin gücünü sergileyen bir Oyun Karakteri Geliştirme sistemi inşa edelim! Farklı dövüş stillerine, özel yeteneklere ve karakterlerin nasıl davranacağını etkileyen bir durum sistemine sahip bir karakter hiyerarşisi oluşturacaksınız.

Kodunuzu yedi dosya halinde düzenleyeceksiniz:

  • DamageType.java: Oyundaki farklı hasar türlerini temsil eden bir enum oluşturun. PHYSICAL, MAGICAL ve RANGED değerlerini ekleyin. Bir private alan description (String), bunu ayarlayan bir constructor ve bir getter ekleyin. Fiziksel hasarın açıklaması "brute force", büyülü hasarın "arcane energy" ve menzilli hasarın "precision strike" olmalıdır.
  • Attackable.java: Savaş yeteneklerini tanımlayan bir arayüz (interface) oluşturun. Saldırıyı açıklayan bir String döndüren attack(Character target) metodunu ve bir DamageType döndüren getDamageType() metodunu bildirin.
  • Healable.java: İyileştirme yetenekleri için bir arayüz oluşturun. İyileştirme eylemini açıklayan bir String döndüren heal(int amount) metodunu bildirin.
  • Character.java: Tüm oyun karakterleri için soyut (abstract) bir temel sınıf oluşturun. name (String), health (int), maxHealth (int) ve level (int) için private alanlar ekleyin. Constructor; name, maxHealth ve level parametrelerini alır ve başlangıçta health değerini maxHealth'e eşitler. Tüm alanlar için getter'ları ekleyin. Sağlığın 0 ile maxHealth arasında kalmasını sağlayan korumalı (protected) bir setHealth(int health) metodu ekleyin. Sağlığı azaltan ve "[name] takes [damage] damage! Health: [health]/[maxHealth]" döndüren bir takeDamage(int damage) metodu oluşturun. Sağlık 0'dan büyükse true döndüren bir isAlive() metodu ekleyin. Bir String döndüren soyut bir getCharacterClass() metodu bildirin.
  • Warrior.java: Character sınıfını genişleten ve Attackable arayüzünü uygulayan bir sınıf oluşturun. Bir private alan strength (int) ekleyin. Constructor; name, maxHealth, level ve strength parametrelerini alır. getCharacterClass() metodunu "Warrior" döndürecek şekilde uygulayın. getDamageType() metodunu PHYSICAL döndürecek şekilde uygulayın. attack(Character target) metodunu; strength artı level kadar hasar verecek, hedefin takeDamage metodunu çağıracak ve "[name] strikes with [damageType description] for [damage] damage!" ifadesini, ardından bir alt satır ve takeDamage sonucunu döndürecek şekilde uygulayın.
  • Mage.java: Character sınıfını genişleten ve hem Attackable hem de Healable arayüzlerini uygulayan bir sınıf oluşturun. Private alanlar intelligence (int) ve mana (int) ekleyin. Constructor; name, maxHealth, level, intelligence ve mana parametrelerini alır. getCharacterClass() metodunu "Mage" döndürecek şekilde uygulayın. getDamageType() metodunu MAGICAL döndürecek şekilde uygulayın. attack(Character target) metodunu; intelligence çarpı 2 kadar hasar verecek şekilde, Warrior ile aynı formatı izleyerek uygulayın. heal(int amount) metodunu; sağlığı geri kazandıracak (setHealth kullanarak) ve "[name] channels healing magic! Health: [health]/[maxHealth]" döndürecek şekilde uygulayın.
  • Main.java: Oyun sisteminizi hayata geçirin! Virgülle ayrılmış bir komut dizisi alacaksınız:
    • CREATE_WARRIOR:name:maxHealth:level:strength
    • CREATE_MAGE:name:maxHealth:level:intelligence:mana
    • ATTACK:attackerName:targetName
    • HEAL:mageName:amount
    • STATUS:characterName

    Bir karakter koleksiyonu tutun. Her komutu işleyin ve şunları yazdırın:

    • CREATE_WARRIOR/CREATE_MAGE: [name] the [characterClass] joins the battle!
    • ATTACK: Saldırı sonucunu yazdırın (attack metodu tarafından döndürülen String)
    • HEAL: İyileştirme sonucunu yazdırın veya karakter bir Mage değilse [name] cannot heal yazdırın
    • STATUS: [name] ([characterClass]) - Level [level] - Health: [health]/[maxHealth] - [Alive/Defeated]

    Tüm komutlardan sonra, --- Battle Summary --- yazdırın ve ardından her karakterin durumunu listeleyin.

Bir girdi alacaksınız: virgülle ayrılmış komut dizisi.

Örneğin, CREATE_WARRIOR:Thorin:100:5:15,CREATE_MAGE:Gandalf:80:7:12:50,ATTACK:Thorin:Gandalf,HEAL:Gandalf:25,STATUS:Gandalf girdisi ile çıktınız şöyle olacaktır:

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

Bu meydan okuma; kalıtım (Character hiyerarşisi), çoklu arayüz uygulaması (Mage hem Attackable hem de Healable uygular), metodlu enumlar (DamageType), polimorfizm (farklı karakter türlerine tek tip davranma) ve kapsüllemeyi (korumalı sağlık yönetimi) ilgi çekici bir oyun sisteminde birleştirir!

Kopya kağıdı

Nesne yönelimli programlama (OOP), karmaşık sistemlerin sınıflar, kalıtım, arayüzler ve tasarım desenleri aracılığıyla modellenmesine olanak tanır.

Sınıf Hiyerarşisi

Ortak özniteliklere sahip bir temel sınıf oluşturun ve bunu özelleştirilmiş sınıflarla genişletin:

public abstract class Character {
    private String name;
    private int health;
    private int maxHealth;
    private int level;
    
    public Character(String name, int maxHealth, int level) {
        this.name = name;
        this.maxHealth = maxHealth;
        this.health = maxHealth;
        this.level = level;
    }
    
    protected void setHealth(int health) {
        this.health = Math.max(0, Math.min(health, maxHealth));
    }
    
    public abstract String getCharacterClass();
}

Arayüzler

Sınıfların uygulayabileceği belirli davranışlar için sözleşmeler tanımlayın:

public interface Attackable {
    String attack(Character target);
    DamageType getDamageType();
}

public interface Healable {
    String heal(int amount);
}

Alanlı Enum'lar

Enum'lar alanlara, yapıcılara ve metotlara sahip olabilir:

public enum DamageType {
    PHYSICAL("brute force"),
    MAGICAL("arcane energy"),
    RANGED("precision strike");
    
    private String description;
    
    private DamageType(String description) {
        this.description = description;
    }
    
    public String getDescription() {
        return description;
    }
}

Çoklu Arayüz Uygulama

Bir sınıf birden fazla arayüzü uygulayabilir:

public class Mage extends Character implements Attackable, Healable {
    private int intelligence;
    private int mana;
    
    @Override
    public String attack(Character target) {
        // Implementation
    }
    
    @Override
    public String heal(int amount) {
        // Implementation
    }
}

Kapsülleme

Erişimi kontrol etmek ve verileri doğrulamak için korumalı (protected) ayarlayıcılar ile özel (private) alanlar kullanın:

protected void setHealth(int health) {
    this.health = Math.max(0, Math.min(health, maxHealth));
}

Çok Biçimlilik

Farklı karakter türlerini ortak temel sınıfları veya arayüzleri aracılığıyla tek tip olarak ele alın; bu, esnek koleksiyonlara ve metot çağrılarına olanak tanır.

Kendin dene

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: Karakterleri tutmak için bir koleksiyon kullanın (LinkedHashMap ekleme sırasını korur)
        // LinkedHashMap<String, Character> characters = new LinkedHashMap<>();
        
        // TODO: Girdiyi tekil komutları almak için virgüle göre bölün
        // String[] commands = input.split(",");
        
        // TODO: Her komutu işleyin:
        // - CREATE_WARRIOR:name:maxHealth:level:strength
        //   Yazdır: "[name] the Warrior joins the battle!"
        // 
        // - CREATE_MAGE:name:maxHealth:level:intelligence:mana
        //   Yazdır: "[name] the Mage joins the battle!"
        // 
        // - ATTACK:attackerName:targetName
        //   attack metodundan gelen saldırı sonucunu yazdırın
        // 
        // - HEAL:mageName:amount
        //   İyileştirme sonucunu yazdırın veya Mage değilse "[name] cannot heal" yazdırın
        // 
        // - STATUS:characterName
        //   Yazdır: "[name] ([characterClass]) - Level [level] - Health: [health]/[maxHealth] - [Alive/Defeated]"
        
        // TODO: Tüm komutlardan sonra "--- Battle Summary ---" yazdırın
        // Ardından her karakterin durumunu yazdırın
    }
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler