win8 开发之旅(18) 足球游戏揭秘4

这节,我们介绍一下DiscoidPosition,TableBorder,Vector2D  这三个类吧.你别开只有这三个类,对这个项目有着至关重要的作用。

①DiscoidPosition——物体的位置的坐标,标记物体的x,y坐标的位置。源代码如下所示:

 1     ///<summary>
 2    /// 物体的位置
 3     /// </summary>
 4     public class DiscoidPosition
 5     {
 6         /// <summary>
 7         /// x坐标
 8         /// </summary>
 9         public double X { get; set; }
10         /// <summary>
11         /// y坐标
12         /// </summary>
13         public double Y { get; set; }
14     }

  这样子,能够定位物体的相应的坐标了,具体情况如图所示:

②TableBorder——字面意思,表面边框的类。这里隐身的意思是,相应物体的边框的类。干什么, 用于碰撞检测和碰撞冲突解决的类,相应的源代码如下:

  1     /// <summary>
  2     /// 表格的边框的属性  边框的属性,用于碰撞检测的类
  3     /// </summary>
  4     public class TableBorder
  5     {
  6         #region attributes
  7         /// <summary>
  8         /// 相应的消息
  9         /// </summary>
 10         public static string message;
 11         //IBallObserver observer;
 12         /// <summary>
 13         /// x坐标
 14         /// </summary>
 15         double x;
 16         /// <summary>
 17         /// y坐标
 18         /// </summary>
 19         double y;
 20         /// <summary>
 21         /// 宽度
 22         /// </summary>
 23         double width;
 24         /// <summary>
 25         /// 高度
 26         /// </summary>
 27         double height;
 28         /// <summary>
 29         /// 位置的向量
 30         /// </summary>
 31         Vector2D position;
 32         /// <summary>
 33         /// 此村的向量
 34         /// </summary>
 35         Vector2D size;
 36         #endregion attributes
 37         /// <summary>
 38         /// 构造函数 进行数据的初始化
 39         /// </summary>
 40         /// <param name="x">x坐标</param>
 41         /// <param name="y">y坐标</param>
 42         /// <param name="width">宽度</param>
 43         /// <param name="height">高度</param>
 44         #region constructor
 45         public TableBorder(int x, int y, int width, int height)
 46         {
 47             //this.observer = observer;
 48             //位置向量的赋值
 49             this.position = new Vector2D(x, y);
 50             //尺寸向量的赋值
 51             this.size = new Vector2D(width, height);
 52         }
 53         #endregion constructor
 54 
 55         #region properties
 56         /// <summary>
 57         /// x坐标
 58         /// </summary>
 59         public double X
 60         {
 61             get { return x; }
 62             set { x = value; }
 63         }
 64         /// <summary>
 65         /// y坐标
 66         /// </summary>
 67         public double Y
 68         {
 69             get { return y; }
 70             set { y = value; }
 71         }
 72         /// <summary>
 73         /// 宽度
 74         /// </summary>
 75         public double Width
 76         {
 77             get { return width; }
 78             set { width = value; }
 79         }
 80         /// <summary>
 81         /// 高度
 82         /// </summary>
 83         public double Height
 84         {
 85             get {  return height; }
 86             set { height = value; }
 87         }
 88         #endregion properties
 89 
 90         #region functions
 91         /// <summary>
 92         /// 进行碰撞检测及碰撞冲突解决的方法
 93         /// </summary>
 94         /// <param name="discoid"></param>
 95         /// <returns></returns>
 96         public RectangleCollision Colliding(Discoid discoid)
 97         {
 98             //默认是没有任何矩形的相交的
 99           RectangleCollision collision = RectangleCollision.None;
101             //x 距离
102             double mediumX = (discoid.LastX + discoid.Position.X) / 2.0;
103            //y距离
104             double mediumY = (discoid.LastY + discoid.Position.Y) / 2.0;
105 
106             //if (!discoid.IsBallInGoal)
107             //{
108             //bool insideWidth = (discoid.X > position.X) && (discoid.X < position.X + size.X);
109             //bool insideHeight = (discoid.Y > position.Y) && (discoid.Y < position.Y + size.Y);
110             //是否在里面的内部
111             bool insideWidth = ((discoid.Position.X > position.X) && (discoid.Position.X < position.X + size.X));
112             //是否在里面的外部
113             bool insideHeight = (discoid.Position.Y > position.Y) && (discoid.Position.Y < position.Y + size.Y);
114 
115             //if ((discoid.X < position.X) && (discoid.X + discoid.Radius > position.X) && (discoid.X - discoid.Radius < position.X + size.X) && insideHeight && (discoid.TranslateVelocity.X + discoid.VSpinVelocity.X > 0))
116             //左方向
117             if ((discoid.LastX < position.X) && (discoid.Position.X + discoid.Radius > position.X) && (discoid.Position.X - discoid.Radius < position.X + size.X) && insideHeight && (discoid.TranslateVelocity.X + discoid.VSpinVelocity.X > 0))
118             {
119                 collision = RectangleCollision.Left;
120             }
121             //else if ((discoid.X > (position.X + size.X)) && (discoid.X - discoid.Radius < position.X + size.X) && (discoid.X + discoid.Radius > position.X) && insideHeight && (discoid.TranslateVelocity.X + discoid.VSpinVelocity.X < 0))
122              //有方向
123             else if ((discoid.LastX + discoid.Radius > position.X + size.X) && (discoid.Position.X - discoid.Radius < position.X + size.X) && (discoid.Position.X + discoid.Radius > position.X) && insideHeight && (discoid.TranslateVelocity.X + discoid.VSpinVelocity.X < 0))
124             {
125                 collision = RectangleCollision.Right;
126             }
127 
128             //if ((discoid.Y < position.Y) && (discoid.Y + discoid.Radius > position.Y) && (discoid.Y - discoid.Radius < position.Y + size.Y) && insideWidth && (discoid.TranslateVelocity.Y + discoid.VSpinVelocity.Y > 0))
129              //顶端的方向
130             if ((discoid.LastY < position.Y) && (discoid.Position.Y + discoid.Radius > position.Y) && (discoid.Position.Y - discoid.Radius < position.Y + size.Y) && insideWidth && (discoid.TranslateVelocity.Y + discoid.VSpinVelocity.Y > 0))
131             {
132                 collision = RectangleCollision.Top;
133             }
134                 //末尾的方向
135             else if ((discoid.Position.Y + discoid.Radius > position.Y + size.Y) && (discoid.Position.Y - discoid.Radius < position.Y + size.Y) && (discoid.Position.Y + discoid.Radius > position.Y) && insideWidth && (discoid.TranslateVelocity.Y + discoid.VSpinVelocity.Y < 0))
136             //else if ((discoid.LastY > (position.Y + size.Y)) && (discoid.Y - discoid.Radius < position.Y + size.Y) && (discoid.Y + discoid.Radius > position.Y) && insideWidth && (discoid.TranslateVelocity.Y + discoid.VSpinVelocity.Y < 0))
137             {
138                 collision = RectangleCollision.Bottom;
139             }
140             //}
141             //最终碰撞的矩形方向
142             return collision;
143        }
144 
145         /// <summary>
146         ///  处理碰撞检测的方法
147         /// </summary>
148         /// <param name="discoid">当前的圆圈的对象</param>
149         /// <param name="collision">碰撞检测的矩形对象</param>
150         public void ResolveCollision(Discoid discoid, RectangleCollision collision)
151         {
152             //合并  的   方缩量
153             double absorption = 0.9f;
154             //  判断上下方向
155             switch (collision)
156             {
157                 case RectangleCollision.Right:
158                 case RectangleCollision.Left:
159                     //dx量
160                     double dX = 0;
161                     //方向是左方
162                     if (collision == RectangleCollision.Left)
163                     {
164                         //  dx=x1+r-x2     相应坐标只差
165                         dX = (discoid.X + discoid.Radius) - this.position.X;
166                     }
167                     else
168                     {
169                          //dx=x1+s-x2-r
170                         dX = (this.position.X + this.size.X ) - (discoid.X + discoid.Radius);
171                     }
172                        //位置x坐标 =x-只差
173                     discoid.Position.X = this.position.X - dX;
174                       //传递的  向量 x坐标  圆圈的xz坐标  坐标大于0的话
175                     if (Math.Sign(discoid.TranslateVelocity.X) == Math.Sign(discoid.VSpinVelocity.X) && discoid.VSpinVelocity.X > 0.0)
176                     {
177                         //圆圈的传递的向量
178                         discoid.TranslateVelocity = discoid.TranslateVelocity.Add(new Vector2D(discoid.VSpinVelocity.X, 0));
179                         //圆圈的spin的  向量
180                         discoid.VSpinVelocity = discoid.VSpinVelocity.Add(new Vector2D(0, discoid.VSpinVelocity.Y));
181                     }
182                     //传递向量的x坐标
183                     discoid.TranslateVelocity.X = discoid.TranslateVelocity.X * (-1.0f * absorption);
184                     break;
185                     //跳出  switch 条件
186                 case RectangleCollision.Bottom:
187                 case RectangleCollision.Top:
188                     //dy循环
189                     double dY = 0;
190                     //如果是顶部
191                     if (collision == RectangleCollision.Top)
192                     {
193                         //dy=y1+r-y2;
194                         dY = (discoid.Y + discoid.Radius) - this.position.Y;
195                     }
196                         //dy=y1-y2-r
197                     else
198                     {
199                         dY = this.position.Y - (discoid.Y + discoid.Radius);
200                     }
201                     //y的距离
202                     discoid.Position.Y = this.position.Y - dY;
203                    //速度相对的话 就赋值给相应传递的 向量
204                     if (Math.Sign(discoid.TranslateVelocity.Y) == Math.Sign(discoid.VSpinVelocity.Y) && discoid.VSpinVelocity.Y > 0.0)
205                     {
206                         discoid.TranslateVelocity = discoid.TranslateVelocity.Add(new Vector2D(0, discoid.VSpinVelocity.Y));
207                         discoid.VSpinVelocity = discoid.VSpinVelocity.Add(new Vector2D(discoid.VSpinVelocity.X, 0));
208                     }
209                     //向量的y轴  的赋值
210                     discoid.TranslateVelocity.Y = discoid.TranslateVelocity.Y * (-1.0f * absorption);
211                     break;
212 
213             }
214         }
215         /// <summary>
216         /// 重写了tostring的方法
217         /// </summary>
218         /// <returns></returns>
219         public override string ToString()
220         {
221             return string.Format("TableBorder({0}, {1}, {2}, {3})", position.X, position.Y, position.X + size.X, position.Y + size.Y);
222         }
223 
224         //public override void Draw(SpriteBatch spriteBatch, Vector2D offset)
225         //{
226         //    Vector2D position = new Vector2D(this.position.X + offset.X, this.position.Y + offset.Y);
227         //    Color color = new Color(255, 255, 255, 255);
228         //    spriteBatch.Draw(texture, position, new Rectangle(0, 0, (int)size.X, (int)size.Y), color, 0f, new Vector2D(0, 0), (1.0f / 1.0f), SpriteEffects.None, 0f);
229         //}
230 
231         #endregion functions
232     }

我这里解决的碰撞检测的类,是通过x,y方法来判断他是否碰撞。具体情况如图所示:判断他的坐标之差与其相应的方向的坐标进行比较,最终来获取相应的方向,最后进行了碰撞解决的方案,就是赋给其向量值(其实物理的中和速度的概念),这里有两个合速度,一个运行的合速度,一个是旋转的合速度。具体情况,如图所示:

③Vector2D——向量类,判断相应合速度的类,具体源代码如下:

  1     /// <summary>
  2     /// 2D画图的类
  3     /// </summary>
  4     public class Vector2D
  5     {
  6         #region attributes
  7         /// <summary>
  8         /// x坐标
  9         /// </summary>
 10         private double x;
 11         /// <summary>
 12         /// y坐标
 13         /// </summary>
 14         private double y;
 15         #endregion attributes
 16 
 17         /// <summary>
 18         /// 构造函数 进行数据的初始化
 19         /// </summary>
 20         /// <param name="vx">x轴的速度</param>
 21         /// <param name="vy">y轴的速度</param>
 22         #region constructor
 23         public Vector2D(double vx, double vy)
 24         {
 25             //x轴的速度
 26             this.x = vx;
 27             //y轴的速度
 28             this.y = vy;
 29         }
 30 
 31         /// <summary>
 32         /// 构造函数
 33         /// </summary>
 34         /// <param name="v">向量的对象</param>
 35         public Vector2D(Vector2D v)
 36         {
 37             //x轴的速度
 38             this.x = v.x;
 39             //y轴的速度
 40             this.y = v.y;
 41         }
 42         #endregion constructor
 43 
 44         #region properties
 45         /// <summary>
 46         /// x轴速度的多少
 47         /// </summary>
 48         public double X
 49         {
 50             get { return x; }
 51             set
 52             {
 53                 //x小于150000
 54                 if (x<=15000)
 55                 {
 56                     x = value;
 57                 }
 58 
 59              
 60             }
 61         }
 62         /// <summary>
 63         /// y轴速度的多少
 64         /// </summary>
 65         public double Y
 66         {
 67             get {  return y; }
 68             set { y = value; }
 69         }
 70         #endregion properties
 71 
 72         #region functions
 73         /// <summary>
 74         /// 添加的方法 
 75         /// </summary>
 76         /// <param name="lhs">lhs向量</param>
 77         /// <param name="rhs">rhs向量</param>
 78         /// <returns>向量的方法</returns>
 79         public Vector2D Add(Vector2D lhs, Vector2D rhs)
 80         {
 81             Vector2D result = new Vector2D(lhs);
 82             //x  轴变化
 83             result.x = result.x + rhs.x;
 84             //y轴 的变化
 85             result.y = result.y + rhs.y;
 86             //返回结果
 87             return (result);
 88         }
 89         /// <summary>
 90         /// 进行添加的方法
 91         /// </summary>
 92         /// <param name="v">第一个向量对象</param>
 93         /// <returns>当前向量的对象</returns>
 94         public Vector2D Add(Vector2D v)
 95         {
 96              //当前的向量的对象 
 97              Vector2D result = new Vector2D(this);
 98             //x轴的变化
 99             result.X = result.X + v.X;
100             //y轴的变化
101             result.Y = result.Y + v.Y;
102             //返回结果
103             return (result);
104         }
105         /// <summary>
106         /// 进行添加的方法
107         /// </summary>
108         /// <param name="f">当前的值</param>
109         /// <returns>当前向量的对象</returns>
110         public Vector2D Add(float f)
111         {
112             //当前的向量的对象
113             Vector2D result = new Vector2D(this);
114             //x轴的变化
115             result.x = result.x + f;
116             //Y轴的变化
117             result.y += f;
118             //返回结果
119             return (result); 
120         }
121 
122         /// <summary>
123         /// 进行的相减的方法
124         /// </summary>
125         /// <param name="lhs">向量1</param>
126         /// <param name="rhs">向量2</param>
127         /// <returns>当前向量的对象</returns>
128         public Vector2D Subtract(Vector2D lhs, Vector2D rhs)
129         {
130             //当前的向量的对象
131             Vector2D result = new Vector2D(lhs);
132             //x轴的变化
133             result.x = result.x - rhs.x;
134             //y周的变化
135             result.y = result.y - rhs.y;
136             //返回结果
137             return(result);
138         }
139 
140         /// <summary>
141         /// 进行相见的方法
142         /// </summary>
143         /// <param name="v">向量</param>
144         /// <returns>当前向量的对象</returns>
145         public Vector2D Subtract(Vector2D v)
146         {
147             //向量的对象
148             Vector2D result = new Vector2D(this);
149             //x轴变化
150             result.X = result.X - v.X;
151             //y周的变化
152             result.Y = result.Y - v.Y;
153             //返回结果
154             return (result);
155         }
156 
157         /// <summary>
158         /// 想成的方法
159         /// </summary>
160         /// <param name="lhs">lh的浮点数</param>
161         /// <param name="rhs">向量的方法</param>
162         /// <returns>想成的方法</returns>
163         public Vector2D Multiply(double lhs, Vector2D rhs)
164         {
165             //向量对象
166             Vector2D result = new Vector2D(rhs);
167             //x坐标变化
168             result.x = result.x * lhs;
169             //y坐标的变化
170             result.Y = result.Y * lhs;
171            //返回结果
172             return (result);
173         }
174         /// <summary>
175         /// 进行象呈的方法
176         /// </summary>
177         /// <param name="lhs">向量对象</param>
178         /// <param name="rhs">浮点变量</param>
179         /// <returns>最后的对象</returns>
180         public Vector2D Multiply(Vector2D lhs, double rhs)
181         {
182             //向量的对象
183             Vector2D result = new Vector2D(lhs);
184             //香橙的方法
185             result.x *= rhs;
186             result.y *= rhs;
187             //返回对象
188             return (result);
189         }
190 
191 
192         public Vector2D Multiply(double d)
193         {
194             Vector2D result = new Vector2D(this);
195             result.x *= d;
196             result.y *= d;
197             return (result);
198         }
199         /// <summary>
200         /// 相应的长度
201         /// </summary>
202         /// <returns></returns>
203         public float Length()
204         {
205             //长度
206             float ret = (float)(Math.Sqrt(Math.Pow(this.x, 2) + Math.Pow(this.y, 2)));
207             //最后的结果
208             return ret;
209         }
210         /// <summary>
211         /// 最终的结果
212         /// </summary>
213         /// <param name="v"></param>
214         /// <returns></returns>
215         public float Dot(Vector2D v)
216         {
217             //最终的结果
218             return ((float)(x * v.X + y * v.Y));
219         }
220         /// <summary>
221         /// 普通的放缩
222         /// </summary>
223         /// <returns></returns>
224         public Vector2D Normalize()
225         {
226             //长度
227             float l = Length();
228             Vector2D result = new Vector2D(this);
229            
230             result.x = result.x / l;
231             result.y = result.y / l;
232             //最终的结果
233             return result;
234         }
235         #endregion functions
236     }

 这是一个模拟数据中的向量加减乘除的类,你会问我向量的加减乘除对这个游戏有什么作用。

加——两个向量的x坐标,y坐标相加生成新的向量。  进行静态物体碰撞有重要的作用。

减——两个向量的x坐标,y坐标相间生成新的向量。进行反响向量碰撞有重要作用。

乘——向量的x坐标,y坐标相乘生成新的向量。 在踢球的过程中有重要的作用。

除——两个向量的x坐标,y坐标相除生成新的向量。

今天,我们把这几个类学习完了,其他的类后面再说。源代码地址:http://51aspx.com/Code/ZCWWorldCupV10

原文地址:https://www.cnblogs.com/manuosex/p/2776857.html