Dinamicamente alterar ou destruir um Texture2D para o desenho e detecção de colisão

StackOverflow https://stackoverflow.com/questions/795673

  •  18-09-2019
  •  | 
  •  

Pergunta

Eu estou usando XNA para um projeto 2D. Eu tenho um problema e eu não sei qual o caminho para resolvê-lo. Eu tenho uma textura (uma imagem) que é desenhado na tela, por exemplo:

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

Agora, eu quero ser capaz de destruir parte dessa estrutura / imagem para que ela se parece com:

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

para que colisão agora vai funcionar tão bem para a nova imagem.

Que maneira seria melhor para resolver este problema:

  1. troca de toda a textura com outra textura, que é transparente nos locais onde ele é destruído.
  2. Use alguns truques com spriteBatch.Draw (sourceRectangle, destinationRectangle) para obter os retângulos desejados tirada, e também fazer a verificação de colisão com isso de alguma forma.
  3. Split a textura em 4 texturas menores cada um dos quais será responsável pela sua detecção próprio desenho / colisão.
  4. Use algum outro espertinho maneira que eu não sei sobre.

Qualquer ajuda seria apreciada. Deixe-me saber se você precisar de mais esclarecimentos / exemplos.

EDIT: Para esclarecer eu vou dar um exemplo de uso para isso. Imagine um pedaço 4x4 da parede que quando tiro em, uma pequena parte 1x1 de que ele seja destruído.

Foi útil?

Solução 4

acabei opção 3 escolher. Basicamente, eu tenho uma classe Tile que contém uma textura e dimention. Dimensão n significa que existem n * n subtiles dentro desse telha. Eu também tenho uma matriz que mantém o controle do que as telhas são destruídos ou não. Minha classe olhares como este em pseudo-código:

 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)

De forma semelhante Eu tenho um método colisão que irá verificar se há colisão:

   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;

E assim por diante. Você pode imaginar como "destruir" certas subtiles, definindo o respectivo valor para 0, e como verificar se toda a telha é destruído. Concedido com esta técnica, os subtiles todos terão a mesma textura. Até agora eu não consigo pensar em uma solução mais simples.

Outras dicas

Vou levar o terceira opção:

3 - Split a textura em 4 menor texturas cada um dos quais será responsável por seu próprio desenho / detecção de colisão.

Não é difícil fazer para. Basicamente é a mesma coisa de Tileset struct. No entanto, você precisará alterar seu código para caber esta abordagem. Leia um pouco sobre telhas em: http: // www-CS- students.stanford.edu/~amitp/gameprog.html#tiles Muitos sites e reserve dito sobre Telhas e como usá-lo para construir mundos do jogo. Mas você pode usar esta lógica de tudo o que o todo é composto a partir de pequenas peças.

Deixe-me rápida notar as outras opções:

1 - Swap a textura inteira com outra textura, que é transparente nos locais onde ele é destruído.

Não .. ter uma imagem diferente para cada posição diferente é ruim. Se você precisa mudar de textura? você vai refazer todas as imagens novamente?

2 - Use alguns truques com spriteBatch.Draw (sourceRectangle, destinationRectangle) para obter o retângulos desejados tirada, e também fazer verificação de colisão com isso de alguma forma.

Infelizmente é não funcionam porque spriteBatch.Draw só funciona com retângulos: (

4 Use alguma outra forma espertinho eu não conhecer.

Eu não posso imaginar qualquer mágica para isso. Talvez, você pode usar uma outra imagem para fazer máscaras. Mas é extremamente processando-caro.

Confira este artigo na Ziggyware. Trata-se de deformáveis ??Terrain , e pode ser o que você está procurando. Essencialmente, a técnica envolve configurações os pixels que você deseja ocultar a transparente.

Opção # 3 vai funcionar.

Um sistema mais robusto (se você não quer ser limitada a caixas) usaria a detecção de colisão per-pixel. O processo funciona basicamente da seguinte forma:

  1. Calcular uma caixa delimitadora (ou círculo) para cada objecto
  2. Verifique se dois objetos se sobrepõem
  3. Para cada sobreposição, blit os sprites em uma superfície oculta, comparando valores de pixel que você vá. Se um pixel já está definido quando você tentar desenhar o pixel a partir do segundo sprite, você tem uma colisão.

Aqui está um exemplo bom XNA (outro artigo Ziggyware, na verdade): 2D por pixel Collision detecção

Alguns mais links:

alguém pode explicar por pixel detecção de colisão

XNA 2-d por pixel colisão

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top