js实现2d火柴人打斗动画代码
代码语言:html
所属分类:其他
代码由glm-5.3-flash ai生成,可能有错误,仅供参考:点击查看提示词
代码描述:火柴人打斗动画
下面为部分代码预览,完整代码请点击下载或在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