说明:
-
运球阶段加入更平滑的身体上下起伏与摆臂摆腿
-
起跳阶段使用缓动函数,使动作更自然
-
投篮阶段加入出手、随挥动作以及篮球抛物线轨迹
-
支持导出 GIF:将 exportGIF 改为 true
本程序在matlab2026a运行可跑通,版本较低,可能会运行报错。
可尝试安装高版本软件《MATLAB2026a版本新特点》
下面为主要程序。
Matlab
clear; clc; close all;
exportGIF = false; % true:导出 GIF
gifName = 'black_stickman_basketball_fast_drop.gif';
fps = 50; % 帧率提高,视觉更流畅
n1 = 95; % 运球阶段:更短,动作更快
n2 = 38; % 起跳合球阶段
n3 = 55; % 投篮飞行阶段
n4 = 70; % 篮球掉落阶段
nFrame = n1 + n2 + n3 + n4;
fig = figure('Color','w','Position',[100 100 1200 680]);
ax = axes(fig);
for k = 1:nFrame
cla(ax);
hold(ax,'on');
axis(ax,'equal');
axis(ax,[0 13 0 7.5]);
ax.XTick = [];
ax.YTick = [];
ax.Box = 'off';
drawCourt(ax);
if k <= n1
%% 阶段1:快速大幅度运球前进
p = (k-1)/(n1-1);
pe = easeInOutSine(p);
x = 1.05 + 5.10*pe;
% 更快、更明显的跑动节奏
cyc = 2*pi*5.8*p;
bob = 0.12*sin(cyc);
ballX = x + 0.78;
ballY = 0.55 + 1.42*abs(sin(cyc));
pose.phase = cyc;
pose.jump = bob;
pose.mode = 'dribble';
pose.ballPos = [ballX, ballY];
pose.bodyLean = 0.16;
pose.armRaise = 0;
pose.followThru = 0;
drawStickmanDynamic(ax, x, 0.38, 1.0, pose);
drawBall(ax, ballX, ballY, 0.22);
elseif k <= n1+n2
%% 阶段2:快速合球 + 大幅屈膝 + 起跳
p = (k-n1)/n2;
pe = easeInOutCubic(p);
x = 6.15 + 0.90*pe;
% 先快速下蹲,再快速起跳
if p < 0.35
q = p/0.35;
jump = -0.28*sin(pi*q/2);
else
q = (p-0.35)/(1-0.35);
jump = -0.28 + 1.20*sin(pi*q/2);
end
ballX = x + 0.50 + 0.18*pe;
ballY = 1.45 + 2.85*pe + jump;
pose.phase = 0;
pose.jump = jump;
pose.mode = 'gather';
pose.ballPos = [ballX, ballY];
pose.bodyLean = 0.12;
pose.armRaise = pe;
pose.followThru = 0;
drawStickmanDynamic(ax, x, 0.38, 1.0, pose);
drawBall(ax, ballX, ballY, 0.22);
elseif k <= n1+n2+n3
%% 阶段3:快速出手 + 篮球飞向篮筐
p = (k-(n1+n2))/n3;
pe = easeOutCubic(min(p,1));
x = 7.05;
% 人物起跳后逐渐下落
jump = 0.82*(1-min(p*1.25,1)).^1.6;
startP = [7.66, 4.38];
ctrlP = [8.85, 6.82];
endP = [10.35, 4.60];
ballPos = (1-pe)^2*startP + 2*(1-pe)*pe*ctrlP + pe^2*endP;
pose.phase = 0;
pose.jump = jump;
pose.mode = 'release';
pose.ballPos = ballPos;
pose.bodyLean = 0.06;
pose.armRaise = 1;
pose.followThru = pe;
drawStickmanDynamic(ax, x, 0.38, 1.0, pose);
drawBall(ax, ballPos(1), ballPos(2), 0.22);
if pe > 0.82
drawNetShake(ax, pe);
end
else
%% 阶段4:投中后篮球掉落 + 地面反弹
p = (k-(n1+n2+n3))/n4;
p = min(max(p,0),1);
x = 7.05;
jump = 0;
% 篮球从篮筐下方掉落,带一点横向漂移
ballX = 10.35 + 0.18*sin(2*pi*p);
% 分段下落 + 反弹
if p < 0.62
q = p/0.62;
ballY = 4.45 - 3.78*(q^2); % 加速下落
else
q = (p-0.62)/(1-0.62);
ballY = 0.67 + 0.95*sin(pi*q).*exp(-1.55*q); % 落地后小幅反弹
end
pose.phase = 0;
pose.jump = jump;
pose.mode = 'celebrate';
pose.ballPos = [ballX, ballY];
pose.bodyLean = 0;
pose.armRaise = 1;
pose.followThru = p;
drawStickmanDynamic(ax, x, 0.38, 1.0, pose);
drawBall(ax, ballX, ballY, 0.22);
drawNetShake(ax, 1);
% 地面撞击提示
if p > 0.60 && p < 0.72
plot(ax,[9.92 10.18],[0.48 0.48],'k-','LineWidth',1.4);
plot(ax,[10.52 10.78],[0.48 0.48],'k-','LineWidth',1.4);
end
end
title(ax,'MATLAB 黑色火柴人打篮球动画:快速动作 + 篮球掉落', ...
'FontSize',18,'FontWeight','bold');
drawnow;
if exportGIF
frame = getframe(fig);
img = frame2im(frame);
[A,map] = rgb2ind(img,256);
if k == 1
imwrite(A,map,gifName,'gif','LoopCount',inf,'DelayTime',1/fps);
else
imwrite(A,map,gifName,'gif','WriteMode','append','DelayTime',1/fps);
end
end
end



完整程序:
分享的文件:基于Matlab生成黑色火柴人运球 + 起跳 + 投篮动作.rar
链接: https://pan.baidu.com/s/1OG7qUyu8-gV8p_WRl95T7Q?pwd=ew6d