我有这个设置,球正在碰撞,当所有球都有速度时效果很好,但现在我试图让它们与静态的碰撞,所以我制作了一个静态球,其中速度始终为 0 并且不能被设置。
但是当发生碰撞时,球(不是静态的)会粘在静态的球上。但我不知道为什么。
我究竟做错了什么?这是用于使它们弹跳的代码。欢迎对代码进行任何其他评论;)
球基:
public abstract class BallBase {
protected Vector _vel;
public virtual Vector Vel {
get { return _vel; }
set { _vel = value; }
}
public Point Pos { get; set; }
public double Rad { get; set; }
public abstract void Tick(double deltaTime, double width, double height);
public abstract Shape Paint();
}
球:
public class Ball : BallBase {
public Ball(Point pos, double rad, Vector vel) {
Pos = pos;
Rad = rad;
_vel = vel;
}
public override Vector Vel {
get { return _vel; }
set { _vel = value; }
}
public override Shape Paint() {
return new Ellipse {
Fill = Brushes.DarkBlue,
Width = Rad*2,
Height = Rad*2,
Margin = new Thickness(Pos.X - Rad, Pos.Y - Rad, 0, 0)
};
}
public override void Tick(double deltaTime, double width, double height) {
Pos = new Point(Pos.X + Vel.X*deltaTime/1000, Pos.Y + Vel.Y*deltaTime/1000);
if ((Pos.X + Rad) > width && Vel.X > 0) Vel = new Vector(Vel.X*-1, Vel.Y);
if ((Pos.Y + Rad) > height && Vel.Y > 0) Vel = new Vector(Vel.X, Vel.Y*-1);
if ((Pos.X - Rad) < 0 && Vel.X < 0) Vel = new Vector(Vel.X*-1, Vel.Y);
if ((Pos.Y - Rad) < 0 && Vel.Y < 0) Vel = new Vector(Vel.X, Vel.Y*-1);
}
}
静态球:
public class StaticBall : BallBase {
public StaticBall(Point pos, double rad) {
Pos = pos;
Rad = rad;
_vel = new Vector(0, 0);
}
public override Vector Vel {
get { return _vel; }
set { }
}
public override Shape Paint() {
return new Ellipse {
Fill = Brushes.Gray,
Width = Rad*2,
Height = Rad*2,
Margin = new Thickness(Pos.X - Rad, Pos.Y - Rad, 0, 0)
};
}
public override void Tick(double deltaTime, double width, double height) {}
}
碰撞处理:
private void HandleCollisions() {
for (int i = 0; i < _ball.Count; ++i) {
for (int j = i + 1; j < _ball.Count; ++j) //let op j=i+1
{
// calculate distance between centers of balls
Vector diff = _ball[i].Pos - _ball[j].Pos;
double distance = diff.Length;
// calculate sum of Radius
double sumRadii = _ball[i].Rad + _ball[j].Rad;
// check collision if dist<sum of diameters
if (distance < sumRadii)
Bounce(i, j);
}
}
}
private void Bounce(int ball1, int ball2) {
// vector that connects between both balls
Vector centerNorm = (_ball[ball1].Pos - _ball[ball2].Pos);
centerNorm.Normalize();
// Project the velocity vector on the centerNorm
Vector projVelocity1 = Dot(centerNorm, _ball[ball1].Vel)*centerNorm;
Vector projVelocity2 = Dot(centerNorm, _ball[ball2].Vel)*centerNorm;
// if in same direction
if (Dot(projVelocity1, projVelocity2) > 0) {
// if the first one is moving faster than the second, don't interfere
// first one is identified by dot with centerNorm
if (Dot(centerNorm, projVelocity1) > 0) {
if (projVelocity1.Length > projVelocity2.Length)
return;
}
else if (projVelocity1.Length < projVelocity2.Length)
return;
}
// they are not moving in the same direction
else if (Dot(centerNorm, projVelocity1) > 0)
return;
// calculate tangetnt
Vector tangentVelocity1 = _ball[ball1].Vel - projVelocity1;
Vector tangentVelocity2 = _ball[ball2].Vel - projVelocity2;
// New vel is sum own tangent and projection of the other
Vector newVelocity1 = tangentVelocity1 + projVelocity2;
Vector newVelocity2 = tangentVelocity2 + projVelocity1;
// collision with static ball is like colliding with a wall
if (_ball[ball1].GetType() == typeof (StaticBall)) newVelocity2 = tangentVelocity2 - _ball[ball2].Vel;
else if (_ball[ball2].GetType() == typeof (StaticBall)) newVelocity1 = tangentVelocity1 - _ball[ball1].Vel;
// assign
_ball[ball1].Vel = newVelocity1;
_ball[ball2].Vel = newVelocity2;
}
编辑:添加的解决方案,由 Tariks 回答