미니 프로젝트: 당근잡기 게임2

지원·2022년 5월 26일
0

Mini Project

목록 보기
2/2

기능

1. Play 버튼 : 버튼 상태변경, 타이머, 카운터 세팅, 아이템 배치
1) 타이머 : 게임 시작 시 디폴트 값에서 1초씩 감소
2) 카운터 : 디폴트 카운트 값(당근카운트)에서 1씩 감소
3) 아이템 배치 : 랜덤으로 X, Y 위치에 아이템 배치
4) 아이템 작동 : 당근 클릭시 당근 아이템 삭제되고 카운터 함수 호출
벌레 클릭시 lost 팝업창 노출

2. Stop 버튼 : 타이머, 팝업창 노출 (Replay)
3. win : 시간 내에 당근 모두 클리어 시 팝업창 노출
4. lose : 벌레 클릭 && Timeout 시 팝업창 노출

1. play 버튼

1) 타이머

타이머는 default 초에서 1초가 지날 때 마다 1씩 감소하는 형태로 구현한다.

setTimeout : 지정한 시간이 지나면 인자 함수를 호출한다.
주의할 점은 이 함수는 "정지구간"을 따로 만들지 않고 "비동기"적으로 동작한다는 점이다.
함수가 완료된 후 다른 함수를 호출하는 구조가 필요하다면 프로미스를 사용하자.

setInterval : 지정한 시간 동안 인자 함수를 호출한다.

clearInterval : 현재 진행되고 있는 함수 호출을 정지한다.

타이머의 분 과 초는 아래와 같이 작성하여 좀 더 편리하게 작성할 수 있다.

const minutes = Math.floor(시간인자 / 60);

1분(=60초)를 기준으로 미만인 소수점은 floor로 0 이나 1, 2로 떨어지게 처리할 수 있다.

const seconds = 시간인자 % 60;

분 에서 나머지 처리를 사용해 초 에 대입되도록 처리하였다.


2) stop 버튼

게임 정지 버튼을 클릭하면 Replay 팝업창이 띄워지고

타이머, 카운트, 요소 클릭 모두 unuse 상태가 되어야 한다.


1-1. 타이머 멈추기

이미 초반에 play 버튼을 클릭할 때 init 함수가 호출되도록 작성했기 때문에

한 번 더 같은 버튼에 click 이벤트를 걸어줄 수가 없다.

그래서 초반에 작성했던 부분에 "게임 상태 조건" 을 걸어

게임이 시작하기 전 click 이벤트는 게임 시작을,

게임이 시작 한 상태의 click 이벤트는 게임 정지로 분류해주었다.

1-2. 팝업창 띄우기

게임 정지 버튼을 클릭하면 display:none 스타일 값을 가진

popup--hidden 클래스를 remove 해주는 함수를 호출했다.


1-3. play, stop, finish 기능

게임에서 가장 큰 졌을 때, 이겼을 때, 정지 버튼을 눌렀을 때 의 세 가지 상황을

gameStatus 변수의 true/false 상태로 각각 상황에 맞는 함수 호출을 조작해주었다.


3) field 내의 모든 클릭 이벤트

당근, 벌레 등의 아이템들을 하나씩 클릭 이벤트를 적용할 수도 있지만

이벤트 위임을 이용하면 코드의 간결화와 더불어 메모리 누수를 방지할 수 있다.


이슈 관리

1) 타이머 정지

timer 디폴트 값이 '0' 이 되었을 때 clearInterval 로 함수를 사용하여

더이상 호출되지 않도록 시도해보았는데 멈추지 않고 -1, -2 ... 마이너스로 끝까지 타이머가 흘러간다.


💡 타이머를 정지시키기 위해서는 setInerval을 반환하는 타이머 객체를 없애주어야 한다.
setInerval 함수는 인터벌 아이디(Interval ID)라고 불리는 숫자를 반환하는데,
인터벌 아이디는 setInterval() 함수를 호출할 때 마다 내부적으로 생성되는 타이머 객체를 가리킨다.
clearInterval 함수에 인터벌 아이디를 인자로 호출해야 코드가 주기적으로 실행되는 것을 중단시킬 수 있다.

2) 팝업 노출

게임 정지 버튼을 클릭했을 때 popup 창의 visibility 값이 "hidden" 에서 "visible"로

변경 되는 것을 구현하려는데 팝업창이 나타나지 않았다.

가만보니 스타일을 visible 값으로 시작했을 때에도 게임이 시작되기 전엔

팝업창이 떠있다가 게임이 시작되고 나서는 팝업창이 사라졌다. 팝업창은 어디로 간걸까?


💡 이유는 field에 팝업창을 겹치게 마크업 작성을 하는 경우,
field에 아무것도 없을 때엔 정상적으로 동작되지만, 만약 field에 이미지가 있다면
이미지 때문인지 팝업이 아예 렌더링되지 않는다. (정확한 이유는 나중에 찾아봐야지)
그래서 팝업창은 field 내부 자식 요소가 아닌 별개의 요소로 작성해주고
field 위로 올라오게 스타일을 수정해주었다.

profile
하루씩 내 자신 넘기⛰️

0개의 댓글