4

我将 XNA 用于 2D 项目。我有一个问题,我不知道用什么方法来解决它。我有一个被绘制到屏幕上的纹理(图像),例如:

|+++|+++|
|---|---|
|+++|+++|

现在我希望能够破坏该结构/图像的一部分,使其看起来像:

|+++|
|---|---|
|+++|+++|

所以现在的碰撞也适用于新图像。

哪种方式会更好地解决这个问题:

  1. 用另一个纹理交换整个纹理,在它被破坏的地方是透明的。
  2. 对 spriteBatch.Draw(sourceRectangle,destinationRectangle) 使用一些技巧来绘制所需的矩形,并以某种方式对此进行碰撞检查。
  3. 将纹理拆分为 4 个较小的纹理,每个纹理将负责其自己的绘图/碰撞检测。
  4. 使用我不知道的其他一些聪明的方法。

任何帮助,将不胜感激。如果您需要更多说明/示例,请告诉我。

编辑:为了澄清,我将为此提供一个使用示例。想象一堵 4x4 的墙,当被射击时,它的一小部分 1x1 被摧毁。

4

4 回答 4

1

我会选择第三个选项:

3 - 将纹理拆分为 4 个较小的纹理,每个纹理负责自己的绘图/碰撞检测。

这并不难。基本上它与 TileSet 结构相同。但是,您需要更改代码以适应这种方法。阅读有关 Tiles 的一些信息:http ://www-cs-students.stanford.edu/~amitp/gameprog.html#tiles 许多网站和书籍都谈到了 Tiles 以及如何使用它来构建游戏世界。但是你可以使用这个逻辑来处理整个由小部分堆肥的所有东西。

让我快速记下其他选项:

1 - 用另一个纹理交换整个纹理,在它被破坏的地方是透明的。

不..对每个不同的位置都有不同的形象是不好的。如果你需要改变纹理?你会重新制作每张照片吗?

2 - 对 spriteBatch.Draw(sourceRectangle,destinationRectangle) 使用一些技巧来绘制所需的矩形,并以某种方式对此进行碰撞检查。

不幸的是,它不起作用,因为 spriteBatch.Draw 仅适用于 Rectangles :(

4使用我不知道的其他一些聪明的方法。

我无法想象这有什么魔力。也许,您可以使用其他图像制作蒙版。但它的处理成本非常高。

于 2009-04-30T01:09:58.207 回答
0

在 Ziggyware 上查看这篇文章。它是关于Deformable Terrain的,可能是您正在寻找的。本质上,该技术涉及将要隐藏的像素设置为透明。

于 2009-04-29T23:10:57.820 回答
0

选项#3 将起作用。

一个更健壮的系统(如果您不想局限于盒子)将使用每像素碰撞检测。该过程基本上如下工作:

  1. 计算每个对象的边界框(或圆)
  2. 检查两个对象是否重叠
  3. 对于每个重叠,将精灵 blit 到隐藏的表面上,同时比较像素值。如果在您尝试从第二个精灵绘制像素时已经设置了一个像素,那么您就会发生碰撞。

这是一个很好的 XNA 示例(实际上是另一篇 Ziggyware 文章):2D Per Pixel Collision Detection

更多链接:

有人可以解释每像素碰撞检测吗

XNA 2-d 每像素碰撞

于 2009-04-30T02:04:09.667 回答
0

我最终选择了选项 3。基本上我有一个包含纹理和尺寸的 Tile 类。维度 n 表示该图块中有 n*n 个子图块。我还有一个数组可以跟踪哪些瓷砖被破坏了。我的类在伪代码中看起来像这样:

 class Tile
     texture
     dimention
     int [,] subtiles; //0 or 1 for each subtile

     public Tile() // constructor
         subtiles = new int[dimention, dimention];
         intialize_subtiles_to(1);

     public Draw() // this is how we know which one to draw
        //iterate over subtiles
        for(int i..
          for(int j ...)
             if(subtiles[i,j] == 1)
                Vector2 draw_pos = Vector2(i*tilewidth,
                                      j*tileheight)                       
                spritebatch.Draw(texture, draw_pos)

以类似的方式,我有一个碰撞方法来检查碰撞:

   public bool collides(Rectangle rect)
       //iterate over subtiles 
       for i...
          for j..
              if(subtiles[i,j]==0) continue;

              subtile_rect = //figure out the rect for this subtile
              if(subtile_rect.intersects(rect))
                   return true;

       return false;

等等。您可以想象如何通过将它们各自的值设置为 0 来“破坏”某些子图块,以及如何检查整个图块是否被破坏。使用这种技术,子图块将具有相同的纹理。到目前为止,我想不出更简单的解决方案。

于 2009-05-04T12:37:49.580 回答