QLab 4 Unscramble Text Effect

Contents

Table of Contents

    Using only Applescript and QLab, create a text effect similar to that seen in "The Matrix", "War Games", "Sleepers", etc. where an "encrypted" phrase appears to be decoded one letter at a time until the phrase is ultimately "solved" by the computer and the entire decoded phrase is revealed.

    This effect works best when used with monospaced fonts. Otherwise, the width of the phrase will shrink & expand with each iteration as narrower letters such as "I" are replaced with fatter letters such as "H", and vice-versa.

    This example uses Digital-7, a monospaced font similar to that seen on an LED display. It can be obtained at http://www.1001fonts.com/digital-7-font.html

    With some revisions, this script MAY work with earlier versions of QLab; however, it was built & tested with Qlab 4.2.

    A demonstration workspace for QLab 4 may be downloaded here.

    The Applescript:

    -- UNSCRAMBLED TEXT EFFECT
    -- MattM, 25-Mar-2018
    -- v1.3
    -- Using only Applescript, create a text effect in QLab similar to that seen in "The 
    -- Matrix", "War Games", "Sleepers", etc. where an "encrypted" phrase appears to be 
    -- decoded one letter at a time until the phrase is ultimately "solved" by the 
    -- computer and the entire decoded phrase is revealed. 
    
    use AppleScript version "2.4" -- Yosemite (10.10) or later
    use scripting additions
    
    -- USER SETTABLE PROPERTIES:
    property solvedPhrase : "This Is A Test Phrase" -- the phrase when fully solved.
    property numberOfCycles : 50 -- number of iterations required to fully solve the phrase
    property cycleDelay : 0.1 -- length of pause (in seconds) between iterations
    
    -- variables used by the script
    property cyclesToSolve : 0 -- for each character, the number of iterations required to "solve"
    property solveKey : {} -- list that charts the cycle at which each letter should be solved.
    property currentPhrase : {} -- placeholder for the half-solved phrase during the current iteration.
    property outputPhrase : "" -- the version of the phrase that's used to update QLab's text cue at the end of each cycle.
    
    tell application id "com.figure53.QLab.4" to tell front workspace
        set theCue to (uniqueID of first cue whose q number is "theWordCue")
    end tell
    
    set letterList to my makeList(solvedPhrase, "") -- make a list of characters out of the phrase to solve
    
    -- make a "solve key" -- generate a random number (cyclesToSolve) for each letter in the phrase.  When the script reaches the "cyclesToSolve"-th cycle, the correct value will be filled in.
    set letterCount to (count of items in letterList)
    repeat with currentLetter from 1 to letterCount
        if item currentLetter of letterList is " " then -- treat spaces between words a little differently.  Bias the script towards solving these first so that the shape of the words starts to emerge first.
            set cyclesToSolve to (random number from (numberOfCycles div 4) to numberOfCycles div 2) -- start solving spaces between words a quarter of the way through the total number of cycles to solve the puzzle.
        else
            set cyclesToSolve to (random number from (numberOfCycles div 2) to numberOfCycles) -- start solving letters halfway through the total number of cycles required to solve the puzzle.
        end if
        set end of solveKey to cyclesToSolve -- tack the value required for each letter onto the end of the solveKey.  At the end of this repeat, we'll have a value for each letter.
    end repeat
    
    -- make a blank currentPhrase list with the number of characters we're solving.
    repeat with currentLetter from 1 to letterCount
        set end of currentPhrase to ""
    end repeat
    
    repeat with currentPass from 1 to numberOfCycles -- loop the number of times we've specified (in numberOfCycles) that should be necessary to solve the full phrase
        repeat with currentLetter from 1 to letterCount -- evaluate each character in the phrase, one letter at a time
            if item currentLetter of solveKey > currentPass then -- if it hasn't been the correct number of cycles, generate another random character for this letter.
                log "not solved"
                set randomCharacter to (random number from 65 to 90) -- A (65) thru Z (90)
                set item currentLetter of currentPhrase to (ASCII character randomCharacter)
            else -- if it's been at least as many cycles as specified in the solveKey for this character, then show the value of the correct character.
                log "solved"
                set item currentLetter of currentPhrase to (item currentLetter of letterList) -- replace the scrambled character with the correct character drawn from letterList
            end if
        end repeat
    
        -- update the displayed phrase in QLab
        tell application id "com.figure53.QLab.4" to tell front workspace
            set outputPhrase to currentPhrase as string
            set live text of cue id theCue to outputPhrase
        end tell
    
        delay cycleDelay -- user-specified pause before starting next cycle.    
    end repeat
    
    
    on makeList(theString, theDelimiter)
        -- save delimiters to restore old settings
        set oldDelimiters to AppleScript's text item delimiters
        -- set delimiters to delimiter to be used
        set AppleScript's text item delimiters to theDelimiter
        -- create the array
        set theArray to every text item of theString
        -- restore the old setting
        set AppleScript's text item delimiters to oldDelimiters
        -- return the result
        return theArray
    end makeList