Making a Puzzle Template

  1. Open Flash and create a new document


  2. Open the Properties Window if it is not already opened



  3. Click on Size to change the document's size:



  4. Change the document size to 650 x 400



  5. Select the Rectangle Tool



  6. Select No Stroke



  7. Select any fill color



  8. Draw a rectangle of any size then select the shape with the Selection Tool and adjust properties in the Properties Window. Make the rectangle 550x300



  9. Click on frame two and insert an blank keyframe (F7)



  10. Click on frame 1


  11. Select the lasso tool



  12. Cut out a puzzle piece from one corner of the rectangle



  13. CTRL+click or Right click on the piece and convert it to a movie clip. While the dialog box is open, name it piece0



  14. Click on Export for Actionscript



  15. In the Properties Window to name the instance a0



  16. Press +X to cut the piece, then click on frame 2 and Paste-in-Place (-Shift-V). (This instance serves to record the position of this piece in the final puzzle. When the Flash movie is published, a script will use this information to make a real picture-bearing puzzle piece, and then will delete this instance).



  17. Repeat the cutting-out process until you've dissected the entire rectangle into movie clips. Remember to name each piece piece0, piece1, piece2, etc.. Do not make more than 20 pieces.


  18. Insert a new Symbol



  19. Name it something like startScreen



  20. Make sure you are in Scene 1


  21. Click on frame 1


  22. Open Library ( +L) and drag an instance of your startScreen movie clip into frame 1. In the Properties Window adjust position



  23. Also in the Properties Window name the instance ss



  24. Double click on the movie clip, you should now be inside startScreen



  25. Add content including a button (you can make your own or find one in Common Libraries). You need to name the instance of your "button" startBtn



  26. Click on scene 1 to get out of your movie clip



  27. Add a new layer



  28. Double click on the layer name and rename it ACTIONS



  29. Click in frame 1 of the ACTIONS layer and open the Actionscript window by clicking on the arrow in the Properties Window:



  30. In the Actionscript window add:
    stop();
    _root.ss.startBtn.onRelease = function() {
        this._visible = 0;
        _root.gotoAndPlay(2);
    };
     



  31. Insert a new Symbol and name it like this:



  32. Save your movie as puzzleTemplate


Adding Sound

  1. Open Audacity and create two wav files, one for pickin up a puzzle piece and one for placing it. If creating your own sound files, save them in your work folder in your folder. (You can also look in demos_and_samples:sounds).


  2. Import sounds to Flash:



  3. Set the linkage to Export for ActionScript (CTRL+click on the sound in the library)


Your Puzzle Content

You have to create 2 swf files. Either or both can be animations. Think of one as your puzzle and one as your main content (the swf that will be displayed after the puzzle is completed). A faded version of your main content will be displayed under where the puzzle pieces should be placed.

If your puzzle is a static image, you will copy the image (the puzzle image) and place it in the first frame of main content.

puzzle.swf—More Information
  1. Create a new Flash document.



  2. Open the Properties Window if it is not already opened



  3. Click on Size to change the document's size:



  4. Change the document size to 550 x 300



  5. Select the Rectangle Tool



  6. Select No Stroke



  7. Select a fill color for your background (if you leave it white, you will not be able to see the edges of the puzzle pieces)



  8. Draw a rectangle of any size then select the shape with the Selection Tool and adjust properties in the Properties Window



  9. This movie can be a static image or an animation. Either way, remember to use layers.



  10. Save file as puzzle in your work folder, but either Export the swf or create an swf (+RETURN). In either case, you will have to move the swf over to your web folder.



main_content.swf—More Information

  1. Create a new Flash document.


  2. Open the Properties Window if it is not already opened



  3. Click on Size to change the document's size:



  4. Change the document size to 550 x 230



  5. If your puzzle.swf is a static image copy all the layers (+C)



  6. Click on frame 1 and paste in place (+SHIFT+V)


  7. Insert a blank keyframe at frame 10


  8. Create a new layer



  9. Name the layer ACTIONS


  10. Click in frame 1 of the actions layer and add the following in the actioscript window:
    stop();
    



  11. Create your main content in frame 10. If you create an animation in the timeline, on the last frame add another script:
    this.gotoAndPlay(10);
    


    If your animation is inside a movie clip on frame 10 then include this script:
    stop();
    



  12. Save file as main_content in your work folder, but either Export the swf or create an swf. In either case, you will have to move the swf over to your web folder.


.as File

This movie uses a class file. Remember the empty movie clip called PuzzlePieceSymbol? This is the script that makes it work. These files are text based and live in the same folder as your flash files.
  1. Open a new actionscript file


  2. Paste the following in the blank document:
      class PuzzlePiece extends MovieClip {
    
        // static (class) properties set by script in the .fla 
        static var puzzleContent : String;
        static var upClick : Sound;
        static var downClick : Sound;
        static var tol : Number;
        static var pieces : Array; 
    
        // static (class) properties for internal use
        private static var maxDepth : Number = 100;
    
        // object properties
        var templatePiece : MovieClip;        // original piece on stage
        var mask : MovieClip;                // the mask for this clip
        var maskPiece : MovieClip;            
        var holder : MovieClip;
        private var _index : Number;
        private var draggable : Boolean = false;  // whether piece is draggable
    
    
        public function PuzzlePiece() {
        }
    
        function init(templatePiece : MovieClip, index : Number) : Void {
            _index = index;    
    
            // make a holder movie clip, and load content into it 
            holder = this.createEmptyMovieClip("holder", 1);
    
            holder.loadMovie(puzzleContent);
    
            //create a mask, and attach the puzzle piece to the mask
            createEmptyMovieClip("mask", 2);
            mask.attachMovie("piece" + index, "piece" + index,  index);
            maskPiece = mask["piece" + index];    // reference to the mask piece
            maskPiece.number = index;        // the piece knows its own number
            setMask(mask);
    
            // move the puzzle piece to its proper position
            this.maskPiece._x = templatePiece._x;
            this.maskPiece._y = templatePiece._y;
    
            // remove the original piece
            templatePiece.swapDepths(99);
            templatePiece.removeMovieClip();
    
            // add this piece to the array of pieces
            pieces.push(this);
    
            // update MaxDepth
            maxDepth = Math.max(maxDepth, this.getDepth());
            
            // assign functions to call on press and release
            this.onPress = pressFunction; 
            this.onRelease = this.onReleaseOutside = releaseFunction;
        }    
    
        public function toString() : String {
        return ("puzzle piece " + _index);
        }
    
        private function pressFunction() {
        if(!draggable) return;
        this.swapDepths(++maxDepth);     // bring piece above other pieces
        downClick.start();                // emit click sound
        this.startDrag();                // start dragging the piece
        delete this.onEnterFrame;            // cancel randomization
        }
    
        private function releaseFunction() {
        if(!draggable) return;
        upClick.start();                // emit a lower-pitched click
        this.stopDrag();                // stop dragging
    
        // check for connection to neighboring pieces
        var otherPiece : MovieClip;
        var maskPiece : MovieClip;
        for(var j in pieces) {
            otherPiece = pieces[j];
            if(otherPiece == this) continue;        
            if( !this.mask.hitTest(otherPiece.mask) ) continue;     
            if( Math.abs(this._x - otherPiece._x) > tol || Math.abs(this._y - otherPiece._y) > tol ) continue;
            for(var m in otherPiece.mask) {
                maskPiece = otherPiece.mask[m];
                var n = this.mask.attachMovie("piece" + maskPiece.number, "piece" + maskPiece.number, maskPiece.number);
                n.number = maskPiece.number;
                n._x = maskPiece._x;
                n._y = maskPiece._y;
            }
            pieces.splice(parseInt(j), 1);
            otherPiece.removeMovieClip();
        }
        _root.checkForCompletion();
        }
    }
    



  3. Save this file as PuzzlePiece.as in the same folder as yor swf files in your web folder.


PuzzleTemplate.fla

  1. Open your PuzzleTemplate.fla file


  2. In frame 2 of the ACTIONS layer add a blank keyframe.


  3. Open the actionscript window:



  4. Copy, paste and complete the following:
    stop();
    
    puzzleContent = "puzzle.swf";
    mainContent = "main_content.swf";
    
    //how many puzzle pieces do you have
    numPieces = ___;
    
    // tolerance (in pixels) for placement of pieces 
    PuzzlePiece.tol = 16;
    
    // set up sounds as class properties of PuzzlePiece class
    PuzzlePiece.downClick = new Sound();
    
    //the sound you want to play on mouseDown
    PuzzlePiece.downClick.attachSound("_____");
    
    PuzzlePiece.upClick = new Sound();
    
    //the sound you want to play on mouseUp
    PuzzlePiece.upClick.attachSound("_____");    
    



  5. Copy, paste and complete the following:
    /***************************************************************
        Preload the puzzle image
    ***************************************************************/
    
    p = _root.createEmptyMovieClip("picture", 1);
    
    h = p.createEmptyMovieClip("holder", 1);
    
    makePuzzle();
    
    /* used for delaying randomization process
    if you want to see the puzzle before 
    breaking it up in pieces use this code
    select a number between 5 and 100 (5 is fastest)*/
    //randomizeInt = setInterval(randomize, __);
    
    /*otherwise use this line*/
    //randomize();
    
    
    loader = new MovieClipLoader();
    loader.addListener(loadListener);
    loader.loadClip(puzzleContent, h);
    



  6. Copy, paste and complete the following:
    /***************************************************************
            Cut the puzzle image into individual pieces
    ***************************************************************/
    function makePuzzle() {
        // initialize the class array "pieces," that holds references 
        //to all puzzle pieces
        PuzzlePiece.pieces = new Array();
        PuzzlePiece.puzzleContent = puzzleContent;
        
        /* Because PuzzlePiece is a subclass of MovieClip, instances are
        created by using attachMovie.  Since this process passes no
        parameters to the constructor, you need to call an initialization
        function separately. */
        //create a loop that loop for each number of pieces
        //(use the variable from the top of the script)
        for (i=0; i<___________; i++) {
            piece = _root.attachMovie("PuzzlePieceSymbol", ["piece"+i], 100+i);
            piece.init(_root["a"+i], i);
        }
        
        // Now that  all the puzzle pieces are on the screen, 
        //you want to dim the original image
        //select a number between 1 and 20 (1 being most transparent)
        p._alpha = __;
        
        /* The main content will be displayed after 
        the puzzle is completed.  As this can be a large
        file, you can load it while the puzzle is being solved*/
        loadListener.onLoadComplete = null;
        loadListener.onLoadProgress = null;
        loader.loadClip(mainContent, h);
    }



  7. Copy, paste and complete the following:
    /***************************************************************
        Check whether the puzzle is finished.  This function is
        called whenever a puzzle piece is released.
    *************************************************************/
    function checkForCompletion() {
        // check if puzzle is done
        if (PuzzlePiece.pieces.length>1) {
        //not done
            return;
        }
        
        // puzzle is done so stop the timer
        clearInterval(timerInt);
        
        
        // remove the completed puzzle, and show the post-completion content
        PuzzlePiece.pieces[0].removeMovieClip();
        
        //reset the alpha to 100%
        p._alpha = ____;
        
        //go to the second frame of your main_content
        p.holder.gotoAndPlay(___);
    }
    



  8. Copy, paste and complete the following:
    /***************************************************************
        Scatter the puzzle pieces. 
    ***************************************************************/
    function randomize() {
        clearInterval(randomizeInt);
        
        // start the timer
        timerInt = setInterval(displayTime, 1000);
        startTime = getTimer();
        
        /* Each puzzle piece has its registration point at (0, 0), but
        that isn't necessarily where its visible content is.  You have to choose 
        a random position which keeps the visible content, determined by the
        maskPiece, on the stage.  */
        for (i in PuzzlePiece.pieces) {
            s = PuzzlePiece.pieces[i];
            s.xr = Math.random()*(Stage.width-50)-s.maskPiece._x;
            s.yr = Math.random()*(Stage.height-50)-s.maskPiece._y;
            
            //every time the playhead enters the frame 
            //you want to call the function gotoDestination
            //which will gradually move the pieces
            s.onEnterFrame = goToDestination;
            
            //you want the piece to be draggable
            s.draggable = _____;
        }
    }
    // Function to move gradually to a destination given by (this.xr, this.yr)
    function goToDestination() {
        this._x = this._x*.7+this.xr*.3;
        this._y = this._y*.7+this.yr*.3;
        if (Math.abs(this._x-this.xr)<2 && Math.abs(this._y-this.yr)<2) {
            this._x = this.xr;
            this._y = this.yr;
            
            //once the pieces have arrived
            //you delete this.xr,this.yr and this.onEnterFrame
            delete this.xr;
            delete ________;
            delete this.onEnterFrame();
        }
    }
    



  9. Copy, paste and complete the following:
    /******************************************
         display a timer at runtime
    *******************************************/
    
    //movieClip.createTextField(instanceName, depth, x, y, width, height)
    _root.createTextField("timer_txt", 8, ___, Stage.height-60, ___, ____);
    
    
    timer_txt.autoSize = "left";
    
    //format the text
    fmt = new TextFormat();
    //font size
    fmt.size = ___;
    
    //font
    fmt.font="____";
    
    //embed the font
    fmt.embedFont=_____;
    
    //set the text
    timer_txt.setNewTextFormat(fmt);
    
    
    function displayTime() {
        s = Math.floor((getTimer()-startTime)/1000);
        m = Math.floor(s/60);
        s -= m*60;
        
        ss = String(s);
        if (ss.length<2) {
            ss = "0"+ss;
        }
        timer_txt.text ="time taken= "+ m+":"+ss;
    }
      
      



  10. Save and publish (make sure you have the following files in the same location:
    • puzzleTemplate.html
    • puzzleTemplate.swf
    • puzzle.swf
    • main_content.swf
    • PuzzlePiece.as



  11. Update homepage to include link to assignment