가장 까다로웠던 게임
오목보드의 12가지 게임 중 만들기 가장 까다로웠던 것은 알까기였습니다. 규칙은 단순한데, 화면 속 구슬이 "알까기답게" 미끄러지도록 만드는 게 어려웠습니다. 그 핵심이 마찰 계수 하나였습니다.
어릴 때 학교 쉬는 시간에 교실에서 바둑판을 펴 놓고 하던 놀이라, 손끝에 남은 감각과 화면 속 구슬이 다르게 움직이면 바로 어색하게 느껴졌습니다.
구슬은 어떻게 멈추나
오목보드 알까기는 화면을 한 번 그릴 때(프레임)마다 구슬을 속도만큼 옮기고, 속도에 마찰 계수를 곱해 줄입니다. 속도가 정해진 값(멈춤 기준) 아래로 떨어지면 멈춥니다. 가장 세게 튕긴 구슬의 처음 속도는 프레임당 20픽셀이고, 구슬이 움직일 수 있는 판의 폭은 524픽셀입니다.
처음 값은 너무 미끄러웠다
| 설정 | 마찰 계수 | 멈춤 기준 | 최대 힘으로 친 구슬이 가는 거리 | 멈출 때까지 |
|---|---|---|---|---|
| 처음 버전 | 0.984 | 0.12 | 1,243픽셀 (판 폭의 2.37배) | 318프레임, 약 5.3초 |
| 2026-06-08 이후 | 0.960 | 0.20 | 495픽셀 (판 폭의 0.94배) | 113프레임, 약 1.9초 |
시간은 1초에 60번 그리는 화면 기준입니다. 처음 값에서는 한 번 세게 치면 구슬이 판을 두 번 넘게 가로지를 만큼 미끄러졌고, 멈출 때까지 5초 넘게 기다려야 했습니다. 이러면 조준이 의미가 없어지고, 판 위의 구슬이 대부분 한 번에 밖으로 나갑니다.
마찰을 프레임당 1.6% 감속에서 4% 감속으로 바꾸자, 가장 세게 쳐도 판을 거의 가로지르는 지점에서 멈추게 됐습니다. 너무 빨리 서면 튕기는 손맛이 없고, 너무 오래 미끄러지면 조준이 의미가 없어서 그 사이 값을 찾는 게 가장 오래 걸렸습니다.
이 값이 만든 플레이 요령
- 판 폭의 10분의 1만 당겨도 최대 힘입니다. 당긴 거리에 0.38을 곱한 값이 속도가 되고 20에서 더 오르지 않으니, 52.6픽셀(판 폭의 10%)부터는 더 당겨도 세지지 않습니다. 길게 당기는 건 힘이 아니라 방향을 정밀하게 잡는 용도입니다.
- 먼 알일수록 힘이 빠집니다. 내 구슬이 굴러가는 동안 계속 느려지므로, 판 폭의 절반쯤 굴러간 뒤에 맞히면 판 한가운데 있던 상대 알은 테두리까지 가기 전에 멈추기 쉽습니다. 먼 알을 무리하게 노리기보다 가까운 알부터 정리하는 게 유리한 이유입니다.
힘 조절과 각도에 대한 더 자세한 요령은 알까기 공략에 정리했습니다.
온라인 대전에서 같은 결과가 나오게
온라인 대전에서는 내가 쏜 구슬이 상대 화면에서도 똑같이 움직여야 합니다. 그래서 물리 계산에 무작위 값을 쓰지 않고, 화면 크기와 상관없이 560×560 크기의 가상 판에서 계산합니다.
쏜 쪽은 어느 구슬을 어느 방향과 세기로 쳤는지와 함께, 자기 화면에서 구슬이 모두 멈춘 뒤의 위치도 보냅니다. 받는 쪽은 같은 샷을 그대로 재생해서 움직임을 보여 주고, 구슬이 멈추면 쏜 쪽이 보낸 최종 위치로 맞춥니다. 같은 계산이라 원래 결과가 같아야 하지만, 소수점 계산의 아주 작은 차이가 쌓여 판정이 갈리는 일이 없도록 쏜 쪽의 결과를 기준으로 삼은 것입니다.
이 방식 때문에 생긴 버그도 있었습니다. 다른 게임은 상대의 수가 도착하면 바로 반영이 끝나는데, 알까기는 구슬이 굴러가는 몇 초 동안 재생이 이어집니다. 그런데 차례를 확인하는 코드가 재생이 끝나기 전에 한 번만 실행돼서, 내 차례가 와도 드래그가 먹지 않았습니다. 구슬이 완전히 멈춘 뒤에 차례를 다시 확인하도록 2026년 9월 6일에 고쳤습니다.
그 뒤에 더한 것
2026년 8월 3일에는 판 가운데에 고정 장애물 3개를 세로로 둔 익스트림 모드를 추가했습니다. 장애물도 구슬끼리 부딪힐 때와 같은 반발 계수(0.9)로 구슬을 튕겨냅니다. 장애물을 이용한 공략은 알까기 공략의 익스트림 모드 항목에 있습니다.
직접 확인하기
- 물리 코드: alkkagi.js (파일 맨 위 FRICTION, MIN_SPEED, MAX_LAUNCH)
- 마찰을 바꾼 커밋: f31c830 (2026-06-08)
- 익스트림 모드 추가: f907971 (2026-08-03)
- 온라인 차례 버그 수정: a4eb611 (2026-09-06)