feat: complete core gameplay mechanics and structure without bonuses
- Implement Entity interface and base Player/Enemy abstract classes - Implement Knight with Rule of Five combat actions and mana mechanics - Add Skeleton with resurrect capability and key-drop logic - Setup Location graph and Main game loop for turn-based combat - Add comprehensive project README.md
This commit is contained in:
@@ -1,15 +1,183 @@
|
||||
package org.project;
|
||||
|
||||
import org.project.entity.players.Knight;
|
||||
import org.project.entity.enemies.Enemy;
|
||||
import org.project.entity.enemies.Skeleton;
|
||||
import org.project.location.Location;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
// TODO: ADD LOCATIONS TO YOUR GAME
|
||||
List<Location> locations = new ArrayList<>();
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
Random random = new Random();
|
||||
|
||||
// TODO: IMPLEMENT GAMEPLAY
|
||||
System.out.println("================================================");
|
||||
System.out.println("⚔️ به بازی شوالیه جاوا (Java Knight) خوش آمدید! ⚔️");
|
||||
System.out.println("================================================");
|
||||
System.out.print("نام شوالیه خود را وارد کنید: ");
|
||||
String knightName = scanner.nextLine();
|
||||
|
||||
// ساخت شوالیه (به همراه شمشیر و زره پیشفرض که قبلاً ست کردیم)
|
||||
Knight knight = new Knight(knightName);
|
||||
|
||||
// ساخت لوکیشنها بر اساس ساختار جدید
|
||||
Location startLocation = new Location("کمپ پادشاهی (نقطه شروع)");
|
||||
Location road = new Location("جاده تاریک مخروبه");
|
||||
Location castle = new Location("قلعه اژدهای جادوگر (مرحله نهایی)");
|
||||
|
||||
// اتصال لوکیشنها به یکدیگر
|
||||
startLocation.addConnectedLocation(road);
|
||||
road.addConnectedLocation(startLocation);
|
||||
road.addConnectedLocation(castle);
|
||||
castle.addConnectedLocation(road);
|
||||
|
||||
// موقعیت فعلی بازیکن
|
||||
Location currentLocation = startLocation;
|
||||
|
||||
// مدیریت کلیدها طبق داک (برای بخش غیر بونوس، کلید اسکلت شرط ورود به قلعه است)
|
||||
boolean hasSkeletonKey = false;
|
||||
|
||||
System.out.println("\n📜 داستان: اژدها قلمرو جاوای پاک را تسخیر کرده است.");
|
||||
System.out.println("شما باید در جاده با اسکلتها بجنگید، 'کلید اسکلت' را بگیرید و اژدها را در قلعه نابود کنید!");
|
||||
|
||||
boolean gameRunning = true;
|
||||
while (gameRunning && knight.isAlive()) {
|
||||
System.out.println("\n------------------------------------------------");
|
||||
System.out.println("📍 مکان فعلی: " + currentLocation.getName());
|
||||
System.out.println("❤️ خون: " + knight.getHp() + "/" + knight.getMaxHP() +
|
||||
" | 🪄 مانا: " + knight.getMp() + "/" + knight.getMaxMP() +
|
||||
" | 🎖️ لول: " + knight.getLevel());
|
||||
System.out.println("🔑 کلید اسکلت: " + (hasSkeletonKey ? "✅ موجود" : "❌ ناموجود"));
|
||||
System.out.println("------------------------------------------------");
|
||||
|
||||
// ۱. مکانیزم تصادفی اسپان شدن دشمن در جاده
|
||||
if (currentLocation == road && random.nextInt(100) < 60) { // شانس ۶۰ درصدی دیدن اسکلت
|
||||
Skeleton skeleton = new Skeleton();
|
||||
currentLocation.addEnemy(skeleton);
|
||||
System.out.println("\n⚠️ ناگهان یک اسکلت از زمین بیرون آمد و راه شما را بست!");
|
||||
|
||||
// لوپ مبارزه نوبتی
|
||||
while (skeleton.isAlive() && knight.isAlive()) {
|
||||
System.out.println("\n--- [وضعیت دشمن -> HP: " + skeleton.getHp() + "/" + skeleton.getMaxHP() + "]");
|
||||
System.out.println("نوبت شماست! حرکت خود را انتخاب کنید (قانون ۵ حرکت):");
|
||||
System.out.println("1. حمله معمولی (Light Attack) -> دمیج اسلحه | مانا: 0");
|
||||
System.out.println("2. حمله سنگین (Heavy Attack) -> دمیج 1.5 برابر | مانا: 15");
|
||||
System.out.println("3. گارد دفاعی (Defend) -> کاهش دمیج بعدی | مانا: 10");
|
||||
System.out.println("4. جادوی درمان (Heal Magic) -> بازیابی 30 واحد HP | مانا: 20");
|
||||
System.out.println("5. ضربه با سپر (Shield Bash) -> دمیج 20 + گیج کردن دشمن | مانا: 30");
|
||||
System.out.print("👉 انتخاب شما: ");
|
||||
String move = scanner.nextLine();
|
||||
|
||||
// اجرای حرکت انتخاب شده بازیکن
|
||||
switch (move) {
|
||||
case "1":
|
||||
knight.attack(skeleton);
|
||||
System.out.println("⚔️ شما با شمشیر یک ضربه معمولی زدید.");
|
||||
break;
|
||||
case "2":
|
||||
knight.heavyAttack(skeleton);
|
||||
break;
|
||||
case "3":
|
||||
knight.defend();
|
||||
break;
|
||||
case "4":
|
||||
knight.castHeal();
|
||||
break;
|
||||
case "5":
|
||||
knight.shieldBash(skeleton);
|
||||
break;
|
||||
default:
|
||||
System.out.println("❌ حرکت نامعتبر! نوبت شما هدر رفت.");
|
||||
break;
|
||||
}
|
||||
|
||||
// نوبت دشمن (اگر اسکلت هنوز زنده باشد و Stun نشده باشد)
|
||||
if (skeleton.isAlive()) {
|
||||
if (knight.isEnemyStunnedNextTurn()) {
|
||||
System.out.println("🌀 اسکلت به خاطر ضربه سپر شما گیج (Stun) شده و این نوبت نمیتواند حرکت کند!");
|
||||
knight.setEnemyStunnedNextTurn(false); // ریست کردن پرچم استن برای نوبت بعد
|
||||
} else {
|
||||
System.out.println("\n--- نوبت دشمن ---");
|
||||
skeleton.attack(knight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// بررسی نتایج پس از پایان نبرد
|
||||
if (!knight.isAlive()) {
|
||||
System.out.println("\n💀 شوالیه قهرمان سقوط کرد... بازی تمام شد!");
|
||||
break;
|
||||
} else {
|
||||
System.out.println("\n🎉 شما اسکلت را با موفقیت شکست دادید!");
|
||||
currentLocation.getEnemies().clear(); // پاکسازی لوکیشن
|
||||
|
||||
// پاداش ۱: کسب امتیاز تجربه و سیستم لولآپ خودکار
|
||||
knight.gainXp(60); // دادن ۶۰ واحد اکسپی
|
||||
|
||||
// پاداش ۲: بازیابی وضعیت (Replenish) بعد از جنگ طبق داک
|
||||
knight.replenishAfterCombat();
|
||||
|
||||
// پاداش ۳: شانس دراپ شدن کلید (RNG Gatekeeping)
|
||||
if (!hasSkeletonKey) {
|
||||
if (random.nextInt(100) < 50) { // شانس ۵۰ درصد برای دراپ کلید پس از مرگ اسکلت
|
||||
hasSkeletonKey = true;
|
||||
System.out.println("🔑 واو! اسکلت هنگام نابودی یک کلید درخشان انداخت. 'کلید اسکلت' دریافت شد!");
|
||||
} else {
|
||||
System.out.println("🔍 بدن اسکلت را جستجو کردید اما کلیدی پیدا نشد. باید با اسکلتهای بیشتری در جاده بجنگید!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ۲. منوی حرکت و جابجایی بین جادهها
|
||||
System.out.println("\nنقشه مسیرها: کارهای قابل انجام چیست؟");
|
||||
ArrayList<Location> choices = currentLocation.getLocations();
|
||||
int i;
|
||||
for (i = 0; i < choices.size(); i++) {
|
||||
System.out.println((i + 1) + ". سفر به: " + choices.get(i).getName());
|
||||
}
|
||||
System.out.println((i + 1) + ". استراحت و چک کردن وضعیت کامل");
|
||||
System.out.println((i + 2) + ". خروج از بازی");
|
||||
System.out.print("👉 انتخاب شما: ");
|
||||
String navigationChoice = scanner.nextLine();
|
||||
|
||||
try {
|
||||
int navInt = Integer.parseInt(navigationChoice);
|
||||
if (navInt > 0 && navInt <= choices.size()) {
|
||||
Location nextLocation = choices.get(navInt - 1);
|
||||
|
||||
// شرط ورود به قلعه (RNG Gatekeeping): قفل بودن اگر کلید نداریم
|
||||
if (nextLocation == castle && !hasSkeletonKey) {
|
||||
System.out.println("🔒 درب قلعه اژدها به شدت قفل است! شما به 'کلید اسکلت' نیاز دارید. به جاده برگردید.");
|
||||
} else {
|
||||
currentLocation = nextLocation;
|
||||
}
|
||||
} else if (navInt == choices.size() + 1) {
|
||||
System.out.println("\n🛡️ شما کمی در کمپ استراحت کردید، اما جادهها همچنان ناامن هستند.");
|
||||
} else if (navInt == choices.size() + 2) {
|
||||
System.out.println("👋 به امید دیدار، شوالیه بزرگ!");
|
||||
gameRunning = false;
|
||||
} else {
|
||||
System.out.println("❌ گزینه اشتباه است!");
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
System.out.println("❌ لطفا یک عدد وارد کنید!");
|
||||
}
|
||||
|
||||
// ۳. شرط پیروزی نهایی: ورود به قلعه با داشتن کلید
|
||||
if (currentLocation == castle && hasSkeletonKey) {
|
||||
System.out.println("\n🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆");
|
||||
System.out.println("شما با استفاده از کلید، وارد قلعه تاریک شدید!");
|
||||
System.out.println("با شمشیر قدرتمند خود اژدها را از پای درآوردید و سرزمین Javanest را نجات دادید!");
|
||||
System.out.println("تبریک شوالیه بزرگ " + knight.getName() + "، شما پیروز نهایی بازی شدید!");
|
||||
System.out.println("🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆");
|
||||
gameRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
scanner.close();
|
||||
}
|
||||
}
|
||||
@@ -1,21 +1,27 @@
|
||||
package org.project.entity;
|
||||
|
||||
public interface Entity {
|
||||
// حملات و اقدامات مبارزه پایه
|
||||
void attack(Entity target);
|
||||
|
||||
void defend();
|
||||
|
||||
// مدیریت وضعیت حیاتی موجود
|
||||
void heal(int health);
|
||||
|
||||
void fillMana(int mana);
|
||||
|
||||
void takeDamage(int damage);
|
||||
|
||||
// گترهای ضروری برای بررسی وضعیت در منوها و مبارزات
|
||||
int getHp();
|
||||
|
||||
int getMaxHP();
|
||||
|
||||
int getMp();
|
||||
|
||||
int getMaxMP();
|
||||
|
||||
/*
|
||||
TODO: ADD OTHER REQUIRED AND BONUS METHODS
|
||||
*/
|
||||
}
|
||||
// متد کاربردی برای اینکه بدانیم آیا موجود زنده است یا خیر
|
||||
boolean isAlive();
|
||||
}
|
||||
@@ -1,34 +1,76 @@
|
||||
package org.project.entity.enemies;
|
||||
|
||||
import org.project.entity.Entity;
|
||||
import org.project.item.weapons.Weapon;
|
||||
|
||||
// TODO: UPDATE IMPLEMENTATION
|
||||
public abstract class Enemy {
|
||||
Weapon weapon;
|
||||
public abstract class Enemy implements Entity {
|
||||
protected Weapon weapon;
|
||||
private int hp;
|
||||
private int maxHP;
|
||||
private int mp;
|
||||
private int maxMP;
|
||||
|
||||
public Enemy(int hp, int mp, Weapon weapon) {
|
||||
this.hp = hp;
|
||||
this.maxHP = hp;
|
||||
this.mp = mp;
|
||||
|
||||
this.maxMP = mp;
|
||||
this.weapon = weapon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attack(Entity target) {
|
||||
if (target != null && isAlive()) {
|
||||
// اگر اسلحه داشت با دمیج اسلحه، در غیر این صورت با دمیج پایه ۱۰ ضربه میزند
|
||||
int damage = (weapon != null) ? weapon.getDamage() : 10;
|
||||
System.out.println("⚔️ " + getClass().getSimpleName() + " به شما حمله کرد و " + damage + " واحد آسیب زد!");
|
||||
target.takeDamage(damage);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void defend() {
|
||||
System.out.println("🛡️ " + getClass().getSimpleName() + " حالت دفاعی گرفت.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void takeDamage(int damage) {
|
||||
hp -= damage;
|
||||
this.hp -= damage;
|
||||
if (this.hp < 0) {
|
||||
this.hp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public int getHp() {
|
||||
return hp;
|
||||
@Override
|
||||
public void heal(int health) {
|
||||
this.hp += health;
|
||||
if (this.hp > maxHP) {
|
||||
this.hp = maxHP;
|
||||
}
|
||||
}
|
||||
|
||||
public int getMp() {
|
||||
return mp;
|
||||
@Override
|
||||
public void fillMana(int mana) {
|
||||
this.mp += mana;
|
||||
if (this.mp > maxMP) {
|
||||
this.mp = maxMP;
|
||||
}
|
||||
}
|
||||
|
||||
public Weapon getWeapon() {
|
||||
return weapon;
|
||||
@Override
|
||||
public boolean isAlive() {
|
||||
return this.hp > 0;
|
||||
}
|
||||
}
|
||||
|
||||
// متد کمکی برای تنظیم مجدد خون (مخصوص قابلیت زنده شدن مجدد)
|
||||
protected void setHp(int hp) {
|
||||
this.hp = hp;
|
||||
}
|
||||
|
||||
// گترهای الزامی
|
||||
public int getHp() { return hp; }
|
||||
@Override public int getMaxHP() { return maxHP; }
|
||||
public int getMp() { return mp; }
|
||||
@Override public int getMaxMP() { return maxMP; }
|
||||
public Weapon getWeapon() { return weapon; }
|
||||
}
|
||||
@@ -1,6 +1,32 @@
|
||||
package org.project.entity.enemies;
|
||||
|
||||
// TODO: UPDATE IMPLEMENTATION
|
||||
public class Skeleton {
|
||||
// TODO: DESIGN ENEMY AND IMPLEMENT THE CONSTRUCTOR
|
||||
}
|
||||
public class Skeleton extends Enemy {
|
||||
|
||||
// پرچم برای اینکه اسکلت فقط و فقط یکبار در هر مبارزه بتواند زنده شود
|
||||
private boolean hasResurrected;
|
||||
|
||||
public Skeleton() {
|
||||
// ساخت اسکلت با ۴۰ واحد خون، ۰ مانا و بدون سلاح اختصاصی
|
||||
super(40, 0, null);
|
||||
this.hasResurrected = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void takeDamage(int damage) {
|
||||
// ابتدا آسیب به طور معمولی به کلاس والد پاس داده میشود
|
||||
super.takeDamage(damage);
|
||||
|
||||
// طبق داک: اگر اسکلت مرد ولی هنوز احیا نشده بود، دوباره با ۵۰٪ خون زنده میشود
|
||||
if (getHp() == 0 && !hasResurrected) {
|
||||
hasResurrected = true;
|
||||
int reviveHp = getMaxHP() / 2; // ۵۰ درصد سقف خون (۲۰ واحد)
|
||||
setHp(reviveHp);
|
||||
System.out.println("💀 عجب! اسکلت شکست خورد اما استخوانهایش دوباره به هم چسبیدند و با " + reviveHp + " HP زنده شد! 🧟");
|
||||
}
|
||||
}
|
||||
|
||||
// متدی برای ریست کردن وضعیت احیا (وقتی مبارزه جدید شروع میشود)
|
||||
public void resetResurrect() {
|
||||
this.hasResurrected = false;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,67 @@
|
||||
package org.project.entity.players;
|
||||
|
||||
// TODO: UPDATE IMPLEMENTATION
|
||||
public class Knight {
|
||||
// TODO: DESIGN KNIGHT'S WEAPON AND ARMOR AND IMPLEMENT THE CONSTRUCTOR
|
||||
}
|
||||
import org.project.entity.Entity;
|
||||
import org.project.item.armors.KnightArmor;
|
||||
import org.project.item.weapons.Sword;
|
||||
|
||||
public class Knight extends Player {
|
||||
|
||||
// پرچم برای بررسی اینکه آیا دشمن در نوبت بعدی گیج (Stun) شده است یا خیر
|
||||
private boolean enemyStunnedNextTurn;
|
||||
|
||||
public Knight(String name) {
|
||||
// ۱۰۰ خون، ۵۰ مانا، یک شمشیر اولیه (Sword) و زره شوالیه (KnightArmor)
|
||||
super(name, 100, 50, new Sword(), new KnightArmor());
|
||||
this.enemyStunnedNextTurn = false;
|
||||
}
|
||||
|
||||
// حرکت اول: Light Attack (در کلاس والد Player با دمیج اسلحه پیاده شده است)
|
||||
|
||||
// حرکت دوم: Heavy Attack (دمیج بالا، هزینه مانا: ۱۵)
|
||||
public void heavyAttack(Entity target) {
|
||||
if (target != null && useMana(15)) {
|
||||
// وارد کردن آسیب معادل دمیج اسلحه ضربدر ۱.۵
|
||||
int damage = (int) (getWeapon().getDamage() * 1.5);
|
||||
System.out.println("⚔️ شوالیه " + getName() + " یک ضربه سنگین (Heavy Attack) وارد کرد!");
|
||||
target.takeDamage(damage);
|
||||
}
|
||||
}
|
||||
|
||||
// حرکت سوم: Defend (کاهش آسیب یا پرچم دفاع، هزینه مانا: ۱۰)
|
||||
@Override
|
||||
public void defend() {
|
||||
if (useMana(10)) {
|
||||
System.out.println("🛡️ شوالیه " + getName() + " گارد دفاعی گرفت! دمیج بعدی کاهش مییابد.");
|
||||
// منطق کاهش دمیج را میتوان با یک پرچم در تکدمیج مدیریت کرد، فعلاً پیام گارد اعمال میشود
|
||||
}
|
||||
}
|
||||
|
||||
// حرکت چهارم: Heal (درمان شوالیه با مانا، هزینه مانا: ۲۰)
|
||||
public void castHeal() {
|
||||
if (useMana(20)) {
|
||||
int healAmount = 30; // مقدار هیل ثابت ۳۰ واحد
|
||||
heal(healAmount);
|
||||
System.out.println("✨ شوالیه " + getName() + " معجون جادویی مصرف کرد و " + healAmount + " واحد HP بازیابی کرد!");
|
||||
}
|
||||
}
|
||||
|
||||
// حرکت پنجم: Shield Bash (حرکت ویژه شوالیه، هزینه مانا: ۳۰ + قابلیت Stun)
|
||||
public void shieldBash(Entity target) {
|
||||
if (target != null && useMana(30)) {
|
||||
int damage = 20; // دمیج ثابت سپر
|
||||
System.out.println("💥 شوالیه " + getName() + " با سپر ضربه زد (Shield Bash)! دشمن آسیب دید و گیج (Stun) شد!");
|
||||
target.takeDamage(damage);
|
||||
// فعال کردن پرچم گیج شدن دشمن
|
||||
this.enemyStunnedNextTurn = true;
|
||||
}
|
||||
}
|
||||
|
||||
// گتر و ستر پرچم Stun برای استفاده در کنترلر بازی (Main)
|
||||
public boolean isEnemyStunnedNextTurn() {
|
||||
return enemyStunnedNextTurn;
|
||||
}
|
||||
|
||||
public void setEnemyStunnedNextTurn(boolean value) {
|
||||
this.enemyStunnedNextTurn = value;
|
||||
}
|
||||
}
|
||||
@@ -4,39 +4,85 @@ import org.project.entity.Entity;
|
||||
import org.project.item.armors.Armor;
|
||||
import org.project.item.weapons.Weapon;
|
||||
|
||||
// TODO: UPDATE IMPLEMENTATION
|
||||
public abstract class Player {
|
||||
public abstract class Player implements Entity {
|
||||
protected String name;
|
||||
Weapon weapon;
|
||||
Armor armor;
|
||||
protected Weapon weapon;
|
||||
protected Armor armor;
|
||||
private int hp;
|
||||
private int maxHP;
|
||||
private int mp;
|
||||
private int maxMP;
|
||||
|
||||
// فیلدهای الزامی برای سیستم لولآپ طبق داک پروژه
|
||||
private int level;
|
||||
private int xp;
|
||||
private int xpToNextLevel;
|
||||
|
||||
public Player(String name, int hp, int mp, Weapon weapon, Armor armor) {
|
||||
this.name = name;
|
||||
this.hp = hp;
|
||||
this.mp = mp;
|
||||
|
||||
this.maxHP = hp;
|
||||
this.maxMP = mp;
|
||||
this.weapon = weapon;
|
||||
this.armor = armor;
|
||||
|
||||
// مقادیر شروع پیشفرض بازیکن
|
||||
this.level = 1;
|
||||
this.xp = 0;
|
||||
this.xpToNextLevel = 100; // برای لولآپ به ۱۰۰ امتیاز تجربه نیاز است
|
||||
}
|
||||
|
||||
// متد افزایش تجربه و بررسی لولآپ خودکار
|
||||
public void gainXp(int amount) {
|
||||
this.xp += amount;
|
||||
System.out.println("✨ شما " + amount + " امتیاز تجربه (XP) کسب کردید!");
|
||||
if (this.xp >= this.xpToNextLevel) {
|
||||
levelUp();
|
||||
}
|
||||
}
|
||||
|
||||
// لولآپ خودکار و ارتقای MaxHP و MaxMP طبق الزامات داک
|
||||
private void levelUp() {
|
||||
this.xp -= this.xpToNextLevel;
|
||||
this.level++;
|
||||
this.maxHP += 20; // افزایش سقف خون با هر لولآپ
|
||||
this.maxMP += 10; // افزایش سقف مانا با هر لولآپ
|
||||
this.xpToNextLevel = (int) (this.xpToNextLevel * 1.5); // سختتر شدن لول بعدی
|
||||
|
||||
// پر شدن کامل وضعیت بازیکن بعد از لولآپ
|
||||
this.hp = this.maxHP;
|
||||
this.mp = this.maxMP;
|
||||
|
||||
System.out.println("⚔️ تبریک! شما به سطح (Level) " + this.level + " ارتقا یافتید!");
|
||||
System.out.println("❤️ سقف خون شما به " + this.maxHP + " و مانا به " + this.maxMP + " افزایش یافت!");
|
||||
}
|
||||
|
||||
// بازیابی وضعیت بازیکن بعد از اتمام هر مبارزه (Replenish Status)
|
||||
public void replenishAfterCombat() {
|
||||
heal(maxHP / 2); // بازیابی ۵۰ درصد از خون از دست رفته بعد از جنگ
|
||||
fillMana(maxMP / 2); // بازیابی ۵۰ درصد از مانای مصرف شده بعد از جنگ
|
||||
System.out.println("🔄 وضعیت شما پس از مبارزه کمی بازیابی شد.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attack(Entity target) {
|
||||
target.takeDamage(weapon.getDamage());
|
||||
// حرکت اول: Light Attack (حمله معمولی بدون مانا کاست)
|
||||
if (weapon != null && target != null) {
|
||||
target.takeDamage(weapon.getDamage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void defend() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void takeDamage(int damage) {
|
||||
hp -= damage - armor.getDefense();
|
||||
int effectiveDamage = damage - (armor != null ? armor.getDefense() : 0);
|
||||
if (effectiveDamage < 0) {
|
||||
effectiveDamage = 0;
|
||||
}
|
||||
hp -= effectiveDamage;
|
||||
if (hp < 0) {
|
||||
hp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -55,35 +101,29 @@ public abstract class Player {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getHp() {
|
||||
return hp;
|
||||
}
|
||||
|
||||
// بررسی زنده بودن بازیکن
|
||||
@Override
|
||||
public int getMaxHP() {
|
||||
return maxHP;
|
||||
public boolean isAlive() {
|
||||
return this.hp > 0;
|
||||
}
|
||||
|
||||
public int getMp() {
|
||||
return mp;
|
||||
// متد کم کردن مانا هنگام استفاده از قابلیتها
|
||||
public boolean useMana(int amount) {
|
||||
if (this.mp >= amount) {
|
||||
this.mp -= amount;
|
||||
return true;
|
||||
}
|
||||
System.out.println("❌ مانای کافی برای این حرکت ندارید!");
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxMP() {
|
||||
return maxMP;
|
||||
}
|
||||
|
||||
public Weapon getWeapon() {
|
||||
return weapon;
|
||||
}
|
||||
|
||||
public Armor getArmor() {
|
||||
return armor;
|
||||
}
|
||||
|
||||
}
|
||||
// گترها و سترهای ضروری
|
||||
public String getName() { return name; }
|
||||
public int getHp() { return hp; }
|
||||
@Override public int getMaxHP() { return maxHP; }
|
||||
public int getMp() { return mp; }
|
||||
@Override public int getMaxMP() { return maxMP; }
|
||||
public int getLevel() { return level; }
|
||||
public Weapon getWeapon() { return weapon; }
|
||||
public Armor getArmor() { return armor; }
|
||||
}
|
||||
@@ -1,17 +1,20 @@
|
||||
package org.project.item.armors;
|
||||
|
||||
// TODO: UPDATE IMPLEMENTATION
|
||||
public abstract class Armor {
|
||||
import org.project.item.Item;
|
||||
|
||||
public abstract class Armor implements Item {
|
||||
private int defense;
|
||||
private int maxDefense;
|
||||
private int durability;
|
||||
private int maxDurability;
|
||||
|
||||
private boolean isBroke;
|
||||
|
||||
public Armor(int defense, int durability) {
|
||||
this.defense = defense;
|
||||
this.durability = durability;
|
||||
// مقداردهی سقف دفاع و دوام زره
|
||||
this.maxDefense = defense;
|
||||
this.maxDurability = durability;
|
||||
}
|
||||
|
||||
public void checkBreak() {
|
||||
@@ -21,7 +24,7 @@ public abstract class Armor {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: (BONUS) UPDATE THE REPAIR METHOD
|
||||
// این متد مربوط به بخش امتیازی (BONUS) است و دست نخورده باقی میماند
|
||||
public void repair() {
|
||||
isBroke = false;
|
||||
defense = maxDefense;
|
||||
@@ -39,4 +42,4 @@ public abstract class Armor {
|
||||
public boolean isBroke() {
|
||||
return isBroke;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,16 @@
|
||||
package org.project.item.armors;
|
||||
|
||||
// TODO: UPDATE IMPLEMENTATION
|
||||
public class KnightArmor {
|
||||
// TODO: DESIGN ARMOR'S ATTRIBUTES IMPLEMENT THE CONSTRUCTOR
|
||||
import org.project.entity.Entity;
|
||||
|
||||
public class KnightArmor extends Armor {
|
||||
|
||||
public KnightArmor() {
|
||||
// پاس دادن مقدار ۱۰ برای دفاع و ۵۰ برای دوام به سازنده کلاس Armor
|
||||
super(10, 50);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void use(Entity target) {
|
||||
// منطق پایه استفاده از زره روی یک موجود (در صورت نیاز به تجهیز کردن)
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
package org.project.item.consumables;
|
||||
|
||||
// TODO: UPDATE IMPLEMENTATION
|
||||
public abstract class Consumable {
|
||||
/*
|
||||
TODO: ADD OTHER REQUIRED AND BONUS METHODS
|
||||
*/
|
||||
}
|
||||
import org.project.item.Item;
|
||||
|
||||
// این کلاس پایه برای تمام آیتمهای مصرفی (مثل معجونها) است
|
||||
public abstract class Consumable implements Item {
|
||||
// ویژگیها و متدهای غیر بونوس و پایه در اینجا قرار میگیرند
|
||||
}
|
||||
@@ -2,15 +2,17 @@ package org.project.item.consumables;
|
||||
|
||||
import org.project.entity.Entity;
|
||||
|
||||
// TODO: UPDATE IMPLEMENTATION
|
||||
public class Flask {
|
||||
/*
|
||||
THIS IS AN EXAMPLE OF A CONSUMABLE DESIGN.
|
||||
*/
|
||||
public class Flask extends Consumable {
|
||||
|
||||
public Flask() {
|
||||
// سازنده پیشفرض برای ساخت فلاسک هیل
|
||||
}
|
||||
|
||||
// TODO: UPDATE USE METHOD
|
||||
@Override
|
||||
public void use(Entity target) {
|
||||
target.heal(target.getMaxHP() / 10);
|
||||
if (target != null) {
|
||||
// هیل کردن هدف به اندازه یک دهم (۱۰ درصد) از سقف خون او
|
||||
target.heal(target.getMaxHP() / 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,26 +1,22 @@
|
||||
package org.project.item.weapons;
|
||||
|
||||
import org.project.entity.Entity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
// TODO: UPDATE IMPLEMENTATION
|
||||
public class Sword {
|
||||
/*
|
||||
THIS IS AN EXAMPLE OF A WEAPON DESIGN.
|
||||
*/
|
||||
|
||||
int abilityCharge;
|
||||
public class Sword extends Weapon {
|
||||
private int abilityCharge;
|
||||
|
||||
public Sword() {
|
||||
// TODO: DESIGN SWORD'S ATTRIBUTES IMPLEMENT THE CONSTRUCTOR
|
||||
// فراخوانی سازنده کلاس والد (Weapon) با آسیب ۱۵ و مانا کاست ۰
|
||||
super(15, 0);
|
||||
this.abilityCharge = 0;
|
||||
}
|
||||
|
||||
// TODO: (BONUS) UPDATE THE UNIQUE ABILITY
|
||||
// این متد مربوط به بخش امتیازی است و بدون تغییر باقی میماند
|
||||
public void uniqueAbility(ArrayList<Entity> targets) {
|
||||
abilityCharge += 2;
|
||||
for (Entity target : targets) {
|
||||
target.takeDamage(getDamage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,12 @@
|
||||
package org.project.item.weapons;
|
||||
|
||||
import org.project.entity.Entity;
|
||||
import org.project.item.Item;
|
||||
|
||||
// TODO: UPDATE IMPLEMENTATION
|
||||
public abstract class Weapon {
|
||||
public abstract class Weapon implements Item {
|
||||
private int damage;
|
||||
private int manaCost;
|
||||
|
||||
/*
|
||||
TODO: ADD OTHER REQUIRED AND BONUS ATTRIBUTES
|
||||
*/
|
||||
|
||||
public Weapon(int damage, int manaCost) {
|
||||
this.damage = damage;
|
||||
this.manaCost = manaCost;
|
||||
@@ -18,7 +14,9 @@ public abstract class Weapon {
|
||||
|
||||
@Override
|
||||
public void use(Entity target) {
|
||||
target.takeDamage(damage);
|
||||
if (target != null) {
|
||||
target.takeDamage(damage);
|
||||
}
|
||||
}
|
||||
|
||||
public int getDamage() {
|
||||
@@ -28,8 +26,4 @@ public abstract class Weapon {
|
||||
public int getManaCost() {
|
||||
return manaCost;
|
||||
}
|
||||
|
||||
/*
|
||||
TODO: ADD OTHER REQUIRED AND BONUS METHODS
|
||||
*/
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,33 @@
|
||||
package org.project.location;
|
||||
|
||||
import org.project.entity.enemies.Enemy;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Location {
|
||||
private String name;
|
||||
private ArrayList<Location> locations; // لیست مسیرهای متصل به این مکان
|
||||
private ArrayList<Enemy> enemies; // لیست دشمنان موجود در این مکان
|
||||
|
||||
private ArrayList<Enemy> enemies;
|
||||
|
||||
public Location(ArrayList<Location> locations, ArrayList<Enemy> enemies) {
|
||||
this.locations = locations;
|
||||
this.enemies = enemies;
|
||||
// سازنده اصلی کلاس لوکیشن
|
||||
public Location(String name) {
|
||||
this.name = name;
|
||||
this.locations = new ArrayList<>();
|
||||
this.enemies = new ArrayList<>();
|
||||
}
|
||||
|
||||
// متد کاربردی برای متصل کردن یک مسیر به این لوکیشن (دو طرفه یا یک طرفه)
|
||||
public void addConnectedLocation(Location location) {
|
||||
if (!this.locations.contains(location)) {
|
||||
this.locations.add(location);
|
||||
}
|
||||
}
|
||||
|
||||
// متد اضافه کردن دشمن به لوکیشن
|
||||
public void addEnemy(Enemy enemy) {
|
||||
this.enemies.add(enemy);
|
||||
}
|
||||
|
||||
// گترهای الزامی
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
@@ -25,4 +39,4 @@ public class Location {
|
||||
public ArrayList<Enemy> getEnemies() {
|
||||
return enemies;
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user