Contents
Articles
Behaviors
Books
Director News
Director Web Sites
FAQ
Games
Mailing Lists
News Groups
Project Examples
Reviews
Software
Tools
Useful Web Sites
Utilities
Xtras

Don't miss these
Narration Tool
Set Quality of a Flash Sprite
Limited Fields
robotduck.com
List Maker
Twain Xtra
Custom Hyperlink Colors And Cursor Change
Download Net Thing
Color Picker MIAWs
Increasing the effeciency of playback
 

 

 

Behavior Move and/or Zoom with ease settings

Added on 5/20/2004

 

Compatibilities:
behavior

This item has not yet been rated

Author: manno (website)

This behavior lets you decide where a sprite should move to when clicked. Zooming is done while moving or after arrival. User definable values: Target location. Target width. Target height. Number of steps of animation (framebased). Movement type (linear, ease-in, -out). Ease level. Zoom or not Wait for zoom until arrival. Manno

---------------------------------------------------
--
-- MoveAndZoom
-- move (and optionally zoom) sprite after it has been clicked
--
-- movement is done from sprite's initial location to target location given in parameters dialogue
-- zoom is done to the width and height given in the parameters dialogue
-- movement and zooming can be done with either equidistance steps of ease-in or ease-out steps
-- movement is done over user defineable number of steps
-- easeing and number of steps settings are equal to both move and zoom
--
--
-- Manno Bult 2004-05-19
-- manno@xs4all.nl
-- (be kind, report bugs, remarks and usage)
--
---------------------------------------------------

property pSprite

-- movement props
property pintTargetX, pintTargetY
property plstXStep, plstYStep
-- zoom props
property pblnZoom, pblnHoldZoom
property plstWStep, plstHStep
property pintTargetWidth, pintTargetHeight
-- animation props
property pblnAnimate
property pfltEase
property psmbTweenType
property pintStepCount

---------------------------
-- event handlers
---------------------------

on beginSprite me
  
  pSprite = sprite(me.spriteNum)
  
  plstXStep = me.createMoveStepList(pSprite.loc[1], pintTargetX, pintStepCount, psmbTweenType, pfltEase)
  plstYStep = me.createMoveStepList(pSprite.loc[2], pintTargetY, pintStepCount, psmbTweenType, pfltEase)
  
  -- if sprite needs to zoom too, calculate steps
  if (pblnZoom) then
    plstWstep = me.createZoomStepList(pSprite.width, pintTargetWidth, pintStepCount, psmbTweenType, pfltEase)
    plstHstep = me.createZoomStepList(pSprite.height, pintTargetHeight, pintStepCount, psmbTweenType, pfltEase)
  end if
  
  pblnAnimate = false
  
end

on mouseUp me
  -- make sure to only animate when this sprite is clicked
  if (the ClickOn <> me.spriteNum) then exit
  pblnAnimate = true
end

on prepareFrame me
  
  if NOT(pblnAnimate) then exit
  
  -- if either of the position lists is empty, stop animating
  if (plstXStep.count > 0) OR (plstYStep.count > 0) then
    me.animateMove()
    
    if NOT(pblnHoldZoom) then
      me.animateZoom()
    end if
    
  else if (pblnHoldZoom) then
    
    if (plstWstep.count > 0) OR (plstHstep.count > 0) then
      me.animateZoom()
    else
      pblnAnimate = false
    end if
    
  else
    pblnAnimate = false
  end if
end

------------------------
-- helpers
------------------------

on animateMove me
  -- pop new x and y values of the lists
  newX = plstXStep[1]
  plstXStep.deleteAt(1)
  newY = plstYStep[1]
  plstYStep.deleteAt(1)
  -- set sprite's loc to those coords
  pSprite.loc = point(newX, newY)
end

on animateZoom me
  -- pop new width and height changes from lists
  deltaW = plstWstep[1]
  plstWstep.deleteAt(1)
  deltaH = plstHstep[1]
  plstHstep.deleteAt(1)
  -- inflate rect with those coords
  pSprite.rect = pSprite.rect.inflate(deltaW, deltaH)
end

-- create a list of zoom steps. devided by 2 for use with rect.inflate
on createZoomStepList me, dept, dest, steps, moveType, ease
  
  if (moveType = #equidistance) then
    l = me.calculateEquidistanceSteps(dept, dest, steps)
  else if (moveType = #easeout) then
    l = me.calculateEaseSteps(dept, dest, steps, ease)
  else if (moveType = #easein) then
    r = me.calculateEaseSteps(dept, dest, steps, ease)
    -- reverse array
    l = []
    c = r.count
    repeat with i = 1 to c
      l.addAt(1, r[i])
    end repeat
  end if
  
  l = l / 2
  
  l = normalizeList(l)
  
  return l
end

-- create lists of coordinates dependent on what type of movement is required
on createMoveStepList me, dept, dest, steps, moveType, ease
  l = []
  
  if (moveType = #equidistance) then
    
    -- get equidistance step distances
    l = me.calculateEquidistanceSteps(dept, dest, steps)
    
  else if (moveType = #easeout) then
    
    -- get ease step distances
    l = me.calculateEaseSteps(dept, dest, steps, ease)
    
  else if (moveType = #easein) then
    
    -- get ease step distances
    r = me.calculateEaseSteps(dept, dest, steps, ease)
    
    -- reverse array
    l = []
    c = r.count
    repeat with i = 1 to c
      l.addAt(1, r[i])
    end repeat
    
  end if
  
  -- add step distances to positions
  positions = [dept]
  c = l.count + 1
  
  repeat with i = 2 to c
    positions[i] = positions[i-1] + l[i-1]
  end repeat
  
  -- pop reference value
  positions.deleteAt(1)
  
  -- make sure last position is exactly right (damned percentages!)
  if(positions[steps] <> dest) then
    positions[steps] = dest
  end if
  
  return positions
  
end

-- create a list of equidistance integers
on calculateEquidistanceSteps me, dept, dest, steps
  
  l = []
  -- calculate distance to move
  dist = dest - dept
  -- calculate distance per step
  thisDist = dist / float(steps)
  
  repeat with i = 1 to steps
    
    -- add to list
    l.add(thisDist)
    
  end repeat
  return l
end

-- create a list of ease floats
on calculateEaseSteps me, dept, dest, steps, ease
  
  l = []
  -- calculate distance to move
  dist = dest - dept
  
  repeat while steps > 0
    
    -- calculate distance of one step from remaining distance
    thisDist = dist / float(steps)
    -- substract this step from remaining distance
    dist = dist - thisDist
    
    -- get ease percent of this step's distance
    rest = part(ease, thisDist)
    
    -- add ease percent of distance to distance of this step
    thisDist = thisDist + rest
    
    -- substract ease percent of distance from distance to go
    dist = dist - rest
    
    -- decrement step
    steps = steps - 1
    
    -- add to list
    l.add(thisDist)
    
  end repeat
  return l
end

-- make each list's entry an integer preserving the sum of the list
on normalizeList l
  
  c = l.count
  
  repeat with i = 1 to c
    
    if(floatP(l[i])) then
      flt = l[i]
      int = integer(l[i])
      remainder = flt - int
      l[i] = int
      if (i < c) then
        l[i+1] = l[i+1] + remainder
      end if
    end if
    
  end repeat
  
  return l
  
end


--  calculate which percentage part is of whole
on perc part, whole
  return (part / float(whole)) * 100
end

-- calculate how much perc is of whole
on part perc, whole
  return (perc / 100.0) * whole
end

-----------------------------
-- behavior definition
-----------------------------

on getPropertyDescriptionList me
  
  moveRange = [#equidistance, #easein, #easeout]
  -- calculate half the diagonal of stage
  w = (the Stage).rect.width / 2
  h = (the Stage).rect.height / 2
  rad = sqrt(power(w, 2) + power(h, 2)) * 2
  
  pL = [:]
  
  pL.addProp(#pintTargetX, [#format: #integer, #default: 0, #comment: "x-coordinate of the target location"])
  pL.addProp(#pintTargetY, [#format: #integer, #default: 0, #comment: "y-coordinate of the target location"])
  
  pL.addProp(#pintStepCount, [#format: #integer, #default: 0, #comment: "In how many steps should sprite move there?"])
  
  pL.addProp(#psmbTweenType, [#format: #symbol, #default: moveRange[1], #range: moveRange, #comment: "Pick a type of movement"])
  
  pL.addProp(#pfltEase, [#format: #float, #default: 0, #range: [#min:0, #max:100], #comment: "If movement is an ease movement, pick ease percentage:"])
  
  pL.addProp(#pblnZoom, [#format: #boolean, #default: false, #comment: "Should sprite zoom?"])
  pL.addProp(#pblnHoldZoom, [#format: #boolean, #default: false, #comment: "Should zoom wait untill move is done?"])
  
  pL.addProp(#pintTargetWidth, [#format: #integer, #default: 0, #range: [#min: 0, #max: rad], #comment: "Sprite's width at end of zoom"])
  pL.addProp(#pintTargetHeight, [#format: #integer, #default: 0, #range: [#min: 0, #max: rad], #comment: "Sprite's height at end of zoom"])
  
  return pL
  
end

on getBehaviorDescription me
  
  out = ""
  
  put "MoveAndZoom" & RETURN after out
  put "-- move (and optionally zoom) sprite after it has been clicked" & RETURN after out
  put "--" & RETURN after out
  put "-- movement is done from sprite's initial location to target location given in parameters dialogue" & RETURN after out
  put "-- zoom is done to the width and height given in the parameters dialogue" & RETURN after out
  put "-- movement and zooming can be done with either equidistance steps of ease-in or ease-out steps" & RETURN after out
  put "-- movement is done over user defineable number of steps" & RETURN after out
  put "-- easeing and number of steps settings are equal to both move and zoom" & RETURN after out
  put "-- " & RETURN after out
  put "--" & RETURN after out
  put "-- Manno Bult 2004-05-19" & RETURN after out
  put "-- manno@xs4all.nl" & RETURN after out
  put "-- (be kind, report bugs, remarks and usage)" & RETURN after out
  
  return out
  
end

 


Contact

MMI
36 South Court Sq
Suite 300
Newnan, GA 30263
USA

Send e-mail