본문 바로가기
개발/Javascript

[js] 생성자, 카드세팅 (ft. 자바스크립트로 자스스톤 게임 구현 ver.2)

by 코딩하는 갓디노 2021. 3. 2.

자스스톤

 

자바스크립트를 이용하여 
자스스톤 게임을 구현하는 예제(ver.2)입니다.
- 카드 세팅, 팩토리, 생성자 패턴 -

 

예제는 인프런의 제로초, "조현영"님의 강의를 들으면서 공부한 내용입니다.

 

구현 내용

1 클릭한 일반(쫄병) 카드 덱에서 필드로 그대로 옮기기 indexOf(), splice(), 카드돔연결 함수
2 카드를 뽑을 때마다 카드 추가로 생성하기 일반카드 총 5개 유지
3 일반 카드를 뽑을 때마다 코스트 점수(시작:10)에서 차감 Number()
4 턴 넘기기(버튼 클릭 이벤트)와 턴 표시  
5 턴 넘길 때마다 코스트 점수 10으로 충전  
6 자기 턴에서 상대편 카드 클릭 방지 카드돔연결 함수 이용
7 필드에 올라간 이미 선택한 카드 클릭 방지  

 

구현 화면

 

script 코드

const 상대영웅 = document.getElementById('rival-hero');
const 내영웅 = document.getElementById('my-hero');
const 상대덱 = document.getElementById('rival-deck');
const 내덱 = document.getElementById('my-deck');
const 상대필드 = document.getElementById('rival-cards');
const 내필드 = document.getElementById('my-cards');
const 상대코스트 = document.getElementById('rival-cost');
const 내코스트 = document.getElementById('my-cost');
const 턴버튼 = document.getElementById('turn-btn');
const 턴타입 = document.getElementById('turn-type');

//가상의 데이터 저장
let 상대덱data = [];
let 내덱data = [];
let 상대영웅data;
let 내영웅data;
let 상대필드data = [];
let 내필드data = [];
let 턴 = true; //true는 나의 턴, false는 상대 턴

//카드 화면 출력
function 카드돔연결(데이터, 돔, 영웅) {
  let 카드 = document.querySelector('.card-hidden .card').cloneNode(true);
  카드.querySelector('.card-cost').textContent = 데이터.cost;
  카드.querySelector('.card-att').textContent = 데이터.att;
  카드.querySelector('.card-hp').textContent = 데이터.hp;

  //영웅일때 cost 감추기
  if (영웅) {
    카드.querySelector('.card-cost').style.display = 'none';
    let 이름 = document.createElement('div');
    이름.textContent = '영웅',
      카드.appendChild(이름);
  }
  //클릭한 카드 덱에서 필드로 그대로 옮기기
  카드.addEventListener('click', function(card) {
    if (턴) { //내 필드, 내턴
      if (!데이터.mine || 데이터.field) { //상대카드를 뽑을 경우, 필드로 옮겨간 카드 클릭 방지)
        return;
      }
      //현재 코스트 점수 파악
      let 현재코스트 = Number(내코스트.textContent); //string에서 number로 바꿈
      if (현재코스트 < 데이터.cost) {
        return;
      }
      let idx = 내덱data.indexOf(데이터);
      내덱data.splice(idx, 1);
      내필드data.push(데이터);
      //화면 업데이트 구현이 어려워 전체 데이터 지웠다가 다시 필드, 덱 출력
      내덱.innerHTML = '';
      내필드.innerHTML = '';
      내필드data.forEach(function(data) { //뽑은 카드 올라감
        카드돔연결(data, 내필드);
      });
      내덱data.forEach(function(data) { //뽑은 카드는 배열에서 사라짐
        카드돔연결(data, 내덱);
      });
      데이터.field = true; //필드에 올라간 카드(위에서 재클릭 방지)
      내코스트.textContent = 현재코스트 - 데이터.cost;
      내덱생성(1); //카드 한개 더 뽑기
    } else { //상대방 필드 상대턴
      if (데이터.mine || 데이터.field) { //내카드를 뽑을 경우,
        return;
      }
      let 현재코스트 = Number(상대코스트.textContent); //string에서 number로 바꿈
      if (현재코스트 < 데이터.cost) {
        return;
      }
      let idx = 상대덱data.indexOf(데이터);
      상대덱data.splice(idx, 1);
      상대필드data.push(데이터);
      상대덱.innerHTML = '';
      상대필드.innerHTML = '';
      //문제. 클릭시 상대편 필드가 아닌 내필드로 옮겨짐 해결 카드공장에 내카드/상대방카드 매개변수 추가
      상대필드data.forEach(function(data) {
        카드돔연결(data, 상대필드);
      });
      상대덱data.forEach(function(data) {
        카드돔연결(data, 상대덱);
      });
      데이터.field = true;
      상대코스트.textContent = 현재코스트 - 데이터.cost;
      상대덱생성(1);
    }
  });

  돔.appendChild(카드);
}


function 상대덱생성(개수) {
  for (let i = 0; i < 개수; i++) {
    상대덱data.push(카드공장());
  }
  //자바스크립트로 바뀐 데이터만 화면 출력시키는 것이 힘들기 때문에 다 지웠다가 출력
  상대덱.innerHTML = '';
  상대덱data.forEach(function(data) {
    카드돔연결(data, 상대덱);
  })
};

function 내덱생성(개수) {
  for (let i = 0; i < 개수; i++) {
    내덱data.push(카드공장(false, true)); //영웅 X, 내카드 O
  }
  //다 지웠다가 출력
  내덱.innerHTML = '';
  내덱data.forEach(function(data) {
    카드돔연결(data, 내덱);
  });
};

function 내영웅생성() {
  내영웅data = 카드공장(true, true); //영웅 O, 내카드 O
  카드돔연결(내영웅data, 내영웅, true);
};

function 상대영웅생성() {
  상대영웅data = 카드공장(true);
  카드돔연결(상대영웅data, 상대영웅, true);
};


function 초기세팅() {
  상대덱생성(5);
  내덱생성(5);
  내영웅생성();
  상대영웅생성();
}

function Card(영웅, 내카드) { //문제해결 내카드 추가
  if (영웅) {
    this.att = Math.ceil(Math.random() * 2);
    this.hp = Math.ceil(Math.random() * 5) + 25;
    this.hero = true;
  } else {
    this.att = Math.ceil(Math.random() * 2);
    this.hp = Math.ceil(Math.random() * 5);
    this.cost = Math.floor((this.att + this.hp) / 2);
  }
  if (내카드) {
    this.mine = true;
  }
}

function 카드공장(영웅, 내카드) {
  return new Card(영웅, 내카드);
}

//턴 넘기기
턴버튼.addEventListener('click', function() {
  턴 = !턴; //true는 false로, false는 true로
  if (턴) {
    내코스트.textContent = 10; //코스트 10으로 채우기
    턴타입.innerHTML = '나의 턴'
  } else {
    상대코스트.textContent = 10;
    턴타입.innerHTML = '상대방 턴'
  }
});

초기세팅();

 

 

반응형

댓글