• 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

  • 相关阅读:
    1022-哈夫曼编码与译码
    openresty 学习笔记二:获取请求数据
    openresty 学习笔记一:环境安装
    Lua在Windows下的安装、配置、运行
    Django框架中logging的使用
    死磕nginx系列--使用upsync模块实现负载均衡
    死磕nginx系列--nginx 限流配置
    死磕nginx系列--使用nginx做cache服务
    死磕nginx系列--使用nginx做负载均衡
    死磕nginx系列--nginx服务器做web服务器
  • 原文地址:https://www.cnblogs.com/manuosex/p/2776857.html
Copyright © 2020-2023  润新知