2017-10-14 16 views
2

Je ne voulais pas vérifier la collision des éléments radiaux. Le problème est, actuellement je vérifie seulement les pixels comme un rectangle parce que les autres images sont natives avec les éléments HTML. Je n'utilise que le canevas pour dessiner l'arrière-plan des limites pour vérifier la transparence alpha.Détecter radial Pixel

this.checkCollision = function checkCollision() { 
    var width = 34; 
    var height = 32; 
    var image = _context.getImageData(_position.x - (height/2), _position.y - (width/2), width, height); 
    var pixels = image.data; 
    var size = image.data.length; 

    // HERE I WANT TO CHECK A RADIAL AREA 
    for(var index = 0; index < size; index += 4) { 
     var RED  = image.data[index]; 
     var GREEN = image.data[index + 1]; 
     var BLUE = image.data[index + 2]; 
     var ALPHA = image.data[index + 3]; 

     if(_debug) { 
      document.querySelector('#debug').innerHTML = JSON.stringify({ 
       POSITION: _position, 
       INDEX:  index, 
       COLOR: { 
        R: RED, 
        G: GREEN, 
        B: BLUE, 
        A: ALPHA 
       } 
      }, 0, 1); 
     } 

     if(ALPHA !== 0) { 
      return true; 
     } 
    } 
    _context.putImageData(image, 0, 0); 
    return false; 
}; 

Aperçu

enter image description here

est ici un travail Fiddle:

https://jsfiddle.net/2bLfd6xp/

Comment puis-je sélectionner une plage de pixels radiale sur getImageData pour vérifier la collision avec le alpha-transparence du boundary.png?

Mon idée est de modifier le tableau de données de pixels d'ici:

var image = _context.getImageData(_position.x - (height/2), _position.y - (width/2), width, height); 

et retirez la edges invisible. Mais quelle est la meilleure pratique pour calculer à partir d'un réseau de pixels basé sur un rectangle une zone radiale pour supprimer ces pixels indésirables?

échantillon:

var image = _context.getImageData(_position.x - (height/2), _position.y - (width/2), width, height); 

var radial_area = selectRadialArea(image, radius); 

function selectRadialArea(pixelArray, radius) { 
    /* 
     Modify `pixelArray` with given `radius`... 
     All pixels outside the `radius` filled with `null`... 
    */ 
    return theNewArray; 
} 

Répondre

2

J'ai trouvé la réponse avec la pensée logique:

D'abord, nous créons un contexte drawable temporaire et puisons dans ce nouveau domaine: deux elemengts

  • an rouge rectangle
  • un arc/cercle transparent avec destination -composite

Le Uint8ClampedArray a donné lieu sera par rapport avec le d'origineUint8ClampedArray. Si la zone est ROUGE, nous cachons les pixels avec null -entries:

this.rectangleToRadial = function rectangleToRadial(source, width, height) { 
    var test  = document.createElement('canvas'); 
    var context  = test.getContext('2d'); 

    // Create an transparent circle and a red removeable area 
    context.beginPath(); 
    context.fillStyle = 'rgba(255, 0, 0, 1)'; 
    context.fillRect(0, 0, width, height); 
    context.globalCompositeOperation = 'destination-out'; 
    context.arc(width/2, height/2, width/2, 0, 2 * Math.PI); 
    context.fillStyle = 'rgba(0, 0, 0, 1)'; 
    context.fill(); 

    // get the data 
    var destination = context.getImageData(0, 0, width, height); 
    var size  = destination.data.length; 

    // check the pixels 
    for(var index = 0; index < size; index += 4) { 
     var RED  = destination.data[index]; 
     var GREEN = destination.data[index + 1]; 
     var BLUE = destination.data[index + 2]; 
     var ALPHA = destination.data[index + 3]; 

     /* 
      if the >>red removeable area<< is given, null the pixel from the source 
     */ 
     if(RED == 255 && GREEN == 0 && BLUE == 0) { 
      // Remove this from source 
      source.data[index]  = null; 
      source.data[index + 1] = null; 
      source.data[index + 2] = null; 
      source.data[index + 3] = null; 
     } 
    } 

    // Return the source `Uint8ClampedArray` 
    return source; 
}; 

Il était facile, quand nous essayons de penser :)

var image = _context.getImageData(_position.x - (height/2), _position.y - (width/2), width, height); 
    var pixels = this.rectangleToRadial(image, width, height);