|
这节,我们介绍一下DiscoidPosition,TableBorder,Vector2D 这三个类吧.你别开只有这三个类,对这个项目有着至关重要的作用。
①DiscoidPosition——物体的位置的坐标,标记物体的x,y坐标的位置。源代码如下所示:
1 ///
2 /// 物体的位置
3 ///
4 public class DiscoidPosition
5 {
6 ///
7 /// x坐标
8 ///
9 public double X { get; set; }
10 ///
11 /// y坐标
12 ///
13 public double Y { get; set; }
14 }
这样子,能够定位物体的相应的坐标了,具体情况如图所示:
②TableBorder——字面意思,表面边框的类。这里隐身的意思是,相应物体的边框的类。干什么, 用于碰撞检测和碰撞冲突解决的类,相应的源代码如下:
1 ///
2 /// 表格的边框的属性 边框的属性,用于碰撞检测的类
3 ///
4 public class TableBorder
5 {
6 #region attributes
7 ///
8 /// 相应的消息
9 ///
10 public static string message;
11 //IBallObserver observer;
12 ///
13 /// x坐标
14 ///
15 double x;
16 ///
17 /// y坐标
18 ///
19 double y;
20 ///
21 /// 宽度
22 ///
23 double width;
24 ///
25 /// 高度
26 ///
27 double height;
28 ///
29 /// 位置的向量
30 ///
31 Vector2D position;
32 ///
33 /// 此村的向量
34 ///
35 Vector2D size;
36 #endregion attributes
37 ///
38 /// 构造函数 进行数据的初始化
39 ///
40 /// x坐标
41 /// y坐标
42 /// 宽度
43 /// 高度
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 ///
57 /// x坐标
58 ///
59 public double X
60 {
61 get { return x; }
62 set { x = value; }
63 }
64 ///
65 /// y坐标
66 ///
67 public double Y
68 {
69 get { return y; }
70 set { y = value; }
71 }
72 ///
73 /// 宽度
74 ///
75 public double Width
76 {
77 get { return width; }
78 set { width = value; }
79 }
80 ///
81 /// 高度
82 ///
83 public double Height
84 {
85 get { return height; }
86 set { height = value; }
87 }
88 #endregion properties
89
90 #region functions
91 ///
92 /// 进行碰撞检测及碰撞冲突解决的方法
93 ///
94 ///
95 ///
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 ///
146 /// 处理碰撞检测的方法
147 ///
148 /// 当前的圆圈的对象
149 /// 碰撞检测的矩形对象
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 ///
216 /// 重写了tostring的方法
217 ///
218 ///
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 ///
2 /// 2D画图的类
3 ///
4 public class Vector2D
5 {
6 #region attributes
7 ///
8 /// x坐标
9 ///
10 private double x;
11 ///
12 /// y坐标
13 ///
14 private double y;
15 #endregion attributes
16
17 ///
18 /// 构造函数 进行数据的初始化
19 ///
20 /// x轴的速度
21 /// y轴的速度
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 ///
32 /// 构造函数
33 ///
34 /// 向量的对象
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 ///
46 /// x轴速度的多少
47 ///
48 public double X
49 {
50 get { return x; }
51 set
52 {
53 //x小于150000
54 if (x |
|
|