В итоге я выбрал вариант 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, и как проверить, уничтожена ли вся плитка.
При использовании этой техники все субтили будут иметь одинаковую текстуру. Пока я не могу придумать более простого решения.