幽灵效果 - RPG Maker MZ

为一些角色提供类似鬼魂的效果
插件名称RS_GhostEffect.js
插件作者biud436
插件版本未知
软件版本MZ
插件汉化未汉化

插件介绍

为一些角色提供类似鬼魂的效果

演示效果

使用注意

这是从 RPG Maker MV 版本移植过来的,因此您可以在开发者工具中显示一些错误:
PixiJS Deprecation Warning:PIXI.RenderTexture.sourceFrame property has been removed Deprecated since V5.0.0

插件代码

//================================================================
// RS_GhostEffect.js
// ---------------------------------------------------------------
// The MIT License
// Copyright (c) 2019 biud436
// ---------------------------------------------------------------
// Free for commercial and non commercial use.
//================================================================
/*:
 * @target MZ
 * @plugindesc This plugin allows you to implement the character effect like as ghost. <RS_GhostEffect>
 * @author biud436
 *
 * @param Uniform
 *
 * @param lifeTime
 * @parent Uniform
 * @type number
 * @desc All of the effects has a lifeTime, After that time, the effect pattern will be changed.
 * @default 100
 * @min 1
 *
 * @param threshold
 * @parent Uniform
 * @type number
 * @desc if threshold is higher, the effect can decrease.
 * @default 0.7
 * @decimals 2
 * @min 0.10
 * @max 1.00
 *
 * @param xoffset
 * @parent Uniform
 * @type number
 * @desc When the value approaches 0.0, it would look like the paper burning.
 * @default 0.07
 * @decimals 2
 *
 * @help
 *
 * Note that this plugin only works in WebGL mode.
 *
 * =======================================================
 * Scripts Call
 * =======================================================
 * In the event command called 'Set Move Route',
 *
 * To activate ghost mode, you call the following script code:
 * this.ghostModeOn();
 *
 * To disable ghost mode, you call the following script code:
 * this.ghostModeOff();
 *
 * =======================================================
 * Plugin Commands
 * =======================================================
 * All of the effects has a lifeTime.
 * After that time, the effect pattern will be changed.
 * The time unit is milliseconds,
 * so setting it to 100 will result in 0.1 second.
 *
 *   GhostEffect lifetime 100
 *
 * If the threshold is close to 1, the effect may be reduced.
 *
 *      GhostEffect threshold 0.7
 *
 * When the value approaches 0.0, it would look like the paper burning.
 *
 * GhostEffect xoffset 0.07
 *
 * =======================================================
 * Version Log
 * =======================================================
 * 2019.01.19 (v1.0.0) - First Release.
 *
 * @command lifetime
 * @desc Set the lifeTime of the ghost effect.
 *
 * @arg value
 * @type number
 * @desc Sets the value of the lifeTime.
 * @default 100
 * @min 1
 *
 * @command threshold
 * @desc Set the threshold of the ghost effect.
 *
 * @arg value
 * @desc Sets the value of the threshold.
 * @type number
 * @default 0.7
 *
 * @command xoffset
 * @desc Set the xoffset of the ghost effect.
 *
 * @arg value
 * @desc Sets the value of the xoffset.
 * @type number
 * @default 0.07
 */

(() => {
    "use strict";

    const pluginParams = $plugins.filter((i) => {
        return i.description.contains("<RS_GhostEffect>");
    });

    const pluginName = pluginParams.length > 0 && pluginParams[0].name;
    const parameters = pluginParams.length > 0 && pluginParams[0].parameters;

    const RS = window.RS || RS;
    RS.GhostEffect = {
        Params: {},
    };

    RS.GhostEffect.Params = RS.GhostEffect.Params || {};

    RS.GhostEffect.Params.lifeTime = parseInt(parameters["lifeTime"] || 100);
    RS.GhostEffect.Params.threshold = parseFloat(
        parameters["threshold"] || 0.7
    );
    RS.GhostEffect.Params.xoffset = parseFloat(parameters["xoffset"] || 0.07);

    //============================================================================
    // PIXI.GhostEffect
    //============================================================================

    PIXI.GhostEffect = function () {
        const vertexSrc = [
            "attribute vec2 aVertexPosition;",
            "attribute vec2 aTextureCoord;",

            "uniform mat3 projectionMatrix;",

            "varying vec2 vTextureCoord;",

            "void main(void){",
            "    gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);",
            "    vTextureCoord = aTextureCoord;",
            "}",
        ].join("\n");

        const fragmentSrc = `
        
        precision mediump float;
        
        uniform vec2 u_scale;
        
        varying vec2 vTextureCoord;
        uniform sampler2D uSampler;
        
        uniform vec2 dimensions;
        uniform float u_xoffset;

        uniform vec4 filterArea;
        uniform vec4 filterClamp;    
                   
        void main(void){
            
            vec4 baseColor = texture2D(uSampler, vTextureCoord);
            
            vec2 vRec = (vTextureCoord * filterArea.xy) / dimensions;
            vRec -= 0.5;
            vRec *= u_scale;
            vRec += 0.5;
            vRec.x += u_xoffset;
            
            vec4 recColor = texture2D(uSampler, vRec);
            
            gl_FragColor = baseColor * recColor;
        }
        `;

        PIXI.Filter.call(this, vertexSrc, fragmentSrc, {
            dimensions: new Float32Array(2),
            u_scale: [0.5, 0.5],
            u_xoffset: 0.07,
        });

        this._effectVal = 0;

        this._time = performance.now();

        this.enabled = true;
        this.resolution = 1;
        this.legacy = true;
    };

    PIXI.GhostEffect.prototype = Object.create(PIXI.Filter.prototype);
    PIXI.GhostEffect.prototype.constructor = PIXI.GhostEffect;

    PIXI.GhostEffect.prototype.apply = function (
        filterManager,
        input,
        output,
        clear
    ) {
        this.uniforms.dimensions[0] = input.sourceFrame.width;
        this.uniforms.dimensions[1] = input.sourceFrame.height;

        filterManager.applyFilter(this, input, output, clear);
    };

    PIXI.GhostEffect.prototype.updateEffect = function () {
        const isInvalidUpdateEffect =
            performance.now() - this._time < RS.GhostEffect.Params.lifeTime;
        if (isInvalidUpdateEffect) return;

        this._effectVal = Math.random();

        if (this._effectVal > RS.GhostEffect.Params.threshold) {
            this._effectVal = RS.GhostEffect.Params.threshold;
        }
        this.uniforms.u_scale[0] = this._effectVal;
        this.uniforms.u_scale[1] = this._effectVal;
        this.uniforms.u_xoffset = RS.GhostEffect.Params.xoffset;

        this._time = performance.now();
    };

    //============================================================================
    // Game_CharacterBase
    //============================================================================

    const alias_Game_CharacterBase_initMembers =
        Game_CharacterBase.prototype.initMembers;
    Game_CharacterBase.prototype.initMembers = function () {
        alias_Game_CharacterBase_initMembers.call(this);
        this._isGhost = false;
    };

    Game_CharacterBase.prototype.isGhost = function () {
        return this._isGhost;
    };

    Game_CharacterBase.prototype.ghostModeOn = function () {
        this._isGhost = true;
    };

    Game_CharacterBase.prototype.ghostModeOff = function () {
        this._isGhost = false;
    };

    Game_Player.prototype.ghostModeOn = function () {
        this._isGhost = true;
        this._followers.forEach((follower) => {
            follower.ghostModeOn();
        });
    };

    Game_Player.prototype.ghostModeOff = function () {
        this._isGhost = false;
        this._followers.forEach((follower) => {
            follower.ghostModeOff();
        });
    };

    //============================================================================
    // Sprite_Character
    //============================================================================

    const alias_Sprite_Character_initialize =
        Sprite_Character.prototype.initialize;
    Sprite_Character.prototype.initialize = function (character) {
        alias_Sprite_Character_initialize.call(this, character);
        this.createGhostEffect();
    };

    const alias_Sprite_Character_update = Sprite_Character.prototype.update;
    Sprite_Character.prototype.update = function () {
        alias_Sprite_Character_update.call(this);
        this.updateGhostEffect();
    };

    Sprite_Character.prototype.createGhostEffect = function () {
        const isValid = this._GhostEffect;

        if (!isValid) {
            this._GhostEffect = new PIXI.GhostEffect();
            if (!this.filters) {
                this.filters = [];
            }
            this.filters = [this._GhostEffect].concat(this.filters);
        } else {
            if (!this.filters) {
                this.filters = [];
            }
            this.filters = this.filters.filter(function (filter) {
                return filter !== isValid;
            }, this);
        }
    };

    Sprite_Character.prototype.updateGhostEffect = function () {
        if (!$gameSystem) return;
        if (!this._GhostEffect) return;
        if (!this._character) return;
        const isValid = this._character.isGhost();
        this._GhostEffect.enabled = isValid;
        if (isValid) {
            this._GhostEffect.updateEffect();
        }
    };

    const alias_Game_Interpreter_pluginCommand =
        Game_Interpreter.prototype.pluginCommand;
    Game_Interpreter.prototype.pluginCommand = function (command, args) {
        alias_Game_Interpreter_pluginCommand.call(this, command, args);
        if (command === "GhostEffect") {
            switch (args[0]) {
                case "lifetime":
                    RS.GhostEffect.Params.lifeTime = Number(args[1] || 100);
                    break;
                case "threshold":
                    RS.GhostEffect.Params.threshold = parseFloat(
                        args[1] || 0.7
                    );
                    break;
                case "xoffset":
                    RS.GhostEffect.Params.xoffset = parseFloat(args[1] || 0.07);
                    break;
            }
        }
    };

    PluginManager.registerCommand(
        pluginName,
        "lifetime",
        /**
         * @param {{value: number}} args
         */
        (args) => {
            RS.GhostEffect.Params.lifeTime = Number(args.value || 100);
        }
    );

    PluginManager.registerCommand(
        pluginName,
        "threshold",
        /**
         * @param {{value: number}} args
         */
        (args) => {
            RS.GhostEffect.Params.threshold = parseFloat(args.value || 0.7);
        }
    );

    PluginManager.registerCommand(
        pluginName,
        "xoffset",
        /**
         * @param {{value: number}} args
         */
        (args) => {
            RS.GhostEffect.Params.xoffset = parseFloat(args.value || 0.07);
        }
    );
})(RS.GhostEffect);
RPGMaker

《暮馆》RPG恐怖解迷

2024-9-28 21:29:40

RPGMaker

标题管理插件 - RPG Maker MZ

2024-12-16 8:32:46

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
搜索