基于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

相关推荐
AI原来如此2 小时前
[特殊字符]2026AI Agent入门学习路径
学习·ai·大模型·ai编程
南汁bbj2 小时前
人工智能发展演进与2026年后学习重点:从“调API“到“造Agent“
人工智能·学习
70asunflower2 小时前
计算机中的绝对路径和相对路径
python·学习
wuxinyan1232 小时前
工业级大模型学习之路016:RAG零基础入门教程(第十二篇):实用进阶功能开发
人工智能·python·学习·rag
xuhaoyu_cpp_java2 小时前
Git学习(一)
经验分享·笔记·git·学习
三品吉他手会点灯3 小时前
C语言学习笔记 - 36.数据类型 - 为什么需要输出控制符
c语言·开发语言·笔记·学习
吃好睡好便好3 小时前
在Matlab中绘制非默认峰值图
开发语言·学习·算法·matlab
阳光九叶草LXGZXJ3 小时前
自制数据库迁移工具-C版-07-HappySunshineV1.6-(支持PG、达梦、Gbase8a)
linux·c语言·开发语言·数据库·学习·postgresql
Bechamz3 小时前
大数据开发学习Day34
java·大数据·学习