끝났다
생각보다 후련하지는 않다
어서 새로운 프로젝트도 하고싶고
지금 짜둔 코드를 계속 리팩토링하고싶기도 하다.
하지만 리팩토링만 어마어마한 시간을 잡아먹지 않을까 두렵기도 하면서
어쨌든 첫 프로젝트를 끝낸 내가 자랑스럽다!
- 목표
목표는 GAME부분과 footer을 마무리하는 것이었다
이틀에 걸쳐 공부를 하다 틈틈히 만들었다고는 하지만 생각보다 GAME 부분에서 고전했다
- 구현 계획
GAME부분은 game board 박스 안에 물고기들이 무작위 위치로 계속 움직이고
물고기를 클릭하면 물고기가 remove된다.
동시에 클릭 위치로 낛시바늘이 이동했다가 x좌표 그대로 game board 박스 위로 다시 올라간다.
실전 코딩
일단 엘리 드림코딩101에서 배운
let ** = false 를 활용해서 게임을 만들어보기로 했다.
let start = false;
const gamePopup = document.querySelector(".game__popup");
gamePopup.addEventListener("click", () => {
if (!start) {
hideStartBtn();
timerForFishMove();
} else {
displayStartBtn();
}
start = !start;
});
이렇게 일단 start 버튼을 가지고 있는 gamePopup을 띄우고
click하게 되면
start가 true가 되어
hideStartBtn과
timerForFishMove
함수가 작동된다.
지금 보고 깨달았는데
displayStartBtn이 작동할 수 없는 구조로 만들었구나..
일단 글을 쓰고 고쳐야겠다
어쨌든 click을 하면 start의 값이 계속 변할 수 있게 코딩하였다
startBtn을 hide하고 display하는 것은 classList.add와 remove로 코딩했고
어려웠던 부분 중 하나인
timerForFishMove()는
let moveSecond = false;
function timerForFishMove() {
fishPosition();
moveSecond = setInterval(fishPosition, 400);
}
이렇게 만들었다.
이 또한 브라우저101강의에서 배운것을 활용했다.
setInterval을 할 때 평소에는 false로 유지되는 변수를 설정하는 것
일단 fishPosition을 받아오고
moveSecond를 setInterval로 설정한다.
** 다시 코드를 보니 fishPosition()을 미리 호출할 필요가 없다. moveSecond를 만들기 전에 진행을 보기 위해서 넣었다가 삭제를 하지 않은 것 같다.
function fishPosition() {
fish.forEach((item) => {
const width = gameBoard.offsetWidth;
const height = gameBoard.offsetHeight;
const randomY = Math.floor(
Math.random() * (height - fishHeight - gameToolsHeight) + gameToolsHeight
);
const randomX = Math.floor(Math.random() * (width - fishWidth));
item.style.top = `${randomY}px`;
item.style.left = `${randomX}px`;
});
}
fishPosition함수는
fish를 forEach로 돌면서 width와 height를 gameBoard에서 받아오고
randomY와 randomX값을 이용해서 gameBoard의 width와 height를 넘지 않는 구간에서 랜덤한 숫자를 가져온다
randomY에만 있는 gameToolsHeight 계산은 gameTools그러니까 낛시바늘이 계속 위치하고 있는 상단 부분까지 fish가 가지 않게 하기 위해서이다.
randomY와 randomX값은
item의 css top과 left에 넣어준다.
드디어 움직이던 물고기
이제는 물고기를 클릭하면 삭제해야 한다.
gameBoard.addEventListener("click", (e) => {
const target = e.target;
if (target.className === "fish") {
target.remove();
} else {
}
});
방법은 간단하다
gameBoard에 click된 target이 fish와 같으면 그 target을 remove해주는 것이다
그러나 catchTool(낛시바늘)이 끼면서 상황은 복잡해졌다
처음에는 catchToolMove라는 함수를 이용해서 클릭한 위치 값을 받아온 다음에
클릭하는 곳에 catchTool이 이동하게 만들었다
그러나
물고기를 누르면 갈고리가 계속 왼쪽 위로 갔다
gameBoard안의 위치를 구해서 갈고리를 위치시켜야 하는데
물고기를 누르면 물고기 안에서의 위치값을 구했기 때문이다.
다시말해 갈고리는 gameBoard 안에서 X와 Y값을 얻는데
물고기를 클릭한 경우 물고기를 전체 박스 크기로 보고 그 안에서 클릭한 좌표로 이동했던 것이다.
따라서 물고기를 클릭했을 때 갈고리가 이동할 수 있는 최대 사이즈가 물고기의 width와 height가 된 것이다.
처음에는 문제 발생 이유를 몰라서 많이 고생했고
문제 발생 이유를 안 이후에는 gameBoard안에서 물고기의 좌표를 구하기 위해 고생했다
물고기의 좌표를 받아오는 함수를 어디에 넣어야 하나, 현재 만들어진 함수들 중 어떤 함수 안에서 매개변수를 받아와야 하는지가 주된 고민이었다.
문제해결방법
gameBoard.addEventListener("click", (e) => {
const target = e.target;
const offsetX = e.offsetX;
const offsetY = e.offsetY;
click한 곳의 offsetX와 Y를 구해서
if (target.className === "fish") {
const fishX = parseInt(target.style.left);
const fishY = parseInt(target.style.top);
target.remove();
catchToolMove(fishX, fishY);
catchToolBack(fishX);
} else {
catchToolMove(offsetX, offsetY);
catchToolBack(offsetX);
}
});
fish가 클릭되었을 때
fish가 현재 위치하고 있는 left와 top값을 받아 각각
fishX와 fishY에 넣어준다.
그리고 fish를 삭제한 후
catchToolMove라는 함수에 fishX와 fishY를 매개변수로 집어넣어주고
(그냥 offsetX와 offsetY를 집어넣으면 gameBoard가 아닌 물고기를 박스로 보고 그 안에서의 X, Y값이 들어오기 때문에)
catchToolBack에는 fishX를 집어넣어준다.
만약 fish를 클릭한 것이 아니라면 그냥 offsetX와 offsetY값을 받아와서 넣는다
gameBoard라는 박스 안에서 클릭한 것으로 인식되기 때문이다.
catchToolMove와 catchToolBack함수
function catchToolMove(X, Y) {
catchTool.style.left = `${X}px`;
catchTool.style.top = `${Y}px`;
catchTool.style.transform = "translate(-50%, -50%)";
}
catchToolMove는 매개변수 두 개를 받아와서
catchTool의 left와 top 값을 정해준다
함수를 만든 목적이 gameBoard를 클릭하면 catchTool이 그 위치로 이동하게 하는 것이어서 X값과 Y값 두 개의 매개변수가 필요하다
transform translate는 클릭위치를 이미지의 왼쪽 상단이 아닌 중앙으로 오게 하기 위함이다.
function catchToolBack(X) {
setTimeout(() => {
catchTool.style.top = `0px`;
catchTool.style.left = `${X}px`;
}, 300);
}
catchToolBack은 매개변수 하나를 받아와서
catchTool의 top값을 0으로, 받아온 매개변수를 left값으로 정해준다.
함수를 만든 목적이 catchToolMove함수가 발생한 후(gameBoard를 클릭하고 catchTool이 이동한 후)
그 위치에서 수직으로 상승해 gameBoard의 상위에 위치하게 하기 위함이기 때문이다.
그리고 catchToolBack의 catchTool의 top값과 left 값을 300ms후에 변경해준다.
이는 갈고리가 원하는 위치로 이동했다가 다시 상승하는 것을 볼 수 있게 하기 위함이다.
footer부분은 어려움 없이 끝냈다
tistory와 github, mail주소를 첨부했다.
header~> main news 부분
ad~>footer부분
링크
https://userju.github.io/FISH-NEWS/
아직 고칠부분이 너무 많지만 첫 프로젝트를 스스로 해냈다는 것이 기쁘다.
지속적으로 리팩토링하고 복잡한 코드를 고칠 예정
'🤸♀️ 내 프로젝트 > FISH-NEWS' 카테고리의 다른 글
[FISH-NEWS] 프로젝트 기록 (0) | 2021.11.05 |
---|---|
[FISH-NEWS] 프로젝트 기록 (0) | 2021.11.02 |
[FISH-NEWS] 프로젝트 기록 (0) | 2021.10.21 |
[FISH-NEWS] 프로젝트 기록 (0) | 2021.10.13 |
[FISH-NEWS] 프로젝트 기록 (0) | 2021.10.12 |