在此 HTML5 代码中,我尝试从对象 [0] 中的发射器发射粒子。
这可以在控制台中使用 objects[0].play
运行。
然而,发射器跟随发射的粒子。
我的问题是,为什么?
HTML 代码
<html>
<head>
<style>
#canv{
border: 1px solid black;
}
</style>
<script src = "setup.js"></script>
<script src = "main.js"></script>
</head>
<body onLoad = "start()">
<canvas width = "500" height = "500" id = "canv"></canvas>
</body>
</html>
setup.js
var objects = [];
var sprites = [];
var c;
var ctx;
var time;
var timeInterval;
function newSprite(url){
var a = sprites.length;
var b = new Image();
b.src = url;
b.onload = function(){
sprites[a] = b;
};
}
function randomN(min, max){
return Math.floor((Math.random()*max) - min);
}
function Vector2(x,y){
this.x = x;
this.y = y;
}
function Particle(pos, life, vel, accel){
this.pos = pos;
this.life = life || Infinity;
this.vel = vel || new Vector2(0,0);
this.accel = accel || new Vector2(0,0);
this.update = function(){
this.pos.x += this.vel.x;
this.pos.y += this.vel.y;
this.vel.x += this.accel.x;
this.vel.y += this.accel.y;
this.life--;
if(this.life <= 0){
return false;
}else{
return true;
}
};
}
function Emitter(pos){
this.pos = pos;
this.actualPos = this.pos;
this.particles = [];
this.forces = [];
this.playing = false;
this.newParticle = function(life, vel, accel){
var a = this.particles.length;
this.particles[a] = new Particle(this.pos, life, vel, accel);
};
this.update = function(){
console.log("(" + this.actualPos.x + ", " + this.actualPos.y + ") " + "(" + this.pos.x + ", " + this.pos.y + ")");
for(var a = 0; a < this.particles.length; a++){
for(var b = 0; b < this.forces.length; b++){
this.forces[b](this.particles[a]);
}
var that = this.particles[a];
var particleAlive = that.update();
if(particleAlive == false){
this.particles.splice(a, 1);
a--;
}
}
};
this.play = function(){
this.playing = true;
};
}
function timeStep(){
for(var a = 0; a < objects.length; a++){
if(objects[a].__proto__.constructor.name == "Emitter"){
if(objects[a].playing == true){
objects[a].update();
}
}
}
objects[1].newParticle(1000, new Vector2(1, 0), new Vector2(0.1, 0));
time++;
}
function gravity(p){
//p.vel.y += 0.1;
}
main.js
function start(){
c = document.getElementById("canv");
ctx = c.getContext('2d');
newSprite("spark.png");
objects[0] = new Emitter(new Vector2(50, 60));
objects[0].forces.push(gravity);
objects[0].newParticle(1000, new Vector2(1, 0), new Vector2(0.1, 0));
objects[1] = new Emitter(new Vector2(100, 100));
objects[1].forces.push(gravity);
time = 0;
timeInterval = window.setInterval(timeStep, 10);
reDraw();
}
function reDraw(){
ctx.clearRect(0, 0, c.width, c.height);
for(var a = 0; a < objects.length; a++){
if(objects[a].__proto__.constructor.name == "Emitter"){
ctx.beginPath();
ctx.arc(objects[a].pos.x, objects[a].pos.y, 5, 0, 2*Math.PI);
ctx.fillStyle = "black";
ctx.fill();
ctx.closePath();
if(objects[a].playing == true){
for(var b = 0; b < objects[a].particles.length; b++){
ctx.beginPath();
ctx.drawImage(sprites[0], objects[a].particles[b].pos.x, objects[a].particles[b].pos.y, 8,8);
//ctx.arc(objects[a].particles[b].pos.x, objects[a].particles[b].pos.y, 5, 0, 2*Math.PI);
ctx.fillStyle = "black";
ctx.fill();
ctx.closePath();
}
}
}
}
requestAnimationFrame(reDraw);
}
最佳答案
您的错误是使用对象引用而不是使用对象的值的一个非常经典的错误:当您创建一个新粒子时,您将其位置设置为发射器的非常位置。< br/>
因此,对粒子位置的任何后续更改都会更改发射器的位置:同样,位置 (pos) 对象是同一个对象。
您想要的是每个粒子都有自己的位置,即具有发射器位置的初始值。
例如,完成:
function Particle(pos, life, vel, accel){
this.pos = new Vector2(pos.x, pos.y);
//...
请注意,速度和加速度也是引用,这在这里不是问题,因为您使用新的 Vector2
来调用构造函数。
但是,您可能希望通过对这两个属性执行复制来保护您的代码免受将来可能出现的错误。
关于javascript - 发射器跟随 Canvas 中的粒子,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29276441/