Copy link to clipboard
Copied
Hi there,
I’ve been trying everything I can think of and looking everywhere for a solution but I can’t get my head around this basic problem.
I have several “Masters” and several “Slaves” movieclips. Both Masters and Slaves can be dragged and rotated (keyboard event) individually inside a MouseDown event, and then dropped inside a MouseUp event.
What I’d like to do is when one or several Slaves clips are touching one Master clip, dragging and rotating the Master will also drag and rotate the Slaves; the Master basically acting as a container.
I got that part working but there is something wrong with the MouseUp event once the Master clip has been rotated and dropped: the Slaves keep changing position with each rotation; while clicking back (MouseDown) on the Master clip put all the Slaves back to their right position.
Here is a sample code with one master and one slave:
----------------------------
Slave.addEventListener(MouseEvent.MOUSE_DOWN, fl_Drag_Slave);
Master.addEventListener(MouseEvent.MOUSE_DOWN, fl_Drag_Master);
// Drag Slave
function fl_Drag_Slave(event:MouseEvent):void
{
Slave.startDrag(); // Drag
stage.addEventListener(KeyboardEvent.KEY_DOWN, fl_Slave_Rotation); // Rotation event listener
stage.addEventListener(MouseEvent.MOUSE_UP, fl_Drop_Slave); // MouseUp event listener
}
// Drop Slave
function fl_Drop_Slave(event:MouseEvent):void
{
Slave.stopDrag();
stage.removeEventListener(KeyboardEvent.KEY_DOWN, fl_Slave_Rotation);
stage.removeEventListener(MouseEvent.MOUSE_UP, fl_Drop_Slave);
}
// Rotate Slave
function fl_Slave_Rotation(event:KeyboardEvent):void
{
if (event.keyCode == 82) // Keycode for the letter "r"
{
Slave.rotation += 45;
}
}
// Drag Master (and Slaves)
function fl_Drag_Master(event:MouseEvent):void
{
if (Slave.hitTestObject(Master))
{
Master.addChild(Slave); // Add the Slave to the Master
Slave.x -= Master.x; // Adjust the Slave's position and rotation
Slave.y -= Master.y;
Slave.rotation -= Master.rotation;
}
Master.startDrag();
stage.addEventListener(KeyboardEvent.KEY_DOWN, fl_Master_Rotation); // Rotation event listener
stage.addEventListener(MouseEvent.MOUSE_UP, fl_Drop_Master); // MouseUp event listener
}
// Drop Master (and Slaves)
function fl_Drop_Master(event:MouseEvent):void
{
if (Slave.hitTestObject(Master))
{
addChild(Slave); // Add the Slave back to the stage
Slave.x += Master.x; // Adjust the Slave's position and rotation
Slave.y += Master.y;
Slave.rotation += Master.rotation;
}
Master.stopDrag();
stage.removeEventListener(KeyboardEvent.KEY_DOWN, fl_Master_Rotation);
stage.removeEventListener(MouseEvent.MOUSE_UP, fl_Drop_Master);
}
// Rotate Master (and Slaves)
function fl_Master_Rotation(event:KeyboardEvent):void
{
if (event.keyCode == 82) // keycode for the letter "r"
{
Master.rotation += 45;
}
}
----------------------------
I think the problem resides in the way I adjust the Slaves clips’ positions when they are added back to the stage during the MouseUp event but I can’t get it to work.
Thanks a lot for your help!
Copy link to clipboard
Copied
Hi.
Here is a suggestion of how you can achieve this. It's not a direct solution to your code, but I hope something may be useful.
One big advantage is that you can have as many masters and slaves as you wish.
Preview:
AS3 code:
import flash.events.MouseEvent;
import flash.display.MovieClip;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.geom.Point;
var currentChild:MovieClip;
var masters:Vector.<MovieClip> = new Vector.<MovieClip>();
var slaves:Vector.<MovieClip> = new Vector.<MovieClip>();
function start():void
{
var mastersCount:uint = 0;
var slavesCount:uint = 0;
for (var i:int = 0, total:int = numChildren; i < total; i++)
{
if (getChildAt(i).name.indexOf("master") == 0)
masters[mastersCount++] = getChildAt(i) as MovieClip;
else if (getChildAt(i).name.indexOf("slave") == 0)
slaves[slavesCount++] = getChildAt(i) as MovieClip;
}
addEventListener(MouseEvent.MOUSE_DOWN, mouseHandler);
addEventListener(MouseEvent.MOUSE_UP, mouseHandler);
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyHandler);
}
function mouseHandler(e:MouseEvent):void
{
if (e.type == MouseEvent.MOUSE_DOWN)
{
if (e.target)
{
currentChild = e.target as MovieClip;
currentChild.startDrag();
}
}
else if (e.type == MouseEvent.MOUSE_UP)
{
currentChild.stopDrag();
currentChild.parent.setChildIndex(currentChild, currentChild.parent.numChildren - 1);
if (currentChild.name.indexOf("master") == 0)
{
currentChild = null;
return;
}
for (var i:int= 0, total:int = masters.length; i < total; i++)
{
if (currentChild.hitTestObject(masters) && currentChild.parent.name.indexOf("master") < 0)
{
var point:Point = new Point(currentChild.x - masters.x, currentChild.y - masters.y);
masters.addChild(currentChild);
currentChild.x = point.x;
currentChild.y = point.y;
currentChild = null;
return;
}
}
currentChild = null;
}
}
function keyHandler(e:KeyboardEvent):void
{
if (e.type == KeyboardEvent.KEY_DOWN)
if (currentChild && e.keyCode == Keyboard.R)
currentChild.rotation += 45;
}
start();
;
FLA download:
animate_cc_as3_master_slave.zip - Google Drive
Regards,
JC
Copy link to clipboard
Copied
Hi JC,
Thanks a lot for the time spent on my case. However, your suggestion implies a total reorganization of the code using notions I’m not familiar with and which seem not as straightforward as I had in mind.
I will nevertheless take a closer look at it and see if I can apply some of your ideas to my code.
I may add that having as many masters and slaves as required is not a problem since they are actually made from external classes. The given sample code was just adapted to a single “Actions layer” for simplicity.
Find more inspiration, events, and resources on the new Adobe Community
Explore Now