Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 发射器跟随画布中的粒子_Javascript_Html_Canvas_Html5 Canvas - Fatal编程技术网

Javascript 发射器跟随画布中的粒子

Javascript 发射器跟随画布中的粒子,javascript,html,canvas,html5-canvas,Javascript,Html,Canvas,Html5 Canvas,在这段HTML5代码中,我尝试从对象[0]中的发射器发射粒子。 这可以与对象[0]一起运行。在控制台中播放。 但是,发射器跟随发射的粒子 我的问题是,为什么 HTML代码 <html> <head> <style> #canv{ border: 1px solid black; } </style> <script src = "setup.js"><

在这段HTML5代码中,我尝试从对象[0]中的发射器发射粒子。 这可以与
对象[0]一起运行。在控制台中播放
。
但是,发射器跟随发射的粒子

我的问题是,为什么

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>

#坎夫{
边框:1px纯黑;
}
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;
}   
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);
}
var对象=[];
变量sprites=[];
var c;
var-ctx;
var时间;
var时间间隔;
函数newSprite(url){
var a=sprites.length;
var b=新图像();
b、 src=url;
b、 onload=函数(){
精灵[a]=b;
};
}
函数随机数n(最小值、最大值){
返回Math.floor((Math.random()*max)-min);
}
函数向量2(x,y){
这个.x=x;
这个。y=y;
}
功能粒子(位置、寿命、级别、加速度){
this.pos=pos;
生命=生命| |无限;
this.vel=vel | |新向量2(0,0);
this.accel=accel | |新矢量2(0,0);
this.update=函数(){
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我没有遵循完整的逻辑,如果这不是原因,那么很抱歉,但这有点奇怪:

function newSprite(url){
    var a = sprites.length;
    var b = new Image();
    b.src = url;

    b.onload = function(){
        sprites[a] = b;
    };
}
在onload运行时,a和b的作用域并不长(我相信):onload事件将作为newSprite之外的新函数调用触发

你不需要这样做吗

    b.onload = function(){
        sprites[sprites.length] = this;
    };

因此,函数在调用时能否正确运行?

您的错误是使用对象引用而不是使用对象的值的一个非常典型的错误:创建新粒子时,您将其位置设置为发射器的非常位置。
因此,后面对粒子位置的任何更改都会更改发射器的位置:同样,位置(pos)对象是同一个对象。
您希望每个粒子都有自己的位置,即发射器位置的初始值。
例如,通过以下方式完成:

function Particle(pos, life, vel, accel){
      this.pos = new Vector2(pos.x, pos.y);
      //...
请注意,速度和加速度也是引用,这不是问题,因为您使用新的
Vector2
调用调用构造函数的函数

但是,您可能希望通过同时为这两个属性执行一个副本来防止代码将来可能出现的错误。

提供一个JSFIDLE可能会有所帮助,这样我们就可以了解您的意思。我尝试了,在剩下的5分钟内,我无法理解语法。我下次会这样做,以解决将来的问题,谢谢。我相信精灵会像我一样工作我很抱歉,但我会接受你的答案,因为将来可能会出现错误,谢谢!谢谢!我完全理解。