You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现点击生成的绿色圆形随时间缓慢消失(仿MOBA游戏)

问题分析

你的代码核心问题是把动画逻辑放在了鼠标点击的单次触发里:当你点击鼠标时,for循环会在同一帧内快速执行完所有半径和透明度的更新,所有绘制操作瞬间完成,视觉上就表现为圆形一闪而过。游戏的动画需要和主渲染循环绑定,逐帧更新状态,才能实现平滑的消失效果。

解决方案

要实现这种点击生成、逐帧消失的效果,需要把每个圆形的状态(位置、大小、透明度)单独存储,然后在主循环的每一帧里更新并绘制这些圆形:

  • 定义圆形状态结构体,保存每个点击生成的圆形的所有必要信息
  • 维护一个列表,存储所有正在播放消失动画的圆形
  • 鼠标点击时只生成新的圆形实例加入列表,不直接执行动画
  • 在主循环里遍历列表,更新每个圆形的大小和透明度,移除已消失的圆形并绘制剩余的
完整示例代码
#include "raylib.h"
#include <vector>

// 定义单个点击圆形的状态
struct ClickCircle {
    float x;
    float y;
    float radius;
    int opacity;
    bool isAlive;
};

// 存储所有正在播放动画的圆形
std::vector<ClickCircle> circles;

void HandleMouseClick() {
    if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
        Vector2 mousePos = GetMousePosition();
        // 创建新的圆形,初始化状态
        ClickCircle newCircle = {
            .x = mousePos.x,
            .y = mousePos.y,
            .radius = 10.0f,
            .opacity = 200,
            .isAlive = true
        };
        circles.push_back(newCircle);
    }
}

void UpdateAndDrawCircles() {
    float delta = GetFrameTime();
    // 遍历更新所有圆形
    for (int i = 0; i < circles.size(); ) {
        ClickCircle& circle = circles[i];
        if (!circle.isAlive) {
            // 移除已消失的圆形
            circles.erase(circles.begin() + i);
            continue;
        }

        // 基于帧率更新半径和透明度(确保不同帧率下动画速度一致)
        circle.radius -= circle.radius / 20 * delta * 60;
        circle.opacity -= circle.opacity / 20 * delta * 60;

        // 判断是否已经消失
        if (circle.opacity <= 0 || circle.radius <= 0) {
            circle.isAlive = false;
            i++;
            continue;
        }

        // 绘制当前状态的圆形
        DrawCircle(circle.x, circle.y, circle.radius, (Color){0, 255, 0, circle.opacity});
        i++;
    }
}

int main() {
    InitWindow(800, 600, "Click Circle Fade");
    SetTargetFPS(60);

    while (!WindowShouldClose()) {
        BeginDrawing();
        ClearBackground(RAYWHITE);

        HandleMouseClick();
        UpdateAndDrawCircles();

        EndDrawing();
    }

    CloseWindow();
    return 0;
}
关键说明
  • 分离逻辑:把点击事件和动画更新完全分开,点击只负责创建实例,动画交给主循环逐帧处理
  • 帧率无关:用GetFrameTime()获取每帧的时间间隔,乘以60把速度统一到60帧的基准,避免不同帧率下动画速度不一致
  • 状态管理:用列表维护所有活跃的圆形,及时移除已消失的实例避免内存占用

内容的提问来源于stack exchange,提问作者ubersmurf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 15:27:30