오늘의 목표

더보기

✔️ 개인과제


⏱️ 오늘의 일정

9:00 ~ 21:00 개인과제


📜 개인과제

9:00 ~ 21:00 개인과제

 

11일에 이어서 개인과제를 진행했다.

game.js 에 몰려있던 클래스들을 각각 분리했다.

 

Logs.js  ( 로그 관리 )

let gInstance = null;

export class CLogs {    
    constructor() {
        if (gInstance) {
            return gInstance;
        }

        this._logs = [];
        gInstance = this;        
    }

    get logs() {
        return this._logs;
    }

    set logs(value) {
        this._logs.push(value);
    }

    printLogs() {
        this._logs.forEach((log) => console.log(log));
    }

    static getInstance() {
        return gInstance;
    }
}

 

Logs는 싱글톤 객체로 게임에 사용하는 모든 로그들을 관리한다.

 

 

Creature.cs ( 생명체 ( 플레이어와 몬스터 부모 ) )

class Creature {
    constructor() {
        this.bonusHP = 30;
        this.bonusRecovoryHP = 0.02;

        this.defenceState = DEFENCE_OFF;
        this.defenceRating = 0.4;

        this.attackPoint = 1;
        this.recovoryHP = 0.2;
        this.name = null;
        this.weapon = null;
        this.inventory = [];

        this.statusEffect = new CStatusEffect(this);
    }

    equipWeapon(weaponType) {
        switch (weaponType) {
            case '1':
                this.weapon = new CMaceWeapon(this);
                break;
            case '2':
                this.weapon = new CSwordWeapon(this);
                break;
            case '3':
                this.weapon = new CTwohandSwordWeapon(this);
                break;
        }
    }

    attack(battleTurn, target) {
        if (this.weapon != null) {
            return this.weapon.WeaponAttack(battleTurn, target);
        }
    }

    defence() {
        this.defenceState = DEFENCE_ON;
    }

    OnDamage(damagePoint) {
        if (this.hp - damagePoint < 0) {
            this.hp = 0;

            return true;
        }
        else {
            this.hp -= damagePoint;

            return false;
        }
    }

    StatusUpdate(stage) {
        this.hp += Math.floor(this.hp * this.recovoryHP) + (rand(1, 3) * stage);
        this.attackPoint += (rand(1, 3) * stage);

        this.recovoryHP += this.bonusRecovoryHP;        

        this.statusEffect.StatusInit();
    }

    Update(battleTurn) {
        let Logs = CLogs.getInstance();

        switch (this.statusEffect.Effect) {
            case STATUS_EFFECT_RESERVE_STUN:
            case STATUS_EFFECT_RESERVE_BLEEDING:
                this.statusEffect.Start(battleTurn);
                break;
            case STATUS_EFFECT_STUN:
            case STATUS_EFFECT_BLEEDING:
                this.statusEffect.Update(battleTurn);
                break;
        }
    }
}

 

Creature에는 StatusUpdate()로 Stage에 따라 랜덤하게 각종 능력치가 상승한다.

EquipWeapon()로 장비를 착용한다.

OnDamage()를 통해 데미지 처리를 한다.

Update()에서는 Creature에 출혈 및 기절 상태이상이 적용된다.

 

Player.cs ( 플레이어 )

export class Player extends Creature {
    constructor() {
        super();

        this.name = "플레이어";
        this.hp = 250;
        this.defensePoint = 0.5;
    }
}

 

플레이어는 선택한 무기로 바로 공격하기 때문에 부모의 attack()을 사용해 상대방을 공격한다.

 

Monster.cs ( 몬스터 )

export class Monster extends Creature {
    constructor() {
        super();

        this.name = "자바스크립트";
        this.hp = 100;
        this.defensePoint = 0.1;
        this.inventory.push(new CMaceWeapon(this));
        this.inventory.push(new CSwordWeapon(this));
        this.inventory.push(new CTwohandSwordWeapon(this));
    }

    attack(battleTurn, target) {
        let Logs = CLogs.getInstance();     

        let weaponChoiceNum = rand(0, 2);

        if (this.inventory.length > 0) {
            if (this.inventory[weaponChoiceNum] != null) {
                this.weapon = this.inventory[weaponChoiceNum];

                Logs.logs = chalk.yellow(`[${battleTurn}] ${this.name}가 ${this.weapon.name}을 장착했습니다.`);

                return this.weapon.WeaponAttack(battleTurn, target);
            }
        }
    }
}

 

몬스터는 attack()을 오버라이딩해서 자신이 소유하고 있는 무기 중 랜덤하게 골라 장착하고 상대방을 공격한다.

 

StausEffect.cs ( 상태이상 )

Update(battleTurn) {
        let Logs = CLogs.getInstance();

        this.EffectCount--;       

        switch (this.Effect) {
            case STATUS_EFFECT_STUN:
                Logs.logs = chalk.cyanBright(`[${battleTurn}] [${this.owner.name}] 기절!! [${this.EffectCount}] 턴 남음`);                
                break;
            case STATUS_EFFECT_BLEEDING:
                Logs.logs = chalk.cyanBright(`[${battleTurn}] [${this.owner.name}] 출혈!! 1턴당 [${this.damage}]씩 체력이 감소합니다. [${this.EffectCount}] 턴 남음`);
                this.owner.OnDamage(this.damage);                
                break;
        }              

        if (this.EffectCount == 0) {

            switch (this.Effect) {
                case STATUS_EFFECT_STUN:
                    Logs.logs = chalk.cyanBright(`[${battleTurn}] [${this.owner.name}] 기절 해제!`);
                    break;
                case STATUS_EFFECT_BLEEDING:
                    Logs.logs = chalk.cyanBright(`[${battleTurn}] [${this.owner.name}] 출혈 해제!`);
                    break;
            }

            this.StatusInit();
        }
    }

 

StatusEffect는 내부적으로 저장하고 있는 Effect의 값에 따라 상태이상을 owner에게 적용한다.

Start()로 상태이상을 적용하고, Update()를 통해 상태이상을 지속시킨다.

 

Weapon.js ( 무기 )

 WeaponAttack(battleTurn, target) {
     let Logs = CLogs.getInstance();

     if (this.owner.statusEffect.Effect == STATUS_EFFECT_STUN) {
         Logs.logs = chalk.cyanBright(`${this.owner.name}가 기절 상태이상에 걸려 공격할 수 없습니다.`);
         return false;
     }

     if (RatingSuccess(this.attackRating)) {
         if (target.defenceState == DEFENCE_ON) {
             target.defenceState = DEFENCE_OFF;

             if (RatingSuccess(target.defenceRating)) { // 상대방의 방어 확률에 따라 방어                                        
                 Logs.logs = chalk.yellow(`[${battleTurn}] ${target.name}가 ${this.owner.name}의 공격을 방어했습니다.`);

                 return false;
             }
             else {
                 Logs.logs = chalk.yellow(`[${battleTurn}] ${target.name}가 ${this.owner.name}의 공격을 방어하지 못했습니다.`);
             }
         }

         let damagePoint = rand(this.minAttackPoint + this.owner.attackPoint, this.maxAttackPoint + this.owner.attackPoint);
         let finalDamagePoint = Math.floor(damagePoint - damagePoint * target.defensePoint);

         if (target.statusEffect.Effect == STATUS_EFFECT_NONE) {
             if (RatingSuccess(this.statusEffectRating)) {
                 if (target.statusEffect != null) {
                     // 상태이상 적용
                     switch (this.weaponType) {
                         case WEAPON_MACE:
                             Logs.logs = chalk.magenta(`[${battleTurn}] ${target.name}에게 기절 상태이상 적용.`);

                             target.statusEffect.Effect = STATUS_EFFECT_RESERVE_STUN;
                             break;
                         case WEAPON_SWORD:
                             target.OnDamage(finalDamagePoint)

                             Logs.logs = chalk.magenta(`[${battleTurn}] ${target.name}에게 연속 공격!!`);
                             Logs.logs = chalk.green(`[${battleTurn}] ${this.owner.name} 공격 성공! ${this.owner.name}가 ${target.name}에게 ${finalDamagePoint} 의 피해를 입혔습니다.`);                                
                             break;
                         case WEAPON_TWO_HAND_SWORD:
                             Logs.logs = chalk.magenta(`[${battleTurn}] ${target.name}에게 출혈 상태이상 적용.`);

                             target.statusEffect.Effect = STATUS_EFFECT_RESERVE_BLEEDING;
                             target.statusEffect.damage = this.owner.attackPoint;
                             break;
                     }
                 }
             }
         }

         Logs.logs = chalk.green(`[${battleTurn}] ${this.owner.name} 공격 성공! ${this.owner.name}가 ${target.name}에게 ${finalDamagePoint} 의 피해를 입혔습니다.`);

         return target.OnDamage(finalDamagePoint);
     }
     else {
         Logs.logs = chalk.red(`[${battleTurn}] ${this.owner.name}의 공격이 빗나갔습니다.`);

         return false;
     }
 }

 

Weapon 클래스에서는 WeaponAttack() 메서드를 이용해 상대방을 공격하고,

무기 종류에 따라 상대방에게 상태이상을 적용한다.

 

🌙 하루를 마치며

캠프에서 제시한 기본과 도전은 모두 구현을 완료했다.

내일 한번 더 테스트 해서 버그가 없는지 확인하고, 제출한 뒤 캠프에서 제공한 Node.js 강의 수업을 들어야겠다.

+ Recent posts