polats Claude Opus 4.8 (1M context) commited on
Commit
366b4b1
·
1 Parent(s): 93d86ab

Smooth the joystick camera-follow (exponential ease via panTo)

Browse files

The follow was a hard snap (flyTo ms=0 each frame; re-issuing the easeInOutQuad
tween would have lagged heavily instead). Added chunkedMap.panTo(wx,wy) — a
direct, clamped camera set with no tween — and the Game now lerps the camera
toward the hero each frame with a ~0.12s time constant (frame-rate independent).
Verified: the camera glides behind the hero with a small, stable trailing lag
(~5px) and eases on start/stop instead of snapping.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Files changed (2) hide show
  1. web/comboBattler.js +14 -3
  2. web/mapSandbox.js +12 -1
web/comboBattler.js CHANGED
@@ -273,6 +273,17 @@ function createChunkedMap(pixi, host, config) {
273
  flyAnim = { fromX: camera.x, fromY: camera.y, fromZ: zoom, toX: wx, toY: wy, toZ, t: 0, dur: Math.max(1, ms), resolve };
274
  });
275
  }
 
 
 
 
 
 
 
 
 
 
 
276
  function bindInput() {
277
  const canvas = app.canvas;
278
  const local = (cx, cy) => {
@@ -523,7 +534,7 @@ function createChunkedMap(pixi, host, config) {
523
  ctx = null;
524
  texCache.clear();
525
  }
526
- return { ready, regenerate, destroy, onChange, getSnapshot, getCamera, tileIndexAt, biomeAt: biomeAt2, getBounds, zoomBy, flyTo, setEnabled, onTick, getEntityLayer, getApp, screenToWorld, worldToScreen, tile: TILE9 };
527
  }
528
 
529
  // ../auto-battler/src/render/tileAutotile.js
@@ -6194,8 +6205,8 @@ function mountComboBattler(pixi, host, opts = {}) {
6194
  dead = true;
6195
  }
6196
  if (joy.active && p && p.alive) {
6197
- const w = fieldToWorld(p.x, p.y);
6198
- map.flyTo(w.x, w.y, map.getCamera().zoom, 0);
6199
  }
6200
  spawnFn && spawnFn(dt);
6201
  R.syncActors(battle, dtMS, battle.t);
 
273
  flyAnim = { fromX: camera.x, fromY: camera.y, fromZ: zoom, toX: wx, toY: wy, toZ, t: 0, dur: Math.max(1, ms), resolve };
274
  });
275
  }
276
+ function panTo(wx, wy) {
277
+ if (flyAnim) {
278
+ const r = flyAnim.resolve;
279
+ flyAnim = null;
280
+ r && r();
281
+ }
282
+ camera.x = wx;
283
+ camera.y = wy;
284
+ clampCamera();
285
+ cameraDirty = true;
286
+ }
287
  function bindInput() {
288
  const canvas = app.canvas;
289
  const local = (cx, cy) => {
 
534
  ctx = null;
535
  texCache.clear();
536
  }
537
+ return { ready, regenerate, destroy, onChange, getSnapshot, getCamera, tileIndexAt, biomeAt: biomeAt2, getBounds, zoomBy, flyTo, panTo, setEnabled, onTick, getEntityLayer, getApp, screenToWorld, worldToScreen, tile: TILE9 };
538
  }
539
 
540
  // ../auto-battler/src/render/tileAutotile.js
 
6205
  dead = true;
6206
  }
6207
  if (joy.active && p && p.alive) {
6208
+ const cam = map.getCamera(), w = fieldToWorld(p.x, p.y), k = 1 - Math.exp(-dt / 0.12);
6209
+ map.panTo(cam.x + (w.x - cam.x) * k, cam.y + (w.y - cam.y) * k);
6210
  }
6211
  spawnFn && spawnFn(dt);
6212
  R.syncActors(battle, dtMS, battle.t);
web/mapSandbox.js CHANGED
@@ -273,6 +273,17 @@ function createChunkedMap(pixi, host, config) {
273
  flyAnim = { fromX: camera.x, fromY: camera.y, fromZ: zoom, toX: wx, toY: wy, toZ, t: 0, dur: Math.max(1, ms), resolve };
274
  });
275
  }
 
 
 
 
 
 
 
 
 
 
 
276
  function bindInput() {
277
  const canvas = app.canvas;
278
  const local = (cx, cy) => {
@@ -523,7 +534,7 @@ function createChunkedMap(pixi, host, config) {
523
  ctx = null;
524
  texCache.clear();
525
  }
526
- return { ready, regenerate, destroy, onChange, getSnapshot, getCamera, tileIndexAt, biomeAt: biomeAt2, getBounds, zoomBy, flyTo, setEnabled, onTick, getEntityLayer, getApp, screenToWorld, worldToScreen, tile: TILE11 };
527
  }
528
 
529
  // ../auto-battler/src/engine/rng.js
 
273
  flyAnim = { fromX: camera.x, fromY: camera.y, fromZ: zoom, toX: wx, toY: wy, toZ, t: 0, dur: Math.max(1, ms), resolve };
274
  });
275
  }
276
+ function panTo(wx, wy) {
277
+ if (flyAnim) {
278
+ const r = flyAnim.resolve;
279
+ flyAnim = null;
280
+ r && r();
281
+ }
282
+ camera.x = wx;
283
+ camera.y = wy;
284
+ clampCamera();
285
+ cameraDirty = true;
286
+ }
287
  function bindInput() {
288
  const canvas = app.canvas;
289
  const local = (cx, cy) => {
 
534
  ctx = null;
535
  texCache.clear();
536
  }
537
+ return { ready, regenerate, destroy, onChange, getSnapshot, getCamera, tileIndexAt, biomeAt: biomeAt2, getBounds, zoomBy, flyTo, panTo, setEnabled, onTick, getEntityLayer, getApp, screenToWorld, worldToScreen, tile: TILE11 };
538
  }
539
 
540
  // ../auto-battler/src/engine/rng.js