Director Tutorials

 

User Tracking with Lists

Lists can be useful to keep track of a user’s path through your presentation, recording the precise order and number of locations visited. If you would like more explantaion of what lists are and related list Lingo, see the The Power of Lists - List Lingo technote.

Open FruitPath.dir and play the movie.

Here’s the movie script:

global gMarkerSequence, gPosition

on startMovie 
  gMarkerSequence = []
  member("sequenceList").text = ""&gMarkerSequence
  gPosition = 1
end

on recordMarker2List
  -- add the Marker (framelabel) to the list
  add(gMarkerSequence, the framelabel)
  -- put the list data into the text member
  -- "sequenceList"using "" to signifying the start of
  -- data (which includes nothing), then '&' to add
  -- the variable data
  member("sequenceList").text = ""&gMarkerSequence
end

on backOne
  -- check there is values in the list to retrace
  if count(gMarkerSequence) then
    -- go to the marker at the end of the list
    go to getLast(gMarkerSequence)
    -- delete the marker at the end of the list
    -- there is not deleteLast() command so
    -- we will need use count(gMarkerSequence)
    -- to return the last value on the list
    -- we can then delete it.
    deleteAt(gMarkerSequence,count(gMarkerSequence))
    member("sequenceList").text = ""&gMarkerSequence
  end if
end

on back2Position
  -- put the number entered into a variable
  -- to identify the position you want to backtrack to
  -- data needs to be converted to a value
  -- e.g. 2 from "2"
  gPosition = value(member("positionID").text)
  -- check poition exists on list
  if count(gMarkerSequence) >= gPosition then
    -- go to the marker at the position specified
    go to (getAt(gMarkerSequence, gPosition))
  else
    alert "That position does not exist!"
  end if 
end

The startMovie handler sets up an empty list variable (gMarkerSequence) and sets the starting postion (gPosition) to 1.
The recordMarker2List handler records the current marker and adds it to the list.
The backOne handler checks if any numbers are in the list, and goes back one from the list.
The back2Position handler goes back to the position entered by the user.

You will notice as you click a fruit on the plate, data is added to the list. The data added is the last position (marker) visited, rather than the new one you enter. We will now adjust how this movie works.

1. With FruitPath.dir open, click on the banana sprite on the plate and then open the Behavior Inspector.

2. You will notice two behaviors are attached to the sprite. Click in the 'go to banana' behavior and then click the Script Window button.

3. The following script appears in the script window
on mouseUp
  recordMarker2List
  go to "banana"
end

Before the behavior sends the playback head to the new location, it records the old one to the list. Delete the line recordMarker2List.

4. Change the 'go to apple', 'go to avocado' and 'go to orange' behaviors in the same way as step 3 above.

5. In the Score, you will notice a frame behavior under each marker in the script channel. This is a 'Hold on Frame' behavior. For each marker, move the frame behavior one frame to the right.

6. Double-click frame 1 of the scripting channel and enter the following:
on enterFrame
  recordMarker2List
end

7. Copy and paste this behavior to frames 10, 20, 30 and 40 i.e., place the behavior under each marker in the script channel.

8. Rewind and play the movie. Now when you click on each fruit the list records the location you go to. But there is a problem. Click 'backtrack one' button. Nothing seems to happen. This is because you are going to the last marker, which is in fact one frame earlier and at that frame the marker is added to the list.

9. Open the movie script and change the backOne handler to
on backOne
  global gMarkerSequence
  -- check there is values in the list to retrace
  if count(gMarkerSequence) > 1 then
    -- delete the marker at the end of the list
    -- there is not deleteLast() command so
    -- we will need use count(gMarkerSequence)
    -- to return the last value on the list
    -- we can then delete it.
    deleteAt(gMarkerSequence,count(gMarkerSequence))
    member("sequenceList").text = ""&gMarkerSequence
    -- go to the following frame after the marker at
    -- the end of the list 
    go to label(getLast(gMarkerSequence))+1
  end if
end

The first change made is to check that there is at least 2 values in the list (greater than 1). The list will always have one value as the movie begins at a marker where a value is added. A second value is important as you will see later.

The second change is to delete the last value of the list before backtracking. This will allow us to go to the 'real' previous marker, rather than just the pervious frame.

The last change is to send the playback head to one frame after the last marker on the list. This will allow us to backtrack without the marker being added to the list. Using the function label( ), a value is returned indicating the frame number of the marker. This allows us to add 1 to that number. Director would not understand "markerName" + 1

The reason why we need 2 values on the list is because when we delete one, we tell Director to go to the last value on on the modified list. If there is only one value on the list (as in the start of the movie) that value won't be removed from the list, allowing the list to always remain at 1 as a minimum.

10. Rewind and play the movie. The completed movie can be found at FruitPathFin.dir.

11. On your own, change the script so that the 'go to position' button goes to a frame after the marker so does not add the marker to the list again

12. Doubleclick the frame behavior under any marker and change the script to:
on exitFrame
  recordMarker2List
  global gMarkerSequence
  NoTimesVisited = 0
  repeat with x = 1 to count(gMarkerSequence)
    if getAt(gMarkerSequence, x) = the frameLabel then
      NoTimesVisited = NoTimesVisited + 1
    end if
  end repeat
  if NoTimesVisited > 1 then
    alert "You have visited this section before!"
  end if
end

This script checks to see if the marker has appeared on the list more than once and tells the user if they have.

Welcome to the use and power of lists:)