Hello world :) Работая над небольшой анимацией, в которой несколько сфер прыгают по холсту, отскакивая друг от друга, от пола, стен и потолков.
Теперь это работает отлично, без сбоев,пока я не добавлю больше сфер, чем можно уместить в области на одном уровне.В этот момент сферы опускаются на один плоский уровень сфер, соединяясь друг с другом и проталкивая других через границы стен, что обычно не происходит.
Однако следует отметить, что я не совсем понимаю функцию, которую использую для достижения результата, так что, скорее всего, это как-то связано с этим.Ниже будут опубликованы мои функции обнаружения столкновений, и, надеюсь, один из вас может помочь мне получить немного дальше:)
Заимствованные функции:
/**
* Rotates coordinate system for velocities
*
* Takes velocities and alters them as if the coordinate system they're on was rotated
*
* @param Object | velocity | The velocity of an individual particle
* @param Float | angle | The angle of collision between two objects in radians
* @return Object | The altered x and y velocities after the coordinate system has been rotated
*/
function rotate(velocity, angle) {
const rotatedVelocities = {
x: velocity.x * Math.cos(angle) - velocity.y * Math.sin(angle),
y: velocity.x * Math.sin(angle) + velocity.y * Math.cos(angle)
};
return rotatedVelocities;
}
/**
* Swaps out two colliding particles' x and y velocities after running through
* an elastic collision reaction equation
*
* @param Object | particle | A particle object with x and y coordinates, plus velocity
* @param Object | otherParticle | A particle object with x and y coordinates, plus velocity
* @return Null | Does not return a value
*/
function resolveCollision(particle, otherParticle) {
const xVelocityDiff = particle.velocity.x - otherParticle.velocity.x;
const yVelocityDiff = particle.velocity.y - otherParticle.velocity.y;
console.log("Resolving");
const xDist = otherParticle.x - particle.x;
const yDist = otherParticle.y - particle.y;
// alert(xVelocityDiff * xDist + yVelocityDiff * yDist)
// Prevent accidental overlap of particles
if (xVelocityDiff * xDist + yVelocityDiff * yDist >= 0) {
console.log("Resolving IF");
// Grab angle between the two colliding particles
const angle = -Math.atan2(otherParticle.y - particle.y, otherParticle.x - particle.x);
// Store mass in var for better readability in collision equation
const m1 = particle.mass;
const m2 = otherParticle.mass;
// Velocity before equation
const u1 = rotate(particle.velocity, angle);
const u2 = rotate(otherParticle.velocity, angle);
// Velocity after 1d collision equation
const v1 = { x: u1.x * (m1 - m2) / (m1 + m2) + u2.x * 2 * m2 / (m1 + m2), y: u1.y };
const v2 = { x: u2.x * (m1 - m2) / (m1 + m2) + u1.x * 2 * m2 / (m1 + m2), y: u2.y };
// Final velocity after rotating axis back to original location
const vFinal1 = rotate(v1, -angle);
const vFinal2 = rotate(v2, -angle);
// Swap particle velocities for realistic bounce effect
particle.velocity.x = vFinal1.x;
particle.velocity.y = vFinal1.y;
otherParticle.velocity.x = vFinal2.x;
otherParticle.velocity.y = vFinal2.y;
}
}
Свойства мяча:
// Objects
function Ball(x, y, dy, dx, radius, color) {
this.x = x
this.y = y
// this.dy = dy;
// this.dx = dx;
this.velocity = {
x:dx,
y:dy
}
this.radius = radius
this.color = color
this.mass = 1;
this.collision = ()=> {
for (var index = 0; index < objects.length; index++) {
var coin = objects[index];
if (this === coin) {
continue;
}
if (getDistance(this.x, this.y, coin.x, coin.y) - (this.radius + coin.radius) < 0) {
// alert('hi');
console.log("collision:");
resolveCollision(this, coin)
}
}
}
}
Ball.prototype.update = function() {
if (this.y + this.radius + this.velocity.y > canvas.height) {
this.velocity.y = (-this.velocity.y * parseFloat(0.85));
}else {
this.velocity.y += gravity;
}
this.y += this.velocity.y;
this.x += this.velocity.x;
if (this.x + this.radius + this.velocity.x > canvas.width) {
this.velocity.x = -this.velocity.x;
}
if (Math.sign(this.velocity.x) === 1) {
this.velocity.x -= 0.01;
} else if (Math.sign(this.velocity.x) === -1) {
this.velocity.x += 0.01;
}
if (this.x - this.radius - this.velocity.x < 0) {
this.velocity.x = Math.abs(this.velocity.x);
}
this.draw()
}
Любая помощь здесь будет очень цениться, я пытаюсь улучшить свои навыки в этой области, и чувствую острую необходимость вернуться и прочитать мои книги по геометрии снова: D