扫描二维码关注官方公众号
返回列表
+ 发新帖
查看: 107|回复: 0

[转载发布] 【自制UI插件】实现显示圆圈形状的倒计时进度条

[复制链接]
累计送礼:
0 个
累计收礼:
0 个
  • TA的每日心情
    开心
    7 天前
  • 签到天数: 174 天

    连续签到: 1 天

    [LV.7]常住居民III

    2563

    主题

    691

    回帖

    1万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    VIP
    6
    卡币
    16443
    OK点
    16
    推广点
    0
    同能卷
    0
    积分
    19725

    灌水之王

    发表于 昨天 01:51 | 显示全部楼层 |阅读模式
    一开始对mv底层框架不太熟悉,就先后尝试使用html5 canvas和webgl绘制图像,结果总是一点反应也没有orz
    后面经历了多次搜集资料和对框架核心源码的解读(这个过程真的很痛苦啊啊啊)就明白了其中的原理:mv里的许多东西都是对PIXI库里的东西的一层层封装,我们的游戏实质上就是一个巨大的PIXI容器(Container对象),里面的许多UI元素(如Sprite、Scene、Window等)都需要被add到里面去。
    但是绘制这种圆弧形状用canvas2dContext的方法会更方便,因为用picture实在是不现实。然后我就发现,Bitmap里就封装了context对象,于是乎我就捣鼓出了下面的代码:
    JAVASCRIPT 代码
    1. Bitmap.prototype.drawArc = function(x, y, radius, startAngle, endAngle, lineWidth, color){
    2.         var context = this._context;
    3.         context.clearRect(0, 0, Graphics.boxWidth, Graphics.boxHeight);
    4.         context.beginPath();
    5.         context.arc(x, y, radius, startAngle, endAngle, true);
    6.         context.strokeStyle = color;
    7.         context.lineWidth = lineWidth;
    8.         context.stroke();
    9.         context.save();
    10.         this._setDirty();
    11. };
    复制代码

    自己为Bitmap定义一个新的绘制圆弧的方法,毕竟直接在外部对Bitmap操作很可能行不通(因为_context是Bitmap的私有成员,不向外提供)。
    紧接着在反复测试中我还学习到,Bitmap不能直接显示在游戏画面上,还需要封装在Sprite对象中,并被add到PIXI容器里面,放在当前场景上,由SceneManager.update去负责倒计时动画的更新。
    完整源码我贴在下面了,还有一些示例截图,欢迎交流,有需改进之处麻烦大佬指出了,非常感谢!!!!新人rm开发者感谢支持!!!

    JAVASCRIPT 代码下载

    [code]//=============================================================================
    // L_CircleGaugeUI.js
    //=============================================================================

    /*:
    * @target MV
    * @plugindesc 自制UI:圆圈形的倒计时进度条
    * @author レナ
    * @help L_CircleGaugeUI.js
    *
    * 插件命令([]括号为可选项):
    * · L_CircleGaugeUI start 倒计时 圆圈半径 [中心X] [中心Y]
    *  开启倒计时。
    * · L_CircleGaugeUI stop
    *  停止倒计时。
    *
    * ◆注意:为保证插件正常使用,请先指定一张空png图片!
    *
    * 使用条款:完全免费使用,可随意更改,允许二次发布,无任何版权限制。
    *
    * ◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆
    *
    * @param duration
    * @text 持续时间
    * @type number
    * @min 1
    * @max 300
    * @default 10
    * @desc 默认倒计时,单位为秒。
    *
    * @param radius
    * @text 圆圈半径
    * @type number
    * @min 50
    * @max 300
    * @default 200
    * @desc 默认圆圈半径,单位为像素。
    *
    * @param centerX
    * @text 圆圈中心X
    * @type number
    * @min 0
    * @max 816
    * @desc 默认圆圈中心(X坐标),单位为像素。
    *
    * @param centerXVariableId
    * @parent centerX
    * @text 变量id
    * @type number
    * @desc 绑定到的变量id。
    *
    * @param centerY
    * @text 圆圈中心Y
    * @type number
    * @min 0
    * @max 624
    * @desc 默认圆圈中心(Y坐标),单位为像素。
    *
    * @param centerYVariableId
    * @parent centerY
    * @text 变量id
    * @type number
    * @desc 绑定到的变量id。
    *
    * @param picName
    * @text 图片
    * @type file
    * @dir img/pictures/
    * @default 0
    */

    (function(){
        Bitmap.prototype.drawArc = function(x, y, radius, startAngle, endAngle, lineWidth, color){
            var context = this._context;
            context.clearRect(0, 0, Graphics.boxWidth, Graphics.boxHeight);

            context.beginPath();
            context.arc(x, y, radius, startAngle, endAngle, true);

            context.strokeStyle = color;
            context.lineWidth = lineWidth;
            context.stroke();

            context.save();
            this._setDirty();
        };

        var pluginName = 'L_CircleGaugeUI';
        var params = PluginManager.parameters(pluginName);

        var duration = Number(params['duration']) || 10;
        var radius = Number(params['radius']) || 50;
        var centerXVariableId = Number(params['centerXVariableId']) || 0;
        var centerYVariableId = Number(params['centerYVariableId']) || 0;
        var centerX = Number(params['centerX']) || Graphics.boxWidth / 2;
        var centerY = Number(params['centerY']) || Graphics.boxHeight / 2;
        var picName = params['picName'] || '0';

        var strokeWidth = 15;   // 圆环宽度(粗细)

        var isCounting = false;

        var bgColor = '#999999';
        var gaugeColor = '#ffffff';

        var bgCircle = null;
        var gaugeCircle = null;
        var gaugeContainer = null;

        function draw(percent){
            if(percent >= 0){
                // 计算对应角度(100%=360°, 0%=0°)
                var startAngle = -Math.PI / 2;
                var endAngle = percent * 2 * Math.PI - Math.PI / 2;
                gaugeCircle.drawArc(centerX, centerY, radius, startAngle, endAngle, strokeWidth, gaugeColor);
            }
        }

        // 倒计时启动方法
        Game_Temp.prototype.startCountdown = function(time, radius, startCallback, endCallback, okCallback){
            if(startCallback) startCallback();
            // 若已有倒计时,先停止
            if(isCounting)this.stopCountdown();

            isCounting = true;
            var totalMillis = time * 1000;
            var elapsedMillis = 0;
            var startTime = Date.now();

            if(!gaugeContainer){
                gaugeContainer = new PIXI.Container();
                SceneManager._scene.addChild(gaugeContainer);
            }

            bgCircle = ImageManager.loadPicture(picName);
            gaugeCircle = ImageManager.loadPicture(picName);

            // 绘制底层灰色时间条
            bgCircle.drawArc(centerX, centerY, radius, 0, 2 * Math.PI, strokeWidth, bgColor);
            var bgCircleSprite = new Sprite(bgCircle);
            gaugeContainer.addChild(bgCircleSprite);

            // 绘制白色时间条
            var gaugeCircleSprite = new Sprite(gaugeCircle);
            gaugeContainer.addChild(gaugeCircleSprite);

            // 动画更新逻辑
            function update(){
                if(!isCounting)return;

                elapsedMillis = Date.now() - startTime;
                var progress = Math.max(0, 1 - (elapsedMillis / totalMillis));

                draw(progress);
                gaugeContainer.addChild(gaugeCircleSprite);

                // 倒计时结束
                if(progress

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?立即注册

    x
    天天去同能,天天有童年!
    回复 送礼论坛版权

    使用道具 举报

    文明发言,和谐互动
    文明发言,和谐互动
    高级模式
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    关闭

    幸运抽奖

    社区每日抽奖来袭,快来试试你是欧皇还是非酋~

    立即查看

    聊天机器人
    Loading...

    QQ|Archiver|手机版|小黑屋|同能RPG制作大师 ( 沪ICP备12027754号-3 )

    GMT+8, 2026-2-21 00:12 , Processed in 0.144300 second(s), 52 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.

    快速回复 返回顶部 返回列表