A Flash Developer Resource Site

Page 1 of 3 123 LastLast
Results 1 to 20 of 52

Thread: collision detection help

  1. #1
    Senior Member
    Join Date
    Apr 2001
    Posts
    102

    collision detection help

    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.

    Any help would greatly be appreciated.

  2. #2
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    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.

  3. #3
    Senior Member
    Join Date
    Apr 2001
    Posts
    102
    I tried the following and got an error.
    Code:
    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.

  4. #4
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    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.

  5. #5
    Senior Member
    Join Date
    Apr 2001
    Posts
    102
    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();
    }

  6. #6
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    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();

  7. #7
    Senior Member
    Join Date
    Apr 2001
    Posts
    102
    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.

  8. #8
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    Sure. I haven't actually been coding this stuff as I've answered, so give me a minute. I'll post a zip with a few .as files.

  9. #9
    Senior Member
    Join Date
    Apr 2001
    Posts
    102
    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.

  10. #10
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    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.
    Attached Files Attached Files

  11. #11
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    And here's a version that does what I just said.
    Attached Files Attached Files

  12. #12
    Senior Member
    Join Date
    Apr 2001
    Posts
    102
    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?

    I appreciate all your help on this.

  13. #13
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    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.

  14. #14
    Senior Member
    Join Date
    Apr 2001
    Posts
    102
    nevermind i got it working in a fla.

  15. #15
    Senior Member
    Join Date
    Apr 2001
    Posts
    102
    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.

  16. #16
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    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.

  17. #17
    Senior Member
    Join Date
    Apr 2001
    Posts
    102
    it does do what i want but as you said appears a bit sticky. How would one make it so that it isn't "sticky"?

  18. #18
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    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.

  19. #19
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    It works, but I still don't like it as much as attempt #2.
    Attached Files Attached Files

  20. #20
    Senior Member
    Join Date
    Apr 2001
    Posts
    102
    this works perfectly now.

    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.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center