我有这个代码,它在画面中叠加画布粒子,然后在一个画面已满时重置整个画布。
通过设置“particles = []”
来完成此操作我想通过仅重置该特定通道的画布来修改此行为。有可能吗?
$(document).ready(function () {
"use strict";
var c = document.getElementById("c"),
ctx = c.getContext("2d"),
WIDTH = c.width = window.innerWidth,
HEIGHT = c.height = window.innerHeight;
var particles = [],
particle = null,
particleCount = 3,
radius = 0,
numParticles = [0, 0, 0, 0, 0, 0],
colors = ["#00FF6D", "E8D90C", "#FF5900", "#C00CE8", "#0D90FF"];
var Vector = function (x, y) {
this.x = x || 0;
this.y = y || 0;
};
Vector.prototype = {
constructor: Vector,
add: function (v) {
this.x += v.x;
this.y += v.y;
},
sub: function (v) {
this.x -= v.x;
this.y -= v.y;
},
mul: function (v) {
this.x *= v.x;
this.y *= v.y;
}
};
var Particle = function (position, velocity, radius, lane, color) {
this.position = position;
this.velocity = velocity;
this.radius = radius;
this.baseRadius = radius;
this.angle = 3;
this.lane = lane;
this.color = color;
};
Particle.prototype = {
constructor: Particle,
update: function (lane) {
this.radius = 3;
this.angle += 10;
this.position.add(this.velocity);
// CHECKS FIRST IF THERE'S ALREADY A PARTICLE IN THE LANE AND THEN SHORTENS THE STOP LENGTH
if (this.position.x > WIDTH - (numParticles[this.lane] + 1) * 120) {
// IF THERE IS ALREADY A PARTICLE ON A LANE THE NUMBER OF PARTICLES PER IS INCREASED
if (this.velocity.x > 0) {
console.log(numParticles[this.lane] + " particles in this lane")
numParticles[this.lane]++;
if (numParticles[this.lane] > 8) {
numParticles[this.lane] = 0;
particles = [];
}
// STOPS THE PARTICLE
this.velocity.x = 0;
}
}
},
render: function (ctx) {
for (var i = 0; i < 10; i++) {
for (var j = 0; j < 5; j++) {
ctx.beginPath()
ctx.fillStyle = this.color;
ctx.arc(this.position.x - i * 12, (this.position.y - 30) + j * 12, this.radius + 0.5, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
}
}
}
};
function addParticle(lane) {
radius = 3;
particle = new Particle(
new Vector(-radius, lane * (HEIGHT) / 5),
new Vector(5),
radius,
lane,
colors[Math.round(Math.random() * 4)]
);
particles.push(particle);
}
requestAnimationFrame(function loop() {
requestAnimationFrame(loop);
ctx.fillStyle = "rgba(0, 0, 0, 0.1)";
ctx.fillRect(0, 0, WIDTH, HEIGHT);
for (var i = 0, len = particles.length; i < len; i++) {
particle = particles[i];
particle.update();
particle.render(ctx);
}
});
//
// ─── SOCKETIO CONNECTION TO NODE WEBSERVER RUNNING OPENCV ───────────────────────
//
var socket = io.connect('http://localhost:8000');
// SEND "CONNECTED" MESSAGE ONCE SUCCSEFULLY CONNECTED
socket.on('connect', function () {
console.log('connected');
});
socket.on('message', function (msg) {
console.log(msg);
// IF NUMBER OF CARS DETECTED IS MORE THAN 0, A PARTICLE WILL BE ADDED RANDOMLY TO ONE OF THE 4 LANES
if (msg >= 0) {
addParticle(Math.round((Math.random() * 3) + 1));
}
});});
答案 0 :(得分:0)
如果你有一个粒子数组,想要删除一些满足某些条件的项目,有几种方法可以做到。
使用Array.filter
创建一个新数组var particles = []; // fill with particles
// remove particles in lane 3 using arrow function
particles = particles.filter(particle => particle.lane !== 3);
// or using via function
particles = particles.filter(function(particle){ return particle.lane !== 3});
此方法确实会创建一个新数组,因此会因GC(垃圾收集)和分配开销而受到一些惩罚。此外,如果您对阵列有多个参考,则需要更新所有参考文献。
var particles = [];
const obj = {
particles : particles, // referance to the array particles.
}
// remove particles in lane 3
particles = particles.filter(particle => particle.lane !== 3)
// the array referenced by obj.particles still has the unfiltered array
obj.particles = particles; // update reference
当需要性能时,可以使用Array.splice从数组中删除项目。它还具有不创建必须传播的新参考的优点。
for(var i = 0; i <particles.length; i++){ // must use particles.length
if(particles[i].lane === 3){
particles.splice(i--,1); // decrease i so you do not skip an item
// as slice will move the index of all
// items above i down one
}
}
// do not use a variable to store the length in the for loop
var len = particles.length
for(var i = 0; i < len; i++){ // will cause unexpected behaviors because
// the array length will change
为获得最佳性能,您需要为所有粒子指定一个标志,以确定粒子是否已更新和渲染。
for(var i = 0; i <particles.length; i++){
particles[i].active = ! particles[i].lane === 3;
}
在更新和渲染之前,您将检查活动是否为真
// in render and update loops
for(var i = 0; i <particles.length; i++){
if(particles[i].active){
particles[i].update(); // or render()
}
}
当然,你有一个不断增长的阵列。要停止数组的无限制增长,请更改设置粒子属性的方式,将方法添加到粒子对象。
function Particle(){}; // constructor
Particle.prototype.set = function(pos,vel,foo,bar){
this.active = true;
this.velocity = vel;
//... and the other properties
}
当您添加粒子时,首先检查粒子数组中是否存在非活动粒子,并通过使用set函数设置其属性来使用它。如果没有非活动粒子,那么您只需创建一个新粒子并将其添加到粒子数组中,并使用set设置其属性。
function addParticle(pos,vel,foo,bar){
var i;
for(i = 0; i < particles.length; i++){
if(! particles[i].active){
particles[i].set(pos,vel,foo,bar);
return;
}
}
// no inactive particles create a new one
particles.push(
new Particle().set(pos,vel,foo,bar);
);
}