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

相关推荐
一隅论数智2 天前
给AI一张“业务概念地图“:本体如何从哲学走向企业智能
大数据·人工智能·经验分享·笔记·学习·学习方法·政务
XiHongShi20162 天前
STM32F407 RTC定时器例程,建议保存
stm32·单片机·学习
爱吃苹果的日记本2 天前
离散数学第六课
学习·离散数学
AI职业加油站2 天前
AI智能体应用工程师证书:政策红利下的职业新风口
大数据·运维·人工智能·学习·职场发展
旖旎夜光2 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
奇思妙想聪明勤奋的小羊2 天前
DeepAgents第5章:子Agent 与上下文隔离—让 Agent学会委派
人工智能·python·学习·语言模型
霍霍的袁2 天前
【C++】map 和 set 的使用 | 从用法到底层
开发语言·c++·学习·visual studio
彧azz2 天前
Linux 环境下 Redis 学习总结:数据类型、持久化、锁、事务、主从与缓存问题
linux·redis·笔记·学习·面试
我爱cope2 天前
【操作系统 | 计算机硬件:CPU、内存与 I/O 如何支撑操作系统?】
学习·操作系统