물고기가 집을 벗어나 층 전체를 헤엄치도록

집 둘레를 타원으로 돌던 것을 걷어냈다. 관계는 분명했지만 꾸미기 게임에는
어울리지 않았다 -- 말뚝에 묶인 것처럼 보였고, 집을 여러 채 지으면
화면이 회전목마 여러 대가 된다.

집은 정원을 세는 단위로만 남고, 헤엄치는 범위는 그 층의 격자 전체다.
제 집 앞에서 시작해 거기서부터 어디로든 간다.

알고리즘은 방향 흔들기다. 목표 지점을 따로 두지 않고 진행 각도만 매 틀
조금씩 흔든다. 그것만으로 충분히 어슬렁거리는 것처럼 보이고 목표를 찍는
방식보다 싸다. 테두리는 닿기 전에 미리 각도를 반사시킨다.

종류마다 다니는 방식을 갈랐다. 같은 식으로 움직이면 여러 마리가 한 화면에
있을 때 움직임이 무늬가 된다.
- 물고기: 빠르고 크게 돌아다닌다
- 게: 세로 성분을 12%로 눌러 바닥을 짚고 걷는다
- 해마: 가로 성분을 35%로 눌러 거의 제자리에서 오르내린다
- 새우: 1~3초마다 0.35초 동안 3.2배로 튄다
- 해파리: 물살에 밀리듯 아주 천천히

화면 위쪽(뒷줄)일수록 작고 흐리게 그려 앞뒤를 읽게 했다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-02 14:49:20 +09:00
parent 1ca381922f
commit 375b340c47
4 changed files with 158 additions and 44 deletions
+9 -11
View File
@@ -55,8 +55,6 @@ const LAYER_SLIDE := 0.32
## 높이를 전부 격자에 주면 칸만 거대해지고 보이는 열은 오히려 줄어든다.
const SHOWCASE_GRID_RATIO := 0.45
const DRAG_THRESHOLD := 5.0
## 물고기가 집을 한 바퀴 도는 속도(라디안/초). 위젯이라 눈에 거슬리지 않게 느리다.
const ORBIT_SPEED := 0.5
var _rng := RandomNumberGenerator.new()
var _lock_reasons := {} ## 구역 인덱스 -> 사유 Label
@@ -463,14 +461,9 @@ func _make_fish(entry: Dictionary) -> void:
items.add_child(node)
node.setup(d, "producer", -1, _fish_area(home, cell, slot), cell, _rng)
# 생물은 모두 집 둘레를 돈다. 고착생물(해초·거품돌)은 이제 집 쪽으로 옮겼으므로
# 여기 들어오는 것은 전부 헤엄치거나 걷는 해양동물이다.
var house_index := int(entry.house)
var cap: int = maxi(Catalog.capacity_of(String(GameState.houses[house_index].id)), 1)
# 집마다 도는 방향을 바꿔 여러 채가 한 화면에 있어도 단조롭지 않게 한다.
var dir := 1.0 if house_index % 2 == 0 else -1.0
node.set_orbit(_orbit_center(home, cell), _orbit_radius(home, cell),
TAU * float(slot) / float(cap), ORBIT_SPEED * dir)
# 집은 몇 마리를 들일 수 있는지 세는 단위일 뿐, 헤엄치는 자리는 층 전체다.
# 제 집 앞에서 시작해 거기서부터 어디로든 돌아다닌다.
node.set_roam(_roam_bounds(home, cell), _rng)
## 어느 생물이 어느 집에 사는지 그릴 때마다 정한다. 집은 정원만 주므로 배정을
@@ -530,6 +523,11 @@ func _orbit_center(home: Rect2, cell: Vector2) -> Vector2:
g.position.y + cell.y * 0.9 + r.y, g.end.y - r.y))
## 그 집이 속한 층에서 헤엄칠 수 있는 범위. 층 전체를 쓰되 가장자리는 조금 남긴다.
func _roam_bounds(home: Rect2, cell: Vector2) -> Rect2:
return _home_bounds(home, cell).grow(-cell.x * 0.3)
## 그 집이 속한 층의 테두리. 생물을 여기 안에 가둔다.
## 예전에는 화면(grid_rect)에 맞춰 잘랐는데, 층이 옆으로 늘어선 지금 그렇게 하면
## 뒤쪽 층의 생물이 전부 첫 층 오른쪽 끝으로 끌려와 제 층에서 사라진다.
@@ -755,7 +753,7 @@ func _begin_drag() -> void:
_drag_node = _node_for(_drag_ref)
# 끄는 동안에는 궤도를 멈춘다. 안 그러면 손을 따라오지 않고 제 길을 간다.
if _drag_node:
_drag_node.orbit_enabled = false
_drag_node.roam_enabled = false
_press_was_drag = true
drag_changed.emit(true)