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.
Görev
KolayKarmaşı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,MAGICALveRANGEDdeğerlerini ekleyin. Bir private alandescription(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ürenattack(Character target)metodunu ve bir DamageType döndürengetDamageType()metodunu bildirin.Healable.java: İyileştirme yetenekleri için bir arayüz oluşturun. İyileştirme eylemini açıklayan bir String döndürenheal(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) velevel(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) birsetHealth(int health)metodu ekleyin. Sağlığı azaltan ve"[name] takes [damage] damage! Health: [health]/[maxHealth]"döndüren birtakeDamage(int damage)metodu oluşturun. Sağlık 0'dan büyükse true döndüren birisAlive()metodu ekleyin. Bir String döndüren soyut birgetCharacterClass()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 alanstrength(int) ekleyin. Constructor; name, maxHealth, level ve strength parametrelerini alır.getCharacterClass()metodunu"Warrior"döndürecek şekilde uygulayın.getDamageType()metodunuPHYSICALdö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 alanlarintelligence(int) vemana(int) ekleyin. Constructor; name, maxHealth, level, intelligence ve mana parametrelerini alır.getCharacterClass()metodunu"Mage"döndürecek şekilde uygulayın.getDamageType()metodunuMAGICALdö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:strengthCREATE_MAGE:name:maxHealth:level:intelligence:manaATTACK:attackerName:targetNameHEAL:mageName:amountSTATUS: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 healyazdı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 - AliveBu 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
}
}
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
1OOP Temelleri
Harici DosyalarOOP'ye GirişSınıflar ve Nesnelerthis Anahtar KelimesiMetotlarAlanlar (Öznitelikler)Yapıcı MetotYapıcı Metot Aşırı YüklemeÖzet - Basit Hesap Makinesi4Kalıtım
Temel Kalıtım (extends)super Anahtar KelimesiMetot Geçersiz Kılma (@Override)Yapıcı Metot ZincirlemeObject SınıfıTekli ve Çok Seviyeli KalıtımNeden Çoklu Sınıf Kalıtımı Yok?Özet - Çalışan Hiyerarşisi7Özel Metotlar ve Object Sınıfı
toString() Metoduequals() ve hashCode()clone() MetoducompareTo() ve ComparableComparator ArayüzüÖzet - Özel Sıralama2Erişim Belirleyiciler ve Kapsülleme
Erişim Seviyelerine Genel BakışGetter ve Setter MetotlarıBilgi Gizlemefinal Anahtar KelimesiÖzet - Banka Hesabı Yöneticisi5Polimorfizm
Metot Aşırı Yükleme TemelleriMetot Geçersiz Kılma (Çalışma Zamanı)Upcasting ve Downcastinginstanceof OperatörüSoyut Sınıflar ve MetotlarÖzet - Şekil Hesaplayıcı8İleri Düzey OOP Kavramları
Kompozisyon vs KalıtımAgregasyon vs KompozisyonDahili, Yuvalanmış ve Anonim SınıflarEnum'lar ve Enum MetotlarıRecords (Java 16+)Sealed Classes (Java 17+)11Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişSingleton KalıbıFactory KalıbıBuilder KalıbıObserver KalıbıStrategy Kalıbı14Final Meydan Okumaları
E-Öğrenme PlatformuBankacılık SistemiOyun Karakteri GeliştirmeAraç Kiralama Servisi3Sınıf Özellikleri ve Statik Üyeler
Instance ve Statik DeğişkenlerStatik MetotlarStatik BloklarSabitler (static final)Özet - Sayaç ve Utility6Arayüzler ve Soyut Sınıflar
Arayüzlere GirişArayüzleri UygulamaÇoklu Arayüz UygulamaArayüzlerde Default ve StaticSoyut Sınıflar ve ArayüzlerFonksiyonel ArayüzlerÖzet - Ödeme Sistemi9Generics
Generics'e GirişGeneric SınıflarGeneric MetotlarSınırlandırılmış Tip ParametreleriWildcard'lar (?, extends, super)Özet - Generic Container12Tasarım Kalıpları Bölüm 2
Komut KalıbıAdaptör KalıbıDekoratör KalıbıŞablon Metot KalıbıDurum KalıbıKompozit KalıbıYineleyici Kalıbı