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