基于Matlab生成黑色火柴人运球 + 起跳 + 投篮动作

说明:

  1. 运球阶段加入更平滑的身体上下起伏与摆臂摆腿

  2. 起跳阶段使用缓动函数,使动作更自然

  3. 投篮阶段加入出手、随挥动作以及篮球抛物线轨迹

  4. 支持导出 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

相关推荐
云空15 小时前
《电子专业完整学习路线图(分两套:本科四年版 / 零基础自学速成版)》
科技·学习·学习方法·高考
min(a,b)15 小时前
学习第16天:LangGraph 与 Agent 工作流编排
学习
woshihuanglaoshi15 小时前
鸿蒙技术进阶全景高级成长体系:从初中级到架构师的技能树/学习路径/项目实战/认证体系系统性方法论
学习·华为·harmonyos
AI即插即用15 小时前
即插即用系列 | IEEE TMI PLG-HN:原型学习引导的 CNN-Transformer 混合网络,攻克乳腺肿瘤分割难题
人工智能·深度学习·神经网络·学习·目标检测·cnn·transformer
for_ever_love__16 小时前
python基础语法学习: 变量, 输入输出, 运算符
网络·python·学习
学习和思考17 小时前
非自动化专业如何自学PLC?我的6个月学习路线图
笔记·学习·自动化·学习方法
拾陆楼17 小时前
PT: DMSA辅助调tree报告前后级余量脚本
后端·学习
机器学习之心19 小时前
基于CEEMDAN-TCN-BiGRU的空气质量指数(AQI)预测研究,五模型对比,实验报告+MATLAB代码
matlab·tcn-bigru·ceemdan·空气质量指数
sbjdhjd19 小时前
大三网安秋招核心学习前言(AI 安全 + Web 漏洞 + 内网渗透全考点)
人工智能·网络协议·学习·安全·网络安全·开源·php
LccKyI20 小时前
C#学习day06(方法/函数及其关键字,附思维导图)
经验分享·学习·c#