2014-11-19 4 views
-1

Я пытаюсь написать getImageData, поэтому всякий раз, когда мой автомобиль попадает в черную часть трека, появляется предупреждение. Однако он не работает, так как автомобиль продолжает двигаться.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); 
    } 

ответ

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 
} 

Кстати: Вместо того, чтобы полагаться на цвет-манипуляции, часто гораздо более надежные и дружественная производительность для проверки невидимых геометрических форм для перекрытия («ограничивающая коробка» или «ограничивающих круги»).

+0

Вы могли бы создать прямоугольники самостоятельно, а затем связать с Element.getBoundingClientRect? – SasukeRinnegan

+0

@SasukeRinnegan Нет, я бы определил прямоугольник для каждого объекта в игре, а затем проверил на наличие столкновений, проверив их координаты. – Philipp

+0

Хорошо спасибо! – SasukeRinnegan

0

, связанный с вашей проблемой, но уместен в свете указанной проблемы, основанной на использовании метода getImageData() для обнаружения столкновений, задачи, которую я недавно предпринимал. Если будущие обновления вашего проекта включают использование переведенных координат, тогда это станет сразу релевантным.

Предупреждение должно быть опубликовано об использовании getImageData() и putImageData() на холсте HTML5. Что сосредоточено на использовании переведенных координат с помощью метода translate().

Хотя большинство методов рисования использовать полученный переведенную систему, getImageData() и putImageData() НЕ использования, что в переводе системы координат, но вместо всегда использовать стандарт системы координат, с (0, 0 координатой), расположенный в верхнем левом углу вашего холста! Я нашел это трудным путем, пытаясь использовать getImageData() для простого алгоритма обнаружения столкновений и задался вопросом, почему во время тестирования, выбирая координаты, которые были , известны, чтобы быть частью рендеринга на холсте, возвратили значения пикселей [ 0, 0, 0, 0] вместо истинных значений пикселей. Это произошло потому, что переведенная система координат использовалась для ссылки на пиксели, о которых идет речь. Когда координаты были изменены на те, которые были бы применены в стандартной системе координат, нужные данные были правильно обнаружены.

Однако, чтобы добавить к путанице, drawImage() DOES использовать переведенные координаты, если они заданы с помощью translate()!

Если в объекте return из 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++) 
 
\t 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++) 
 
\t txt += rightData.data[i].toString()+" "; 
 

 
alert(txt); 
 

 
</script> 
 

 
</html>

Когда выше простой тест выполняется, первое уведомление будет давать данные пикселя [0, 0, 0, 0], соответствующее прозрачные данные в верхнем правом углу экрана, в то время как второе предупреждение даст правильные данные для нарисованных пурпурных пикселей в центре холста. Обратите внимание, что те, кто ожидает [255, 0, 255, 255], на самом деле будут видеть что-то вроде [255, 0, 255, 239], и изменение строки не влияет на это.

Смежные вопросы