设为首页收藏本站同能贴吧 切换语言 繁体中文
开启辅助访问 切换到窄版
搜索附件  
同能RPG制作大师 › 附件中心 › 同能RM技术讨论区 › RPG Maker MV 讨论区 › 【自制UI插件】实现显示圆圈形状的倒计时进度条: L_CircleGaugeUI.zip

【自制UI插件】实现显示圆圈形状的倒计时进度条: L_CircleGaugeUI.zip

 

【自制UI插件】实现显示圆圈形状的倒计时进度条:
一开始对mv底层框架不太熟悉,就先后尝试使用html5 canvas和webgl绘制图像,结果总是一点反应也没有orz
后面经历了多次搜集资料和对框架核心源码的解读(这个过程真的很痛苦啊啊啊)就明白了其中的原理:mv里的许多东西都是对PIXI库里的东西的一层层封装,我们的游戏实质上就是一个巨大的PIXI容器(Container对象),里面的许多UI元素(如Sprite、Scene、Window等)都需要被add到里面去。
但是绘制这种圆弧形状用canvas2dContext的方法会更方便,因为用picture实在是不现实。然后我就发现,Bitmap里就封装了context对象,于是乎我就捣鼓出了下面的代码:
JAVASCRIPT 代码
自己为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
简体中文
繁體中文
English(英语)
日本語(日语)
Deutsch(德语)
Русский язык(俄语)
بالعربية(阿拉伯语)
Türkçe(土耳其语)
Português(葡萄牙语)
ภาษาไทย(泰国语)
한어(朝鲜语/韩语)
Français(法语)
关闭

幸运抽奖

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

立即查看

Loading...

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

GMT+8, 2026-10-29 22:20 , Processed in 0.090790 second(s), 20 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

返回顶部