How to drag and drop sprite at cocos2d-x html5

hello,
how i can drag some sprite and drop it to other place in screen?
can you tell me some code?

thank you

1 Like

This would require a few events to be implemented: onTouchStart, onTouchMove, and onTouchEnd.

onTouchStart:
* Check that the point is in the bounding box of the Sprite (cc.Rect.CCRectContainsPoint);
* If so, dragging has started.

onTouchMove:
* If dragging has started for a Sprite, get the (X, Y) coordinates of the touch, and move the Sprite to a new position.

onTouchEnd:
* Dragging for this Sprite has ended.

In my touch controls implementation, each touch event (start, move, end) has a unique identifier with it. So if touch “1” starts and is contained inside of my Sprite rectangle, I assigned the identifier “1” to the Sprite as well.

This way, when touch “1” moves, I know to move the Sprite with identifier “1”. This allows you to distinguish for multiples touches.

Similarly, when touch “1” ends, you know to un-assign identifer “1” from the Sprite since there is no longer an interaction occurring.

This is all fairly high-level, but if you have any questions about specific implementation, ask away :slight_smile:

thanks for replying,

this is code where i have implementation :
onTouchesMoved:function (touches, event)
{
if (cc.Rect.CCRectContainsPoint(circle.boundingBox(), touches[0]))
{
this.circle.setPosition(cc.p(touches[0].getLocation().x, touches[0].getLocation().y));
}
}

CMIIW… ^^

You may have to add a bit more to filter out multiple touches, etc. but that looks like a good starting point.

    if (cc.Rect.CCRectContainsPoint(circle.getBoundingBox(), touches[0])) {
        this.circle.setPosition(cc.p(touches[0].getLocation().x, touches[0].getLocation().y));
    }

One potential issue is that the bounding box of a Sprite is the rectangle that contains the Sprite, meaning if your image is a circle, the corners (outside of the circle) will still give a valid click result. Alternative to getBoundingBox you could do some math to get the distance from the center of the sprite to the touch point and if that distance exceeds some value, then it will not trigger the touch.

I am using a pure HTML5 implementation instead of the Cocos2d-HTML5 touch implementation because of some issues I see on my BlackBerry Playbook, but maybe this can give you some ideas.

    onTouchStart: function (e) {
        'use strict';
        var touches, touch, point, n, m;

        e.preventDefault();
        touches = e.changedTouches;

        for (n = 0; n < touches.length; n = n + 1) {
            touch = touches[n];
            point = new cc.Point(touch.clientX, this.height - touch.clientY);
            if (cc.Rect.CCRectContainsPoint(circle.getBoundingBox(), point) === true) {
                if (circle.identifier === -1) {
                    circle.identifier = touch.identifier;
                    /* DO STUFF WITH THE CIRCLE ON TOUCH START HERE. */
                }
            }
        }
    },

    onTouchMove: function (e) {
        'use strict';
        var touches, touch, point, n, m;

        e.preventDefault();
        touches = e.changedTouches;

        for (n = 0; n < touches.length; n = n + 1) {
            touch = touches[n];
            point = new cc.Point(touch.clientX, this.height - touch.clientY);
            if (circle.identifier === touch.identifier) {
                /* DO STUFF WITH THE CIRCLE ON TOUCH MOVE HERE. */
            }
        }
    },

    onTouchEnd: function (e) {
        'use strict';
        var touches, touch, point, n, m;

        e.preventDefault();
        touches = e.changedTouches;

        for (n = 0; n < touches.length; n = n + 1) {
            touch = touches[n];
            point = new cc.Point(touch.clientX, this.height - touch.clientY);
            if (circle.identifier === touch.identifier) {
                /* DO STUFF WITH THE CIRCLE ON TOUCH END HERE. */
                circle.identifier = -1;
            }
        }
    },

The Cocos2d-HTML5 implementation may be a little different though. Specifically I’m not sure:

  1. Whether you have access to changedTouches.
  2. Whether identifier will be a valid value. For me it wasn’t, hence the need for pure HTML5.

can i use this implementation in cocos2dx-html5 ?
touch = touches[n];
point = new cc.Point(touch.clientX, this.height - touch.clientY);

what do you mean about (touch.clientX, this.height - touch.clientY) ? why i must to decrease this.height with touch.clientY?

thanks ^^

Hi there,

This is compatible with Cocos2d-HTML5, but it isn’t the usual implementation. This is a pure HTML5 implementation (in my development I had issues getting a unique identifier on my platform with the Cocos2d-HTML5 implementation of touch events.) The code above shows the logic of handling the touches (which could likely be implemented with the Cocos2d-HTML5 touches), but if you want to actually use pure HTML5 touches, you would require:

canvas.addEventListener('touchstart', this.onTouchStart, false);
canvas.addEventListener('touchmove', this.onTouchMove, false);
canvas.addEventListener('touchend', this.onTouchEnd, false);

Where canvas would be your main

element.

The reason for:

point = new cc.Point(touch.clientX, this.height - touch.clientY);

Is that with HTML5 touches, the coordinate (0, 0) is at the top-left corner of the screen. But Cocos2d-HTML5’s coordinate system places (0, 0) at the bottom-left corner of the screen. The subtraction converts from HTML5 to Cocos2d-HTML5 coordinates.

If you are using the pure approach, you will need to make the adjustment. If you are using the Cocos2d-HTML5 touch events, you wouldn’t have to make any adjustment.