What i am trying to do is make a bunch of objects able to be arranged on a screen kind of like a customizable preview layout. Although i have objects that i don't want to be able to overlap.
If i have 3 boxes spread out on the stage and i move one i want it to detect if i overlap one to stop and not let me overlap it. I basically need a collision detection script. The issue is all three boxes can be dragged so it can't be just set values it has to be constantly updatable so that if i move one object (box 1) then move (box 2) it has to detect the position and see if it overlaps and if so not let drag any further.
If your objects are all boxes that are not rotated, then they should correspond directly to their bounding boxes, and you can use the hitTestObject method. Actual collision detection and resolution is a complex and nifty topic, but you don't seem to need a physics engine, just a warning system.
You'd put something like this in the mouseMove handler active when something is startDragged.
Code:
var d:DisplayObject;
for (var i:int = 0; i < thingies.length; i++){
d = thingies[i];
if (currentDragged == d){
continue;
}
if (currentDragged.hitTestObject(d)){
letGo(); //should also be your mouseUp handler when dragging.
}
}
I've left a lot of things unsaid up there. You'll need to set up listeners for various events and keep track of what you're dragging (currentDragged) and everything you want to check (thingies). Let me know if I've been too high-level.
function mouseIsDown(event:MouseEvent):void {
var myObj:MovieClip = event.target.name
myObj.startDrag();
}
function mouseReleased(event:MouseEvent):void {
var myObj:MovieClip = event.target.name
myObj.stopDrag();
}
I was basically making it so that i wouldn't have to make an event listener for each object i wanted to move.
i don't get a compiler error however when i click on the object to see if it moves i get the following error in the output window.
TypeError: Error #1034: Type Coercion failed: cannot convert "titleObj" to flash.display.MovieClip.
at widgetCreator_fla::MainTimeline/mouseIsDown()
I figured if i declared whatever i clicked on as a variable i could then make it clickable and draggable and then also incorporate the hit test.
You're close. Why'd you put the .name in there? Try it without. A name is a String, whereas the target is an Object. So, you'll have to cast it to something with the startDrag/stopDrag method.
Code:
function mouseIsDown(event:MouseEvent):void {
var myObj:Sprite = Sprite(event.target)
myObj.startDrag();
}
function mouseReleased(event:MouseEvent):void {
var myObj:Sprite = Sprite(event.target)
myObj.stopDrag();
}
I cast to Sprite because it's the lowest level thing that has startDrag and stopDrag. You could use MovieClip just as easily.
what do i define thingies as and also current dragged? I have the following and its throwing errors cause those are not defined
Code:
function mouseMoved(event:MouseEvent):void {
//var myObj:Sprite = Sprite(event.target)
//myObj.startDrag();
var d:DisplayObject;
for (var i:int = 0; i < thingies.length; i++){
d = thingies[i];
if (currentDragged == d){
continue;
}
if (currentDragged.hitTestObject(d)){
mouseReleased(); //should also be your mouseUp handler when dragging.
}
}
}
function mouseReleased(event:MouseEvent):void {
var myObj:Sprite = Sprite(event.target)
myObj.stopDrag();
}
currentDragged should be a variable in the object you are defining all these functions in. It should probably be a Sprite. thingies should be an array of all the objects you want to check for collisions. It should also be defined on the same object as currentDragged. When you populate it depends on how you add your collidable objects.
I also notice that your mouseUp handler actually uses the event passed in. I was assuming that it would not. If all it's supposed to be doing is calling stopDrag, then replace the call to mouseReleased in mouseMoved with currentDragged.stopDrag();
can you post a test file with a bunch of boxes that are movieclips on the stage to show me cause im getting a bit confused. A example file would be great.
one thing i have noticed in my tests that im having a issue with is that i can get it to stopDrag when it detects a collision but basically i want to be able to drag it the other way like after i release my mouse and try again in another direction.
Here you go. I think I see what you mean in your last post. The objects act kind of "sticky" because the stopDrag doesn't happen until they are already overlapping. Then the next drags can only go a short ways until it detects that they are still overlapping.
A better design might be to not let them drop the currentDragged on top of something else. That is, don't check on mouseMove, but on MouseUp. Of course, then you have to drop on both mouseDown and mouseUp, but that's not terrible.
im assuming i have to make the document class DragThingy? Also what do you mean i would have to "drop on both mousedown and mouseUp". Do you mean i would have to duplicate the code i would use on mouseUp for MouseDown?
Care to attach a fla file for both these examples?
The document class should be Main, not DragThingy. See my last post for what I mean by drop on both.
I can't actually attach a fla because I have no way of creating one. I don't actually have Flash, I'm using FlashDevelop and always do all actionscript projects.
as far as the drop on both i want it to stopDrag when it overlaps But then allow it to be draged in the other direction either when clicked again or some other way. Right now there is no stopDrag when the boxes overlap.
The first zip I posted has the stopDrag when they overlap. It does not actually resolve the overlap, so subsequent drags appear "sticky". But it does do what you want.
If you look at the end of the mouseMove function, I have a comment that says "here, we really should resolve any residual overlap between c and d".
If you put a function call there that separated c and d so that they no longer overlapped, the stickiness would go away. To do this properly, you'd have to look at some actual collision resolver engines. It's complex stuff. But we could hack it, by going back to the last non-overlap position. Allow me some time and I'll post a third version if my idea works.
one thing i did notice thought that i forget to mention is all my shapes are squares/rectangular but are not the same. So like i have one shape with an instance name of titleObj, one with previewObj, one with buttonObj. Would i just put those in an array so the for loop could check for them?
If you could post an updated code snipet that would be great. I really appreciate your help.