用于检测颜色冲突的getImageData不起作用

时间:2014-11-19 20:41:26

标签: javascript arrays html5 for-loop html5-canvas

我正在尝试编写一个getImageData,因此每当我的汽车撞到轨道的黑色部分时,就会发出警报。然而,它不起作用,因为汽车继续前进。

有人可以帮我弄清楚getImageData数组并可能修复我的代码吗?

//Setting the canvas and context
    var canvas = document.getElementById('gameCanvas');
    var context = canvas.getContext('2d');
    //Uploading car
    var car = new Image();
    car.src = "file:///H:/Desktop/Game/img/car.png";

    //Setting properties of car
    var x = 450;
    var y = 730;
    var speed = 10;
    var angle = 990;
    var mod = 0;

    //Event listeners for keys
    window.addEventListener("keydown", keypress_handler, false);
    window.addEventListener("keyup", keyup_handler, false);

    //Interval for animation
    var moveInterval = setInterval(function () {
        draw();
    }, 30);

    //Drawing the car turning and changing speed
    function draw() {
        context.clearRect(0, 0, canvas.width, canvas.height);

        x += (speed * mod) * Math.cos(Math.PI / 180 * angle);
        y += (speed * mod) * Math.sin(Math.PI / 180 * angle);

        context.save();
        context.translate(x, y);
        context.rotate(Math.PI / 180 * angle);
        context.drawImage(car, -(car.width / 2), -(car.height / 2));
        context.restore();
    }

    //Setting the keys
    function keyup_handler(event) {
        console.log('a');
        if (event.keyCode == 38 || event.keyCode == 40) {

            mod = 0;
        }
    }

    //Setting all of the keys
    function keypress_handler(event) {
        console.log(event.keyCode);
        if (event.keyCode == 38) {
            mod = 1;
        }
        if (event.keyCode == 40) {
            mod = -1;
        }
        if (event.keyCode == 37) {
            angle -= 5;
        }
        if (event.keyCode == 39) {
            angle += 5;
        }
    }

    //INSERT COLOUR DETECTION CODE TEST
    (function () {
        var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
        window.requestAnimationFrame = requestAnimationFrame;
    })();

    function collideTest(){
        var stopColour = context.getImageData(x - 5, y - 5,60,60);
        for (var i = 0; i < stopColour.data.length; i += 4) {
            if (stopColour.data[i] == 190707) {
                alert("black");
            }
        }
    }

    function render(){

        var canvas = document.getElementById('gameCanvas');
        var context = canvas.getContext('2d');

        var car = new Image();
        car.src = "file:///H:/Desktop/Game/img/car.png";

        requestAnimationFrame(render);
    }

2 个答案:

答案 0 :(得分:1)

imagedata数组是一个数组,其中每个条目的值介于0到255之间(4个数组条目表示一个RGBA像素)。我不知道你究竟是怎么想出数字190707的,但是stopColour.data[i] == 190707永远不会是true,因为你不会遇到数组中255以上的值。

如果要在所有三个颜色通道上检查具有特定颜色的匹配项,则需要检查三个值。

var collision_red = // red-part of your collision color between 0 and 255
var collision_green = // green-part of your collision color between 0 and 255
var collision_blue = // blue-part of your collision color between 0 and 255

// ...

if ( stopColour.data[i + 0] == collision_red &&
     stopColour.data[i + 1] == collision_green &&
     stopColour.data[i + 2] == collision_blue ) {

     // collision
}

顺便说一句:它不是依赖于颜色键控,而是检查重叠的不可见几何形状(“边界框”或“边界圆”),它通常更加强大且性能友好。

答案 1 :(得分:0)

以下不是直接与您的问题相关,但是根据所述问题的相关性,以使用getImageData()进行碰撞检测为中心,这也是我最近尝试过的一项任务。如果您项目的未来更新包括使用翻译的坐标,那么这将立即 相关。

必须发出关于在HTML5画布上使用getImageData()和putImageData()的警告。其中心是通过translate()方法使用平移坐标。

虽然大多数绘图方法使用生成的平移坐标系,但getImageData()和putImageData()不要使用该平移坐标系,而是始终使用标准坐标系,(0,0)位于画布的左上角!我发现这很困难,尝试使用getImageData()进行简单的碰撞检测算法,并想知道为什么在测试期间选择已知的坐标作为画布上渲染图像的一部分,返回像素值[0,0,0,0],而不是真实的像素值。之所以发生这种情况,是因为翻译的坐标系用于引用相关像素。当坐标改变为在标准坐标系中应用的坐标时,正确检测到所需的数据。

然而,为了增加混乱,drawImage() DOES 使用translate()设置翻译后的坐标!

如果getImageData()在返回对象中出现看似奇怪的数据,则在使用translate()实现转换坐标系时,这就是原因。这意味着必须保存标准坐标系中画布的翻译原点的坐标,并将那些保存的原始坐标添加到的坐标值中翻译坐标系。这是一个非常简单的测试,说明了这一点:

<html>
<head>

</head>

<body>

<canvas id="MyCanvas" width="401" height="401" style="background-color: rgba(0, 0, 0, 0); border: 1px solid rgba(0, 255, 0, 1);">

</body>

<script language="JavaScript">

//Get my canvas handle and 2d plotting context ...

myCanvas = document.getElementById("MyCanvas");
myCanvasCtx = myCanvas.getContext("2d");

//Get the centre of your canvas in standard coordinates
//with (0, 0) at the top left hand corner ...

cx = Math.floor(myCanvas.width/2);
cy = Math.floor(myCanvas.height/2);

//Translate the origin for drawing to this central position ...

myCanvasCtx.translate(cx, cy);

//Do some image plotting here, using your new translated coordinates ... for this quick example,
//I'll simply plot some pixels using the usual path routines ...

tx = 0;    //origin AFTER translation, which is now in the centre
ty = 0;    //of the canvas

myCanvasCtx.strokeStyle = "rgba(255, 0, 255, 1)";    //set magenta foreground colour

myCanvasCtx.beginPath();
myCanvasCtx.moveTo(tx, ty);
myCanvasCtx.lineTo(tx + 1, ty);
myCanvasCtx.lineTo(tx + 1, ty + 1);
myCanvasCtx.lineTo(tx, ty + 1);
myCanvasCtx.lineTo(tx, ty);
myCanvasCtx.stroke();

//Now look at what happens if you try using your translated coordinates with getImageData():

wrongData = myCanvasCtx.getImageData(tx, ty, 1, 1);

txt = "Wrong data using translated coordinates of centre :";
for (i=0; i<4; i++)
	txt += wrongData.data[i].toString()+" ";

alert(txt);

//On the other hand, you should see data corresponding to magenta pixels if you do this:

rightData = myCanvasCtx.getImageData(tx + cx, ty + cy, 1, 1);

txt = "Right data using standard coordinates of centre :";
for (i=0; i<4; i++)
	txt += rightData.data[i].toString()+" ";

alert(txt);

</script>

</html>

当运行上述简单测试时,第一个警报将给出[0,0,0,0]的像素数据,对应于屏幕右上角的透明数据,而第二个警报将产生画布中心绘制的品红色像素的正确数据。请注意,期望[255,0,255,255]的那些实际上会看到类似[255,0,255,239]的内容,而更改行上限似乎不会影响这一点。