dr.ugi Posted November 27, 2013 Share Posted November 27, 2013 Hi,Is is possible to drag many objects at once? Together? I would think that putting all sprites into one group and adding drag to the group would work, but drag doen't work on groups... Any ideas? Thanks. spinnerbox 1 Link to comment Share on other sites More sharing options...
hackenstein Posted November 27, 2013 Share Posted November 27, 2013 This is afaik not possible with phasers drag implementation. However should be able to do this yourself. Use sprite.events.onInputDown to register when and where the user clicked on one of your sprites. With game.input.onUp you know when he has released the button. While he has not released the button you can update the group coordinates yourself in the update function in relation to the current coordinates of the input and the position you got when he clicked on your sprite. Link to comment Share on other sites More sharing options...
dr.ugi Posted November 27, 2013 Author Share Posted November 27, 2013 Thanks a lot.It's sad that groups don't have this functionality. I did some sort od handle for group and update group position based on the handle... Will work for now.Thanks Link to comment Share on other sites More sharing options...
rich Posted November 27, 2013 Share Posted November 27, 2013 It's actually a bit more complex than you'd think. A Group doesn't have any area itself, it's infinite in all directions - so there's no detecting if you've clicked on it. But you can click on a child easily, however should the drag update all other children, just that child OR the group x/y placement itself? (which in turn would update the other children to, only maybe not in the way you'd expect). And then what about nested groups? I like the feature, it's just not as straight forward to implement as it appears on the surface jdnichollsc and spinnerbox 2 Link to comment Share on other sites More sharing options...
Anny Posted April 1, 2014 Share Posted April 1, 2014 Hi I'm really new to phaser I am trying to make something like a factory, where you have to drag and drop "products" that come out of a machine. I created these products as a group but now when I try to drag them, it keeps pointing to the last element created, not to the product i'm clicking on. I'm not sure how to implement this, I saw somewhere on the examples that they used as a parameter _ball and _brick and that somehow works with the current brick. But I don't see how to do this with clicking. I also need to "unite" somehow different elements of a group to create something bigger. Should I do this with diferent functions like the tank examples or is it doable with groups? Thank you so much in advance Here's the code on pastebin http://www.pastebin.ca/2690180 Link to comment Share on other sites More sharing options...
MarkRhodes Posted January 22, 2015 Share Posted January 22, 2015 See below! Link to comment Share on other sites More sharing options...
MarkRhodes Posted January 22, 2015 Share Posted January 22, 2015 It may not be the most efficient, but for simplicity, I just create an invisible sprite the same size as the group and make that a child of the group, then add the input controls to that. i.e. var group = game.add.group(); //add stuff to group etc... var fakeHitZone = game.add.sprite(0, 0, 'spritesheet', 'invisible-box', group); fakeHitZone.width = group.width; fakeHitZone.height = group.height; fakeHitZone.inputEnabled = true; fakeHitZone.events.onInputDown.add(functionToRun); //add more events if required.. Here 'invisible-box' is a 1*1 transparent pixel. Just be aware that changes to the size of the group have to be manually applied to the hit zone too. Link to comment Share on other sites More sharing options...
ptdnet Posted February 13, 2015 Share Posted February 13, 2015 I got tired of waiting for group dragging so I added it. I'll figure out how to get a pull request with the GitHub stuff later, but for now you can do what I used to do... After you have your group set up, drop a transparent "sprite" on top of it with game.add.sprite(yourGroup.x, yourGroup.y, "somePng"); Set its width and height to equal the group's width and height. Now make the sprite draggable. Every game update, just set the group's x and y equal to the sprite's x and y. That's essentially what my mod does anyway, just more automatic. Link to comment Share on other sites More sharing options...
doyouknowyou Posted April 11, 2015 Share Posted April 11, 2015 I got tired of waiting for group dragging so I added it. I'll figure out how to get a pull request with the GitHub stuff later, but for now you can do what I used to do... After you have your group set up, drop a transparent "sprite" on top of it with game.add.sprite(yourGroup.x, yourGroup.y, "somePng"); Set its width and height to equal the group's width and height. Now make the sprite draggable. Every game update, just set the group's x and y equal to the sprite's x and y. That's essentially what my mod does anyway, just more automatic. Do you have an example of this? And are you updated each child's x/y individually? Link to comment Share on other sites More sharing options...
Anatol Posted September 29, 2017 Share Posted September 29, 2017 I'm just reviving this old thread. I had the same issue and wanted to make an entire group draggable. I came up with this approach which doesn't require to add a hit area: const group = game.add.group() const item1 = game.add.image( 0, 0, 'item1', null, group ) const item2 = game.add.image( 0, 0, 'item2', null, group ) makeDraggableGroup( group ) function makeDraggableGroup ( g ) { g.forEach( makeDraggable ) } function makeDraggable ( obj ) { if ( obj.inputEnabled === undefined ) return obj.inputEnabled = true obj.input.enableDrag() obj.events.onDragUpdate.add( handleDragUpdate ) // optional: // obj.events.onDragStart.add( handleDragStart ) // obj.events.onDragStop.add( handleDragStop ) } function handleDragUpdate ( obj, pointer, x, y, snapPoint, isFirstUpdate ) { if ( isFirstUpdate ) { obj.origin = new Phaser.Point( obj.x, obj.y ) obj.parent.origin = new Phaser.Point( obj.parent.x, obj.parent.y ) } obj.parent.x = obj.parent.origin.x + x obj.parent.y = obj.parent.origin.y + y obj.x = obj.origin.x obj.y = obj.origin.y } // optional: // function handleDragStart ( obj ) { // console.log( 'start drag', obj ) // } // function handleDragStop ( obj ) { // console.log( 'stop drag', obj ) // } Just note that the above code only considers direct children. If you have nested groups you'd need to drill into each sub group. Something like replacing the if ( obj.inputEnabled === undefined ) return with if ( obj.children ) obj.forEach( makeDraggable ) But it'd need some more work than just this for nested groups. Link to comment Share on other sites More sharing options...
Anatol Posted September 29, 2017 Share Posted September 29, 2017 Here's an improved version that seems to work better to make Phaser groups draggable. Actually it doesn't matter if you pass it a group or other item, it works for anything you want to make draggable. It also includes nested groups and you can pass your (optional) callbacks. Also the previous code had an issue when children had positions other than (0,0) as the dragged group would jump by that offset. So here is a more general approach: function makeDraggable ( { item, startCallback, stopCallback, updateCallback } ) { if ( item.forEach ) { item.forEach( makeDraggableObject ) } else { makeDraggableObject( item ) } function makeDraggableObject ( obj ) { if ( obj.forEach ) { obj.forEach( makeDraggableObject ) return } obj.inputEnabled = true obj.input.enableDrag() obj.origin = new Phaser.Point( obj.x, obj.y ) const callback = item.forEach ? handleDragUpdate : updateCallback if ( callback ) obj.events.onDragUpdate.add( callback ) if ( startCallback ) obj.events.onDragStart.add( startCallback ) if ( stopCallback ) obj.events.onDragStop.add( stopCallback ) } function handleDragUpdate ( obj, pointer, x, y, snapPoint, isFirstUpdate ) { if ( isFirstUpdate ) { obj.startDragPos = new Phaser.Point( obj.x, obj.y ) item.startDragPos = new Phaser.Point( item.x, item.y ) } item.x = item.startDragPos.x - obj.origin.x + x item.y = item.startDragPos.y - obj.origin.y + y obj.x = obj.startDragPos.x obj.y = obj.startDragPos.y if ( updateCallback ) updateCallback( obj, pointer, x, y, snapPoint, isFirstUpdate ) } } Usage, e.g.: const group = game.add.group() const item1 = game.add.image( 100, -50, 'item1', null, group ) const item2 = game.add.image( -100, 50, 'item2', null, group ) makeDraggable( { item: group, startCallback: handleDragStart, stopCallback: handleDragStop, updateCallback: handleDragUpdate, } ) function handleDragStart ( obj ) { console.log( 'START DRAG', obj ) } function handleDragStop ( obj ) { console.log( 'STOP DRAG', obj ) // makeDraggable adds the original position to the object as obj.origin // we can use this e.g. to tween rebound the item to it's origin TweenMax.to( obj, 1, { x: obj.origin.x, y: obj.origin.y, ease: Elastic.easeOut } ) } function handleDragUpdate ( obj, pointer, x, y, snapPoint, isFirstUpdate ) { console.log( 'UPDATE DRAG', obj ) } Link to comment Share on other sites More sharing options...
Recommended Posts