Project

[JS/연습/객체/OOP] Text RPG 구현 -2

메인 페이지화면 구현하기

View(HTML,CSS)구현

See the Pen TextRPG_view(2) by Doge (@DogeIsFree) on CodePen.

DOM 객체선언하기

JS로 HTML을 컨트롤 해야하므로 , 필요한 DOM객체들을 선언해주도록 하자. 

화면태그 DOM

// ScreenTag (view)
const $startPage = document.querySelector("#startpage");
const $mainPage= document.querySelector("#mainpage");

버튼태그DOM

//buttonTag
const $btn_adventure = document.querySelector(".adventure");
const $btn_rest = document.querySelector(".rest");
const $btn_end = document.querySelector(".end");

Player태그 DOM

//playerTag
const $player_name = document.querySelector("#name");
const $player_lv = document.querySelector(".level");
const $player_hp = document.querySelector(".hp");
const $player_atk =  document.querySelector(".atk");
const $player_exp = document.querySelector(".exp");

 

Game 객체 

start메서드

  • player객체를 생성하고, player 객체의 정보를 화면에 출력합니다.
  • start메서드에서 ,버튼에 이벤트를 등록합시다.
  • EventListener의 Callback 함수는 Handler의 이름을 붙여서, Game객체안의 method형태로 구현을 할겁니다.
  • 객체 안의 this는 객체 자신을 가리킵니다.
  start(name){
    /* main Menu Button */
    $btn_adventure.addEventListener('click',this.adventureHandler);
    $btn_rest.addEventListener('click',this.restHandler);
    $btn_end.addEventListener('click',this.endHandler);
    this.player=new Player(this,name);
    this.updatePlayerStat();
  }

updatePlayerStat()

  • player객체의 정보를 화면에 출력하는 메서드입니다.
  //player State 정보주입
  updatePlayerStat(){
    const { player } = this;
    if(player===null){
      $player_name.textContent='';
      $player_hp.textContent='';
      $player_atk.textContent='';
      $player_lv.textContent='';
      $player_exp.textContent='';
      return;
    }
    $player_name.textContent= player.name;
    $player_lv.textContent=`${player.level}Lv`;
    $player_hp.textContent=`HP:${player.hp}/${player.maxHp}`;
    $player_atk.textContent=`ATK:${player.atk}`;
    $player_exp.textContent=`EXP:${player.exp}/${20*player.level}`;
    $player_btHp.textContent = `내 체력${this.player.hp}`;
  }

changeScreen()

  • 화면전환이 일어나는 메서드입니다.
  • 화면전환은 빈번하게 일어나기 때문에, 메서드로 따로 빼서 , call하는 형식으로 구현하겠습니다.
  changeScreen(page){
    if(page==="main"){
      $mainPage.style.display='flex';
      $adventurePage.style.display='none';
      $startPage.style.display='none';
    }else if(page==="start"){
      $mainPage.style.display='none';
      $adventurePage.style.display='none';
      $startPage.style.display='flex';
    }else if(page==="adventure"){
      $mainPage.style.display='none';
      $adventurePage.style.display='flex';
      $startPage.style.display='none';
    }
  }

Monster객체 

  • 몬스터의 정보를 갖고 있습니다.
  • {game,hp,exp,img,atk} 5가지의 프로퍼티를 가집니다.
  • attack() 메서드를 가집니다.
class Monster{
  constructor(game,name,hp,exp,img,atk){
    this.game=game;
    this.name=name;
    this.hp=hp;
    this.exp=exp;
    this.img=img;
    this.atk=atk;
  }
  attack(target){
    target.hp -=this.atk;
  }
}

updateMonsterStat()

  • Monster의 변한 정보를 화면에 출력하는 역할을 합니다.
  //Monster 정보주입
  updateMonsterStat(){
    const {monster} = this;
    if (monster===null){
      $monster_name.textContent='';
      $monster_atk.textContent='';
      $monster_hp.textContent='';
      $monster_Exp.textContent='';
      return
    }
    $monster_name.textContent=monster.name;
    $monster_atk.textContent=`ATK:${monster.atk}`;
    $monster_hp.textContent=`HP:${monster.hp}`;
    $monster_Exp.textContent=`Exp:${monster.exp}`;
    $monster_Img.src=monster.img;
  }

AdventureHandler()

  • "모험하기" 클릭 시 , 발생하는 이벤트입니다. 
  • 모험하기 클릭 시,  "모험화면"으로 화면이 전환되고 , Monster가 등장해야 합니다.
  • 몬스터가 생성되어야하고, 몬스터 정보가 화면에 출력되어야 합니다.
  • ArrowFunction으로 작성합니다. 혹은, Binding을 해주어야 합니다.
    • adventureHandler는 callback 함수 , 즉 비동기함수에 들어갑니다. 따라서, 비동기 함수는 callback 함수 내부의 this를 보장하지 못합니다. (AddEventListener의 경우, 앞에 있는 DOM이 this가 됩니다)
    • 따라서, Callback 함수를 ArrowFunction으로 구현하거나, 비동기 함수로 넣어줄 때, () => this.adventureHandler()와 같이 return 값으로 함수를 주는 형태로 구현하거나, apply,call과 같은 bind함수를 이용해야합니다.
adventureHandler = (e) =>{
	e.preventDefault();
    this.changeScreen("adventure");
    /*몬스터 생성*/
    const randomIdx = Math.floor(Math.random()*this.monsterLst.length);
    const randomMonster = this.monsterLst[randomIdx];
    this.monster = new Monster(this,randomMonster.name,randomMonster.hp,
    randomMonster.exp,randomMonster.img,randomMonster.atk);
    /* 몬스터 화면 출력*/
    this.updateMonsterStat();
}

restHandler()

  • "휴식하기" 클릭 시 , 발생하는 이벤트 입니다.
  • player의 hp가 maxHp만큼 회복되어야 합니다.(포켓몬 센터)
  • 변경된 정보를 화면에 반영해줍니다. (항상 데이터와 view는 통일 시켜주어야합니다)
  //휴식
  restHandler = (e)=>{
    e.preventDefault();
    const {player} = this;
    player.hp = player.maxHp;
    this.updatePlayerStat();
  }

endHandler()

  • 끝내기 클릭시, 발생하는 이벤트입니다.
  • 모든 객체를 초기화하고, 비동기 함수들을 지워줍니다.
  • 메인화면으로 돌아갑니다.
  endHandler = (e) =>{
    e.preventDefault();
    /*remove player ,monster*/ 
    this.player=null;
    this.monster=null;
    this.updatePlayerStat();
    this.updateMonsterStat();
    /*remove Event*/
    $btn_adventure.removeEventListener('click',this.adventureHandler);
    $btn_rest.removeEventListener('click',this.restHandler);
    $btn_end.removeEventListener('click',this.endHandler);
    $btn_bt_attack.removeEventListener('click',this.attackHandler);
    $btn_bt_run.removeEventListener('click',this.runHandler);
    $btn_bt_heal.removeEventListener('click',this.healHandler);
    
    this.changeScreen("start");
    game=null;
  }

 

 

refer

제로초님의 렛츠기릿 자바스크립트강의

제로초님의 블로그의 자동 텍스트 RPG 만들기