躲避光标和其他粒子的粒子



我正在尝试创建一个简单的香草JS程序,其中x数量的粒子/对象在屏幕上生成,它们需要相互躲避和鼠标。对于我使用的整体回避https://gist.github.com/christopher4lis/f9ccb589ee8ecf751481f05a8e59b1dc粒子相互躲避效果很好,但现在我只能实现鼠标躲避功能了。

我所尝试的一切都以粒子相互重叠或其他一些错误告终。

有人对如何处理这种情况有什么建议吗?或者可能会删除以前项目中的代码片段吗?

import {c, canvas, mouse, people} from "./canvas.js";
import {distance} from "./utils.js";
// @ts-ignore
import {resolveCollision} from './util-elastic-collision.js';
export default class Person {
private velocity: { x: number, y: number };
private mass: number;
constructor(
private _x: number,
private _y: number,
private radius: number,
) {
this.velocity = {
x: (Math.random() - 0.5) * 2,
y: (Math.random() - 0.5) * 2,
}
this.mass = 1;
}
get x() {
return this._x;
}
set x(x: number) {
this._x = x;
}
get y() {
return this._y;
}
set y(y: number) {
this._y = y;
}
draw() {
c.beginPath();
c.arc(this._x, this._y, this.radius, 0, Math.PI * 2);
c.fill();
}
update() {
this.draw();
this.keepDistance();
// Bounce off the mouse // Failed
for (let i = 0; i < people.length; i++) {
let dist = distance(mouse.x, mouse.y, people[i].x, people[i].y) - 6 * this.radius;
if (dist <= 0) {
people[i].x += (mouse.x > people[i].x + this.radius) ? -1 : 1;
people[i].y += (mouse.y > people[i].y + this.radius) ? -1 : 1;
}
}

// Bounce off the walls
if (this._x - this.radius < 0 || this._x + this.radius > canvas.width) {
this.velocity.x *= -1;
}
if (this._y - this.radius < 0 || this._y + this.radius > canvas.height) {
this.velocity.y *= -1;
}
this._x += this.velocity.x;
this._y += this.velocity.y;
}
keepDistance() {
// Bounce off other people
for (let i = 0; i < people.length; i++) {
if (people[i] === this) continue;
let dist = distance(this._x, this._y, people[i].x, people[i].y) - 4 * this.radius;
if (dist <= 0) {
resolveCollision(this, people[i]);
}
}
}

}

首先我要更改:
dist = distance(this._x, this._y, people[i].x, people[i].y) - 4 * this.radius;

到以下位置:
dist = distance(this._x, this._y, people[i].x, people[i].y) - (this.radius + people[i].radius);

当你的圆圈是不同半径的时,这应该会给你带来真实的碰撞


然后在鼠标对象碰撞时,我会从以下内容开始:

var dist = distance(mouse.x, mouse.y, people[i].x, people[i].y) - people[i].radius;
if (dist <= 100) {
let m = new Person(mouse.x, mouse.y, 100);
//TODO set proper velocity
m.velocity = { x: 2, y: 2 };
resolveCollision(m, people[i]);
}

通过这种方式,我们重用resolveCollision,保持与其他对象之间的碰撞相同的效果。您确实需要找到一种方法来为鼠标设置适当的速度,因为它假设鼠标正在左右移动。

当我们引入鼠标resolveCollision时,我注意到了另一件事,它只是交换了速度:
https://github.com/AlverPalk/collision/blob/master/src/ts/util-elastic-collision.js#L58
我认为它还应该降低碰撞时的速度,因为碰撞时的能量损失,如果不是每次与鼠标的碰撞都会增加速度,使整个系统移动得非常快


代码在我的分叉上:
https://github.com/heldersepu/collision/commits/master

最新更新