您的位置:首页 > 编程语言 > C#

C# 模拟WIN7水泡屏保(弹球模拟)

2012-02-06 22:56 831 查看
  用C# GDI+ 来模拟 WIN7 的水泡屏保.需要解决以下三个问题: 1.水泡与边缘碰撞的模拟 2.水泡之间的碰撞模拟. 3.创建水泡(Ball)的类

  

  1.水泡与边缘碰撞的模拟其实很简单. 一开始.我还觉得还需要用反弹公式去计算. 后来才发现. 只在X,Y(水泡的位置),在到边缘时取下负值即可模拟.

    

View Code

// 得到反弹向量
PointF GetReflectVector(float x1,float y1,float x2,float y2)
{
// v' = v - 2 * (V * N) * N
// N 为单位向量
// 因为传入的x2,y2 并不是单位向量,所以需要分别除以它的长度. 得到单位向量.
float len2 = GetLength(x2,y2);
float bxx = x2 / len2;
float byy = y2 / len2;

float dotValue = Dot (x1,y1,bxx,byy);
float xval = x1 - 2 * dotValue * bxx;
float yval = y1 - 2 * dotValue * byy;
return (new PointF(xval,yval));
}
//判断是否是运行背离
bool isApart(Ball b1,Ball b2)
{
Vector2 b1Vec = new Vector2(b1.XVel,b1.YVel);
Vector2 cenVec = new Vector2(b2.X - b1.X,b2.Y - b1.Y);
if (Vector2.DotProduct(b1Vec,cenVec) < 0 ) {
return true;
}
else return false;
}
// 碰撞
void Collision(Ball ball,List<Ball> balls)
{
foreach (Ball b in balls) {
if (!Object.Equals(b,ball)) {
float dis = (float)Math.Sqrt(Math.Pow((ball.X - b .X),2) + Math.Pow((ball.Y - b.Y),2));
if (dis <= (ball.Radius + b.Radius) && !isApart(ball,b))
{
PointF rel1 =  GetReflectVector(ball.XVel,ball.YVel,(ball.X - b.X),(ball.Y - b.Y));
ball.XVel = rel1.X;
ball.YVel = rel1.Y;
rel1 =  GetReflectVector(b.XVel,b.YVel,(ball.X - b.X),(ball.Y - b.Y));
b.XVel = rel1.X;
b.YVel = rel1.Y;
}
}
}
}


  

演示效果如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: