zoukankan      html  css  js  c++  java
  • [翻译]XNA系列教程 2D碰撞教程2:像素检测

    PS:转自__Vincent Zhang__的文章

    2D碰撞教程2:像素检测

    本教程详细讲解了像素碰撞检测的实现

    这个教程的代码是在前一个教程:2D碰撞教程1:矩形检测中实现的,在进行下面的教程前请确保已经完成教程1的学习。

    绪论
          在前一个例子当中,你已经通过举行碰撞检测实现了一个躲避下落物体游戏。而矩形只是通过你加载的纹理贴图的大小来决定的,并不能准确的代表你的游戏角色的大小,因此在游戏当中你会发现出现一些误差。例如,在这种情况下游戏角色并没有碰到下落的物体,但是背景却指示为游戏角色已经被下落的物体击中。这是由于在这种情况下两个纹理贴图出现了重合,而矩形的检测就认为两者已经产生了碰撞。
         我们期望的情况在没有被下落物体击中,即便是纹理贴图相互重合也认为游戏角色没有被集中。
        为了达到上述的目标,我们的代码必须能够做到只有在物体像素产生碰撞之后再响应碰撞,这个就叫做像素检测。

    第一步:取得纹理数据
         像素检测需要得到每一个纹理贴图的像素数据,为了访问每一个像素,我们必须调用Texture2D.GetData。通过这个方法你可以将纹理贴图的数据复制到你所定义的一个数组,当然数组的格式为默认的Color类型。

         1. 首先,你需要在game类中为每一个贴图声明Color数组。

    1 // The color data for the images; used for per-pixel collision
    2 Color[] personTextureData;
    3 Color[] blockTextureData;

        2.之后,使用Texture2D.GetData方法将贴图中的每一个像素复制到你所定义的数组当中。当然,这一步必须当纹理贴图加载之后。在LoadGraphicsContent方法中添加下面粗体代码。

    1 // Load textures
    2 blockTexture = content.Load<Texture2D>("Content/Block");
    3 personTexture = content.Load<Texture2D>("Content/Person");
    4 // Extract collision data
    5 blockTextureData =    new Color[blockTexture.Width * blockTexture.Height];
    6 blockTexture.GetData(blockTextureData);personTextureData =    new Color[personTexture.Width * personTexture.Height];
    7 personTexture.GetData(personTextureData);

         3. 对每一个纹理贴图你都需要分配一个color数组,这个数据是一维的,也就是说贴图的颜色数据会按照顺序依次存储到这个数组当中。一旦这个数组的空间被分配,那么GetData函数会将纹理贴图中的像素数据填充入这个数组当中。

    第二步:像素检测的实现
    现在你已经有了所需要的数据,那么根据这些数据你可以完成像素碰撞检测。这个方法首先需要一对纹理题图的包围矩形和他们的颜色数据。

         1. 首先,将下面的方法添加到你的代码当中。

    1 static bool IntersectPixels(Rectangle rectangleA, Color[] dataA,Rectangle rectangleB, Color[] dataB)

        2.这个方法主要包括两个部分,第一,他将识别出两个包围矩形的重合部分,这个重合区域也许存在,也许不存在。第二,这个方法会循环的检测重合区域的像素颜色,如果发现物体的像素产生了碰撞,那么这个方法将返回true,如果经过对像素的检测没有发现碰撞,那么将返回false。

       3. 将下面的代码添加到IntersectPixels方法当中。

    Code

         4.  这四个变量定义了矩形重合的区域。如果没有重合区域的话,right的值会小于left或者bottom的值会小于top,或者这两种情况同时存在。我们通过一个嵌套的for循环来自动判断是否有重合区域。

         5. 将下面的代码依次添加如上面的方法。

    Code

    这个for循环会依照从左至右,从上到下的顺序读取每一个像素的颜色,我们需要将矩形的世界坐标转换为本地坐标。我们对本地坐标进行判断,如果两者都不是0(0代表透明)的话,那么则可以判断出现了碰撞。

    注意
    在教程1当中我们已经讲过纹理处理器会自动将洋红色转换为透明色。

    第三步:调用像素碰撞检测
    现在你已经完成了像素碰撞检测的方法,你需要在原有的举行碰撞的地方调用这个方法。

        1.在Updata方法中修改代码如下。

    Code

         2.好了,编译并运行这个游戏。

         恭喜你!
    你现在已经掌握了像素碰撞检测的技能了。

  • 相关阅读:
    C#之app.config、exe.config和vshost.exe.config作用区别
    C#中decimal ,double,float的区别
    C#中取整,向上取,向下取
    mybatis中的#和$的区别
    mybatis在xml文件中处理大于号小于号的方法
    ORACLE分页查询SQL语法——高效的分页
    移除powerdesigner中Recent Files中无效链接的文件
    Visual Studio提示“无法启动IIS Express Web服务器”的解决方法
    ORA-12638: 身份证明检索失败 的解决办法
    态度决定一切《跟任何人都聊得来》
  • 原文地址:https://www.cnblogs.com/315358525/p/1522944.html
Copyright © 2011-2022 走看看