Random movement within an irregularly constrained sprite (EDITED)
Mar 14, 2012 12:34 PM
Tags: none (add) #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.




