2

我不想检查径向元素的碰撞。

问题是,目前我只将像素检查为矩形,因为其他图像是原生的 HTML 元素。

我只使用画布绘制边界背景来检查 alpha 透明度。

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;
};

预习

在此处输入图像描述

这是一个工作小提琴:

https://jsfiddle.net/2bLfd6xp/

我如何选择一个径向像素范围getImageData来检查与 alpha 透明度的碰撞boundary.png

我的想法是从这里修改像素数据数组:

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

并删除不可见的edges. 但是,从基于矩形的像素阵列计算径向区域以移除这些不需要的像素的最佳做法是什么?

样品:

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;
}
4

1 回答 1

2

我用逻辑思维找到了答案:

首先,我们创建一个临时的可绘制上下文并在这个新区域中绘制两个元素:

  • 一个红色矩形
  • 带有目的地的透明弧/圆 -复合

结果Uint8ClampedArray将与原始结果进行比较。如果该区域是RED,我们使用null条目隐藏像素: Uint8ClampedArray

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;
};

当我们尝试思考时,这很容易:)

    var image   = _context.getImageData(_position.x - (height / 2), _position.y - (width / 2), width, height);
    var pixels  = this.rectangleToRadial(image, width, height);
于 2017-10-14T15:36:03.780 回答