Articles Archive
Articles Search
Director Wiki
 

Automating Your Authoring, Part 2

July 18, 2001
by Danny Kodicek

Last week, we started our look at using Lingo behind the scenes, in the authoring mode. This week, we'll push Lingo's use as a production tool a little farther, by using it for Score Recording: altering the movie's Score programmatically.

One technique can be illustrated by this utility, which takes a flat Flash movie (flat in the sense that all animation occurs in one timeline - the technique will only work in this case) and converts it to a set of sequentially-numbered bitmaps at the end of the Internal cast. The special trick here is to use the posterframe property of Flash members, which specifies the default frame of the Flash member used to display it in the cast. This is the frame which is called up when you ask for the image of the Flash member.

Warning: Getting the image of Flash members was broken in the Shockwave 8 player. This has been fixed in 8.5, but it is safest to restrict this technique to authoring and Projectors until 8.5 has reasonable coverage.

on createflashframes mem

  if stringp (mem) or integerp (mem) then mem = member (mem)
  f = mem.framecount
  l = string (f).length - 1
  start = (the number of members of castlib 1)
  repeat with i = 1 to f
    mem.posterframe = i
    m = new (#bitmap, member ( start + i, 1))
    m.image = mem.image
    n = string (i)
    repeat with j = n.length to l
      put "0" before n
    end repeat
    
    m.name = mem.name & "." & n
  end repeat

end

Changing the Score

All the changes I've described so far affect the Cast -- altering and creating new cast members. Director also uses a number of special commands which allow you to make changes at author time to the Score. These come under the heading of Score Recording. This is not the time to go into Score Recording in detail - it's been covered before, but I'm going to give a few simple examples to round off the discussion.

As before, I'm mostly interested in using Score Recording as a means to simplify those boring, mechanical tasks. How about this one: Your score includes a number of Flash movies, but you're concerned about performance rather than file size, so you decide to convert them all into bitmaps. Let's adapt the behaviour above and use it for a Score Recording session. We'll assume that your Flash movies are all based in single frames with a looping behaviour in the framescript. Now we'll use a script that searches through the score for Flash movies, then if it finds them it creates a set of bitmaps using the createflashframes handler we used before (actually, I'm using a slightly simplified version which names the Flash frame's name.1, name.2, etc, rather than name.001, name.002, etc), removes the framescript, stretches out the frames to fit the length of the animation and places the bitmaps sequentially in the channel.

on convertflash

  beginrecording
    lst = the lastframe
    repeat with i = 1 to lst
      go to frame i
      repeat with j = 1 to the lastchannel
        if sprite (j).type <> 0 then
          mem = sprite (j).member
          if mem.type = #flash then
            f = mem.framecount
            if member (mem.name & "." & f).number = -1 then
              createflashframes2 (mem)
            end if
            the framescript = void
            lst = lst+f-1
            i = i+f-1
            sprite (j).member = member (mem.name & ".1")
            repeat with k = 2 to f
              insertframe
              sprite (j).member = member (mem.name & "." & k)
            end repeat
            exit repeat
          end if
        end if
      end repeat
    end repeat
  endrecording

end

on createflashframes2 mem

  if stringp (mem) or integerp (mem) then mem = member (mem)
  f = mem.framecount
  start = (the number of members of castlib 1)
  repeat with i = 1 to f
    mem.posterframe = i
    m = new (#bitmap, member (start + i, 1))
    m.image = mem.image
    
    m.name = mem.name & "." & i
  end repeat

end

Obviously, this is highly simplified - you might want to try making a more versatile script which can deal with multiple Flash movies on the same frame, or movies which span more than one frame.

As I say, I'm not going to go into Score Recording in any more detail - there's a lot of it, and in many ways, all the same advice as in the previous sections applies just as well here. Look into the scoreSelection property, for example, to perform the same function as the selection of castlib property, restricting your Score Recording operations to the sprites you have selected. But just for fun, here's one final script on the Flash-to-bitmap theme. This one finds all Flash movies and converts them to a film loop of bitmaps, which it places in the score in the same place. Again, this is only an example, and if you really wanted to do something like this you'd probably be advised to play with it a bit.

This is the most complicated script here, but conceptually it's not much harder than the previous one. The only clever part is the creation of the filmloops. What I do is to copy the Score into a dummy film loop. Then I clear the score, create the Score of my film loop and copy it in, then restore the original. The complication is that setting the Score from the media of a film loop doesn't work during Score Recording, so I have to skip out of the Score Recording session to update everything. Don't worry about this too much if you're confused - it's a pretty obscure technique!

on convertflash2

  l = []
  beginrecording
    lst = the lastframe
    repeat with i = 1 to lst
      go to frame i
      repeat with j = 1 to the lastchannel
        if sprite (j).type <> 0 then
          mem = sprite (j).member
          if mem.type = #flash then
            f = mem.framecount
            if member (mem.name & "." & f).number = -1 then
              createflashframes2 (mem)
            end if
            m = new (#filmloop)
            m.name = mem.name && "loop"
            l.add ([mem, m, sprite (j).loc])
            sprite (j).member = m
          end if
        end if
      end repeat
    end repeat
  endrecording
  sc = new (#filmloop)
  sc.media = the score
  repeat with loops in l
    the score = loops[2].media
    beginrecording
      repeat with k = 1 to f
        go to frame k
        sprite (1).member = member (loops[1].name & "." & k)
        sprite (1).loc = loops[3]
      end repeat
      updateframe
    endrecording
    loops[2].media = the score
  end repeat
  the score = sc.media
  erase sc

end

Well, I hope this trawl through a few possibilities has given you some idea of the power of this technique. In general (Score Recording aside), the Lingo involved tends to be quite simple. The trick lies in recognising when you are doing something repetitive and how you can automate it. Keep watching what you're doing, and any time you're getting bored with something, there's probably a way to save yourself the effort. And after a while, you'll have built up a library of time-saving scripts which will be useful to you many a time in the future.

A text file containing the scripts for this article is available. Just copy and paste into your Script window.

Danny is a mathematician by training, an occasional writer, actor and, for the last four years, programmer. He is self-taught in Director and it occasionally shows. He is part of the company Wellspring Interactive Ltd and has just finished working as Head of Clues on their first major project, TimeHunt.

Copyright 1997-2017, Director Online. Article content copyright by respective authors.