我正在为学校做一个项目,它的想法是,一个球开始移动并撞到另一个球,开始那个球移动,然后移动并撞到另一个球,直到最终整个网格移动并改变颜色。
我目前遇到的问题如下。
首先,这些球偶尔会不断相互碰撞和反弹,基本上会导致人们癫痫发作,因为它们闪烁着各种不同的颜色。
其次,球会从屏幕上弹开,我希望屏幕边缘像保险杠或碰撞物体一样,这样物体就不会弹到屏幕之外。
这是我的代码
function setup() {
createCanvas(750, 750);
noStroke();
balls = [];
for (x=0;x<25;x++){
for (y=0;y<25;y++){
b = new Ball(10+ x*30, 10+ y*30);
balls.push(b);
}
}
balls[210].vel = p5.Vector.random2D().mult(0.3);
}
function draw(){
background(220);
for (b of balls){
b.update();
b.checkCollision(balls);
}
for (b of balls){
b.draw();
}
}
class Ball{
constructor(x,y){
this.pos = createVector(x,y);
this.vel = createVector(0,0);
this.color = 'white';
}
update(){
this.pos.add(this.vel);
}
draw(){
fill(this.color);
circle(this.pos.x, this.pos.y, 20);
}
checkCollision(others){
for (const other of others){
if (other != this){
const d = this.pos.dist(other.pos);
if (d < 20){
this.vel.mult(-0.3);
this.pos = this.pos.sub(1,1);
other.pos = other.pos;
other.vel = p5.Vector.random2D().mult(0.3);
this.color = random(['red','pink','purple','blue','green','orange','yellow','olive','maroon','magenta','indigo','teal','violet','crimson','gold','azure','coral','cyan','emerald']);
other.color = random(['red','pink','purple','blue','green','orange','yellow','olive','maroon','magenta','indigo','teal','violet','crimson','gold','azure','coral','cyan','emerald']);
}
}
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.6.0/p5.js"></script>
如有任何帮助,我们将不胜感激!
我尝试添加一个位置修改器来处理两个圆圈不断碰撞的问题,但这似乎使它从屏幕上反弹成为一个更大的问题。我还没能想到解决它出界问题的方法,或者让屏幕边界充当保险杠。
我在您的代码中添加了一些内容,并更改了根据当前速度设置的颜色,以便更好地进行测试交互可视化。
const c_colors = ['red', 'pink', 'purple', 'blue', 'green', 'orange', 'yellow', 'olive', 'maroon', 'magenta', 'indigo', 'teal', 'violet', 'crimson', 'gold', 'azure', 'coral', 'cyan', 'emerald'];
function setup() {
createCanvas(750, 750);
noStroke();
balls = [];
for (x = 0; x < 9; x++) {
for (y = 0; y < 9; y++) {
b = new Ball(35 + x * 80, 35 + y * 80);
balls.push(b);
}
}
balls[55].vel = p5.Vector.random2D().mult(5);
}
function draw() {
background(220);
for (b of balls) {
//b.checkCollision(balls);
b.update();
}
for (b of balls) {
b.draw();
}
}
class Ball {
constructor(x, y) {
this.pos = createVector(x, y);
this.vel = createVector(0, 0);
this.color = 'white';
this.radius = 25;
}
update() {
this.pos.add(this.vel);
this.vel.mult(0.99);
this.checkCollision(balls);
let velMagNorm = p5.Vector.mag(this.vel);
this.color = lerpColor(color(255), color(255, 0, 0), velMagNorm);
}
draw() {
fill(this.color);
circle(this.pos.x, this.pos.y, this.radius * 2);
}
checkCollision(others) {
if (this.pos.x <= this.radius || this.pos.x >= width - this.radius)
this.vel.x *= -1;
if (this.pos.y <= this.radius || this.pos.y >= height - this.radius)
this.vel.y *= -1;
for (const other of others) {
if (this == other)
continue;
const d = this.pos.dist(other.pos);
const vec = p5.Vector.sub(this.pos, other.pos);
const velMag = p5.Vector.mag(this.vel);
const normVec = vec.normalize();
if (d < this.radius * 2) {
this.vel.add(p5.Vector.mult(normVec, velMag * 0.99));
other.vel.add(p5.Vector.mult(normVec, -velMag * 0.99));
//this.color = random(c_colors);
//other.color = random(c_colors);
}
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.6.0/p5.js"></script>
最终的问题在于,球在随机方向上移动,没有规定什么是可行的区域,什么不是可行的移动区域 - 即,如果碰撞发生在向下运动中,则不要向上移动,反之,如果向下移动并与某物发生碰撞,则不要继续向下移动。为了解决这个问题,我根据命中条件规定了方向 - 增强碰撞检测,而不仅仅是检测发生了碰撞