이 게임에서 일어나는 일
이 포켓볼 게임은 "당구대 위의 공 두 개"로 단순화된 물리 퍼즐입니다. 흰 큐볼 하나와 빨간 목표 공 하나가 360×220 크기의 테이블 위에 있고, 네 모서리에 포켓이 있습니다. 큐볼을 뒤로 끌었다 놓아 목표 공을 맞히고, 목표 공이 포켓에 들어가면 1점입니다. 총 10번의 기회가 주어지므로 점수는 0에서 10 사이이며, 점수 자체가 "10번 중 몇 번 넣었는가"를 뜻합니다. 손의 감각보다 각도와 힘을 계산하는 쪽이 이기는 게임이라, 아래에 실제 코드 값으로 계산한 힘 표와 조준 예시를 정리했습니다.
규칙 정리
- 잡기: 큐볼 중심에서 40 이내를 누르면 드래그가 시작됩니다. 공을 정확히 누를 필요는 없지만, 그 범위 밖에서는 시작되지 않습니다.
- 발사: 끌어당긴 방향의 반대로 발사됩니다. 끈 거리가 8 미만이면 발사되지 않고 시도 횟수도 줄지 않으며, 90를 넘으면 최대 힘으로 계산됩니다.
- 속도: 속도는 끈 거리의 10분의 1(프레임당)입니다. 최대 9까지 올라갑니다.
- 마찰: 매 프레임 속도에 0.986를 곱하고, 속도가 0.06 아래로 내려가면 멈춥니다. 공은 구르지도 회전하지도 않고, 벽에 닿으면 손실 없이 반사됩니다.
- 공끼리 충돌: 크기와 무게가 같은 두 공이 부딪히면 충돌 방향의 속도 성분만 서로 교환합니다. 정면으로 맞히면 큐볼이 멈추고 목표 공이 그 속도를 이어받습니다.
- 포켓: 네 모서리 포켓의 중심에서 반지름 14 안에 공 중심이 들어오면 빠집니다. 속도 제한은 없어서 빠르게 지나가도 빠집니다.
- 성공·파울: 목표 공만 들어가면 +1점. 큐볼이 포켓에 빠지면 파울이며 점수가 없습니다. 둘 다 빠진 경우도 파울입니다.
- 다음 샷: 큐볼은 매번 시작 위치(70, 110)로 돌아옵니다. 목표 공은 들어갔을 때만 새로 놓이며, 못 넣은 경우에는 멈춘 자리에 그대로 남습니다. 단, 큐볼 시작 위치에서 32 이내에 멈춘 목표 공은 겹침을 피하려고 새 위치로 옮겨집니다.
- 새 목표 공 위치: 가로 40~320, 세로 40~180 안에서 무작위로 정하되 큐볼 시작 위치에서 80 이상 떨어진 곳에 놓입니다. 이 난수는
Math.random()으로 보안용이 아닙니다.
드래그 거리와 힘
속도는 끈 거리에 비례하고 마찰은 프레임마다 같은 비율로 작용하므로, 직선으로만 간다고 가정하면 이동 거리는 처음 속도에 비례합니다. 아래 표는 코드 상수로 빌드 시 계산한 값이며, 벽 반사와 충돌은 포함하지 않은 직선 이동 기준입니다. "1px당 각도"는 마우스를 1픽셀 움직일 때 발사 방향이 바뀌는 각도로, 오래 끌수록 미세한 조준이 가능하다는 사실을 보여 줍니다.
| 끈 거리 | 힘 | 처음 속도 | 정지까지 이동 거리 | 정지까지 시간 | 1px당 각도 |
|---|---|---|---|---|---|
| 8 | 9% | 0.80 | 약 53 | 3.1초 | 7.13도 |
| 20 | 22% | 2.00 | 약 139 | 4.2초 | 2.86도 |
| 30 | 33% | 3.00 | 약 210 | 4.6초 | 1.91도 |
| 45 | 50% | 4.50 | 약 317 | 5.1초 | 1.27도 |
| 60 | 67% | 6.00 | 약 424 | 5.5초 | 0.95도 |
| 75 | 83% | 7.50 | 약 531 | 5.7초 | 0.76도 |
| 90 | 100% | 9.00 | 약 639 | 5.9초 | 0.64도 |
테이블 가로가 360이므로 힘 50%(끈 거리 45)에서도 직선으로 약 317를 가서 가로 길이에 가깝고, 최대 힘이면 약 639로 테이블을 두 번 가까이 가로지릅니다. 공이 멈추는 데 걸리는 시간도 최대 힘에서 약 5.9초로 길어서, 세게 치면 목표 공이 벽에 여러 번 부딪히며 포켓을 놓칠 가능성이 높습니다. 반대로 힘 20% 정도에서도 약 139를 가므로 근거리 샷에는 이 정도면 충분합니다.
포켓 위치
포켓은 테이블의 네 모서리에만 있고 가운데 변에는 없습니다. 공의 중심은 벽에서 반지름 8보다 가까워질 수 없어서 모서리 포켓의 중심과 공이 접근 가능한 가장 구석 사이는 약 0.6에 불과합니다. 즉 벽을 따라 굴러 모서리에 도달한 공도 포켓에 빠집니다.
| 포켓 | 중심 좌표(x, y) | 인식 반지름 |
|---|---|---|
| 좌상단 | (8.4, 8.4) | 14 |
| 우상단 | (351.6, 8.4) | 14 |
| 좌하단 | (8.4, 211.6) | 14 |
| 우하단 | (351.6, 211.6) | 14 |
계산 예시: 고스트 볼 조준
포켓볼의 기본 조준법은 목표 공이 포켓 쪽으로 가려면 큐볼이 어느 지점에서 맞아야 하는지를 먼저 정하는 것입니다. 목표 공 중심에서 포켓 반대 방향으로 공 지름(16)만큼 떨어진 "가상 공(고스트 볼)" 위치에 큐볼 중심이 도달하면, 충돌 방향이 목표 공→포켓 방향과 일치합니다.
예시 1. 직접 겨냥. 목표 공이 (260, 60)에 있고 우상단 포켓(351.6, 8.4)을 노린다고 하겠습니다. 포켓까지는 약 105, 고스트 볼 위치는 (246.1, 67.9)이고, 큐볼은 시작 위치에서 이 점을 향해 수평선 기준 13.5도 위쪽(화면 위)으로 약 181를 가야 합니다. 이때 큐볼 진행 방향과 목표 공→포켓 방향의 각도 차이는 약 15.9도(컷 각)입니다. 코드와 같은 물리로 시뮬레이션하면, 방향이 정확할 때 끈 거리 40~90 구간에서 49가지 값이 성공하고, 40보다 짧게 끌면 힘이 모자라 목표 공이 포켓까지 가지 못합니다.
예시 2. 허용 오차. 같은 상황에서 끈 거리 64로 쳤을 때 방향이 정확한 각도에서 위·아래로 ±0.50도 안팎까지는 성공합니다(0.25도 간격으로 확인). 위 표의 1px당 각도를 보면 끈 거리 90에서도 1픽셀이 0.64도라서, 거리가 먼 샷일수록 허용 오차가 손의 정밀도에 근접합니다. 목표 공이 포켓에서 멀수록 어려운 이유가 이 숫자에 있습니다.
예시 3. 정밀도와 힘의 맞교환. 방향과 힘이 같은 드래그 한 번으로 정해지기 때문에 둘은 따로 조절되지 않습니다. 끈 거리 20에서는 1픽셀이 2.9도나 바뀌지만 75에서는 0.76도입니다(캔버스가 360px 폭으로 표시될 때 기준이며, 화면에서 더 작게 줄어 표시되면 1픽셀의 각도가 더 커집니다). 그러므로 멀리 있는 목표 공을 노릴 때는 힘이 큰 샷을 감수해야 정밀하고, 힘을 줄이면 방향이 거칠어집니다. 가까운 목표 공이 먼 공보다 훨씬 쉬운 이유입니다.
코드 규칙에서 나오는 실전 팁
- 힘은 필요한 만큼만. 힘이 크면 정지까지 이동 거리가 길어져 두 공이 모두 벽을 여러 번 맞고 돌아다닙니다. 이 과정에서 큐볼이 모서리 포켓으로 흘러가 파울이 될 수 있으므로, 목표 공이 포켓 가까이 있으면 약하게 치는 편이 안전합니다.
- 정면 충돌은 큐볼이 멈춥니다. 두 공의 질량이 같고 마찰이 충돌에 작용하지 않으므로, 중심을 정확히 맞히면 큐볼은 그 자리에 멈추고 목표 공이 모든 속도를 가져갑니다. 그래서 정면 샷은 큐볼 낙하 위험이 가장 낮습니다.
- 비스듬히 맞히면 큐볼이 비껴 갑니다. 컷 각이 클수록 목표 공이 받는 속도 성분이 줄어듭니다. 이 게임은 충돌 방향의 속도만 교환하므로, 컷 각이 크면 같은 끈 거리에도 목표 공이 느리게 출발합니다.
- 벽을 이용한 뱅크샷도 가능합니다. 벽 반사는 입사각과 반사각이 같은 단순 반사라서 거울을 쓰듯 목표 지점을 벽 건너편에 대칭 이동시켜 조준할 수 있습니다. 다만 오차가 반사마다 커집니다.
- 실패한 샷의 결과를 이용하세요. 목표 공은 못 넣으면 멈춘 자리에 남고 큐볼만 시작 위치로 돌아옵니다. 공이 포켓 가까이에 멈췄다면 다음 샷은 더 쉬워지고, 중앙에 멈췄다면 새로 계산해야 합니다.
흔한 실수와 오해
- 당긴 방향으로 공이 나간다고 착각하기 쉽지만, 이 게임에서는 반대 방향입니다. 점선이 나가는 방향을 보여 줍니다.
- 큐볼이 목표 공에 닿지 못해도 시도 횟수는 소모됩니다. 연습용 시험 샷이 따로 없으므로 모든 발사가 10번의 기회에 포함됩니다.
- 파울이 되어도 점수는 깎이지 않지만, 한 번의 기회를 잃습니다.
- 화면에서 손을 뗄 때 캔버스 밖이어도 발사됩니다. 그래서 캔버스 바깥으로 끌어도 안전하게 조준할 수 있습니다.
한계와 저장되는 정보
이 게임은 공 두 개와 네 개의 모서리 포켓으로 이루어진 단순한 모델이라 실제 당구나 포켓볼의 스핀, 쿠션 마찰, 여러 공의 배치, 규칙(파울 후 상대 배치 등)은 반영하지 않습니다. 또 연습용으로는 시험 샷이 불가능하며 10번의 기회가 바로 기록이 됩니다. 최고 기록은 이 브라우저의 localStorage에 pool-billiards-best 키로 저장되며, 게임이 끝났을 때에만 갱신됩니다. 서버 전송이나 기기 간 동기화는 없고, 사이트 데이터를 삭제하면 사라집니다.
다른 물리·타이밍 게임도 즐겨보세요
비슷한 감각의 게임을 원한다면 미니 골프 게임이나컬링 스톤 게임, 벽에 튕기는 퍽을 다루는 에어하키 게임도 확인해보세요.
자주 묻는 질문
공이 회전(스핀)도 하나요?
아니요. 이 게임은 직선 이동과 벽·공 충돌만 구현한 단순화된 물리 게임으로, 실제 당구처럼 회전을 주는 기능은 없습니다.
목표 공의 위치가 매번 바뀌나요?
목표 공이 포켓에 들어갔을 때만 새 위치로 바뀝니다. 못 넣었다면 멈춘 자리에 그대로 있습니다. 큐볼 시작 위치와 너무 가까이 멈춘 경우에는 겹침을 피하려고 새 위치로 옮겨집니다.
큐볼이 포켓에 빠지면 어떻게 되나요?
파울로 처리되어 그 샷은 점수 없이 끝나고, 시도 횟수 1회가 소모됩니다. 큐볼은 시작 위치로 돌아옵니다.
고주사율 모니터에서 공이 더 빨리 움직이나요?
아니요. 물리 계산을 초당 60번의 고정 간격으로 처리하므로 화면 주사율과 관계없이 같은 속도로 움직입니다.
최고 기록은 언제 저장되나요?
10번의 시도를 모두 마친 뒤 그 판의 성공 횟수가 이전 최고 기록보다 높을 때 localStorage(pool-billiards-best)에 저장됩니다. 새 게임을 눌러 중간에 끝내면 그 판은 기록되지 않습니다.