我有以下代码,我尝试在其中创建基本粒子碰撞的引擎。但是,它无法渲染并留下一个空画布,并显示错误:“粒子不是构造函数”。请帮助解决这个问题,以及对引擎的建议。
我尝试将临时“Particle”变量更改为“p”。我的代码如下:
var Canvas = document.createElement('canvas');
Canvas.width = 300;
Canvas.height = 300;
Canvas.style = 'border: 1px solid black';
document.body.appendChild(Canvas);
var CTX = Canvas.getContext('2d');
var ParticleIndex = [];
function Particle(X, Y, Xvel, Yvel, Size, Xfric, Yfric, Xacc, Yacc, Bounce){
this.X = X;
this.Y = Y;
this.XVel = Xvel;
this.YVel = Yvel;
this.Size = Size;
this.Xfric = Xfric;
this.Yfric = Yfric;
this.Xacc = Xacc;
this.Yacc = Yacc;
this.Bounce = Bounce
this.appendToIndex = function(){
ParticleIndex.push(this);
}
this.Render = function(){
CTX.fillRect(this.X, this.Y, this.Size, this.Size);
};
this.Physics = function(){
this.X += this.Xvel;
for(var i = 0; i < ParticleIndex.length; i++){
if(isCollide(this, ParticleIndex[i])){
this.X -= this.Xvel
this.Xvel *= this.Bounce * -1;
}
}
this.Y += this.Yvel;
for(var i = 0; i < ParticleIndex.length; i++){
if(isCollide(this, ParticleIndex[i])){
this.Y -= this.Yvel
this.Yvel *= this.Bounce * -1;
}
}
this.Xvel *= this.Xfric;
this.Yvel *= this.Yfric;
}
}
function isCollide(a, b) {
return !(
((a.Y + a.Size) < (b.Y)) ||
(a.Y > (b.Y + b.Size)) ||
((a.X + a.Size) < b.X) ||
(a.X > (b.X + b.Size))
);
}
function Render(){
CTX.clearRect(0, 0, Canvas.width, Canvas.height);
for(var k = 0; k < ParticleIndex.length; k++){
ParticleIndex[k].Physics;
ParticleIndex[k].Render;
}
}
for(var j = 0; j < 100; j++){
var p = new Particle(
Math.round(Math.random() * Canvas.width),
Math.round(Math.random() * Canvas.height),
(Math.random * 10) - 5,
(Math.random * 10) - 5,
5,
0.9,
0.9,
0,
0,
0.8
)
p.appendToIndex();
p.Render();
}
alert('Rendering...');
Render()
以下为错误部分:
for(var j = 0; j < 100; j++){
var p = new Particle(
Math.round(Math.random() * Canvas.width),
Math.round(Math.random() * Canvas.height),
(Math.random * 10) - 5,
(Math.random * 10) - 5,
5,
0.9,
0.9,
0,
0,
0.8
)
p.appendToIndex();
p.Render();
}
感谢您的阅读。
您似乎缺少函数调用(其中一些)的
()
,并且函数 Physics()
还不能很好地工作 - 这是因为错误的变量名称(XVel
vs Xvel
)。最后的奖励是,你不能与自己相撞,因此将这个条件添加到 isCollide
。
您可能遇到的其他问题是边界(更新:我对这种情况做了一些检查)和时间因素,您应该有变量
t
,它将根据经过的时间而不是根据超时的频率增加。
还可以考虑为此使用库,例如 matter.js
var Canvas = document.createElement('canvas');
Canvas.width = 400;
Canvas.height = 180;
Canvas.style = 'border: 1px solid black';
document.body.appendChild(Canvas);
var CTX = Canvas.getContext('2d');
var ParticleIndex = [];
function Particle(X, Y, Xvel, Yvel, Size, Xfric, Yfric, Xacc, Yacc, Bounce) {
this.X = X;
this.Y = Y;
this.Xvel = Xvel;
this.Yvel = Yvel;
this.Size = Size;
this.Xfric = Xfric;
this.Yfric = Yfric;
this.Xacc = Xacc;
this.Yacc = Yacc;
this.Bounce = Bounce
this.appendToIndex = function() {
ParticleIndex.push(this);
}
this.Render = function() {
CTX.fillRect(this.X, this.Y, this.Size, this.Size);
};
this.Physics = function() {
this.X += this.Xvel;
for (var i = 0; i < ParticleIndex.length; i++) {
if (isCollide(this, ParticleIndex[i])) {
this.X -= this.Xvel
this.Xvel *= this.Bounce * -1;
}
}
this.Y += this.Yvel;
for (var i = 0; i < ParticleIndex.length; i++) {
if (isCollide(this, ParticleIndex[i])) {
this.Y -= this.Yvel
this.Yvel *= this.Bounce * -1;
}
}
this.Xvel *= this.Xfric;
this.Yvel *= this.Yfric;
// boundaries
if (this.X < 0) {
this.X = 0
this.Xvel *= this.Bounce * -1;
}
if (this.Y < 0) {
this.Y = 0
this.Yvel *= this.Bounce * -1;
}
if (this.X + this.Size > Canvas.width - 1) {
this.X = Canvas.width - this.Size - 1
this.Xvel *= this.Bounce * -1;
}
if (this.Y + this.Size > Canvas.height - 1) {
this.Y = Canvas.height - this.Size - 1
this.Yvel *= this.Bounce * -1;
}
}
}
function isCollide(a, b) {
if (a == b) {
return false
}
return !(
((a.Y + a.Size) < (b.Y)) ||
(a.Y > (b.Y + b.Size)) ||
((a.X + a.Size) < b.X) ||
(a.X > (b.X + b.Size))
);
}
function Render() {
CTX.clearRect(0, 0, Canvas.width, Canvas.height);
for (var k = 0; k < ParticleIndex.length; k++) {
ParticleIndex[k].Physics();
ParticleIndex[k].Render();
}
requestAnimationFrame(Render)
}
for (var j = 0; j < 10; j++) {
var Size = 12;
var p = new Particle(
Math.round(Math.random() * (Canvas.width - Size)),
Math.round(Math.random() * (Canvas.height - Size)),
(Math.random() * 10) - 5,
(Math.random() * 10) - 5,
Size,
0.999,
0.999,
0,
0,
1
)
p.appendToIndex();
// p.Render();
}
Render()