HelloSun commited on
Commit
b502f83
·
verified ·
1 Parent(s): aa16154

Fix hero spinning while walking/attacking: face only when moving, keep attack facing, stop walking into target

Browse files
Files changed (1) hide show
  1. index.html +20 -7
index.html CHANGED
@@ -851,7 +851,10 @@ button.big.ghost { background:rgba(20,16,10,.8); color:var(--gold); }
851
 
852
  // movement: joystick / keyboard overrides path
853
  const sp = HERO_SPEED * (t < H.slowUntil ? 0.6 : 1) * (t < H.stunUntil ? 0 : 1);
854
- let manual = false;
 
 
 
855
  if (S.joy.on || S.keyDir) {
856
  const [vx, vy] = S.joy.on ? [S.joy.vx, S.joy.vy] : S.keyDir;
857
  const len = Math.hypot(vx, vy);
@@ -860,9 +863,16 @@ button.big.ghost { background:rgba(20,16,10,.8); color:var(--gold); }
860
  const wx = (vx / HW + vy / HH) / 2, wy = (vy / HH - vx / HW) / 2;
861
  const wl = Math.hypot(wx, wy) || 1;
862
  const k = sp * dt * Math.min(1, len);
863
- moveEnt(M, H, wx / wl * k, wy / wl * k, H.r);
864
- H.dir = dirOf(wx, wy);
865
- setAnim(H, 'run');
 
 
 
 
 
 
 
866
  manual = true;
867
  H.path = []; H.chase = false; H.pending = null;
868
  }
@@ -880,9 +890,10 @@ button.big.ghost { background:rgba(20,16,10,.8); color:var(--gold); }
880
  }
881
  if (H.path.length) {
882
  if (followPath(M, H, H.path, sp, dt)) {
 
883
  const nx = H.path.length ? H.path[0] : null;
884
- if (nx) H.dir = dirOf(nx[0] - H.x, nx[1] - H.y);
885
- setAnim(H, 'run');
886
  }
887
  } else if (t >= H.lockUntil) setAnim(H, 'stance');
888
  }
@@ -898,6 +909,8 @@ button.big.ghost { background:rgba(20,16,10,.8); color:var(--gold); }
898
  if (H.target && !H.target.dead) {
899
  const inRange = dist(H.x, H.y, H.target.x, H.target.y) <= S.world.classes[H.cls].range + 0.25;
900
  if (inRange) {
 
 
901
  if (S.auto) autoFight();
902
  else if (S.atkOn && H.atkCd <= 0) doBasic();
903
  }
@@ -1467,7 +1480,7 @@ button.big.ghost { background:rgba(20,16,10,.8); color:var(--gold); }
1467
  get state() {
1468
  const H = S.H;
1469
  return H && S.M ? {
1470
- map: S.M.id, hero: { x: H.x, y: H.y, hp: H.hp, mp: H.mp, lvl: H.lvl, xp: H.xp, dead: H.dead, potions: H.potions, target: H.target ? H.target.def.name : null, tx: H.target ? H.target.x : null, ty: H.target ? H.target.y : null, path: H.path.length, chase: H.chase, atkCd: H.atkCd },
1471
  enemies: S.enemies.filter((e) => !e.dead).length, kills: S.kills, auto: S.auto, lock: S.lock,
1472
  } : null;
1473
  },
 
851
 
852
  // movement: joystick / keyboard overrides path
853
  const sp = HERO_SPEED * (t < H.slowUntil ? 0.6 : 1) * (t < H.stunUntil ? 0 : 1);
854
+ let manual = false, walking = false;
855
+ // while an attack animation is playing, keep the attack facing and do not replace the swing with run/stance
856
+ const attacking = t < H.lockUntil;
857
+ const inReach = H.target && !H.target.dead && dist(H.x, H.y, H.target.x, H.target.y) <= S.world.classes[H.cls].range + 0.25;
858
  if (S.joy.on || S.keyDir) {
859
  const [vx, vy] = S.joy.on ? [S.joy.vx, S.joy.vy] : S.keyDir;
860
  const len = Math.hypot(vx, vy);
 
863
  const wx = (vx / HW + vy / HH) / 2, wy = (vy / HH - vx / HW) / 2;
864
  const wl = Math.hypot(wx, wy) || 1;
865
  const k = sp * dt * Math.min(1, len);
866
+ let mx = wx / wl * k, my = wy / wl * k;
867
+ // already in reach of the locked target: do not walk into it (that made the hero overshoot back and forth)
868
+ if (inReach && mx * (H.target.x - H.x) + my * (H.target.y - H.y) > 0) { mx = 0; my = 0; }
869
+ const x0 = H.x, y0 = H.y;
870
+ moveEnt(M, H, mx, my, H.r);
871
+ // face the walking direction only when we actually moved (pushing against a blocker must not spin the sprite)
872
+ const moved = Math.hypot(H.x - x0, H.y - y0);
873
+ walking = moved > k * 0.3;
874
+ if (!attacking && walking) H.dir = dirOf(wx, wy);
875
+ if (!attacking) setAnim(H, walking ? 'run' : 'stance');
876
  manual = true;
877
  H.path = []; H.chase = false; H.pending = null;
878
  }
 
890
  }
891
  if (H.path.length) {
892
  if (followPath(M, H, H.path, sp, dt)) {
893
+ walking = true;
894
  const nx = H.path.length ? H.path[0] : null;
895
+ if (nx && !attacking) H.dir = dirOf(nx[0] - H.x, nx[1] - H.y);
896
+ if (!attacking) setAnim(H, 'run');
897
  }
898
  } else if (t >= H.lockUntil) setAnim(H, 'stance');
899
  }
 
909
  if (H.target && !H.target.dead) {
910
  const inRange = dist(H.x, H.y, H.target.x, H.target.y) <= S.world.classes[H.cls].range + 0.25;
911
  if (inRange) {
912
+ // standing and fighting: keep facing the target (no turning back and forth while attacking)
913
+ if (!walking && !attacking) faceHero(H.target.x - H.x, H.target.y - H.y);
914
  if (S.auto) autoFight();
915
  else if (S.atkOn && H.atkCd <= 0) doBasic();
916
  }
 
1480
  get state() {
1481
  const H = S.H;
1482
  return H && S.M ? {
1483
+ map: S.M.id, hero: { x: H.x, y: H.y, hp: H.hp, mp: H.mp, lvl: H.lvl, xp: H.xp, dead: H.dead, potions: H.potions, target: H.target ? H.target.def.name : null, tx: H.target ? H.target.x : null, ty: H.target ? H.target.y : null, chase: H.chase, atkCd: H.atkCd, dir: H.dir, anim: H.anim.n, path: H.path.length },
1484
  enemies: S.enemies.filter((e) => !e.dead).length, kills: S.kills, auto: S.auto, lock: S.lock,
1485
  } : null;
1486
  },