чистый код перетаскивания в Javascript Canvas - PullRequest
7 голосов
/ 16 декабря 2011

Я ищу самый быстрый и легкий способ перетаскивания форм и спрайтов на JS Canvas для разработки игр.

Я начал с проверки расстояния, используя текущее положение мыши и происхождение окружностей.Это работает, но когда они накладываются друг на друга, у нас возникают проблемы, и я не знаю, насколько хорошо это будет работать при тестировании нескольких спрайтов и других фигур на каждом «кадре».

Любые комментарии или указатели на лучшие методы приветствуются!

Я бы предпочел не использовать такую ​​библиотеку, как jQuery, так как я стремлюсь к чистой скорости и легкости и, конечно, к изучению реальных методов!Вот где я нахожусь:

//add the canvas listeners and functions

canvas.addEventListener("mousemove",mousemove);
canvas.addEventListener("mousedown",mousedown);
canvas.addEventListener("mouseup",mouseup);

function mousemove(e){
    mouseX = e.layerX - canvas.offsetLeft;
    mouseY = e.layerY - canvas.offsetTop;

//for each circle stored in my array of Circle objects, is my mouse within its'           
//bounds? If so, set the circles' (X,Y) to my mouse's (X,Y)

    for(i=0;i<circArray.length;i++){
        dx = mouseX - circArray[i].x;
        dy = mouseY - circArray[i].y;
        dist = Math.sqrt((dx*dx) + (dy*dy));
        if(draggable && dist < circArray[i].r){         
            circArray[i].x = mouseX;
            circArray[i].y = mouseY;
        }
    }
}

function mousedown(){
        draggable = true;
}

function mouseup(){
        draggable = false;
}

1 Ответ

3 голосов
/ 29 декабря 2011

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

Другими словами: при поиске mousedown для объекта попадания в зарезервированном порядке вы рисуете объекты (таким образом, сначала наносится удар по самому верхнему элементу), сохраняете этот элемент попадания, а затем mousedrag просто передает координаты / дельту этому элементу.

//start with only the mousedown event attached
canvas.addEventListener("mousedown",mousedown);

//and some vars to track the dragged item
var dragIdx = -1;
var dragOffsetX, dragOffsetY;

function mousedown(e){
    //...calc coords into mouseX, mouseY
    for(i=circArray.length; i>=0; i--){ //loop in reverse draw order
        dx = mouseX - circArray[i].x;
        dy = mouseY - circArray[i].y;
        if (Math.sqrt((dx*dx) + (dy*dy)) < circArray[i].r) {         
            //we've hit an item
            dragIdx = i; //store the item being dragged
            dragOffsetX = dx; //store offsets so item doesn't 'jump'
            dragOffsetY = dy;
            canvas.addEventListener("mousemove",mousemove); //start dragging
            canvas.addEventListener("mouseup",mouseup);
            return;
        }
    }
}

function mousemove(e) {
     //...calc coords
     circArray[dragIdx].x = mouseX + dragOffsetX; //drag your item
     circArray[dragIdx].y = mouseY + dragOffsetY;
     //...repaint();
}

function mouseup(e) {
     dragIdx = -1; //reset for next mousedown
     canvas.removeListener(.... //remove the move/up events when done
}

Мой JS ржавый в данный момент, но это должно дать идею. DragOffsetX / Y используется для предотвращения перехода элемента к курсору при нажатии. Вы также можете просто сохранить старую координату мыши и добавить дельту к вашему элементу.

Кроме того, вместо сохранения индекса для элемента перетаскивания вы можете сохранить ссылку на него или, возможно, массив ссылок для перетаскивания нескольких элементов. И вместо того, чтобы напрямую манипулировать вашими предметами, вы можете поместить на них интерфейс mousedown / drag / up, чтобы они могли с ним работать. Это облегчит смешивание с другими типами предметов.

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

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