JavaScript/이상형 월드컵

JavaScript 이상형 월드컵 만들기 (2) - 게임 진행

칠구의 스터디 2024. 1. 31. 17:16

저번에 화면 구현을 완료했고 이번엔 게임을 진행해보았다.

솔직히 금방 끝날 줄 알았는데 생각보다 오류가 많이 발생해서 오래걸림 ㅠㅠ

 

<script>
    var text = "";
    var images = []; //이미지 데이터들을 담을 곳
    var rounds = ["16강", "8강", "4강", "결승", "우승자"]; // 라운드별 이미지 수
    var roundIndex = 0; // 현재 라운드 인덱스
    var matches = rounds[roundIndex] === "16강" ? 8 : (rounds[roundIndex] === "8강" ? 4 : (rounds[roundIndex] === "4강" ? 2 : 1)); // 현재 라운드의 경기 수
    var currentMatch = 0; // 현재 진행 중인 경기
    var sImages = []; // 선택한 이미지 저장 배열
    var winnerImage = "우승자";


    //오디오 함수 
    function play() {
      var audio = document.getElementById('audio_play');
      if (audio.paused) {
        audio.play();
      } else {
        audio.pause();
        audio.currentTime = 0;
      }
    }

    // 이미지 파일 이름 배열 생성 (img 폴더 안에 있는 이미지 파일)
    for (var i = 1; i <= 16; i++) {
      // 이미지 파일 이름을 형식에 맞게 생성 (01,02이런것도 표시 가능!!)
      var fileName = "../img/mm" + (i < 10 ? "0" : "") + i + ".jpg";
      images.push(fileName);
    }

    //이미지가 랜덤으로 배정
    images.sort(function(a, b) {
      return 0.5 - Math.random();
    });

    //이미지를 보여줌
    showImg(currentMatch);
    //이미지 2개와 라운드 (16강,8강... 이런거)
    function showImg(matchIndex) {
      var matchStartIndex = matchIndex * 2;
      document.getElementById('image1').src = images[matchStartIndex];
      document.getElementById('image2').src = images[matchStartIndex + 1];
      document.getElementById('round').innerHTML = rounds[roundIndex];
    }

    //이게 선택한 이미지를 저장하고 다음 라운드에 보내는 함수
    function change(n) {
    sImages[currentMatch] = images[currentMatch * 2 + n]; //여기가 선택한 이미지 -
    currentMatch++; // 경기를 계속 진행

    //경기 진행
    if (currentMatch >= matches) {
    if (roundIndex < rounds.length - 1) {
      roundIndex++; // 다음 라운드로 진행
      matches = rounds[roundIndex] === "16강" ? 8 : (rounds[roundIndex] === "8강" ? 4 : (rounds[roundIndex] === "4강" ? 2 : 1));
      currentMatch = 0; // 경기 종료를 나타냄

       // 우승자가 결정됨
      if (roundIndex === rounds.length - 1) {
        winnerImage = sImages[0]; //우승자
        document.getElementById('cal').innerHTML = "";
        document.getElementById('winnerImage').src = winnerImage;
        document.getElementById('winnerContainer').style.display = 'block';
        // 이미지 요소를 숨김 -> 우승자는 1개니깐
        document.getElementById('image1').style.display = 'none';
        document.getElementById('image2').style.display = 'none';
      } else {
        // 다음 라운드의 이미지를 랜덤으로 설정 
        images = sImages.slice(0, matches * 2);
        images.sort(function (a, b) {
          return 0.5 - Math.random();
        });
        showImg(currentMatch);
      }
    } else {
      // 모든 라운드가 종료됨 -> '당신의 이상형' 텍스트를 보여줌
      document.getElementById('cal').innerHTML = "당신의 이상형";
    }
  } else {
    showImg(currentMatch);
  }
}
document.getElementById('cal').innerHTML = text; //미리 설정했던 텍스트를 보여줌 (16강,8강... 이런거)

사용된 자바스크립트이다. 해당 코드는 16강으로 라운드마다 rounds랑 matchs 만 다르고 다 똑같다.

 


이미지 업로드

이미지들은 mm01....mm16 이런식으로 저장해둬서 손쉽게

for (var i = 1; i <= 16; i++) {
      // 이미지 파일 이름을 형식에 맞게 생성 (01,02이런것도 표시 가능!!)
      var fileName = "../img/mm" + (i < 10 ? "0" : "") + i + ".jpg";
      images.push(fileName);
    }

이렇게 구현했다. 이번에 비교연산자를 통해 01,02...이런 0x 숫자를 나타낼 수 있는 지 첨 알았다.

밑에 나오겠지만 images.push를 통해 보여줄 이미지들을 보낸다.

 


이미지 보여주기

이미지를 보여주는 함수는 showImg으로 showImg(currentMatch)을 사용해서 현재 진행 상황을 알 수 있도록 하였다.

 showImg(currentMatch);
    function showImg(matchIndex) {
      var matchStartIndex = matchIndex * 2;
      document.getElementById('image1').src = images[matchStartIndex];
      document.getElementById('image2').src = images[matchStartIndex + 1];
      document.getElementById('round').innerHTML = rounds[roundIndex];
    }

앞서 push한 이미지들이 여기서 보여진다. 

라운드에 맞게 이미지들이 보여진다.

 


선택한 이미지 저장

라운드를 진행하면서 선택한 이미지를 저장하는 함수는 change이다

 function change(n) {
    sImages[currentMatch] = images[currentMatch * 2 + n]; 
    currentMatch++;

선택할 이미지(sImages)를 다 선택했으면 다음 라운드로 넘어가지게 된다

 


경기 진행

만약 16강이라면 currentMatch는 16 , matches는 8이 된다 -->> 8:4 , 4:2 , 2:1 이런식으로 진행이 되며

currentMatch 이게 0이되면 경기 종료 , 즉 우승자가 나오는 시스템이다.

 

우승자는 구분을 위해 winnerImage를 사용했고 getElementById('cal').innerHTML을 통해 미리 설정해뒀던

텍스트가 보여서 라운드 진행률을 알 수 있게 하였다

 

우승자를 보여줄 땐 원래 게임을 진행할 때 보여주던 컨테이너를 숨기고

winnerContainer(우승자 화면 전용)가 보여지게 하였다.

 if (currentMatch >= matches) {
    if (roundIndex < rounds.length - 1) {
      roundIndex++; 
      matches = rounds[roundIndex] === "16강" ? 8 : (rounds[roundIndex] === "8강" ? 4 : (rounds[roundIndex] === "4강" ? 2 : 1));
      currentMatch = 0; 

       if (roundIndex === rounds.length - 1) {
        winnerImage = sImages[0];
        document.getElementById('cal').innerHTML = "";
        document.getElementById('winnerImage').src = winnerImage;
        document.getElementById('winnerContainer').style.display = 'block';
       
        document.getElementById('image1').style.display = 'none';
        document.getElementById('image2').style.display = 'none';
      } else {
        images = sImages.slice(0, matches * 2);
        images.sort(function (a, b) {
          return 0.5 - Math.random();
        });
        showImg(currentMatch);
      }
    } else {
      document.getElementById('cal').innerHTML = "당신의 이상형";
    }
  } else {
    showImg(currentMatch);
  }
}
document.getElementById('cal').innerHTML = text;

번외 - 오류 해결한 부분

 

선택한 이미지가 다음 라운드에 올라오지 않은 오류

function getRandomImages() {
      var selectedImages = [];
      while (selectedImages.length < 8) {
        var randomIndex = Math.floor(Math.random() * images.length);
        var selectedImage = images.splice(randomIndex, 1)[0];
        selectedImages.push(selectedImage);
      }
      return selectedImages;
    }
    
     if (rounds[roundIndex] === "16강") {
      images = getRandomImages();
    }

    images.sort(function(a, b) {
      return 0.5 - Math.random();
    });

처음에 사용하던 코드이다. 

처음에 선택한 이미지를 담는 함수인 sImages 하나만 사용하면 이게 제대로 작동을 안하는 줄 알고

selectedImages를 새로 만들어서 해봤다

이땐 라운드별로 다 써야하는 지 알았다... (16강따로 , 8강따로...)

 

 

해결 코드 ⬇️⬇️

if (currentMatch >= matches) {
    if (roundIndex < rounds.length - 1) {
      roundIndex++; 
      matches = rounds[roundIndex] === "16강" ? 8 : (rounds[roundIndex] === "8강" ? 4 : (rounds[roundIndex] === "4강" ? 2 : 1));
      currentMatch = 0;
      
      
      
      
      else {
        images = sImages.slice(0, matches * 2);
        images.sort(function (a, b) {
          return 0.5 - Math.random();
        });
        showImg(currentMatch);
      }

 

알고 보니 무작위로 이미지를 업로드하려고 사용했던 getRandomImages가 문제였다...

솔직히 정확하게 어디가 오류를 일으켰는진 알 순 없지만 해당부분인 getRandomImages ,selectedImages을 

삭제하니 거짓말처럼 오류가 사라지고 정상적으로 작동했다 ㅠㅠㅠㅠ

 

하나의 함수 sImages 만 사용해도 정상적으로 구현된다는 점에서 자바스크립트의 파워를 다시 한번 깨달았고

오류가 계속 날땐 스트레스도 많이 받고 짜증났지만 해결되니 기분이 너무 좋다 ㅎㅎ