Web Dev/Game Development :: 게임개발

게임 만들며 자바스크립트 배우기 (1/7) 메모리 게임(Memory Game)

HJPlumtree 2020. 5. 18. 22:35

밑의 글로 내려가기전 이 글을 먼저 읽어보는걸 추천 드립니다.

https://forgottenknowledge.tistory.com/entry/%EA%B2%8C%EC%9E%84-%EB%A7%8C%EB%93%A4%EB%A9%B0-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%B0%B0%EC%9A%B0%EA%B8%B007

 

게임 만들며 자바스크립트 배우기(0/7)

웹 개발을 독학하며 배우고 있습니다. FreeCodeCamp 커리큘럼을 따라가고 있고, 6개의 인증서를 다 받으면 풀스택이 될 수 있다고 하네요. 2번째 인증서까지 받았고 다음 부트스트랩으로 넘어가기전

forgottenknowledge.tistory.com

 

결과물은 이렇게 나옵니다.

 

코딩에 들어가기전 준비물

여기선 축구팀으로 설명하지만 원하는 이미지로 사용하면 되겠죠?

1. 미리 깔아놓을 공 그림 1개와 6개의 축구팀로고, 사이즈 :100x100px (총 7개의 이미지) 

2. 뒷 배경을 위한 큰 이미지 여기선 경기장 이미지 가로 2000px 썼습니다.

 

총 8개의 이미지를 코딩을 하게될 폴더에 images 폴더를 새로만들어서 넣어두면 준비끝!

 

밑의 함수들을 사용하게 됩니다.

미리 알고 있으면 편하게 볼 수 있을거에요

• push()

• querySelector()

• SetAttribute()

• getAttribute()

• appendChild()

• Math.random()

• sort()

• For loops

• createElement()

 

 

그럼 HTML 부터 시작합니다.

 

HTML

<html>
  <head>
    <meta charset='UTF-8'>
    <title>Memory Game</title>
    //css랑 javascript 연결잊지 마세요.
    <link rel="stylesheet" href="style.css"></link>
    <script src="script.js" charset="UTF-8"></script>
  </head>
  <body>
 	//제목
    <h1>Football Memory Game</h1> 
    
    //점수판 만들어 줍니다
    <h3>SCORE: <span id="result"></span></h3>
    
    //이 div에 모든 축구팀이 들어갈거에요
    <div class="grid">
    </div>
    
    //찾은 팀을 밑에 알려주기위해
    <p id="foundTeam"></p>

  </body>
</html>

 

 

CSS

*{
  //font-family 무시해도 되요. 기본 폰트가 마음에 안들어 인터넷에서 다운받은 폰트입니다
  font-family: 'Candara';
  padding: 0;
  margin: 0;
}

h1{
  //padding으로 크게 마들어, 배경색을 초록색으로 글자색은 흰색
  padding: 30px;
  display: block;
  background: #25a519;
  font-size: 4rem;
  color: #fff;
}
h3{
  //점수 폰트 사이즈도 키워주고 흰색으로
  font-size: 2rem;
  color: #fff;
  margin: 20px;
}

#foundTeam{
  //찾은 팀을 보여줄 텍스트
  color: #fff;
  font-size: 3rem;
}


/*
결과물 보면 이미지가 투명도 있게 들어간거 보셨나요?
그 작업을 위한 body와 body:before 설정입니다.
*/
body {
  //가운데정렬
  text-align: center;
  background: #000;
}
body:before {
  background-image: url('images/stadium.jpg');
  content: '';
  width: 100%;
  height: 100%;
  display: block;
  position: absolute;
  opacity: 0.3;
  z-index: -1;
}

.grid {
  //flex로 만들어서 게임 판을 좌우 400px, 높이 300px로 만들어주고, margin으로 가운데 정렬
  display: flex;
  flex-wrap: wrap;
  width: 400px;
  height: 300px;
  margin: 0 auto;
}

 

 

대망의 Javascript

//HTML이 완전히 로딩되고 시작
document.addEventListener('DOMContentLoaded', () => {

  //가장 먼저 배열을 만들어서 메모리 카드에 사용할 카드 각 2장씩 저장합니다.
  //즉 6개의 팀 로고 2개씩 전체 12개 팀 배열에 저장
  const cardArray  = [
    {
      name: 'acmilan',
      img: 'images/acmilan.jpg'
    },
    {
      name: 'acmilan',
      img: 'images/acmilan.jpg'
    },
    {
      name: 'barcelona',
      img: 'images/barcelona.jpg'
    },
    {
      name: 'barcelona',
      img: 'images/barcelona.jpg'
    },
    {
      name: 'juventus',
      img: 'images/juventus.jpg'
    },
    {
      name: 'juventus',
      img: 'images/juventus.jpg'
    },
    {
      name: 'manchestercity',
      img: 'images/manchestercity.jpg'
    },
    {
      name: 'manchestercity',
      img: 'images/manchestercity.jpg'
    },
    {
      name: 'manchesterunited',
      img: 'images/manchesterunited.jpg'
    },
    {
      name: 'manchesterunited',
      img: 'images/manchesterunited.jpg'
    },
    {
      name: 'realmadrid',
      img: 'images/realmadrid.jpg'
    },
    {
      name: 'realmadrid',
      img: 'images/realmadrid.jpg'
    }
  ]

  //카드의 순서를 섞어줍니다.
  cardArray.sort(() => 0.5 - Math.random());


  /*
  querySelector는 선택한 첫 번째 요소를 찾는다.
  클래스 grid를 가지고 있는 첫 번째 녀석을 grid에 저장.
  같은 방법으로 result, foundTeam 도 변수에 저장
  */
  var grid = document.querySelector('.grid');
  var result = document.querySelector('#result');
  var foundTeam = document.querySelector('#foundTeam');
  
  //밑에 사용할 변수들 입니다.
  var cardChosen = [];
  var cardChosenId = [];
  var cardsWon = [];
  
  
  //판을 만드는 함수
  function createBoard() {
    //위에서 만든 카드배열 만큼 반복
    for (let i = 0; i <cardArray.length; i++) {
    
      //img요소 즉 img 태그를 만들어주는 코드
      var card = document.createElement('img');
      
      //만든 img요소에 기본 카드의 공 이미지를 만들어주고, 아이디(i)를 순서대로 넣어준다
      card.setAttribute('src', 'images/ball.jpg');
      card.setAttribute('id', i);
      
      //위에서 img 태그 만들어서, 주소 넣어주고, 아이디 넣어줬지만 이제는 진짜 html에 넣어줄시간
      grid.appendChild(card);
      
      //카드가 클릭되면 flipCard 함수를 실행하라!
      card.addEventListener('click', flipCard);
    }
  }
  
 
 
 
 //밑에 함수 중 flipCard 함수부터 보면 편합니다.
  
  //2장의 카드가 같은지 다른지 알아보자는 함수
  function checkForMatch() {
    //querySelector에 All을 붙여서 모든 img 요소(태그)를 가져온다
    let cards = document.querySelectorAll('img');
    
    //2개의 카드가 저장됬겠죠 cardChosen과 cardChosen 변수에
    //저장된 2장의 카드의 id 순서대로 저장 
    let optionOneId = cardChosenId[0];
    let optionTwoId = cardChosenId[1];

    // 2장의 카드가 들어와서, 같은 팀 이름이면 실행됩니다.
    if(cardChosen[0] === cardChosen[1]) {
      //foundTeam은 뭐라고 했죠? 그죠 매치시킨 팀이에요
      //2장이 같으니까 밑에 찾은 팀 이름을 적어줍니다. 골 넣었다고도 외쳐주고요
      //cardChosen[0]을 한 이유는 cardChosen에는 같은 팀이름이 ['팀이름', '팀이름'] 있어서에요
      foundTeam.textContent = 'Goaaaaaaaaal! '+ cardChosen[0].toUpperCase() + ' Scored!';
      
      //맞춘 팀을 cardsWon 변수에 저장
      //2개 팀을 맞추면 [['팀이름1', '팀이름1'], ['팀이름2', '팀이름2']] 이렇게 저장되있겠죠
      cardsWon.push(cardChosen);

      //선택된 2장의 팀이 달랐을 경우
    } else {
      //간단합니다, 2장의 카드를 다시 공 이미지로 변경
      cards[optionOneId].setAttribute('src', 'images/ball.jpg')
      cards[optionTwoId].setAttribute('src', 'images/ball.jpg')
      }
      
      //결과에는 cardsWon의 길이를 넣어주면 점수가 되죠.
      result.textContent = cardsWon.length;

      //맨~~처음 12장의 팀을 배열에 저장했죠.
      //2장씩 짝을 맞추는 거니까 반을 나누면 점수랑 같아집니다. 같으면 result에 축하한다고 변경 
      if(cardsWon.length === cardArray.length/2){
        result.textContent = 'Congratulations! You won the game!';
      }
      
    // 2장의 카드가 맞던, 틀리던 선택된 카드의 배열을 리셋해줍니다.
    cardChosen = [];
    cardChosenId = [];

  }
  
  //flipCard 함수는 카드를 돌려보는 기능을 해준다.
  function flipCard() {
    //카드 아이디를 저장할 변수를 만들어주고 id를 넣어준다.
    //this 추가설명 위에서 '클릭되면 flipCard를 실행하라'라고 했을 때 그 클릭된 친구가
    //여기로 넣어오고 그 친구의 id를 저장하는 거에요
    var cardId = this.getAttribute('id');

    //앞에서 미리 만들어놓은 배열에 지금 들어온 아이디를 가진 팀의 이름을 넣어주기
    cardChosen.push(cardArray[cardId].name);
    
    //그리고 그 팀의 순번(id)도 넣어주기
    cardChosenId.push(cardId);
    
    //또 this로 클릭된 이 카드의 src 주소를 공 이미지 -> 선택된 팀 이미지로 변경
    this.setAttribute('src', cardArray[cardId].img);

    //2개의 카드가 선택됬다면 틀렸는지 맞았는지 알아볼 시간
    if(cardChosen.length === 2) {
      //0.5초 뒤에 2개가 같은 카드인지 아닌지 판별하는 checkForMatch 함수 실행
      setTimeout(checkForMatch, 500);
    }
  }
  
  //판을 만들어 주는 이 함수를 적어주지 않으면 아무것도 일어나지 않아요
  createBoard();
})