//============================================================================= // TRP_ParticleMZ_SubEmitter.js //============================================================================= /* このソフトウェアは正規に購入したユーザーのみが利用規約に従って使用することができます。 また、このソフトウェアはMITライセンス、ならびにApache 2.0ライセンスで配布されている製作物が含まれています。 http://www.opensource.org/licenses/mit-license http://www.apache.org/licenses/LICENSE-2.0 */ //============================================================================= /*: * @target MZ * @plugindesc サブエミッター機能の有効化 * @author Thirop * @base TRP_ParticleMZ * @orderAfter TRP_ParticleMZ * @help * 【更新履歴】 * 1.21 2022/05/02 制御文字が反映されない不具合の修正 * 1.13 2021/10/27 慣性が正しく働かない不具合修正 * 1.09 2021/08/18 本体設定「キャッシュ設定(β)」に対応 * 1.08 2021/06/30 Safari/iOSで生じる起動時エラー修正 * 1.00 2021/04/10 初版。 * * @command set * @text set/サブエミッターのセット * @desc サブエミッターをセット(親エミッターの再生直後に実行すること) * * @arg id * @text 親エミッターID * @desc 対象とする(再生中の)親エミッターID * * @arg name * @text 設定名 * @desc サブエミッターとして再生する設定名 * * @arg timing * @text 開始タイミング * @desc 射出を開始するタイミング(0~1) * @default 0 * * @arg endTiming * @text 終了タイミング * @desc 射出を終了するタイミング(0~1)、-1で無効。emitterLifetimeか早いほうが優先。 * @default -1 * * @arg speedRate * @text 慣性速度 * @desc 慣性の影響度合い(0~1で0%~100%) * @default 0 * * @arg inheritAngle * @text 角度の継承 * @desc 角度の継承モード。0で親パーティクルの角度の影響なし、1で影響あり。 * @default 0 * * @arg inheritScale * @text 拡大率乗数の継承 * @desc 拡大率乗数の継承モード。0で親パーティクルのminimumScaleMultiplierの影響なし、1で影響あり。 * @default 0 * * @arg delay * @text _ディレイ * @desc 1以上とすると、指定フレーム後にコマンドを実効。 * @default 0 * @type number * @min 0 * */ //============================================================================= //PRAGMA_END: subEmitterHeader //PRAGMA: englishHeader //PRAGMA_END: englishHeader (function(){ 'use strict'; //PRAGMA: subEmitterRegisterCommands (()=>{ var pluginName = 'TRP_ParticleMZ_SubEmitter'; var command = 'set'; PluginManager.registerCommand(pluginName, command, function(args){ //this > interpreter var argsArr = Object.values(args) var delay = Number(argsArr.pop())||0; var pCommand = command; argsArr.unshift(pCommand); argsArr.unshift('sub'); var eventId = this.eventId(); if(delay>0){ $gameScreen._particle.reservePluginCommand(delay,this,argsArr,eventId); }else{ $gameScreen._particle.pluginCommand(this,argsArr,eventId); } }); })(); //PRAGMA_END: subEmitterRegisterCommands /*! ***************************************************************************** Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. See the Apache Version 2.0 License for specific language governing permissions and limitations under the License. ***************************************************************************** */ /* global Reflect, Promise */ var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; function __extends(d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; /***************************************************************************** */ //PRAGMA: subEmitterPluginSetting var baseParameters = PluginManager.parameters('TRP_ParticleMZ'); //PRAGMA_END: subEmitterPluginSetting var LC = TRP_Localize.localize.bind(TRP_Localize,'parSe'); var _Game_Particle_particleData= Game_Particle.prototype.particleData; Game_Particle.prototype.particleData = function(eventId,id,target,name,z,x,y,image){ var data = _Game_Particle_particleData.apply(this,arguments); if(data.subs){ data.subs = null; } return data; }; var _Game_Particle_pluginCommand= Game_Particle.prototype.pluginCommand; Game_Particle.prototype.pluginCommand = function(interpreter,args,eventId){ var sub = args[0].toLowerCase(); if(sub === 'sub'){ this.processSubEmitterCommand(interpreter,args,eventId); }else{ _Game_Particle_pluginCommand.call(this,interpreter,args,eventId); } }; Game_Particle.prototype.processSubEmitterCommand = function(interpreter,args,eventId){ this.convertEscapeCharacters(args); var main = args.shift(); var sub = args.shift().toLowerCase(); if(!isNaN(eventId)){ this.processArgsEventId(args,eventId); } if(sub==='set'||sub==='play'||sub==='edit'){ if(sub==='set'||sub==='play'){ Game_Particle.prototype.particleSubEmitterSet.apply(this,args); }else if(sub==='edit'){ if(Game_Particle.prototype.particleSubEmitterEdit.apply(this,args) && interpreter){ interpreter.wait(1); } } } }; Game_Particle.prototype.particleSubEmitterSet = function(id,name,timing=0,endTiming=-1,speedRate=0,inheritAngle=0, inheritScale=0){ var data = this.dataWithId(id); if(!data){ return; } var subEmitters = data.subs; if(!subEmitters){ subEmitters = data.subs = []; } var length = subEmitters.length; for(var i=0; i=3 ? data[2]||0 : -1; var speedRate = data[3]||0; var inheritAngle = data[4]||0; var inheritScale = data[5]||0; var config = Game_Particle.configDataWithName(name); var image = config.image||baseParameters.defaultImage; var bitmaps = this.bitmapsWithImage(image); var textures = this._texturesWithBitmaps(image,bitmaps); emitter.setSubEmitter(container,textures,config,timing,endTiming,speedRate,inheritAngle,inheritScale); }; ParticleEmitter.prototype.particleConstructor = function(){ return this._subData ? TRP_ParticleEx : TRP_Particle; }; ParticleEmitter.prototype.emitterConstructor = function(){ return this._subData ? TRP_EmitterEx : TRP_Emitter; }; ParticleEmitter.prototype.subEmitter = function(name){ return this._emitter._subEmitters ? this._emitter._subEmitters[this._subNames.indexOf(name)] : null; }; var _ParticleEmitter_loopParticles = ParticleEmitter.prototype.loopParticles; ParticleEmitter.prototype.loopParticles = function(loopX,loopY){ _ParticleEmitter_loopParticles.call(this,loopX,loopY,this._emitter); if(this._subEmitters){ var length = this._subEmitters.length; for(var i=0; i0)return; _super.prototype.destroy.call(this); var length = this._subEmitters.length; for(var i=0; i1){ this.particlesPerWave = Math.ceil(Math.min(this._originalParticlesPerWave,this._originalParticlesPerWave*(target/naturalCapacity)))||1; naturalCapacity = this.naturalCapacity(this._originalFrequency,this.particlesPerWave); } this.frequency = Math.max(this._originalFrequency,this._originalFrequency / (target/naturalCapacity)); //sub limit var length = this._subEmitters.length; for(var i=0; i=this.timing){ data._emit = true; data._spawn = true; data._emitterLife = this.emitterLifetime }else{ return; } }else if(this.endTiming>=0 && lerp>=this.endTiming){ data._spawnTimer = 0; data._emitterLife = 0; data._emit = false; return; } if (!this._parent) return; if (this._autoUpdate) { delta = delta / pixi.settings.TARGET_FPMS / 1000; } //update existing particles var prevX, prevY; //if the previous position is valid, store these for later interpolation if (data._prevPosIsValid) { prevX = data._prevEmitterPos.x; prevY = data._prevEmitterPos.y; } //store current position of the emitter as local variables var curX = ep.x + this.spawnPos.x; var curY = ep.y + this.spawnPos.y; var posChanged = data._prevPosIsValid && (prevX!==curX || prevY!==curY); //spawn new particles if (this._emit) { //decrease spawn timer data._spawnTimer -= delta < 0 ? 0 : delta; //while _spawnTimer < 0, we have particles to spawn while (data._spawnTimer <= 0) { //determine if the emitter should stop spawning if (data._emitterLife > 0) { data._emitterLife -= this._frequency; if (data._emitterLife <= 0) { data._spawnTimer = 0; data._emitterLife = 0; data._emit = false; break; } } //determine if we have hit the particle limit if (this.particleCount >= this.maxParticles) { data._spawnTimer += this._frequency; continue; } //determine the particle lifetime var lifetime = void 0; if (this.minLifetime == this.maxLifetime) lifetime = this.minLifetime; else lifetime = Math.random() * (this.maxLifetime - this.minLifetime) + this.minLifetime; //only make the particle if it wouldn't immediately destroy itself if (-data._spawnTimer < lifetime) { //If the position has changed and this isn't the first spawn, //interpolate the spawn position var emitPosX = void 0, emitPosY = void 0; if (data._prevPosIsValid && posChanged) { //1 - _spawnTimer / delta, but _spawnTimer is negative var lerp = 1 + data._spawnTimer / delta; emitPosX = (curX - prevX) * lerp + prevX; emitPosY = (curY - prevY) * lerp + prevY; } else //otherwise just set to the spawn position { emitPosX = curX; emitPosY = curY; } //create enough particles to fill the wave (non-burst types have a wave of 1) var i = 0; for (var len = Math.min(this.particlesPerWave, this.maxParticles - this.particleCount); i < len; ++i) { //see if we actually spawn one if (this.spawnChance < 1 && Math.random() >= this.spawnChance) continue; //create particle var p = void 0; if (this._poolFirst) { p = this._poolFirst; this._poolFirst = this._poolFirst.next; p.next = null; } else { p = new this.particleConstructor(this); } //set a random texture if we have more than one if (this.particleImages.length > 1) { // if using ordered art if (this._currentImageIndex !== -1) { // get current art index, then increment for the next particle p.applyArt(this.particleImages[this._currentImageIndex++]); // loop around if needed if (this._currentImageIndex < 0 || this._currentImageIndex >= this.particleImages.length) { this._currentImageIndex = 0; } } // otherwise grab a random one else { p.applyArt(this.particleImages[Math.floor(Math.random() * this.particleImages.length)]); } } else { //if they are actually the same texture, a standard particle //will quit early from the texture setting in setTexture(). p.applyArt(this.particleImages[0]); } //set up the start and end values p.alphaList.reset(this.startAlpha); p.speedList.reset(this.startSpeed); if (this.minimumSpeedMultiplier != 1) { p.speedMultiplier = Math.random() * (1 - this.minimumSpeedMultiplier) + this.minimumSpeedMultiplier; } p.acceleration.x = this.acceleration.x; p.acceleration.y = this.acceleration.y; p.maxSpeed = this.maxSpeed; if (this.minimumScaleMultiplier != 1) { p.scaleMultiplier = Math.random() * (1 - this.minimumScaleMultiplier) + this.minimumScaleMultiplier; } p.scaleList.reset(this.startScale); p.colorList.reset(this.startColor); //randomize the rotation speed if (this.minRotationSpeed == this.maxRotationSpeed) p.rotationSpeed = this.minRotationSpeed; else p.rotationSpeed = Math.random() * (this.maxRotationSpeed - this.minRotationSpeed) + this.minRotationSpeed; p.rotationAcceleration = this.rotationAcceleration; p.noRotation = this.noRotation; //set up the lifetime p.maxLife = lifetime; //set the blend mode p.blendMode = this.particleBlendMode; //set the custom ease, if any p.ease = this.customEase; //set the extra data, if any p.extraData = this.extraData; //set additional properties to particle this.applyAdditionalProperties(p); //call the proper function to handle rotation and position of particle this._spawnFunc(p, emitPosX, emitPosY, i); if(this.inheritScale>0){ p.scaleMultiplier *= ep.scaleMultiplier; } //initialize particle p.init(); //inertia p.iVelocity.x = this.speedRate*ep.velocity.x; p.iVelocity.y = this.speedRate*ep.velocity.y; p._doInertia = !!(p.iVelocity.x||p.iVelocity.y); //inheritAngle if(this.inheritAngle>0){ var v1Rotation = Math.atan2(ep.velocity.y, ep.velocity.x); utils.rotatePoint(v1Rotation/utils.DEG_TO_RADS, p.velocity); p.rotation += v1Rotation; } //update the particle by the time passed, so the particles are spread out properly p.update(-data._spawnTimer); //we want a positive delta, because a negative delta messes things up //add the particle to the display list if (!p.parent) { if (this.addAtBack) this._parent.addChildAt(p, 0); else this._parent.addChild(p); } else { //kind of hacky, but performance friendly //shuffle children to correct place var children = this._parent.children; //avoid using splice if possible if (children[0] == p) children.shift(); else if (children[children.length - 1] == p) children.pop(); else { var index = children.indexOf(p); children.splice(index, 1); } if (this.addAtBack) children.unshift(p); else children.push(p); } //add particle to list of active particles if (this._activeParticlesLast) { this._activeParticlesLast.next = p; p.prev = this._activeParticlesLast; this._activeParticlesLast = p; } else { this._activeParticlesLast = this._activeParticlesFirst = p; } ++this.particleCount; } } //increase timer and continue on to any other particles that need to be created data._spawnTimer += this._frequency; } //if the position changed before this update, then keep track of that data._prevEmitterPos.x = curX; data._prevEmitterPos.y = curY; data._prevPosIsValid = true; } }; return TRP_SubEmitter; }(ParticleEmitter.TRP_Emitter)); //============================================================================= // TRP_ParticleEx //============================================================================= var TRP_Particle = ParticleEmitter.TRP_Particle; var TRP_ParticleEx = /** @class */(function(_super){ __extends(TRP_ParticleEx,_super); var utils = PIXI.particles.ParticleUtils; function TRP_ParticleEx(emitter){ var _this = _super.call(this,emitter)||this; _this.subEmitters = null; _this.subEmitterData = []; return _this; }; TRP_ParticleEx.prototype.kill = function () { var emitters = this.subEmitters; var length = emitters ? emitters.length : 0; for(var i=0; i0){ return; } } _super.prototype.kill.call(this); } TRP_ParticleEx.prototype.update = function(delta){ var lerp = _super.prototype.update.call(this,delta); if(this._wait>0)return lerp; var emitters = this.subEmitters; var length = emitters ? emitters.length : 0; var subLerp = lerp<0 ? 1 : lerp; for(var i=0; i