简易组件: 让 prefab 像粒子一样运动

正在学 creator,先练习写了个小组件。可以让 Prefab 像粒子一样发射和运动。
有类似需求的可以凑合用一下。

SpriteGroup.js

var FreeMove = require("FreeMove");
cc.Class({
extends: cc.Component,
properties: {
    toggle: {
        default: false,
        visible: false,
    },
    playOnLoad: true,
    prefab:{
        default: null,
        type: cc.Prefab,
    },

    //target相当于坐标系
    target:{
        default: null,
        type: cc.Node,
    },
    duration: -1,
    emitterRate: 5,
    life: 1,
    lifeVar: 0,
    maxCount:{
        default: 20,
        type: cc.Integer,
    },

    useOpacity: true,
    startOpacity: {
        default:255,
        range: [0,255,1],
    },
    endOpacity: {
        default:255,
        range: [0,255,1],
    },


    useScale: true,
    startScale: 1,
    startScaleVar: 0,
    endScale: 1,
    endScaleVar: 0,

    useSpin: true,
    startSpin: 0,
    startSpinVar: 0,
    endSpin: 0,
    endSpinVar: 0,

    gravity: cc.p(0,0),
    angle: 0,
    angleVar: 0,
    speed: 0,
    speedVar: 0,

},

start: function () {
    if (!this.prefab) {
        cc.log('Emitter require a Prefab!');
        return;
    }
    this.count = 0;
    this.emitterInterval = 1 / this.emitterRate;        
    if (this.playOnLoad) {
        this.turnOn();
    }
    this.prefabPool = new cc.NodePool();
},

turnOn: function() {
    if (this.toggle = true) {
        this.turnOff();
    }
    this.schedule( this.addPrefab, this.emitterInterval);
    this.toggle = true;
    if (this.duration >= 0) {
        this.scheduleOnce( this.turnOff, this.duration);
    }
},

turnOff: function() {
    if (this.toggle = true) {
        this.unschedule(this.addPrefab);
        this.unschedule(this.turnOff);
        this.toggle = false;
    }
},

addPrefab: function() {

    if (this.toggle && this.count < this.maxCount) {
        let speed = this.speed + 2 * Math.random() * this.speedVar - this.speedVar;
        let angle = this.angle + 2 * Math.random() * this.angleVar - this.angleVar;
        let node = null;
        if(this.prefabPool.size()>0){
            node = this.prefabPool.get();               
        } else{
            node = cc.instantiate(this.prefab);
            node.addComponent("FreeMove");              
        }
        
        let removePrefab = cc.callFunc(function(target,arg){
            this.prefabPool.put(arg);
            this.count -= 1;
        },this,node);

        let life = this.life + this.lifeVar * Math.random() ;
        node.runAction(cc.sequence(cc.delayTime(life),removePrefab));
        node.getComponent("FreeMove").setState({
                x: this.node.x - this.node.width/2 - this.target.x + Math.random()*this.node.width,
                y: this.node.y - this.node.height/2 - this.target.y + Math.random()*this.node.height,
                vx: speed * Math.cos(angle*Math.PI/180),
                vy: speed * Math.sin(angle*Math.PI/180),
                ax: this.gravity.x,
                ay: this.gravity.y}
        );            

        if (this.useOpacity) {
            node.opacity = this.startOpacity;
            node.runAction(cc.fadeTo(life,this.endOpacity));
        }
        
        if (this.useScale) {
            node.scale = this.startScale + 2 * Math.random() * this.startScaleVar - this.startScaleVar;
            node.runAction(cc.scaleTo(life,this.endScale + 2 * Math.random() * this.endScaleVar - this.endScaleVar));
        }

        if (this.useSpin) {
            node.rotate = this.startSpin + 2 * Math.random() * this.startSpinVar - this.startSpinVar;
            node.runAction(cc.rotateTo(life,this.endSpin + 2 * Math.random() * this.endSpinVar - this.endSpinVar));
        }

        node.parent = this.target;
        this.count += 1;   
    }
},

onDestroy: function() {
    this.prefabPool.clear();
}
});

FreeMove.js

cc.Class({
extends: cc.Component,

properties: {

},

// use this for initialization
onLoad: function (){
    this.isPlaying = true;
},

pause: function () {
    this.isPlaying = false;
},

resume: function () {
    this.isPlaying = true;
},

setState: function (opt){
    this.t = 0;
    this.type = opt.type;
    if (opt.x) {
        this.x0 = this.node.x = opt.x;
    } else {
        this.node.x = this.node.x || 0;
        this.x0 = this.node.x;
    }
    if (opt.y) {
        this.y0 = this.node.y = opt.y;
    } else {
        this.node.y = this.node.y || 0;
        this.y0 = this.node.y;
    }

    this.vx = opt.vx || 0;
    this.vy = opt.vy || 0;
    this.ax = opt.ax || 0;
    this.ay = opt.ay || 0;

},

update: function (dt) {
    if (this.isPlaying) {
        this.t += dt;
        this.node.x = this.x0 + this.vx * this.t + this.ax * this.t * this.t /2;
        this.node.y = this.y0 + this.vy * this.t + this.ay * this.t * this.t /2; 
    }
},
});
3赞