正在学 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;
}
},
});