A Flash Developer Resource Site

Page 3 of 3 FirstFirst 123
Results 41 to 52 of 52

Thread: collision detection help

  1. #41
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    Some minor changes can take care of it. This is related to the issue I mentioned about the mouseDown listener and currentTarget. If you make each of your draggable things have the mouseDown listener instead of the stage, you can use currentTarget instead of target, and be assured that the currentTarget should be draggable.
    After making that change, you'd have to keep two arrays: one which contains the things that are draggable, and one which contains everything which must be tested against. Note that the second should include all of the first.
    I don't have time to make these changes right now, but I may be able to get you something over the weekend. In the meantime, I encourage you to experiment and try to get it working yourself, you may just surprise yourself.

  2. #42
    Senior Member
    Join Date
    Apr 2001
    Posts
    102
    i appreciate your help greatly im sorry if i sound like im nagging.

    I believe i did everything you said but now it doesn't seem to be dragging any item. I added the mouseUp event listener inside the mouseDown event listener and also add the new array and push the object names i didn't want draggable inside that array. Maybe im doing something wrong.

    I don't get any compile errors or anything it just doesn't drag any item when mouse down and doesn't obey notDraggable array.

    attached is my code file.
    Attached Files Attached Files

  3. #43
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    I'll attempt to look at it tomorrow. Good luck.

  4. #44
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    I've updated your last code with what I intended. I have not been able to test it because of all the references to undefined things.
    The major changes are:
    1. changed nonDraggableItems to collidableItems, and made it a class property
    2. moved init to respond to ADDED_TO_STAGE so there's a chance to put children on the Main before initializing it.
    3. populated collidableItems to include all draggableItems as well as the others.
    4. added the mouseDown listener to each of the draggables.
    5. changed the mouseMove function to check against collidableItems instead of draggableItems
    Attached Files Attached Files

  5. #45
    Senior Member
    Join Date
    Apr 2001
    Posts
    102
    the code works pretty much now however the dragging doesn't seem to be the same as it was? if go and drag the object "verticalBtns" or "previewObj" and it wont let me drag it past a certain posiition cause essentially i have a hidden element above it around x=427.45, y=174.95

    The reason i think this is cause i have an object called horizontalBtns hidden when loaded and if selected from the drop down menu then verticalBtns hides and horizontalBtns is visible. When the object is hidden i basically don't want it to detect the collision?

    Do i just add that in an if statement or something? Any help would be appreciated. Where should i add it?

  6. #46
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    The way the code is written, you cannot drag anything over something in the collideableItems array, regardless of whether that thing is visible or not. If you want something no longer to be collideable, the neatest way to do it would be to take it out of the collideableItems array. However, if you just want to prevent things with alpha==0 from being collideable, you could put that test in the mouseMove function. Just test whether d is invisible just like you test whether d is the currentDragged.

    As I said, a more flexible way to do it would be to manipulate the collidableItems array as you hide and show new collidable items.

  7. #47
    Senior Member
    Join Date
    Apr 2001
    Posts
    102
    so then do something like this?

    What im trying to do is take out the item in the array like you stated when i select an item and add a new one in its place. So basically verticalBtns, and horizontalBtns wont be in the array to begin with and should be added and atken out based on the item you self in my if/else statement.

    This doesn't seem to work though

    [code]
    draggableItems.push(getChildByName('titleObj'), getChildByName('previewObj'), getChildByName('verticalBtns'), getChildByName('downloadBtn'), getChildByName('shareBtn'));

    public function btnGroupHandler(event:Event):void {

    if (btnGroupCB.selectedLabel== "Vertical") {
    trace("selected Vertical");
    verticalBtns.visible = true;
    horizontalBtns.visible = false;
    collidableItems.splice(2,1, getChildByName('verticalBtns'))

    } else if (btnGroupCB.selectedLabel == "Horizontal") {
    trace("selected Horizontal");
    verticalBtns.visible = false;
    horizontalBtns.visible = true;
    collidableItems.splice(2,1, getChildByName('horizontalBtns'))
    trace(collidableItems)
    }
    }

  8. #48
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    If you've left the code mostly as is, then it looks like you are defining that btnGroupHandler function inside the init function. That won't work, move it outside, like any other function.

    The idea of your code seems sound, but instead of having a hardcoded index for the verticalBtns or horizontalBtns, you can use indexOf to find them.

    Code:
    public function btnGroupHandler(event:Event):void {
      var toSwapOut:DisplayObject;
      var toSwapIn:DisplayObject;
      if (btnGroupCB.selectedLabel== "Vertical") {
        trace("selected Vertical");
        toSwapIn = verticalBtns;
        toSwapOut = horizontalBtns;
      } else if (btnGroupCB.selectedLabel == "Horizontal") {
        trace("selected Horizontal");
        toSwapIn = horizontalBtns;
        toSwapOut = verticalBtns;
      }
      toSwapOut.visible = false;
      toSwapIn.visible = true;
      var where:int = collidableItems.indexOf(toSwapOut);
      if (where != -1){ //if it IS in there, remove it
        collidableItems.splice(where, 1);
      }
      where = collidableItems.indexOf(toSwapIn);
      if (where == -1){ //if it is NOT in there, add it.
        collidableItems.push(toSwapIn);
      }
      trace("collidableItems now: "+collidableItems);
    }
    Also, not to criticize too much, but whenever you are asking for help and you say something like "it doesn't work", you need to provide as much relevant information about why it doesn't work as you can. Any error messages whether at compile or runtime, or even just saying that there are no error messages.

  9. #49
    Senior Member
    Join Date
    Apr 2001
    Posts
    102
    my function wasnt inside the init function. I did however do the method indexOf for the startIndex property in splice and that seems to work i think but it doesn't seem to be removing the item.

    When i trace out the array after i have spliced it i get the following:
    ,,,[object MovieClip],[object MovieClip],[object vertical_8],[object MovieClip],[object horizontal_48]

    why does it say vertical_8 under it? and also horizontal_48? Those are not the names i gave it or the types i assigned it in the array? Should it say object MovieClip for all of them? Also why the three commas before?

    This is the code i am using:
    Code:
    public function btnGroupHandler(event:Event):void {
    
    	if (btnGroupCB.selectedLabel== "Vertical") {
    		//trace("selected Vertical");
    		verticalBtns.visible = true;
    		horizontalBtns.visible = false;
    				
    				
    	} else if (btnGroupCB.selectedLabel == "Horizontal") {
    		//trace("selected Horizontal");
    		verticalBtns.visible = false;
    		horizontalBtns.visible = true;
    		collidableItems.splice(collidableItems.indexOf("verticalBtns"), 1, getChildByName("horizontalBtns"));
    trace(collidableItems)
    	}
    }
    Any help to get this to remove the item from the array so i can drag it overtop the hidden item would be great.

    I really appreciate your help.

  10. #50
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    The three commas indicate that there are 3 empty entries in the array before the first thing you actually see. This could be because they were null when added to the array, or because the array's content has been set to null since then.

    It probably says [object vertical_8] because it's a symbol in your library. All such symbols get a class, whether you specify it or not. "vertical_8" is the classname that flash generated for that symbol.

    I notice you're not splicing in the Vertical case. That could be why you see both in the array. I suggest tracing collidableItems before the splice too, so you can see exactly how the splice affects it.

    OH! I just noticed that in your splice statement, you have index of the String "verticalBtns". The string isn't in collidableItems; the actual verticalBtns movie is. Remove the quotes. And while you're at it, get rid of the "getChildByName" call because you already have a reference to it.
    Code:
    ...
    collidableItems.splice(collidableItems.indexOf(verticalBtns), 1, horizontalBtns);
    ...

  11. #51
    Senior Member
    Join Date
    Apr 2001
    Posts
    102
    that worked but now one i tem previewObj seems to not be draggable?

    Code:
    package {
    
    	import flash.display.MovieClip;
    	import flash.display.Sprite;
    	import flash.display.DisplayObject;
    	import flash.events.MouseEvent;
    	import flash.geom.Point;
    	import flash.geom.Rectangle;
    	import flash.events.Event;
    	import fl.controls.ComboBox;
    	import fl.events.ComponentEvent;
    
    	public class Main extends flash.display.Sprite {
    		private var currentDragged:Sprite;
    		private var draggableItems:Array;
    		private var collidableItems:Array;
    		private var lastGoodPos:Point;
    
    		public function Main():void {
    
    			addEventListener(Event.ADDED_TO_STAGE, init);
    			
    		}
    
    		public function init(event:Event):void{
    			draggableItems = new Array();
    			//These items MUST be already added, or this will not work.
    			draggableItems.push(getChildByName('titleObj'), getChildByName('previewObj'), getChildByName('verticalBtns'), getChildByName('horizontalBtns'), getChildByName('downloadBtn'), getChildByName('shareBtn'));
    			collidableItems = new Array();
    			collidableItems.push(getChildByName('videoBtn'), getChildByName('wallpaperBtn'), getChildByName('ringtoneBtn'));
    			var d:DisplayObject;
    			for (var i:int = 0; i < draggableItems.length; i++){
    				d = draggableItems[i];
    				if (null == d){
    					trace('I told you, they have to be already added.  found null in draggableItems.');
    				}else{
    					collidableItems.push(d);
    					d.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
    				}
    			}
    			//addEventListener(MouseEvent.MOUSE_UP, mouseUp);
    			
    			// info button choice positioning
    			infoCB.prompt =  "select one..";
    			infoCB.addItem({label:"Top Right"});
    			infoCB.addItem({label:"Top Left"});
    			infoCB.addItem({label:"Bottom Left"});
    			infoCB.addItem({label:"Bottom Right"});
    
    			//
    			btnGroupCB.prompt =  "select one..";
    			btnGroupCB.addItem({label:"Vertical"});
    			btnGroupCB.addItem({label:"Horizontal"});
    			
    			//
    			btnPosCB.prompt =  "select one..";
    			btnPosCB.addItem({label:"Previw Left/Buttons Right"});
    			btnPosCB.addItem({label:"Previw Right/Buttons Left"});
    			
    			btnPosCB.selectedIndex = 0;
    			
    			btnGroupCB.selectedIndex = 0;
    			infoCB.selectedIndex = 0;
    
    			btnPosCB.addEventListener(Event.CHANGE, btnPosHandler);
    			btnGroupCB.addEventListener(Event.CHANGE, btnGroupHandler);
    			infoCB.addEventListener(Event.CHANGE, infoPosHandler);
    			
    			horizontalBtns.visible = false;
    			
    			collidableItems.splice(collidableItems.indexOf(verticalBtns), 1, horizontalBtns);
    			
    		}
    		
    		public function btnGroupHandler(event:Event):void {
    
    			if (btnGroupCB.selectedLabel== "Vertical") {
    				//trace("selected Vertical");
    				verticalBtns.visible = true;
    				horizontalBtns.visible = false;
    				trace("before array edited: " + collidableItems)
    				collidableItems.splice(collidableItems.indexOf(horizontalBtns), 1, verticalBtns);
    				trace("after array edited: " + collidableItems)
    				
    				
    			} else if (btnGroupCB.selectedLabel == "Horizontal") {
    				//trace("selected Horizontal");
    				verticalBtns.visible = false;
    				horizontalBtns.visible = true;
    				trace("before array edited: " + collidableItems)
    				collidableItems.splice(collidableItems.indexOf(verticalBtns), 1, horizontalBtns);
    				trace("after array edited: " + collidableItems)
    			}
    		}
    		
    		public function infoPosHandler(event:Event):void {
    
    			if (infoCB.selectedLabel== "Top Right") {
    				trace("selected top right");
    			} else if (infoCB.selectedLabel == "Top Left") {
    				trace("selected top left");
    			} else if (infoCB.selectedLabel == "Bottom Left") {
    				trace("selected bottom left");
    			} else if (infoCB.selectedLabel == "Bottom Right") {
    				trace("selected bottom right");
    			}
    		}
    		
    		public function btnPosHandler(event:Event):void {
    
    			if (btnGroupCB.selectedLabel== "Previw Left/Buttons Right") {
    				verticalBtns.x = 420;
    				verticalBtns.y = 191;
    				
    			} else if (btnGroupCB.selectedLabel == "Previw Right/Buttons Left") {
    				verticalBtns.x = 210
    				verticalBtns. y = 191
    			}
    		}
    		
    		/*
    		public function renderLayout(event:Event):void {
    			getChildByName("horizontalBtns") == new Bitmap()
    			addChild(btnsRender);
    		}
    		
    		renderBtn.addEventListener(MouseEvent.CLICK, renderLayout);
    		*/
    		
    		public function mouseDown(event:MouseEvent):void {
    			var obj:Object = event.currentTarget;
    			
    			addEventListener(MouseEvent.MOUSE_UP, mouseUp);
    			
    			if (draggableItems.indexOf(obj) != -1) {
    				currentDragged = Sprite(obj);
    				currentDragged.startDrag();
    				lastGoodPos = getPoint(currentDragged);
    				addEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
    			}
    		}
    		public function mouseUp(event:MouseEvent = null):void {
    			if (null != currentDragged) {
    				currentDragged.stopDrag();
    				currentDragged = null;
    				removeEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
    			}
    		}
    		public function mouseMove(event:MouseEvent):void {
    			var d:DisplayObject;
    			var hitSomething:Boolean = false;
    			for (var i:int = 0; i < collidableItems.length; i++) {
    				d = collidableItems[i];
    				if (currentDragged == d) {
    					continue;
    				}
    				if ((null != currentDragged) && (null != d)) {
    					if (currentDragged.hitTestObject(d) || !checkBounds(currentDragged)) {
    						//trace("ouch!  stop hitting me!");
    						var c:Sprite = currentDragged;
    						mouseUp();
    						trace("bad pos: "+getPoint(c));
    						setPosition(c, lastGoodPos);
    						hitSomething = true;
    					}
    				}
    			}
    			if (!hitSomething) {
    				lastGoodPos = getPoint(currentDragged);
    				//trace("lastGoodPos set to: "+lastGoodPos);
    			}
    		}
    		private function checkBounds(obj:DisplayObject):Boolean {
    			//assumes you have a boundsObj on stage.  Consider saving Rectangle directly.
    			var checkRect:Rectangle = boundsObject.getBounds(stage);
    			return checkRect.containsRect(obj.getBounds(stage));
    		}
    		private function getPoint(d:DisplayObject):Point {
    			return new Point(d.x,d.y);
    		}
    		private function setPosition(d:DisplayObject, p:Point):void {
    			d.x = p.x;
    			d.y = p.y;
    		}
    	}
    }

  12. #52
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    I notice you have a call to collidableItems.splice in the init function. Edit: now that it's formatted, I see a different issue. The splice call you have there will result in verticalBtns being replaced by horizontalBtns. That's all fine and dandy, except that now you'll have horizontalBtns in there twice, which will mess you up later. That's partially why I used a separate remove and add in my code which manipulated the collidableItems array, so that it wouldn't depend on the state of that array beforehand.

    I don't see why previewObj would behave differently from any of the other draggables, unless of course the preview isn't added yet when the Main is. Might want to check for typos wherever you've defined/added previewObj.
    Last edited by 5TonsOfFlax; 12-03-2007 at 07:37 PM.

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