0 Replies Latest reply: Mar 14, 2012 12:34 PM by Natalie Butler RSS

    Random movement within an irregularly constrained sprite (EDITED)

    Natalie Butler

      (NEW EDIT AT BOTTOM)

       

      So, basically, I'm making a little program that crudely simulates an ant colony. I have little tunnels the ant-sprites can travel down, as well as chambers, in an irregularly-shaped sprite.

       

      I am not the most advanced at Director, but at least I've figured some things out. I found code on an open-source website (openspark, actually) that allows for an object to be dragged inside an irregular shape that has a matte ink.

       

      It's all well and good that the ants can be dragged within this boundary, but is there any way to have them use a Random Movement and Rotation behavior that is confined by the same laws? Or is that impossible / extremely hard?

       

      By the way, I already have a middleman behavior I use to toggle between dragging and random movement, so that does not factor into my question. I just need to know how to alter the Random Movement behavior so that it abides by the same constraint rules as my dragging behavior, if possible.

       

      Here is the code I'm using for dragging. I made a couple edits from the original, but not much.

      Don't worry about the canJumpGaps function of this code, as I am using a touch screen and it will never be used.

       

       

       

      property spriteNum

      property canJumpGaps    

      -- set to TRUE on mouseDown if the shiftDown

      property pSprite

      -- this draggable sprite

      property pConstraintSprite

      -- sprite to which this sprite is constrained

      property pConstraintAlpha

      -- alpha channel image of constraining member

      property pOffset

      -- offset between this sprite's loc and the mouse

      property pCurrentLoc

      -- last known position of this draggable sprite with respect to the constraining sprite

       

       

      -- EVENT HANDLERS --

       

      on beginSprite(me)

        pSprite  = sprite(spriteNum)

        pConstraintSprite = sprite(1)

       

        -- We'll use the value of the alpha channel to detect holes in the sprite

        pConstraintAlpha  = pConstraintSprite.member.image.extractAlpha()

      end beginSprite

       

       

       

      on mouseDown(me)

        canJumpGaps = the shiftDown

       

        if not pCurrentLoc then

          -- The user has not yet dragged the sprite anywhere.  Find out its

          -- current position with respect to the constraint sprite.

          pCurrentLoc = pConstraintSprite.mapStageToMember(pSprite.loc)

       

          if not pCurrentLoc then

            -- The mouse is not over an opaque part of the constraint

            -- sprite.  It can't be dragged at all.

            exit

          end if

        end if

       

        -- Start dragging

      pOffset = pSprite.loc - the mouseLoc

      end mouseDown

       

       

       

      on exitFrame(me)

        if not pOffset then

          -- The user is not dragging the sprite

          exit

        end if

       

      if the mouseDown then

          me.mMoveSprite()

        else

          -- The user just released the mouse

         pOffset = 0

        end if

      end exitFrame

       

       

       

       

      -- PRIVATE METHOD --

       

      on mMoveSprite(me) ---------------------------------------------------

        -- SENT BY exitFrame()

        -- ACTION: Calculates how near to the current mouseLoc the draggable

        --         sprite can be dragged.

        --------------------------------------------------------------------

       

        tMouseLoc = the mouseLoc + pOffset

        -- Find where the mouse is with respect to the constraint member

      tImageLoc = pConstraintSprite.mapStageToMember(tMouseLoc)

       

        if voidP(tImageLoc) then

          -- The mouse is currently outside the constraint sprite.  Use a

          -- slower but more powerful method of determining the relative

          -- position.

          tLeft = pConstraintSprite.left

          tTop = pConstraintSprite.top

          tImageLoc = tMouseLoc-point(tLeft, tTop)

       

        else if canJumpGaps then

          -- Check if the mouse is over a non-white area of the constraint

          -- member

         tAlpha = pConstraintAlpha.getPixel(tImageLoc, #integer)

        end if

       

        if tAlpha then

          -- Let the mouse move to this spot

       

      else -- Can't jump gaps or the mouse is over a gap

       

          -- Find how near the dragged sprite can get

          tDelta  = pCurrentLoc - tImageLoc

          tDeltaH = tDelta.locH

          tDeltaV = tDelta.locV

       

          tSteps = max(abs(tDeltaH), abs(tDeltaV))

          if not tSteps then

            -- The mouse hasn't moved since the last exitFrame

            exit

          end if

       

          tSteps = integer(tSteps)

      if float(tSteps) <> 0 then

      tStep  = tDelta / float(tSteps)

      -- This makes sure I'm not dividing by zero.

      else

      tStep  = 1

      end if

       

      repeat while tSteps

      -- Move one pixel towards the mouse

      tSteps = tSteps - 1

      tLoc = tImageLoc + (tStep * tSteps)

       

      -- Test that we are still on an opaque area

      tAlpha = pConstraintAlpha.getPixel(tLoc, #integer)

      if not tAlpha then

      -- We've gone a step too far: move back to an opaque area

      tSteps = tSteps + 1

      exit repeat

      end if

      end repeat

      end if

       

      -- Update the absolute and relative positions of the draggable

      -- sprite.

      tAdjust     = tSteps * tStep

      pCurrentLoc = tImageLoc + tAdjust -- relative to constrain sprite

      tMouseLoc   = tMouseLoc + tAdjust -- relative to the stage

       

      -- Move the sprite

      pSprite.loc = tMouseLoc

      end mMoveSprite

       

       

       

       

      Thank you SO incredibly much to anyone who can help. This is for a senior project of mine in undergrad, and I really appreciate any help I can get. My resources on Director are limited, especially for odd issues like this.

       

      ----

       

      EDIT:

       

      So I found out that a way to do collision detection in Director is by using getPixel().

      I found this protected dcr file that is a perfect example of the way in which I want my ant objects to interact with walls:

      http://xfiles.funnygarbage.com/~colinholgate/dcr/irregular.dcr

       

      I've been trying to build a getPixel() collision detection mechanism for hours but have been unsuccessful.

       

      Basically, what I want the behavior to do is... get the pixel color of the tunnel sprite (sprite 2) at the center of the ant sprite. If the pixel color is white (the transparent background color surrounding the tunnel shape), I want to tell the Random Movement and Direction behavior this:

       

      pSprite.pPath = VOID

      sendSprite(pSprite, #mNewPath)

      pSprite.pRotate = VOID

      sendSprite(pSprite, #mNewRotation)

       

      This tells the Random Movement behavior to stop moving and determine a new path. The behavior should probably also offset the center of the sprite by a couple pixels when this happens so it is no longer over an opaque area and the Random Movement behavior won't get stuck.

      Will this work? If not, could anyone help me in building a collision detection behavior based on getPixel? This doesn't seem like it'd be all that difficult - at least in theory.