js实现2d火柴人打斗动画代码

代码语言:html

所属分类:其他

代码由glm-5.3-flash ai生成,可能有错误,仅供参考:点击查看提示词

代码描述:火柴人打斗动画

代码标签: js 2d 火柴人 打斗 动画 代码

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>火柴人格斗 · Stick Fight</title>
<style>
  html,body{margin:0;padding:0;height:100%;background:#05070e;overflow:hidden;
    font-family:system-ui,-apple-system,"PingFang SC","Microsoft YaHei",sans-serif}
  #cv{display:block;width:100vw;height:100vh;cursor:pointer}
  #hint{position:fixed;left:14px;bottom:12px;color:rgba(200,210,235,.5);font-size:12px;line-height:1.7;
    text-shadow:0 1px 3px rgba(0,0,0,.8);user-select:none;pointer-events:none}
  #ui{position:fixed;right:14px;bottom:12px;display:flex;gap:8px}
  #ui button{padding:7px 13px;font-size:12px;color:#c8d2ea;background:rgba(14,20,38,.62);
    border:1px solid rgba(160,180,255,.22);border-radius:6px;cursor:pointer;letter-spacing:1px;transition:all .15s}
  #ui button:hover{background:rgba(50,70,130,.55);color:#fff}
  #ui button.on{border-color:#ff9a4d;color:#ffb677;background:rgba(70,45,20,.5)}
</style>
</head>
<body>
<canvas id="cv"></canvas>
<div id="hint">键盘可随时接管左侧角色:A/D 移动 · J 出拳 · K 踢腿 · L 格挡 · Space 跳跃<br>点击画面任意位置:慢动作特写</div>
<div id="ui">
  <button id="bPause">暂停</button>
  <button id="bReplay">重播</button>
  <button id="bSlow">慢动作</button>
  <button id="bFx" class="on">特效:开</button>
</div>

<script>'use strict';
/* =====================================================================
   火柴人格斗 · 单文件 Canvas 2D 动画(无任何外部依赖)
   分区:配置常量 / 工具与缓动 / 骨骼模型 / 动作库(关键帧) / 特效系统 /
        物理 / 战斗判定 / 状态机与AI / 相机 / 渲染 / 主循环 / 输入与UI
   ===================================================================== */

// ===== 配置常量 =====
const CFG = {
  G: 0.55,            // 重力加速度(像素/帧^2)
  JUMP_VY: 9.6,       // 起跳初速度
  WALK_SPD: 2.1,      // 移动速度
  FRIC_GROUND: .86,   // 地面摩擦(速度衰减系数)
  FRIC_AIR: .985,     // 空中阻力
  HP_MAX: 100,        // 最大血量
  STAGE: 520,         // 舞台半宽(世界坐标边界)
  SEP_DIST: 34,       // 双方最小间距
  AUTO_SLOW_HP: 25,   // 血量低于此值自动进入慢动作
  KO_TIME: 115,       // K.O. 后定格时长(帧)
  FADE_TIME: 26,      // 回合切换淡入淡出时长(帧)
  SHAKE_DECAY: .88,   // 屏幕震动每帧衰减
  SHAKE_MAX: 22,      // 震动上限
  ROLL_SPD: 7,        // 翻滚初速度
  TRAIL_LEN: 12,      // 残影记录帧数
};
const BONE = { torso:26, head:10.5, neck:6, uarm:17, farm:16, thigh:22, shin:21 }; // 骨骼长度
const FONT = '"PingFang SC","Microsoft YaHei","Noto Sans SC",system-ui,sans-serif';

// ===== 工具与缓动 =====
const clamp = (v,a,b)=> v<a?a:(v>b?b:v);
const rnd   = (a,b)=> a+Math.random()*(b-a);
const dist2 = (p,q)=>{ const dx=p[0]-q[0], dy=p[1]-q[1]; return Math.sqrt(dx*dx+dy*dy); };
const EASE = {
  l : t=>t,
  i : t=>t*t*t,
  o : t=>1-Math.pow(1-t,3),
  o4: t=>1-Math.pow(1-t,4),
  io: t=> t<.5 ? 4*t*t*t : 1-Math.pow(-2*t+2,3)/2,          // easeInOutCubic
  ob: t=>{ const c=1.70158, u=t-1; return 1+(c+1)*u*u*u+c*u*u; }, // easeOutBack(回弹)
};

// ===== 骨骼模型 =====
// 姿势:py=骨盆离地高度;lean=躯干前倾;head=头部附加角;
// fu/fl=前臂肩角/肘角;bu/bl=后臂;ft/fs=前腿髋角/膝角;bt/bs=后腿
const BASE_POSE = { py:42, lean:.08, head:.06, fu:.42, fl:1.45, bu:-.35, bl:1.15, ft:.22, fs:-.52, bt:-.18, bs:-.45 };
// 由姿势计算全身关节点(世界坐标:x 向右,y 向下,地面 y=0)
function computeJoints(f, p){
  const fx=f.facing, S=Math.sin, C=Math.cos;
  const px=f.x, py=-(f.y+p.py);
  const J={};
  J.pelvis=[px,py];
  const tA=p.lean;
  J.neck=[px+S(tA)*BONE.torso*fx, py-C(tA)*BONE.torso];
  const hA=tA+p.head;
  J.head=[J.neck[0]+S(hA)*BONE.neck*fx, J.neck[1]-C(hA)*BONE.neck];
  J.sh =[J.neck[0]-S(tA)*3*fx, J.neck[1]+C(tA)*3];   // 肩(颈下移3px)
  J.hipF=[px+3*fx, py]; J.hipB=[px-3*fx, py];        // 双腿髋部前后错开
  const seg=(o,a,l)=>[o[0]+S(a)*l*fx, o[1]+C(a)*l];
  J.elbF=seg(J.sh ,p.fu     ,BONE.uarm ); J.hndF=seg(J.elbF,p.fu+p.fl,BONE.farm);
  J.elbB=seg(J.sh ,p.bu     ,BONE.uarm ); J.hndB=seg(J.elbB,p.bu+p.bl,BONE.farm);
  J.kneeF=seg(J.hipF,p.ft   ,BONE.thigh); J.ftF =seg(J.kneeF,p.ft+p.fs,BONE.shin);
  J.kneeB=seg(J.hipB,p.bt   ,BONE.thigh); J.ftB =seg(J.kneeB,p.bt+p.bs,BONE.shin);
  return J;
}
// 绕某点旋转全部关节(翻滚用)
function rotAll(J, cx, cy, a){
  const c=Math.cos(a), s=Math.sin(a);
  for(const k in J){ const dx=J[k][0]-cx, dy=J[k][1]-cy;
    J[k][0]=cx+dx*c-dy*s; J[k][1]=cy+dx*s+dy*c; }
}
function cloneJ(J){ const o={}; for(const k in J) o[k]=[J[k][0],J[k][1]]; return o; }

// ===== 动作库(关键帧 + 缓动插值)=====
const ACT={};
function def(name, dur, keys, opt){ ACT[name.........完整代码请登录后点击上方下载按钮下载查看

网友评论0