2013-04-15 4 views
4

У меня есть массив, который заполнен позициями многих разных объектов в моей игре, и то, что я пытаюсь достичь, - это когда мышь находится на объекте на холсте, пользователь может щелкните, а затем появится окно (будет меню).Мышь щелкните по массиву объектов javascript Canvas

Вот код, у меня есть уже:

this.init_inv = function(value){ 
    canvas.onmousemove = function (e) { 
     var x, y; 
     for(var i = 0;i < value.length; i++){ 
      // Get the mouse position relative to the canvas element. 
      if (e.layerX || e.layerX) { //for firefox 
       x = e.layerX; 
       y = e.layerY; 
      } 
      x-=canvas.offsetLeft; 
      y-=canvas.offsetTop; 

      if(x>=value[i][0] && x <= (value[i][0] + value[i][2]) && 
       y<=value[i][1]&& y >= (value[i][1]-value[i][2])){ 
       document.body.style.cursor = "pointer"; 
       inObject=true; 
      } 
      else{ 
       document.body.style.cursor = ""; 
       inObject=false; 
      } 
     } 
    }; 
    canvas.addEventListener("click", on_click, false); 
}; 

Обработчик нажмите выглядит следующим образом:

function on_click(e) { 
    if (inLink) { 
     var dataString = {"save": "true", "level":level, "location_X":pos_X, "location_Y":pos_Y}; 
     $.ajax({ 
      type:"POST", 
      url:"PHP/class.ajax.php", 
      data: dataString, 
      dataType: "JSON", 
      success: function(success){ 
       alert("Saved"); 
      }, 
      error:function(){ 
       alert("Not Saved"); 
      } 
     }); 
    } 
    if(inObject){ 
     console.log("hovering"); 
    } 
} 

У меня есть отдельный обработчик щелчка, потому что мне нужно обрабатывать щелчки на разных частях разные холсты.

Я считаю, что проблема заключается в том, как я читаю значения в массиве, но не знаю, как это сделать. Я знаю это, потому что, если я ввожу int, где значения value[i][0] и т. Д., Я могу щелкнуть в указанной области и триггерах щелчка, и я получаю журнал консоли.

массив выглядит следующим образом:

var array = [ 
    [pos_x,pox_y, size] 
    //etc... 
]; 
+0

Обычно вы справляетесь с этим, перемещая элементы на холсте и просто прикрепляя к ним обработчики кликов, а не отслеживая mousemove и определяя позицию щелчка, просматривая вещи в массиве; есть ли причина, по которой вы не просто используете эту встроенную функциональность? –

+0

Возможно, вам захочется взглянуть на библиотеку, такую ​​как [KineticJS] (http://www.html5canvastutorials.com/kineticjs/html5-canvas-listen-or-dont-listen-to-events-with-kineticjs/), чтобы помочь вам если вы хотите реагировать на события по конкретным элементам на холсте. @ChrisMoschini Canvas не позволяет связать обработчики событий с элементами холста, поскольку все растрируется, а векторы не сохраняются. –

+0

Как вы определяете другую часть холста? единственный способ, которым я могу думать, - это 1 слушатель мыши, который имеет 2 разных ifs, основанных на местоположении. Пример 1D: if (x <10) {listener1}, если (x <20) {слушатель 2} – Drakoumel

ответ

0

так, а не устанавливать inObject к истинным или ложным, вы можете установить его в ложное первоначально, а затем установить его в i, так что вы знаете, какой объект действительно был выбран ,

убедитесь, что inObject определен вне функции, поэтому вы можете получить к ней доступ позже.

Я перефразировать ваш код немного, чтобы сделать краткий обзор того, как я бы структурировать этот

//first of all, name your stuff what it is, rather than array, name it meaningfully 
// and since we don't have a huge amount(1000+) of menu items, we can just use them as objects 
// arrays are faster, but for clarity purposes, we don't need the speed and might as well have readable code 
var menuboxes = [ 
    {x: 10, y: 10, size: 100}, 
    {x: 115, y: 10, size: 100} 
]; 

//i suggest using underscore, but this could be converted to a regular each 
_.each(menuboxes, function(box, n){ 
    context.fillRect(box.x, box.y, box.size, box.size); 
}); 

var on_click = function(e){ 
    // this doesn't change for each item, so define x and y outside of the boxes loop 
    x = e.layerX - canvas.offsetLeft; 
    y = e.layerY - canvas.offsetTop; 
    clickTarget = false 
    _.each(menuboxes, function(box, n){ 
    if(box.x < x && x < box.x + box.size && 
     // no need to invert y, use it like you use x 
     box.y < y && y < box.y + box.size) { 
     clickTarget = n; 
     } 
    }); 
    if(clickTarget !== false){ 
    openMenu(clickTarget); 
    } 
}; 

var openMenu = function(n){ 
    console.log("You opened box", n, menuboxes[n]); 
    // menu opening code here 
} 

canvas.addEventListener("click", on_click, false); 

это непроверенная, но должен дать вам несколько советов. Я предлагаю использовать jquery и подчеркивание на данный момент, и в конечном итоге coffeescript, когда вы узнаете веревки. JQuery очень важен из-за особенностей браузера, подчеркивание очень полезно и быстро, а coffeescript - единственный способ сделать читаемый код в некоторых ситуациях. скопируйте код в http://js2coffee.org, чтобы узнать, насколько короче он может быть.

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