Skip navigation
Natalie Butler
Currently Being Moderated

Random movement within an irregularly constrained sprite (EDITED)

Mar 14, 2012 12:34 PM

Tags: #random #movement #constrain #irregular #random_movement #constraint

(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.

 

More Like This

  • Retrieving data ...

Bookmarked By (0)

Answers + Points = Status

  • 10 points awarded for Correct Answers
  • 5 points awarded for Helpful Answers
  • 10,000+ points
  • 1,001-10,000 points
  • 501-1,000 points
  • 5-500 points